From 93ffa2ba8014ef9a54db267018f34878892566bc Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 2 May 2019 13:26:44 +0530 Subject: board: stm32mp1: Add Avenger96 board support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for Avenger96 board from Arrow Electronics based on STM32MP157 MPU. This board is one of the Consumer Edition (CE) boards of the 96Boards family and has the following features: SoC: STM32MP157AAC PMIC: STPMIC1A RAM: 1024 Mbyte @ 533MHz Storage: eMMC v4.51: 8 Gbyte microSD Socket: UHS-1 v3.01 Ethernet Port: 10/100/1000 Mbit/s, IEEE 802.3 Compliant Wireless: WiFi 5 GHz & 2.4GHz IEEE 802.11a/b/g/n/ac Bluetooth®v4.2 (BR/EDR/BLE) USB: 2x Type A (USB 2.0) Host and 1x Micro B (USB 2.0) OTG Display: HDMI: WXGA (1366x768)@ 60 fps, HDMI 1.4 LED: 4x User LED, 1x WiFi LED, 1x BT LED More information about this board can be found in 96Boards website: https://www.96boards.org/product/avenger96/ Signed-off-by: Manivannan Sadhasivam Reviewed-by: Patrice Chotard --- board/st/stm32mp1/README | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'board') diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README index 1cd3534ae4..b0c8325061 100644 --- a/board/st/stm32mp1/README +++ b/board/st/stm32mp1/README @@ -37,6 +37,7 @@ Currently the following boards are supported: + stm32mp157c-ed1 + stm32mp157a-dk1 + stm32mp157c-dk2 ++ stm32mp157a-avenger96 3. Boot Sequences ================= @@ -84,6 +85,9 @@ the supported device trees for stm32mp157 are: + dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel dts: stm32mp157c-dk2 ++ avenger96: Avenger96 board from Arrow Electronics + dts: stm32mp157a-avenger96 + 5. Build Procedure ================== @@ -140,6 +144,11 @@ the supported device trees for stm32mp157 are: # make stm32mp15_basic_defconfig # make DEVICE_TREE=stm32mp157c-dk2 all + d) basic boot on avenger96 + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157a-avenger96 all + 6. Output files BootRom and TF-A expect binaries with STM32 image header @@ -182,6 +191,20 @@ You can select the boot mode, on the board ed1 with the switch SW1 SD-Card 1 1 Recovery 0 0 +- Boot mode of Avenger96 can be selected using switch S3 + + ----------------------------------- + Boot Mode BOOT2 BOOT1 BOOT0 + ----------------------------------- + Recovery 0 0 0 + NOR 0 0 1 + SD-Card 1 0 1 + eMMC 0 1 0 + NAND 0 1 1 + Reserved 1 0 0 + Recovery 1 1 0 + SD-Card 1 1 1 + Recovery is a boot from serial link (UART/USB) and it is used with STM32CubeProgrammer tool to load executable in RAM and to update the flash devices available on the board (NOR/NAND/eMMC/SDCARD). -- cgit From 87471649a561404a36e9e854d45be95d1599b1c0 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 2 May 2019 18:07:14 +0200 Subject: stm32mp1: support dynamic MTDPARTS This patch configure the default value for mtdids and mtparts dynamically according the presence of nor and nand in the board device tree Signed-off-by: Patrick Delaunay Signed-off-by: Christophe Kerello Signed-off-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'board') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 76917b022e..360b0df9f6 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -504,3 +504,88 @@ void board_quiesce_devices(void) { setup_led(LEDST_OFF); } + +#ifdef CONFIG_SYS_MTDPARTS_RUNTIME + +#define MTDPARTS_LEN 256 +#define MTDIDS_LEN 128 + +/** + * The mtdparts_nand0 and mtdparts_nor0 variable tends to be long. + * If we need to access it before the env is relocated, then we need + * to use our own stack buffer. gd->env_buf will be too small. + * + * @param buf temporary buffer pointer MTDPARTS_LEN long + * @return mtdparts variable string, NULL if not found + */ +static const char *env_get_mtdparts(const char *str, char *buf) +{ + if (gd->flags & GD_FLG_ENV_READY) + return env_get(str); + if (env_get_f(str, buf, MTDPARTS_LEN) != -1) + return buf; + + return NULL; +} + +/** + * update the variables "mtdids" and "mtdparts" with content of mtdparts_ + */ +static void board_get_mtdparts(const char *dev, + char *mtdids, + char *mtdparts) +{ + char env_name[32] = "mtdparts_"; + char tmp_mtdparts[MTDPARTS_LEN]; + const char *tmp; + + /* name of env variable to read = mtdparts_ */ + strcat(env_name, dev); + tmp = env_get_mtdparts(env_name, tmp_mtdparts); + if (tmp) { + /* mtdids: "=, ...." */ + if (mtdids[0] != '\0') + strcat(mtdids, ","); + strcat(mtdids, dev); + strcat(mtdids, "="); + strcat(mtdids, dev); + + /* mtdparts: "mtdparts=:>;..." */ + if (mtdparts[0] != '\0') + strncat(mtdparts, ";", MTDPARTS_LEN); + else + strcat(mtdparts, "mtdparts="); + strncat(mtdparts, dev, MTDPARTS_LEN); + strncat(mtdparts, ":", MTDPARTS_LEN); + strncat(mtdparts, tmp, MTDPARTS_LEN); + } +} + +void board_mtdparts_default(const char **mtdids, const char **mtdparts) +{ + struct udevice *dev; + static char parts[2 * MTDPARTS_LEN + 1]; + static char ids[MTDIDS_LEN + 1]; + static bool mtd_initialized; + + if (mtd_initialized) { + *mtdids = ids; + *mtdparts = parts; + return; + } + + memset(parts, 0, sizeof(parts)); + memset(ids, 0, sizeof(ids)); + + if (!uclass_get_device(UCLASS_MTD, 0, &dev)) + board_get_mtdparts("nand0", ids, parts); + + if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) + board_get_mtdparts("nor0", ids, parts); + + mtd_initialized = true; + *mtdids = ids; + *mtdparts = parts; + debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts); +} +#endif -- cgit From 7f90cd6150efd0bcf6293bbf35293d19d5e17a41 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 2 May 2019 18:36:01 +0200 Subject: board: stm32mp1: Add env_ext4_get_dev_part() and env_ext4_get_intf() This allows to : - select the current device to save the environment file - select the correct EXT4 boot device instance and partition to save the environment file. For EXT4, device is mmc, device instance is 0 for sdcard or 1 for eMMC. The partition is set to "auto" to select the first partition with bootable flag. Signed-off-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'board') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 360b0df9f6..316cd48195 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -505,6 +506,29 @@ void board_quiesce_devices(void) setup_led(LEDST_OFF); } +#if defined(CONFIG_ENV_IS_IN_EXT4) +const char *env_ext4_get_intf(void) +{ + u32 bootmode = get_bootmode(); + + switch (bootmode & TAMP_BOOT_DEVICE_MASK) { + case BOOT_FLASH_SD: + case BOOT_FLASH_EMMC: + return "mmc"; + default: + return ""; + } +} + +const char *env_ext4_get_dev_part(void) +{ + static char *const dev_part[] = {"0:auto", "1:auto", "2:auto"}; + u32 bootmode = get_bootmode(); + + return dev_part[(bootmode & TAMP_BOOT_INSTANCE_MASK) - 1]; +} +#endif + #ifdef CONFIG_SYS_MTDPARTS_RUNTIME #define MTDPARTS_LEN 256 -- cgit From 8f24b1a4a97cbeb8f2756be62bd524f166423406 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 2 May 2019 18:28:05 +0200 Subject: stm32mp1: Add env_get_location() In case of several environment location support, env_get_location is needed to select the correct location depending of the boot device . Signed-off-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'board') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 316cd48195..4f7d24acaa 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -506,6 +507,28 @@ void board_quiesce_devices(void) setup_led(LEDST_OFF); } +enum env_location env_get_location(enum env_operation op, int prio) +{ + u32 bootmode = get_bootmode(); + + if (prio) + return ENVL_UNKNOWN; + + switch (bootmode & TAMP_BOOT_DEVICE_MASK) { +#ifdef CONFIG_ENV_IS_IN_EXT4 + case BOOT_FLASH_SD: + case BOOT_FLASH_EMMC: + return ENVL_EXT4; +#endif +#ifdef CONFIG_ENV_IS_IN_UBI + case BOOT_FLASH_NAND: + return ENVL_UBI; +#endif + default: + return ENVL_NOWHERE; + } +} + #if defined(CONFIG_ENV_IS_IN_EXT4) const char *env_ext4_get_intf(void) { -- cgit From e5c38fdd3af552f7c8cc8233b4cb62033275bc7e Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 9 May 2019 14:25:36 +0200 Subject: stm32mp1: Update env_get_location for NOR support Update env_get_location() to be able to save environment into NOR (SPI_FLASH). Series-cc: pde, cke, pch, uboot-stm32 Cover-letter: Add saveenv support for STM32MP1 This series adds saveenv support for STM32MP1 on several boot devices. STM32MP1 is able to boot on eMMC, sdcard and NOR (NAND support is not fully supported). On eMMC and sdcard, environment is saved in EXT4 partition On NOR, environment is saved in a dedicated partition On NAND, environment is saved in a UBI volume. This series: - enables NAND and NOR support on ev1 board - enables ENV_IS_IN_SPI_FLASH, ENV_IS_IN_UBI, ENV_IS_IN_EXT4 flags - fixes get_mtdparts() - allows to override interface, device and partition for ext4 environment - updates rule to set ENV_IS_NOWHERE value - introduce ENV_IS_IN_DEVICE END Signed-off-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'board') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 4f7d24acaa..af607c5874 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -523,6 +523,10 @@ enum env_location env_get_location(enum env_operation op, int prio) #ifdef CONFIG_ENV_IS_IN_UBI case BOOT_FLASH_NAND: return ENVL_UBI; +#endif +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + case BOOT_FLASH_NOR: + return ENVL_SPI_FLASH; #endif default: return ENVL_NOWHERE; -- cgit From 28c064e66bc4cd6097cdf39410cf4b9c2ad9d35d Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Apr 2019 18:09:38 +0200 Subject: board: stm32mp1: Update power supply check via USB TYPE-C Add 2 new checks: - detect when USB TYPE-C cable is not plugged correctly. In this case, GND and VBUS pins are connected but not CC1 and CC2 pins. - detect is an USB Type-C charger supplies more than 3 Amps which is not compliant with the USB Type-C specification In these 2 situations, stop the boot process and let red led blinks forever. V cc1 | V cc2 | power supply | red led | console message range (Volts) |range (Volts)| (Amps) | blinks | --------------|-------------|--------------|---------|----------------------------------- > 2.15 | < 0.2 | > 3 | for ever| USB TYPE-C charger not compliant with specification [2.15 - 1.23[ | < 0.2 | 3 | NO | NO [1.23 - 0.66[ | < 0.2 | 1.5 | 3 times | WARNING 1.5A power supply detected [0.66 - 0] | < 0.2 | 0.5 | 2 times | WARNING 500mA power supply detected < 0.2 | < 0.2 | | for ever| ERROR USB TYPE-C connection in unattached mode > 0.2 | > 0.2 | | for ever| ERROR USB TYPE-C connection in unattached mode Signed-off-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 69 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'board') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index af607c5874..88bc8814c4 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -62,9 +62,10 @@ */ DECLARE_GLOBAL_DATA_PTR; +#define USB_LOW_THRESHOLD_UV 200000 #define USB_WARNING_LOW_THRESHOLD_UV 660000 #define USB_START_LOW_THRESHOLD_UV 1230000 -#define USB_START_HIGH_THRESHOLD_UV 2100000 +#define USB_START_HIGH_THRESHOLD_UV 2150000 int checkboard(void) { @@ -265,9 +266,10 @@ static int board_check_usb_power(void) ofnode node; unsigned int raw; int max_uV = 0; + int min_uV = USB_START_HIGH_THRESHOLD_UV; int ret, uV, adc_count; - u8 i, nb_blink; - + u32 nb_blink; + u8 i; node = ofnode_path("/config"); if (!ofnode_valid(node)) { debug("%s: no /config node?\n", __func__); @@ -319,6 +321,8 @@ static int board_check_usb_power(void) if (!adc_raw_to_uV(adc, raw, &uV)) { if (uV > max_uV) max_uV = uV; + if (uV < min_uV) + min_uV = uV; pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__, adc->name, adc_args.args[0], raw, uV); } else { @@ -333,27 +337,66 @@ static int board_check_usb_power(void) * continue. */ if (max_uV > USB_START_LOW_THRESHOLD_UV && - max_uV < USB_START_HIGH_THRESHOLD_UV) + max_uV <= USB_START_HIGH_THRESHOLD_UV && + min_uV <= USB_LOW_THRESHOLD_UV) return 0; - /* Display warning message and make u-boot,error-led blinking */ - pr_err("\n*******************************************\n"); + pr_err("****************************************************\n"); + + /* + * If highest and lowest value are either both below + * USB_LOW_THRESHOLD_UV or both above USB_LOW_THRESHOLD_UV, that + * means USB TYPE-C is in unattached mode, this is an issue, make + * u-boot,error-led blinking and stop boot process. + */ + if ((max_uV > USB_LOW_THRESHOLD_UV && + min_uV > USB_LOW_THRESHOLD_UV) || + (max_uV <= USB_LOW_THRESHOLD_UV && + min_uV <= USB_LOW_THRESHOLD_UV)) { + pr_err("* ERROR USB TYPE-C connection in unattached mode *\n"); + pr_err("* Check that USB TYPE-C cable is correctly plugged *\n"); + /* with 125ms interval, led will blink for 17.02 years ....*/ + nb_blink = U32_MAX; + } - if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) { - pr_err("* WARNING 500mA power supply detected *\n"); + if (max_uV > USB_LOW_THRESHOLD_UV && + max_uV <= USB_WARNING_LOW_THRESHOLD_UV && + min_uV <= USB_LOW_THRESHOLD_UV) { + pr_err("* WARNING 500mA power supply detected *\n"); nb_blink = 2; - } else { - pr_err("* WARNING 1.5A power supply detected *\n"); + } + + if (max_uV > USB_WARNING_LOW_THRESHOLD_UV && + max_uV <= USB_START_LOW_THRESHOLD_UV && + min_uV <= USB_LOW_THRESHOLD_UV) { + pr_err("* WARNING 1.5mA power supply detected *\n"); nb_blink = 3; } - pr_err("* Current too low, use a 3A power supply! *\n"); - pr_err("*******************************************\n\n"); + /* + * If highest value is above 2.15 Volts that means that the USB TypeC + * supplies more than 3 Amp, this is not compliant with TypeC specification + */ + if (max_uV > USB_START_HIGH_THRESHOLD_UV) { + pr_err("* USB TYPE-C charger not compliant with *\n"); + pr_err("* specification *\n"); + pr_err("****************************************************\n\n"); + /* with 125ms interval, led will blink for 17.02 years ....*/ + nb_blink = U32_MAX; + } else { + pr_err("* Current too low, use a 3A power supply! *\n"); + pr_err("****************************************************\n\n"); + } ret = get_led(&led, "u-boot,error-led"); - if (ret) + if (ret) { + /* in unattached case, the boot process must be stopped */ + if (nb_blink == U32_MAX) + hang(); return ret; + } + /* make u-boot,error-led blinking */ for (i = 0; i < nb_blink * 2; i++) { led_set_state(led, LEDST_TOGGLE); mdelay(125); -- cgit From edacf2682146859b53f2289e528c423d59ba884a Mon Sep 17 00:00:00 2001 From: Christophe Roullier Date: Fri, 17 May 2019 15:08:43 +0200 Subject: board: stm32mp1: Add board_interface_eth_init Called to configure Ethernet PHY interface selection and configure clock selection in RCC Ethernet clock tree. Signed-off-by: Christophe Roullier --- board/st/stm32mp1/stm32mp1.c | 68 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) (limited to 'board') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 88bc8814c4..776929350f 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -53,9 +53,9 @@ #define SYSCFG_PMCSETR_ETH_SELMII BIT(20) #define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) -#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII (0 << 21) -#define SYSCFG_PMCSETR_ETH_SEL_RGMII (1 << 21) -#define SYSCFG_PMCSETR_ETH_SEL_RMII (4 << 21) +#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 +#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) +#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) /* * Get a global data pointer @@ -550,6 +550,68 @@ void board_quiesce_devices(void) setup_led(LEDST_OFF); } +/* board interface eth init */ +/* this is a weak define that we are overriding */ +int board_interface_eth_init(phy_interface_t interface_type, + bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg) +{ + u8 *syscfg; + u32 value; + + syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + + if (!syscfg) + return -ENODEV; + + switch (interface_type) { + case PHY_INTERFACE_MODE_MII: + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | + SYSCFG_PMCSETR_ETH_REF_CLK_SEL; + debug("%s: PHY_INTERFACE_MODE_MII\n", __func__); + break; + case PHY_INTERFACE_MODE_GMII: + if (eth_clk_sel_reg) + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | + SYSCFG_PMCSETR_ETH_CLK_SEL; + else + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; + debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__); + break; + case PHY_INTERFACE_MODE_RMII: + if (eth_ref_clk_sel_reg) + value = SYSCFG_PMCSETR_ETH_SEL_RMII | + SYSCFG_PMCSETR_ETH_REF_CLK_SEL; + else + value = SYSCFG_PMCSETR_ETH_SEL_RMII; + debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + if (eth_clk_sel_reg) + value = SYSCFG_PMCSETR_ETH_SEL_RGMII | + SYSCFG_PMCSETR_ETH_CLK_SEL; + else + value = SYSCFG_PMCSETR_ETH_SEL_RGMII; + debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__); + break; + default: + debug("%s: Do not manage %d interface\n", + __func__, interface_type); + /* Do not manage others interfaces */ + return -EINVAL; + } + + /* clear and set ETH configuration bits */ + writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | + SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, + syscfg + SYSCFG_PMCCLRR); + writel(value, syscfg + SYSCFG_PMCSETR); + + return 0; +} + enum env_location env_get_location(enum env_operation op, int prio) { u32 bootmode = get_bootmode(); -- cgit