Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell
authorTom Rini <trini@konsulko.com>
Mon, 31 Aug 2020 13:43:13 +0000 (09:43 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 31 Aug 2020 13:43:13 +0000 (09:43 -0400)
- MVEBU Espressobin fixes and enhancements (fix switch security
  issue, enable MVNETA, enable SD-card, fix COMPHY nodes, default
  env variables, etc)
- MMC Xenon: Set signal voltage and max base clock
- a37xx PCI driver: Depend on DM_GPIO and remove #ifdef's

arch/arm/dts/armada-3720-db.dts
arch/arm/dts/armada-3720-espressobin.dts
arch/arm/dts/armada-3720-turris-mox.dts
board/Marvell/mvebu_armada-37xx/board.c
configs/mvebu_espressobin-88f3720_defconfig
doc/README.marvell
drivers/mmc/xenon_sdhci.c
drivers/pci/Kconfig
drivers/pci/pci-aardvark.c
include/configs/mvebu_armada-37xx.h

index 1b219c4..1b1b66b 100644 (file)
 &pcie0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_pins>;
-       reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
+       reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 84e2c2a..4534f5f 100644 (file)
                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 {
        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";
 &pcie0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_pins>;
-       reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
+       reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
index 0f0a6ce..974270c 100644 (file)
 &pcie0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_pins>;
-       reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
+       reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
        status = "disabled";
 };
index 9bea198..7b9c322 100644 (file)
@@ -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
index 5136f02..0c1c92d 100644 (file)
@@ -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
index 3364617..5416bc3 100644 (file)
@@ -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.
index 356dd98..7f9a579 100644 (file)
@@ -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;
 
index c19d09b..dd1cc65 100644 (file)
@@ -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
index 711b930..b2c4177 100644 (file)
@@ -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),
 };
index ca662b0..905ce09 100644 (file)
@@ -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 */
 
 
 #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 */