diff options
Diffstat (limited to 'board')
-rw-r--r-- | board/st/stm32mp1/Kconfig | 4 | ||||
-rw-r--r-- | board/st/stm32mp1/MAINTAINERS | 5 | ||||
-rw-r--r-- | board/st/stm32mp1/README | 36 | ||||
-rw-r--r-- | board/st/stm32mp1/cmd_stboard.c | 2 | ||||
-rw-r--r-- | board/st/stm32mp1/extlinux.conf | 20 | ||||
-rw-r--r-- | board/st/stm32mp1/fit_copro_kernel_dtb.its | 103 | ||||
-rw-r--r-- | board/st/stm32mp1/fit_kernel_dtb.its | 82 | ||||
-rw-r--r-- | board/st/stm32mp1/spl.c | 14 | ||||
-rw-r--r-- | board/st/stm32mp1/stm32mp1.c | 190 |
9 files changed, 428 insertions, 28 deletions
diff --git a/board/st/stm32mp1/Kconfig b/board/st/stm32mp1/Kconfig index 87216c0963..4fa2360b4f 100644 --- a/board/st/stm32mp1/Kconfig +++ b/board/st/stm32mp1/Kconfig @@ -22,4 +22,8 @@ config CMD_STBOARD This compile the stboard command to read and write the board in the OTP. +config TARGET_STM32MP157C_DK2 + bool "support of STMicroelectronics STM32MP157C-DK2 Discovery Board" + default y + endif diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS index 3bf4c21b60..2930947716 100644 --- a/board/st/stm32mp1/MAINTAINERS +++ b/board/st/stm32mp1/MAINTAINERS @@ -1,9 +1,10 @@ STM32MP1 BOARD M: Patrick Delaunay <patrick.delaunay@st.com> L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) +T: git https://gitlab.denx.de/u-boot/custodians/u-boot-stm.git S: Maintained -F: arch/arm/dts/stm32mp157* -F: board/st/stm32mp1 +F: arch/arm/dts/stm32mp15* +F: board/st/stm32mp1/ F: configs/stm32mp15_basic_defconfig F: configs/stm32mp15_optee_defconfig F: configs/stm32mp15_trusted_defconfig diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README index 428357cfa0..c807e0842e 100644 --- a/board/st/stm32mp1/README +++ b/board/st/stm32mp1/README @@ -139,7 +139,6 @@ the supported device trees for stm32mp157 are: # make DEVICE_TREE=<name> all - example: a) trusted boot on ev1 # export KBUILD_OUTPUT=stm32mp15_trusted @@ -190,7 +189,7 @@ the supported device trees for stm32mp157 are: 6. Switch Setting for Boot Mode =============================== -You can select the boot mode, on the board ed1 with the switch SW1 +You can select the boot mode, on the board with one switch : - on the daugther board ed1 with the switch SW1 : BOOT0, BOOT1, BOOT2 @@ -358,3 +357,36 @@ on bank 0 to access to internal OTP: 4 check env update STM32MP> print ethaddr ethaddr=12:34:56:78:9a:bc + +10. Coprocessor firmware +======================== + +U-Boot can boot the coprocessor before the kernel (coprocessor early boot). + +A/ Manuallly by using rproc commands (update the bootcmd) + Configurations + # env set name_copro "rproc-m4-fw.elf" + # env set dev_copro 0 + # env set loadaddr_copro 0xC1000000 + + Load binary from bootfs partition (number 4) on SDCard (mmc 0) + # ext4load mmc 0:4 ${loadaddr_copro} ${name_copro} + => ${filesize} updated with the size of the loaded file + + Start M4 firmware with remote proc command + # rproc init + # rproc load ${dev_copro} ${loadaddr_copro} ${filesize} + # rproc start ${dev_copro} + +B/ Automatically by using FIT feature and generic DISTRO bootcmd + + see examples in this directory : + + Generate FIT including kernel + device tree + M4 firmware + with cfg with M4 boot + $> mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb + + Then using DISTRO configuration file: see extlinux.conf to select + the correct configuration + => stm32mp157c-ev1-m4 + => stm32mp157c-dk2-m4 diff --git a/board/st/stm32mp1/cmd_stboard.c b/board/st/stm32mp1/cmd_stboard.c index f781c364cf..04352ae8ed 100644 --- a/board/st/stm32mp1/cmd_stboard.c +++ b/board/st/stm32mp1/cmd_stboard.c @@ -60,7 +60,7 @@ static int do_stboard(cmd_tbl_t *cmdtp, int flag, int argc, ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), &otp, sizeof(otp)); - if (ret) { + if (ret < 0) { puts("OTP read error"); return CMD_RET_FAILURE; } diff --git a/board/st/stm32mp1/extlinux.conf b/board/st/stm32mp1/extlinux.conf new file mode 100644 index 0000000000..2b4632804d --- /dev/null +++ b/board/st/stm32mp1/extlinux.conf @@ -0,0 +1,20 @@ +# Generic Distro Configuration for STM32MP157 +menu title Select the boot mode +TIMEOUT 20 +DEFAULT stm32mp157c-ev1 + +LABEL stm32mp157c-ev1 + KERNEL /fit_kernel_dtb.itb#ev1 + APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 + +LABEL stm32mp157c-ev1-m4 + KERNEL /fit_copro_kernel_dtb.itb#ev1-m4 + APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 + +LABEL stm32mp157c-dk2 + KERNEL /fit_kernel_dtb.itb#dk2 + APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 + +LABEL stm32mp157c-dk2-m4 + KERNEL /fit_copro_kernel_dtb.itb#dk2-m4 + APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 diff --git a/board/st/stm32mp1/fit_copro_kernel_dtb.its b/board/st/stm32mp1/fit_copro_kernel_dtb.its new file mode 100644 index 0000000000..3e08fd943e --- /dev/null +++ b/board/st/stm32mp1/fit_copro_kernel_dtb.its @@ -0,0 +1,103 @@ +/* + * Compilation: + * mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb + */ + +/dts-v1/; +/ { + description = "U-Boot fitImage for stm32mp157"; + #address-cells = <1>; + + images { + + copro { + description = "M4 copro"; + data = /incbin/("rproc-m4-fw.elf"); + type = "copro"; + arch = "arm"; + compression = "none"; + load = <0xC0800000>; + hash-1 { + algo = "sha1"; + }; + }; + + kernel { + description = "Linux kernel"; + data = /incbin/("zImage"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "none"; + load = <0xC0008000>; + entry = <0xC0008000>; + hash-1 { + algo = "sha1"; + }; + }; + + fdt-dk2 { + description = "FDT dk2"; + data = /incbin/("stm32mp157c-dk2.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + hash-1 { + algo = "sha1"; + }; + }; + + fdt-ev1 { + description = "FDT ev1"; + data = /incbin/("stm32mp157c-ev1.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + hash-1 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "dk2-m4"; + + dk2-m4 { + description = "dk2-m4"; + loadables = "copro"; + kernel = "kernel"; + fdt = "fdt-dk2"; + hash-1 { + algo = "sha1"; + }; + }; + + dk2 { + description = "dk2"; + kernel = "kernel"; + fdt = "fdt-dk2"; + hash-1 { + algo = "sha1"; + }; + }; + + ev1-m4 { + description = "ev1-m4"; + loadables = "copro"; + kernel = "kernel"; + fdt = "fdt-ev1"; + hash-1 { + algo = "sha1"; + }; + }; + + ev1 { + description = "ev1"; + kernel = "kernel"; + fdt = "fdt-ev1"; + hash-1 { + algo = "sha1"; + }; + }; + }; +}; diff --git a/board/st/stm32mp1/fit_kernel_dtb.its b/board/st/stm32mp1/fit_kernel_dtb.its new file mode 100644 index 0000000000..18d03ebf3c --- /dev/null +++ b/board/st/stm32mp1/fit_kernel_dtb.its @@ -0,0 +1,82 @@ +/* + * Compilation: + * mkimage -f fit_kernel_dtb.its fit_kernel_dtb.itb + * + * Files in linux build dir: + * - arch/arm/boot/zImage + * - arch/arm/boot/dts/stm32mp157c-dk2.dtb + * - arch/arm/boot/dts/stm32mp157c-ev1.dtb + * + * load mmc 0:4 $kernel_addr_r fit_kernel_dtb.itb + * bootm $kernel_addr_r + * bootm $kernel_addr_r#dk2 + * bootm $kernel_addr_r#ev1 + * + * or use extlinux.conf in this directory + */ + +/dts-v1/; +/ { + description = "U-Boot fitImage for stm32mp157"; + #address-cells = <1>; + + images { + kernel { + description = "Linux kernel"; + data = /incbin/("zImage"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "none"; + load = <0xC0008000>; + entry = <0xC0008000>; + hash-1 { + algo = "sha1"; + }; + }; + + fdt-dk2 { + description = "FDT dk2"; + data = /incbin/("stm32mp157c-dk2.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + hash-1 { + algo = "sha1"; + }; + }; + + fdt-ev1 { + description = "FDT ev1"; + data = /incbin/("stm32mp157c-ev1.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + hash-1 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "dk2"; + + dk2 { + description = "dk2"; + kernel = "kernel"; + fdt = "fdt-dk2"; + hash-1 { + algo = "sha1"; + }; + }; + + ev1 { + description = "ev1"; + kernel = "kernel"; + fdt = "fdt-ev1"; + hash-1 { + algo = "sha1"; + }; + }; + }; +}; diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c index e19be0f770..e65ff288ea 100644 --- a/board/st/stm32mp1/spl.c +++ b/board/st/stm32mp1/spl.c @@ -27,5 +27,19 @@ void spl_board_init(void) STPMIC1_BUCKS_MRST_CR, STPMIC1_MRST_BUCK(STPMIC1_BUCK3), STPMIC1_MRST_BUCK(STPMIC1_BUCK3)); + + /* Check if debug is enabled to program PMIC according to the bit */ + if ((readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) && !ret) { + printf("Keep debug unit ON\n"); + + pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, + STPMIC1_MRST_BUCK_DEBUG, + STPMIC1_MRST_BUCK_DEBUG); + + if (STPMIC1_MRST_LDO_DEBUG) + pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR, + STPMIC1_MRST_LDO_DEBUG, + STPMIC1_MRST_LDO_DEBUG); + } #endif } diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 279c7b7797..fc14ad375c 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -5,8 +5,8 @@ #include <common.h> #include <adc.h> #include <bootm.h> -#include <config.h> #include <clk.h> +#include <config.h> #include <dm.h> #include <env.h> #include <env_internal.h> @@ -18,9 +18,11 @@ #include <mtd.h> #include <mtd_node.h> #include <phy.h> +#include <remoteproc.h> #include <reset.h> #include <syscon.h> #include <usb.h> +#include <watchdog.h> #include <asm/io.h> #include <asm/gpio.h> #include <asm/arch/stm32.h> @@ -102,7 +104,7 @@ int checkboard(void) if (!ret) ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), &otp, sizeof(otp)); - if (!ret && otp) { + if (ret > 0 && otp) { printf("Board: MB%04x Var%d Rev.%c-%02d\n", otp >> 16, (otp >> 12) & 0xF, @@ -232,6 +234,7 @@ int g_dnl_board_usb_cable_connected(void) } #endif /* CONFIG_USB_GADGET */ +#ifdef CONFIG_LED static int get_led(struct udevice **dev, char *led_string) { char *led_name; @@ -264,12 +267,42 @@ static int setup_led(enum led_state_t cmd) ret = led_set_state(dev, cmd); return ret; } +#endif + +static void __maybe_unused led_error_blink(u32 nb_blink) +{ +#ifdef CONFIG_LED + int ret; + struct udevice *led; + u32 i; +#endif + + if (!nb_blink) + return; + +#ifdef CONFIG_LED + ret = get_led(&led, "u-boot,error-led"); + if (!ret) { + /* make u-boot,error-led blinking */ + /* if U32_MAX and 125ms interval, for 17.02 years */ + for (i = 0; i < 2 * nb_blink; i++) { + led_set_state(led, LEDST_TOGGLE); + mdelay(125); + WATCHDOG_RESET(); + } + } +#endif + + /* infinite: the boot process must be stopped */ + if (nb_blink == U32_MAX) + hang(); +} +#ifdef CONFIG_ADC static int board_check_usb_power(void) { struct ofnode_phandle_args adc_args; struct udevice *adc; - struct udevice *led; ofnode node; unsigned int raw; int max_uV = 0; @@ -395,23 +428,11 @@ static int board_check_usb_power(void) pr_err("****************************************************\n\n"); } - ret = get_led(&led, "u-boot,error-led"); - 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); - } - led_set_state(led, LEDST_ON); + led_error_blink(nb_blink); return 0; } +#endif /* CONFIG_ADC */ static void sysconf_init(void) { @@ -454,7 +475,9 @@ static void sysconf_init(void) * => U-Boot set the register only if VDD < 2.7V (in DT) * but this value need to be consistent with board design */ - ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev); + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(stm32mp_pwr_pmic), + &pwr_dev); if (!ret) { ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(stm32mp_bsec), @@ -465,11 +488,11 @@ static void sysconf_init(void) } ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); - if (!ret) + if (ret > 0) otp = otp & BIT(13); - /* get VDD = pwr-supply */ - ret = device_get_supply_regulator(pwr_dev, "pwr-supply", + /* get VDD = vdd-supply */ + ret = device_get_supply_regulator(pwr_dev, "vdd-supply", &pwr_reg); /* check if VDD is Low Voltage */ @@ -505,6 +528,73 @@ static void sysconf_init(void) #endif } +#ifdef CONFIG_DM_REGULATOR +/* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */ +static int dk2_i2c1_fix(void) +{ + ofnode node; + struct gpio_desc hdmi, audio; + int ret = 0; + + node = ofnode_path("/soc/i2c@40012000/hdmi-transmitter@39"); + if (!ofnode_valid(node)) { + pr_debug("%s: no hdmi-transmitter@39 ?\n", __func__); + return -ENOENT; + } + + if (gpio_request_by_name_nodev(node, "reset-gpios", 0, + &hdmi, GPIOD_IS_OUT)) { + pr_debug("%s: could not find reset-gpios\n", + __func__); + return -ENOENT; + } + + node = ofnode_path("/soc/i2c@40012000/cs42l51@4a"); + if (!ofnode_valid(node)) { + pr_debug("%s: no cs42l51@4a ?\n", __func__); + return -ENOENT; + } + + if (gpio_request_by_name_nodev(node, "reset-gpios", 0, + &audio, GPIOD_IS_OUT)) { + pr_debug("%s: could not find reset-gpios\n", + __func__); + return -ENOENT; + } + + /* before power up, insure that HDMI and AUDIO IC is under reset */ + ret = dm_gpio_set_value(&hdmi, 1); + if (ret) { + pr_err("%s: can't set_value for hdmi_nrst gpio", __func__); + goto error; + } + ret = dm_gpio_set_value(&audio, 1); + if (ret) { + pr_err("%s: can't set_value for audio_nrst gpio", __func__); + goto error; + } + + /* power-up audio IC */ + regulator_autoset_by_name("v1v8_audio", NULL); + + /* power-up HDMI IC */ + regulator_autoset_by_name("v1v2_hdmi", NULL); + regulator_autoset_by_name("v3v3_hdmi", NULL); + +error: + return ret; +} + +static bool board_is_dk2(void) +{ + if (CONFIG_IS_ENABLED(TARGET_STM32MP157C_DK2) && + of_machine_is_compatible("st,stm32mp157c-dk2")) + return true; + + return false; +} +#endif + /* board dependent setup after realloc */ int board_init(void) { @@ -523,12 +613,15 @@ int board_init(void) board_key_check(); #ifdef CONFIG_DM_REGULATOR + if (board_is_dk2()) + dk2_i2c1_fix(); + regulators_enable_boot_on(_DEBUG); #endif sysconf_init(); - if (IS_ENABLED(CONFIG_LED)) + if (CONFIG_IS_ENABLED(CONFIG_LED)) led_default_state(); return 0; @@ -536,9 +629,14 @@ int board_init(void) int board_late_init(void) { + char *boot_device; #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG const void *fdt_compat; int fdt_compat_len; + int ret; + u32 otp; + struct udevice *dev; + char buf[10]; fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", &fdt_compat_len); @@ -548,21 +646,44 @@ int board_late_init(void) else env_set("board_name", fdt_compat + 3); } + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), + &dev); + + if (!ret) + ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + if (!ret && otp) { + snprintf(buf, sizeof(buf), "0x%04x", otp >> 16); + env_set("board_id", buf); + + snprintf(buf, sizeof(buf), "0x%04x", + ((otp >> 8) & 0xF) - 1 + 0xA); + env_set("board_rev", buf); + } #endif +#ifdef CONFIG_ADC /* for DK1/DK2 boards */ board_check_usb_power(); +#endif /* CONFIG_ADC */ + + /* Check the boot-source to disable bootdelay */ + boot_device = env_get("boot_device"); + if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb")) + env_set("bootdelay", "0"); return 0; } void board_quiesce_devices(void) { +#ifdef CONFIG_LED setup_led(LEDST_OFF); +#endif } /* 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) { @@ -771,3 +892,26 @@ int ft_board_setup(void *blob, bd_t *bd) return 0; } #endif + +static void board_copro_image_process(ulong fw_image, size_t fw_size) +{ + int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */ + + if (!rproc_is_initialized()) + if (rproc_init()) { + printf("Remote Processor %d initialization failed\n", + id); + return; + } + + ret = rproc_load(id, fw_image, fw_size); + printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", + id, fw_image, fw_size, ret ? " Failed!" : " Success!"); + + if (!ret) { + rproc_start(id); + env_set("copro_state", "booted"); + } +} + +U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process); |