diff options
-rw-r--r-- | arch/arm/dts/armada-3720-db.dts | 2 | ||||
-rw-r--r-- | arch/arm/dts/armada-3720-espressobin.dts | 30 | ||||
-rw-r--r-- | arch/arm/dts/armada-3720-turris-mox.dts | 2 | ||||
-rw-r--r-- | board/Marvell/mvebu_armada-37xx/board.c | 109 | ||||
-rw-r--r-- | configs/mvebu_espressobin-88f3720_defconfig | 5 | ||||
-rw-r--r-- | doc/README.marvell | 40 | ||||
-rw-r--r-- | drivers/mmc/xenon_sdhci.c | 79 | ||||
-rw-r--r-- | drivers/pci/Kconfig | 1 | ||||
-rw-r--r-- | drivers/pci/pci-aardvark.c | 29 | ||||
-rw-r--r-- | include/configs/mvebu_armada-37xx.h | 15 |
10 files changed, 284 insertions, 28 deletions
diff --git a/arch/arm/dts/armada-3720-db.dts b/arch/arm/dts/armada-3720-db.dts index 1b219c423b..1b1b66b94d 100644 --- a/arch/arm/dts/armada-3720-db.dts +++ b/arch/arm/dts/armada-3720-db.dts @@ -159,6 +159,6 @@ &pcie0 { pinctrl-names = "default"; pinctrl-0 = <&pcie_pins>; - reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/dts/armada-3720-espressobin.dts b/arch/arm/dts/armada-3720-espressobin.dts index 84e2c2adba..4534f5ff29 100644 --- a/arch/arm/dts/armada-3720-espressobin.dts +++ b/arch/arm/dts/armada-3720-espressobin.dts @@ -67,18 +67,29 @@ device_type = "memory"; reg = <0x00000000 0x00000000 0x00000000 0x20000000>; }; + + vcc_sd_reg0: regulator@0 { + compatible = "regulator-gpio"; + regulator-name = "vcc_sd0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-type = "voltage"; + states = <1800000 0x1 + 3300000 0x0>; + gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>; + }; }; &comphy { max-lanes = <3>; phy0 { - phy-type = <PHY_TYPE_PEX0>; - phy-speed = <PHY_SPEED_2_5G>; + phy-type = <PHY_TYPE_USB3_HOST0>; + phy-speed = <PHY_SPEED_5G>; }; phy1 { - phy-type = <PHY_TYPE_USB3_HOST0>; - phy-speed = <PHY_SPEED_5G>; + phy-type = <PHY_TYPE_PEX0>; + phy-speed = <PHY_SPEED_2_5G>; }; phy2 { @@ -110,6 +121,15 @@ status = "okay"; }; +&sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + bus-width = <4>; + cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; + vqmmc-supply = <&vcc_sd_reg0>; + status = "okay"; +}; + &spi0 { status = "okay"; pinctrl-names = "default"; @@ -145,6 +165,6 @@ &pcie0 { pinctrl-names = "default"; pinctrl-0 = <&pcie_pins>; - reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts index 0f0a6ce65d..974270cc8c 100644 --- a/arch/arm/dts/armada-3720-turris-mox.dts +++ b/arch/arm/dts/armada-3720-turris-mox.dts @@ -172,6 +172,6 @@ &pcie0 { pinctrl-names = "default"; pinctrl-0 = <&pcie_pins>; - reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; status = "disabled"; }; diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c index 9bea1986d4..7b9c3223ed 100644 --- a/board/Marvell/mvebu_armada-37xx/board.c +++ b/board/Marvell/mvebu_armada-37xx/board.c @@ -44,6 +44,7 @@ DECLARE_GLOBAL_DATA_PTR; /* Switch Port Registers */ #define MVEBU_SW_LINK_CTRL_REG (1) #define MVEBU_SW_PORT_CTRL_REG (4) +#define MVEBU_SW_PORT_BASE_VLAN (6) /* Global 2 Registers */ #define MVEBU_G2_SMI_PHY_CMD_REG (24) @@ -207,8 +208,16 @@ int board_network_enable(struct mii_dev *bus) * FIXME: remove this code once Topaz driver gets available * A3720 Community Board Only * Configure Topaz switch (88E6341) + * Restrict output to ports 1,2,3 only from port 0 (CPU) * Set port 0,1,2,3 to forwarding Mode (through Switch Port registers) */ + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1), + MVEBU_SW_PORT_BASE_VLAN, BIT(0)); + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(2), + MVEBU_SW_PORT_BASE_VLAN, BIT(0)); + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(3), + MVEBU_SW_PORT_BASE_VLAN, BIT(0)); + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0), MVEBU_SW_PORT_CTRL_REG, 0x7f); mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1), @@ -234,3 +243,103 @@ int board_network_enable(struct mii_dev *bus) return 0; } + +#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_ENV_IS_IN_SPI_FLASH) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + int ret; + int spi_off; + int parts_off; + int part_off; + + /* Fill SPI MTD partitions for Linux kernel on Espressobin */ + if (!of_machine_is_compatible("marvell,armada-3720-espressobin")) + return 0; + + spi_off = fdt_node_offset_by_compatible(blob, -1, "jedec,spi-nor"); + if (spi_off < 0) + return 0; + + /* Do not touch partitions if they are already defined */ + if (fdt_subnode_offset(blob, spi_off, "partitions") >= 0) + return 0; + + parts_off = fdt_add_subnode(blob, spi_off, "partitions"); + if (parts_off < 0) { + printf("Can't add partitions node: %s\n", fdt_strerror(parts_off)); + return 0; + } + + ret = fdt_setprop_string(blob, parts_off, "compatible", "fixed-partitions"); + if (ret < 0) { + printf("Can't set compatible property: %s\n", fdt_strerror(ret)); + return 0; + } + + ret = fdt_setprop_u32(blob, parts_off, "#address-cells", 1); + if (ret < 0) { + printf("Can't set #address-cells property: %s\n", fdt_strerror(ret)); + return 0; + } + + ret = fdt_setprop_u32(blob, parts_off, "#size-cells", 1); + if (ret < 0) { + printf("Can't set #size-cells property: %s\n", fdt_strerror(ret)); + return 0; + } + + /* Add u-boot-env partition */ + + part_off = fdt_add_subnode(blob, parts_off, "partition@u-boot-env"); + if (part_off < 0) { + printf("Can't add partition@u-boot-env node: %s\n", fdt_strerror(part_off)); + return 0; + } + + ret = fdt_setprop_u32(blob, part_off, "reg", CONFIG_ENV_OFFSET); + if (ret < 0) { + printf("Can't set partition@u-boot-env reg property: %s\n", fdt_strerror(ret)); + return 0; + } + + ret = fdt_appendprop_u32(blob, part_off, "reg", CONFIG_ENV_SIZE); + if (ret < 0) { + printf("Can't set partition@u-boot-env reg property: %s\n", fdt_strerror(ret)); + return 0; + } + + ret = fdt_setprop_string(blob, part_off, "label", "u-boot-env"); + if (ret < 0) { + printf("Can't set partition@u-boot-env label property: %s\n", fdt_strerror(ret)); + return 0; + } + + /* Add firmware partition */ + + part_off = fdt_add_subnode(blob, parts_off, "partition@firmware"); + if (part_off < 0) { + printf("Can't add partition@firmware node: %s\n", fdt_strerror(part_off)); + return 0; + } + + ret = fdt_setprop_u32(blob, part_off, "reg", 0); + if (ret < 0) { + printf("Can't set partition@firmware reg property: %s\n", fdt_strerror(ret)); + return 0; + } + + ret = fdt_appendprop_u32(blob, part_off, "reg", CONFIG_ENV_OFFSET); + if (ret < 0) { + printf("Can't set partition@firmware reg property: %s\n", fdt_strerror(ret)); + return 0; + } + + ret = fdt_setprop_string(blob, part_off, "label", "firmware"); + if (ret < 0) { + printf("Can't set partition@firmware label property: %s\n", fdt_strerror(ret)); + return 0; + } + + return 0; +} +#endif diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig index 5136f02806..0c1c92d4ff 100644 --- a/configs/mvebu_espressobin-88f3720_defconfig +++ b/configs/mvebu_espressobin-88f3720_defconfig @@ -6,7 +6,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_NR_DRAM_BANKS=1 CONFIG_TARGET_MVEBU_ARMADA_37XX=y CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0x180000 +CONFIG_ENV_OFFSET=0x3F0000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_DM_GPIO=y CONFIG_DEBUG_UART_BASE=0xd0012000 @@ -80,3 +80,6 @@ CONFIG_USB_ETHER_RTL8152=y CONFIG_USB_ETHER_SMSC95XX=y CONFIG_SHA1=y CONFIG_SHA256=y +CONFIG_MVNETA=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_OF_BOARD_SETUP=y diff --git a/doc/README.marvell b/doc/README.marvell index 336461745c..5416bc3035 100644 --- a/doc/README.marvell +++ b/doc/README.marvell @@ -13,7 +13,8 @@ Build Procedure 2. Set the cross compiler: - # export CROSS_COMPILE=/path/to/toolchain/aarch64-marvell-linux-gnu- + # sudo apt-get install gcc-aarch64-linux-gnu + # export CROSS_COMPILE=aarch64-linux-gnu- 3. Clean-up old residuals: @@ -30,7 +31,7 @@ Build Procedure 5. Configure the device-tree and build the U-Boot image: - Compile u-boot and set the required device-tree using: + For the Armada-70x0/80x0 DB board compile u-boot and set the required device-tree using: # make DEVICE_TREE=<name> @@ -42,12 +43,45 @@ Build Procedure In order to prevent this, the required device-tree MUST be set during compilation. All device-tree files are located in ./arch/arm/dts/ folder. + For other DB boards (MacchiatoBin, EspressoBin and 3700 DB board) compile u-boot with + just default device-tree from defconfig using: + + # make + NOTE: The u-boot.bin should not be used as a stand-alone image. The ARM Trusted Firmware (ATF) build process uses this image to generate the - flash image. + flash image. See TF-A Build Instructions for Marvell Platforms for more details at: + https://trustedfirmware-a.readthedocs.io/en/latest/plat/marvell/armada/build.html Configuration update --------------------- To update the U-Boot configuration, please refer to doc/README.kconfig + +Permanent ethernet MAC address +------------------------------- + Prior flashing new U-Boot version (as part of ATF image) it is suggested to backup + permanent ethernet MAC address as it is stored only in U-Boot env storage (SPI or eMMC). + Some boards like EspressoBin have MAC address printed on sticker. To print current MAC + address run: + + # echo $ethaddr + + MAC addresses 00:51:82:11:22:00, 00:51:82:11:22:01, 00:51:82:11:22:02, 00:51:82:11:22:03 + and F0:AD:4E:03:64:7F are default hardcoded values found in Marvell's and Armbian U-Boot + forks and therefore *not* unique. Usage of static hardcoded MAC addresses should be avoided. + When original address is lost (e.g. erased by Armbian boot scripts for EspressoBin) it is + suggested to generate new random one. + + After flashing new U-Boot version it is suggested to reset U-Boot env variables to default + and then set correct permanent ethernet MAC address. + + # env default -a + # setenv ethaddr XX:XX:XX:XX:XX:XX + # saveenv + + Where XX:XX:XX:XX:XX:XX is permanent ethernet MAC address. + + Recent Linux kernel versions use correct permanent ethernet MAC address from U-Boot env as + U-Boot will inject it into kernel's device-tree. diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c index 356dd9846d..7f9a579c83 100644 --- a/drivers/mmc/xenon_sdhci.c +++ b/drivers/mmc/xenon_sdhci.c @@ -22,6 +22,7 @@ #include <linux/libfdt.h> #include <malloc.h> #include <sdhci.h> +#include <power/regulator.h> DECLARE_GLOBAL_DATA_PTR; @@ -42,6 +43,14 @@ DECLARE_GLOBAL_DATA_PTR; #define SDHC_SYS_EXT_OP_CTRL 0x010C #define MASK_CMD_CONFLICT_ERROR BIT(8) +#define SDHC_SLOT_EMMC_CTRL 0x0130 +#define ENABLE_DATA_STROBE_SHIFT 24 +#define SET_EMMC_RSTN_SHIFT 16 +#define EMMC_VCCQ_MASK 0x3 +#define EMMC_VCCQ_1_8V 0x1 +#define EMMC_VCCQ_1_2V 0x2 +#define EMMC_VCCQ_3_3V 0x3 + #define SDHC_SLOT_RETUNING_REQ_CTRL 0x0144 /* retuning compatible */ #define RETUNING_COMPATIBLE 0x1 @@ -108,6 +117,8 @@ DECLARE_GLOBAL_DATA_PTR; #define MMC_TIMING_MMC_HS400 10 #define XENON_MMC_MAX_CLK 400000000 +#define XENON_MMC_3V3_UV 3300000 +#define XENON_MMC_1V8_UV 1800000 enum soc_pad_ctrl_type { SOC_PAD_SD, @@ -128,6 +139,8 @@ struct xenon_sdhci_priv { void *pad_ctrl_reg; int pad_type; + + struct udevice *vqmmc; }; static int xenon_mmc_phy_init(struct sdhci_host *host) @@ -208,6 +221,51 @@ static void armada_3700_soc_pad_voltage_set(struct sdhci_host *host) writel(ARMADA_3700_SOC_PAD_3_3V, priv->pad_ctrl_reg); } +static int xenon_mmc_start_signal_voltage_switch(struct sdhci_host *host) +{ + struct xenon_sdhci_priv *priv = host->mmc->priv; + u8 voltage; + u32 ctrl; + int ret = 0; + + /* If there is no vqmmc regulator, return */ + if (!priv->vqmmc) + return 0; + + if (priv->pad_type == SOC_PAD_FIXED_1_8V) { + /* Switch to 1.8v */ + ret = regulator_set_value(priv->vqmmc, + XENON_MMC_1V8_UV); + } else if (priv->pad_type == SOC_PAD_SD) { + /* Get voltage info */ + voltage = sdhci_readb(host, SDHCI_POWER_CONTROL); + voltage &= ~SDHCI_POWER_ON; + + if (voltage == SDHCI_POWER_330) { + /* Switch to 3.3v */ + ret = regulator_set_value(priv->vqmmc, + XENON_MMC_3V3_UV); + } else { + /* Switch to 1.8v */ + ret = regulator_set_value(priv->vqmmc, + XENON_MMC_1V8_UV); + } + } + + /* Set VCCQ, eMMC mode: 1.8V; SD/SDIO mode: 3.3V */ + ctrl = sdhci_readl(host, SDHC_SLOT_EMMC_CTRL); + if (IS_SD(host->mmc)) + ctrl |= EMMC_VCCQ_3_3V; + else + ctrl |= EMMC_VCCQ_1_8V; + sdhci_writel(host, ctrl, SDHC_SLOT_EMMC_CTRL); + + if (ret) + printf("Signal voltage switch fail\n"); + + return ret; +} + static void xenon_mmc_phy_set(struct sdhci_host *host) { struct xenon_sdhci_priv *priv = host->mmc->priv; @@ -334,6 +392,13 @@ static int xenon_sdhci_set_ios_post(struct sdhci_host *host) uint speed = host->mmc->tran_speed; int pwr_18v = 0; + /* + * Signal Voltage Switching is only applicable for Host Controllers + * v3.00 and above. + */ + if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) + xenon_mmc_start_signal_voltage_switch(host); + if ((sdhci_readb(host, SDHCI_POWER_CONTROL) & ~SDHCI_POWER_ON) == SDHCI_POWER_180) pwr_18v = 1; @@ -394,6 +459,18 @@ static int xenon_sdhci_probe(struct udevice *dev) /* Set default timing */ priv->timing = MMC_TIMING_LEGACY; + /* Get the vqmmc regulator if there is */ + device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc); + /* Set the initial voltage value to 3.3V if there is regulator */ + if (priv->vqmmc) { + ret = regulator_set_value(priv->vqmmc, + XENON_MMC_3V3_UV); + if (ret) { + printf("Failed to set VQMMC regulator to 3.3V\n"); + return ret; + } + } + /* Disable auto clock gating during init */ xenon_mmc_set_acg(host, false); @@ -426,7 +503,7 @@ static int xenon_sdhci_probe(struct udevice *dev) host->ops = &xenon_sdhci_ops; host->max_clk = XENON_MMC_MAX_CLK; - ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); + ret = sdhci_setup_cfg(&plat->cfg, host, XENON_MMC_MAX_CLK, 0); if (ret) return ret; diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index c19d09bc41..dd1cc65229 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -30,6 +30,7 @@ config PCI_AARDVARK bool "Enable Aardvark PCIe driver" default n depends on DM_PCI + depends on DM_GPIO depends on ARMADA_3700 help Say Y here if you want to enable PCIe controller support on diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c index 711b930d0f..b2c417701f 100644 --- a/drivers/pci/pci-aardvark.c +++ b/drivers/pci/pci-aardvark.c @@ -148,6 +148,7 @@ struct pcie_advk { void *base; int first_busno; struct udevice *dev; + struct gpio_desc reset_gpio; }; static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg) @@ -613,10 +614,7 @@ static int pcie_advk_probe(struct udevice *dev) { struct pcie_advk *pcie = dev_get_priv(dev); -#if CONFIG_IS_ENABLED(DM_GPIO) - struct gpio_desc reset_gpio; - - gpio_request_by_name(dev, "reset-gpio", 0, &reset_gpio, + gpio_request_by_name(dev, "reset-gpios", 0, &pcie->reset_gpio, GPIOD_IS_OUT); /* * Issue reset to add-in card through the dedicated GPIO. @@ -631,15 +629,14 @@ static int pcie_advk_probe(struct udevice *dev) * possible before PCIe PHY initialization. Moreover, the PCIe * clock should be gated as well. */ - if (dm_gpio_is_valid(&reset_gpio)) { + if (dm_gpio_is_valid(&pcie->reset_gpio)) { dev_dbg(pcie->dev, "Toggle PCIE Reset GPIO ...\n"); - dm_gpio_set_value(&reset_gpio, 0); + dm_gpio_set_value(&pcie->reset_gpio, 1); mdelay(200); - dm_gpio_set_value(&reset_gpio, 1); + dm_gpio_set_value(&pcie->reset_gpio, 0); + } else { + dev_warn(pcie->dev, "PCIE Reset on GPIO support is missing\n"); } -#else - dev_dbg(pcie->dev, "PCIE Reset on GPIO support is missing\n"); -#endif /* DM_GPIO */ pcie->first_busno = dev->seq; pcie->dev = pci_get_controller(dev); @@ -647,6 +644,16 @@ static int pcie_advk_probe(struct udevice *dev) return pcie_advk_setup_hw(pcie); } +static int pcie_advk_remove(struct udevice *dev) +{ + struct pcie_advk *pcie = dev_get_priv(dev); + + if (dm_gpio_is_valid(&pcie->reset_gpio)) + dm_gpio_set_value(&pcie->reset_gpio, 1); + + return 0; +} + /** * pcie_advk_ofdata_to_platdata() - Translate from DT to device state * @@ -687,5 +694,7 @@ U_BOOT_DRIVER(pcie_advk) = { .ops = &pcie_advk_ops, .ofdata_to_platdata = pcie_advk_ofdata_to_platdata, .probe = pcie_advk_probe, + .remove = pcie_advk_remove, + .flags = DM_FLAG_OS_PREPARE, .priv_auto_alloc_size = sizeof(struct pcie_advk), }; diff --git a/include/configs/mvebu_armada-37xx.h b/include/configs/mvebu_armada-37xx.h index ca662b0ce7..905ce09b7a 100644 --- a/include/configs/mvebu_armada-37xx.h +++ b/include/configs/mvebu_armada-37xx.h @@ -37,7 +37,7 @@ /* * Other required minimal configurations */ -#define CONFIG_SYS_LOAD_ADDR 0x00800000 /* default load adr- 8M */ +#define CONFIG_SYS_LOAD_ADDR 0x06000000 /* default load adr */ #define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */ #define CONFIG_SYS_MAXARGS 32 /* max number of command args */ @@ -90,12 +90,15 @@ #include <config_distro_bootcmd.h> +/* fdt_addr and kernel_addr are needed for existing distribution boot scripts */ #define CONFIG_EXTRA_ENV_SETTINGS \ - "scriptaddr=0x4d00000\0" \ - "pxefile_addr_r=0x4e00000\0" \ - "fdt_addr_r=0x4f00000\0" \ - "kernel_addr_r=0x5000000\0" \ - "ramdisk_addr_r=0x8000000\0" \ + "scriptaddr=0x6d00000\0" \ + "pxefile_addr_r=0x6e00000\0" \ + "fdt_addr=0x6f00000\0" \ + "fdt_addr_r=0x6f00000\0" \ + "kernel_addr=0x7000000\0" \ + "kernel_addr_r=0x7000000\0" \ + "ramdisk_addr_r=0xa000000\0" \ BOOTENV #endif /* _CONFIG_MVEBU_ARMADA_37XX_H */ |