From 1ad133066494c9875abb5e88ba9f6ef8322b1dde Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Mon, 26 Jan 2026 16:23:43 +0530 Subject: [PATCH 01/80] ARM: dts: add dtsi for exynos7870-a2corelte (Samsung Galaxy A2 Core) Add a framebuffer node to the DTSI in order to ensure that display continues to work, as since v6.19 of devicetree-rebasing sources, it uses Samsung's DECON (Display Enhancement CONtroller) for display, which is, as of yet, not supported in U-Boot. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi diff --git a/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi b/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi new file mode 100644 index 00000000000..c22ed7efea5 --- /dev/null +++ b/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 Kaustabh Chakraborty + */ + +/ { + chosen { + #address-cells = <2>; + #size-cells = <1>; + ranges; + + framebuffer@67000000 { + compatible = "simple-framebuffer"; + reg = <0x0 0x67000000 (540 * 960 * 4)>; + width = <540>; + height = <960>; + stride = <(540 * 4)>; + format = "a8r8g8b8"; + }; + }; +}; From 5689cc9c6fb590d5d62e6b137fab4179cd7a1beb Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Mon, 26 Jan 2026 16:23:44 +0530 Subject: [PATCH 02/80] ARM: dts: add dtsi for exynos7870-j6lte (Samsung Galaxy J6) Add a framebuffer node to the DTSI in order to ensure that display continues to work, as since v6.19 of devicetree-rebasing sources, it uses Samsung's DECON (Display Enhancement CONtroller) for display, which is, as of yet, not supported in U-Boot. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos7870-j6lte-u-boot.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 arch/arm/dts/exynos7870-j6lte-u-boot.dtsi diff --git a/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi b/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi new file mode 100644 index 00000000000..9d944b127ee --- /dev/null +++ b/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Kaustabh Chakraborty + */ + +/ { + chosen { + #address-cells = <2>; + #size-cells = <1>; + ranges; + + framebuffer@67000000 { + compatible = "simple-framebuffer"; + reg = <0x0 0x67000000 (720 * 1480 * 4)>; + width = <720>; + height = <1480>; + stride = <(720 * 4)>; + format = "a8r8g8b8"; + }; + }; +}; From 3f2ab427c13e4883cb5dddb4c54d3cedc0f93669 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Mon, 26 Jan 2026 16:23:45 +0530 Subject: [PATCH 03/80] ARM: dts: add dtsi for exynos7870-on7xelte (Samsung Galaxy J7 Prime) Add a framebuffer node to the DTSI in order to ensure that display continues to work, as since v6.19 of devicetree-rebasing sources, it uses Samsung's DECON (Display Enhancement CONtroller) for display, which is, as of yet, not supported in U-Boot. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi diff --git a/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi b/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi new file mode 100644 index 00000000000..c7bd7103e70 --- /dev/null +++ b/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 Kaustabh Chakraborty + */ + +/ { + chosen { + #address-cells = <2>; + #size-cells = <1>; + ranges; + + framebuffer@67000000 { + compatible = "simple-framebuffer"; + reg = <0x0 0x67000000 (1080 * 1920 * 4)>; + width = <1080>; + height = <1920>; + stride = <(1080 * 4)>; + format = "a8r8g8b8"; + }; + }; +}; From de6b405e615232817322416b89bcde637ade40d4 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 17:43:46 +0100 Subject: [PATCH 04/80] video: exynos: node variable should not be unsigned THe variable 'node' is assigned a value of an int, tested for being less than or equal to zero then passed as an argument to a function that takes an int so 'node' should not be unsigned. Fix it. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/video/exynos/exynos_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/exynos/exynos_fb.c b/drivers/video/exynos/exynos_fb.c index 0407a3f51b0..1cc1bd92e57 100644 --- a/drivers/video/exynos/exynos_fb.c +++ b/drivers/video/exynos/exynos_fb.c @@ -350,7 +350,7 @@ void exynos_fimd_window_off(struct exynos_fb_priv *priv, unsigned int win_id) void exynos_fimd_disable_sysmmu(void) { u32 *sysmmufimd; - unsigned int node; + int node; int node_list[2]; int count; int i; From 548e9a254c7d0bd9796decfea43d7759070c7312 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Wed, 1 Oct 2025 11:05:10 +0100 Subject: [PATCH 05/80] video: nexell: unsigned parameter cannot be negative The parameter 'alpha' is declared as an unsigned type so cannot be negative. The code to test it as being less than zero will always fail and so is redundant and should be removed. This issue was found by Smatch. Signed-off-by: Andrew Goodbody Reviewed-by: Stefan Bosch Signed-off-by: Minkyu Kang --- drivers/video/nexell/soc/s5pxx18_soc_mlc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/video/nexell/soc/s5pxx18_soc_mlc.c b/drivers/video/nexell/soc/s5pxx18_soc_mlc.c index c8cf833f308..2c8348bf633 100644 --- a/drivers/video/nexell/soc/s5pxx18_soc_mlc.c +++ b/drivers/video/nexell/soc/s5pxx18_soc_mlc.c @@ -1641,8 +1641,6 @@ void nx_mlc_set_layer_alpha256(u32 module_index, u32 layer, u32 alpha) u32 register_data; register struct nx_mlc_register_set *pregister; - if (alpha < 0) - alpha = 0; if (alpha > 255) alpha = 255; From 3b9f3620b8a26b8b2d580371eefd140791d124e4 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:39 +0530 Subject: [PATCH 06/80] board: samsung: exynos-mobile: simplify parsing RAM banks from device tree Remove the baked-in bank addresses used for figuring out RAM banks from device tree. Instead, sequentially fill in the bank addresses and sizes, and doing away with an extra array for specifying bases. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- board/samsung/exynos-mobile/exynos-mobile.c | 38 ++++++++------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index 8ef38816abf..915bda64082 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -27,7 +27,6 @@ DECLARE_GLOBAL_DATA_PTR; struct exynos_board_info { const char *name; const char *chip; - const u64 *const dram_bank_bases; char serial[64]; @@ -54,10 +53,6 @@ static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { struct mm_region *mem_map = exynos_mem_map; -static const u64 exynos7870_common_dram_bank_bases[CONFIG_NR_DRAM_BANKS] = { - 0x40000000, 0x80000000, 0x100000000, -}; - static const char *exynos_prev_bl_get_bootargs(void) { void *prev_bl_fdt_base = (void *)get_prev_bl_fdt_addr(); @@ -157,7 +152,6 @@ static struct exynos_board_info exynos_board_info_match[] = { /* Samsung Galaxy A2 Core */ .name = "a2corelte", .chip = "exynos7870", - .dram_bank_bases = exynos7870_common_dram_bank_bases, .match = exynos7870_fdt_match, .match_model = "A260", .match_max_rev = U8_MAX, @@ -165,7 +159,6 @@ static struct exynos_board_info exynos_board_info_match[] = { /* Samsung Galaxy J6 */ .name = "j6lte", .chip = "exynos7870", - .dram_bank_bases = exynos7870_common_dram_bank_bases, .match = exynos7870_fdt_match, .match_model = "J600", .match_max_rev = U8_MAX, @@ -173,18 +166,17 @@ static struct exynos_board_info exynos_board_info_match[] = { /* Samsung Galaxy J7 Prime */ .name = "on7xelte", .chip = "exynos7870", - .dram_bank_bases = exynos7870_common_dram_bank_bases, .match = exynos7870_fdt_match, .match_model = "G610", .match_max_rev = U8_MAX, }, }; -static void exynos_parse_dram_banks(const struct exynos_board_info *board_info, - const void *fdt_base) +static void exynos_parse_dram_banks(const void *fdt_base) { u64 mem_addr, mem_size = 0; - u32 na, ns, i, j; + u32 na, ns, i; + int index = 1; int offset; if (fdt_check_header(fdt_base) < 0) @@ -199,6 +191,9 @@ static void exynos_parse_dram_banks(const struct exynos_board_info *board_info, continue; for (i = 0; ; i++) { + if (index > CONFIG_NR_DRAM_BANKS) + break; + mem_addr = fdtdec_get_addr_size_fixed(fdt_base, offset, "reg", i, na, ns, &mem_size, false); @@ -208,17 +203,12 @@ static void exynos_parse_dram_banks(const struct exynos_board_info *board_info, if (!mem_size) continue; - for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) { - if (board_info->dram_bank_bases[j] != mem_addr) - continue; - - mem_map[j + 1].phys = mem_addr; - mem_map[j + 1].virt = mem_addr; - mem_map[j + 1].size = mem_size; - mem_map[j + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE; - break; - } + mem_map[index].phys = mem_addr; + mem_map[index].virt = mem_addr; + mem_map[index].size = mem_size; + mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + index++; } } } @@ -334,7 +324,7 @@ int board_early_init_f(void) return -ENODATA; board_info = (const struct exynos_board_info *)gd->board_type; - exynos_parse_dram_banks(board_info, gd->fdt_blob); + exynos_parse_dram_banks(gd->fdt_blob); /* * Some devices have multiple variants based on the amount of * memory and internal storage. The lowest bank base has been @@ -342,7 +332,7 @@ int board_early_init_f(void) * For variants with more memory, the previous bootloader should * overlay the devicetree with the required extra memory ranges. */ - exynos_parse_dram_banks(board_info, (const void *)get_prev_bl_fdt_addr()); + exynos_parse_dram_banks((const void *)get_prev_bl_fdt_addr()); return 0; } From 23ad0660c11b72a9f720362c801e2e47e9ecd4dc Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:40 +0530 Subject: [PATCH 07/80] board: samsung: exynos-mobile: resolve env vars without board_info data Move environment variable setup procedure to exynos_env_setup(). This function is independent of data from exynos_board_info as it is due for removal in the succeding commits. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- board/samsung/exynos-mobile/exynos-mobile.c | 89 +++++++++++++++++---- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index 915bda64082..c17d7052b1c 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -18,6 +18,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -213,6 +214,76 @@ static void exynos_parse_dram_banks(const void *fdt_base) } } +static void exynos_env_setup(void) +{ + const char *bootargs = exynos_prev_bl_get_bootargs(); + const char *dev_compatible, *soc_compatible; + char *ptr; + char buf[128]; + int nr_compatibles; + int offset; + int ret; + + if (bootargs) { + /* Read the cmdline property which stores the serial number. */ + ret = cmdline_get_arg(bootargs, "androidboot.serialno", &offset); + if (ret > 0) { + strlcpy(buf, bootargs + offset, ret); + env_set("serial#", buf); + } + } + + nr_compatibles = ofnode_read_string_count(ofnode_root(), "compatible"); + if (nr_compatibles < 2) { + log_warning("%s: expected 2 or more compatible strings\n", + __func__); + return; + } + + ret = ofnode_read_string_index(ofnode_root(), "compatible", + nr_compatibles - 1, &soc_compatible); + if (ret) { + log_warning("%s: failed to read SoC compatible\n", + __func__); + return; + } + + ret = ofnode_read_string_index(ofnode_root(), "compatible", 0, + &dev_compatible); + if (ret) { + log_warning("%s: failed to read device compatible\n", + __func__); + return; + } + + /* , => platform = */ + ptr = strchr(soc_compatible, ','); + if (ptr) + soc_compatible = ptr + 1; + env_set("platform", soc_compatible); + + /* , => board = - */ + strlcpy(buf, dev_compatible, sizeof(buf) - 1); + ptr = strchr(buf, ','); + if (ptr) + *ptr = '-'; + env_set("board", buf); + + /* + * NOTE: Board name usually goes as -, but + * upstream device trees for Exynos SoCs are -. + * Extraction of from the board name is required. + */ + ptr = strchr(dev_compatible, ','); + if (ptr) + dev_compatible = ptr + 1; + + /* EFI booting requires the path to correct DTB, specify it here. */ + snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", soc_compatible, + dev_compatible); + env_set("fdtfile", buf); +} + static int exynos_fastboot_setup(void) { struct blk_desc *blk_dev; @@ -371,23 +442,7 @@ int board_init(void) int misc_init_r(void) { - const struct exynos_board_info *board_info; - char buf[128]; - - if (!gd->board_type) - return -ENODATA; - board_info = (const struct exynos_board_info *)gd->board_type; - - env_set("platform", board_info->chip); - env_set("board", board_info->name); - - if (strlen(board_info->serial)) - env_set("serial#", board_info->serial); - - /* EFI booting requires the path to correct dtb, specify it here. */ - snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", board_info->chip, - board_info->name); - env_set("fdtfile", buf); + exynos_env_setup(); return exynos_fastboot_setup(); } From 6220037e7c1bb2086f862bc031b2bfd14009d865 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:41 +0530 Subject: [PATCH 08/80] board: samsung: exynos-mobile: disable MULTI_DTB_FIT support MULTI_DTB_FIT allowed a single U-Boot image to be booted in multiple devices, but it was not a scalable solution; as more devices are added, the U-Boot binary is bound to increase, space taken up by devicetrees which are not even used. The other approach is to be able to build separate images for multiple devices using the same "board" defined in U-Boot. This is used by qcom_phone to support muitiple devices. Follow the said approach for Exynos devices as well, disable MULTI_DTB_FIT for this board. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- board/samsung/exynos-mobile/exynos-mobile.c | 154 -------------------- configs/exynos-mobile_defconfig | 2 - 2 files changed, 156 deletions(-) diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index c17d7052b1c..412dfa7555c 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -25,17 +24,6 @@ DECLARE_GLOBAL_DATA_PTR; #define lmb_alloc(size, addr) \ lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) -struct exynos_board_info { - const char *name; - const char *chip; - - char serial[64]; - - int (*const match)(struct exynos_board_info *); - const char *match_model; - const u8 match_max_rev; -}; - /* * The memory mapping includes all DRAM banks, along with the * peripheral block, and a sentinel at the end. This is filled in @@ -85,94 +73,6 @@ static const char *exynos_prev_bl_get_bootargs(void) return bootargs_prop->data; } -static int exynos7870_fdt_match(struct exynos_board_info *board_info) -{ - const char *prev_bl_bootargs; - int val, ret; - - prev_bl_bootargs = exynos_prev_bl_get_bootargs(); - if (!prev_bl_bootargs) - return -1; - - /* - * Read the cmdline property which stores the - * bootloader/firmware version. An example value of the option - * can be: "J600GDXU3ARH5". This can be used to verify the model - * of the device. - */ - ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.bootloader", &val); - if (ret < 0) { - log_err("%s: unable to find property for bootloader version (%d)\n", - __func__, ret); - return -1; - } - - if (strncmp(prev_bl_bootargs + val, board_info->match_model, - strlen(board_info->match_model))) - return -1; - - /* - * Read the cmdline property which stores the hardware revision. - * This is required to allow selecting one of multiple dtbs - * available of a single device, varying in hardware changes in - * different revisions. - */ - ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.revision", &val); - if (ret < 0) - ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.hw_rev", &val); - if (ret < 0) { - log_err("%s: unable to find property for bootloader revision (%d)\n", - __func__, ret); - return -1; - } - - if (strtoul(prev_bl_bootargs + val, NULL, 10) > board_info->match_max_rev) - return -1; - - /* - * Read the cmdline property which stores the serial number. - * Store this in the board info struct. - */ - ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.serialno", &val); - if (ret > 0) - strlcpy(board_info->serial, prev_bl_bootargs + val, ret); - - return 0; -} - -/* - * This array is used for matching the models and revisions with the - * devicetree used by U-Boot. This allows a single U-Boot to work on - * multiple devices. - * - * Entries are kept in lexicographical order of board SoCs, followed by - * board names. - */ -static struct exynos_board_info exynos_board_info_match[] = { - { - /* Samsung Galaxy A2 Core */ - .name = "a2corelte", - .chip = "exynos7870", - .match = exynos7870_fdt_match, - .match_model = "A260", - .match_max_rev = U8_MAX, - }, { - /* Samsung Galaxy J6 */ - .name = "j6lte", - .chip = "exynos7870", - .match = exynos7870_fdt_match, - .match_model = "J600", - .match_max_rev = U8_MAX, - }, { - /* Samsung Galaxy J7 Prime */ - .name = "on7xelte", - .chip = "exynos7870", - .match = exynos7870_fdt_match, - .match_model = "G610", - .match_max_rev = U8_MAX, - }, -}; - static void exynos_parse_dram_banks(const void *fdt_base) { u64 mem_addr, mem_size = 0; @@ -331,46 +231,6 @@ static int exynos_fastboot_setup(void) return 0; } -int board_fit_config_name_match(const char *name) -{ - struct exynos_board_info *board_info; - char buf[128]; - unsigned int i; - int ret; - - /* - * Iterate over exynos_board_info_match[] to select the - * appropriate board info struct. If not found, exit. - */ - for (i = 0; i < ARRAY_SIZE(exynos_board_info_match); i++) { - board_info = exynos_board_info_match + i; - snprintf(buf, sizeof(buf), "%s-%s", board_info->chip, - board_info->name); - - if (!strcmp(name, buf)) - break; - } - if (i == ARRAY_SIZE(exynos_board_info_match)) - return -1; - - /* - * Execute match logic for the target board. This is separated - * as the process may be different for multiple boards. - */ - ret = board_info->match(board_info); - if (ret) - return ret; - - /* - * Store the correct board info struct in gd->board_type to - * allow other functions to access it. - */ - gd->board_type = (ulong)board_info; - log_debug("%s: device detected: %s\n", __func__, name); - - return 0; -} - int timer_init(void) { ofnode timer_node; @@ -389,21 +249,7 @@ int timer_init(void) int board_early_init_f(void) { - const struct exynos_board_info *board_info; - - if (!gd->board_type) - return -ENODATA; - board_info = (const struct exynos_board_info *)gd->board_type; - exynos_parse_dram_banks(gd->fdt_blob); - /* - * Some devices have multiple variants based on the amount of - * memory and internal storage. The lowest bank base has been - * observed to have the same memory range in all board variants. - * For variants with more memory, the previous bootloader should - * overlay the devicetree with the required extra memory ranges. - */ - exynos_parse_dram_banks((const void *)get_prev_bl_fdt_addr()); return 0; } diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index 3a0b455b169..ead4ea4493e 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -25,8 +25,6 @@ CONFIG_CMD_POWEROFF=y CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y CONFIG_OF_UPSTREAM=y -CONFIG_OF_LIST="exynos/exynos7870-a2corelte exynos/exynos7870-j6lte exynos/exynos7870-on7xelte" -CONFIG_MULTI_DTB_FIT=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y CONFIG_CLK_EXYNOS7870=y From e215c1a558f0c01cdefd9cf90b190bb220c058b6 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:42 +0530 Subject: [PATCH 09/80] board: samsung: exynos-mobile: enable OF_BOARD support OF_BOARD allows to choose the internal device tree in runtime. Use it to pass the external FDT as an internal one if it is not present. This approach is also used by qcom-phone, and it reduces boot image size. It is expected that an external FDT is present as U-Boot is packaged as an Android boot image. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- board/samsung/exynos-mobile/exynos-mobile.c | 9 +++++++++ configs/exynos-mobile_defconfig | 1 + 2 files changed, 10 insertions(+) diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index 412dfa7555c..1f61f28de5f 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -231,6 +231,15 @@ static int exynos_fastboot_setup(void) return 0; } +int board_fdt_blob_setup(void **fdtp) +{ + /* If internal FDT is not available, use the external FDT instead. */ + if (fdt_check_header(*fdtp)) + *fdtp = (void *)get_prev_bl_fdt_addr(); + + return 0; +} + int timer_init(void) { ofnode timer_node; diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index ead4ea4493e..846f9e24bd3 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_POWEROFF=y CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y CONFIG_OF_UPSTREAM=y +CONFIG_OF_BOARD=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y CONFIG_CLK_EXYNOS7870=y From 743b91bab77ee5cb1dbc47f8d1f1245be9f01823 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:43 +0530 Subject: [PATCH 10/80] configs: exynos-mobile: remove DEFAULT_DEVICE_TREE and add OF_UPSTREAM_BUILD_VENDOR Since the build documentation recommends using the DEVICE_TREE= make flag, and the "board" supports multiple devices, remove the default device tree option so as to enforce the make flag during build. OF_UPSTREAM_BUILD_VENDOR is added so as to build all device trees associated with the vendor with their U-Boot includes. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- configs/exynos-mobile_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index 846f9e24bd3..c7d206f94ac 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -7,7 +7,6 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x16000 CONFIG_TARGET_EXYNOS_MOBILE=y CONFIG_NR_DRAM_BANKS=3 -CONFIG_DEFAULT_DEVICE_TREE="exynos/exynos7870-a2corelte" CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_ARMV8_CNTFRQ_BROKEN=y @@ -26,6 +25,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y CONFIG_OF_UPSTREAM=y CONFIG_OF_BOARD=y +CONFIG_OF_UPSTREAM_BUILD_VENDOR=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y CONFIG_CLK_EXYNOS7870=y From ac93c4534fab65e2cb9ee18164c98d247eea844f Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:44 +0530 Subject: [PATCH 11/80] doc: board: samsung: exynos-mobile: add DEVICE_TREE make flag in build Since there is only one internal device tree allowed in U-Boot, the DEVICE_TREE flag is required for building images for various devices. Document it in the build guide. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- doc/board/samsung/exynos-mobile.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/board/samsung/exynos-mobile.rst b/doc/board/samsung/exynos-mobile.rst index 37718af1fea..d0173b1f8cb 100644 --- a/doc/board/samsung/exynos-mobile.rst +++ b/doc/board/samsung/exynos-mobile.rst @@ -25,12 +25,13 @@ If a cross-compiler is required, install it and set it up like so: export CROSS_COMPILE=aarch64-linux-gnu- -Then, run the following commands to build U-Boot: +Then, run the following commands to build U-Boot (replace ```` with the +upstream DTB path for the target device): .. prompt:: bash $ make O=.output exynos-mobile_defconfig - make O=.output -j$(nproc) + make DEVICE_TREE= O=.output -j$(nproc) If successful, the U-Boot binary will be present in ``.output/u-boot.bin``. From be1b1cd641f058a19d2ec5e1ab3bb4d81a3e1e78 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:45 +0530 Subject: [PATCH 12/80] doc: board: samsung: exynos-mobile: use u-boot-nodtb.bin for packaging process U-Boot for this board is programmed to use the external DTB if an internal device tree is not available. This makes it safe to build boot images using the non-DTB U-Boot binary, while taking up less space. Reflect this change in documentation. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- doc/board/samsung/exynos-mobile/exynos7870.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/board/samsung/exynos-mobile/exynos7870.rst b/doc/board/samsung/exynos-mobile/exynos7870.rst index bbd857580b8..37562e272b4 100644 --- a/doc/board/samsung/exynos-mobile/exynos7870.rst +++ b/doc/board/samsung/exynos-mobile/exynos7870.rst @@ -53,7 +53,7 @@ Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image: .. prompt:: bash $ mkbootimg -o u-boot.img \ - --kernel .output/u-boot.bin \ + --kernel .output/u-boot-nodtb.bin \ --dt stub-dt.img Offsets are not provided to ``mkbootimg`` as S-BOOT ignores them. From 579349593a8444166e6e7d1d65326c4b56ab104b Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:46 +0530 Subject: [PATCH 13/80] ARM: dts: exynos7870-a2corelte: add properties to make S-BOOT happy Add properties in the DTSI file which is required for S-BOOT when used an external device tree when booting into U-Boot. S-BOOT is Samsung's proprietary bootloader, which chainloads U-Boot. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi b/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi index c22ed7efea5..7d97afcc64f 100644 --- a/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi +++ b/arch/arm/dts/exynos7870-a2corelte-u-boot.dtsi @@ -4,6 +4,11 @@ */ / { + /* These properties are required by S-BOOT. */ + model_info-chip = <7870>; + model_info-hw_rev = <0>; + model_info-hw_rev_end = <255>; + chosen { #address-cells = <2>; #size-cells = <1>; From cc77806b5d3d8f88d2d9e914fcb8224c0ef192fb Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:47 +0530 Subject: [PATCH 14/80] ARM: dts: exynos7870-j6lte: add properties to make S-BOOT happy Add properties in the DTSI file which is required for S-BOOT when used an external device tree when booting into U-Boot. S-BOOT is Samsung's proprietary bootloader, which chainloads U-Boot. Since this device has multiple bank nodes, add memory nodes for each RAM bank. This is the format S-BOOT recognizes, and (re)populates it with the correct bank sizes. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos7870-j6lte-u-boot.dtsi | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi b/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi index 9d944b127ee..aa499ecf479 100644 --- a/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi +++ b/arch/arm/dts/exynos7870-j6lte-u-boot.dtsi @@ -4,6 +4,11 @@ */ / { + /* These properties are required by S-BOOT. */ + model_info-chip = <7870>; + model_info-hw_rev = <0>; + model_info-hw_rev_end = <255>; + chosen { #address-cells = <2>; #size-cells = <1>; @@ -18,4 +23,24 @@ format = "a8r8g8b8"; }; }; + + /* + * S-BOOT will populate the memory nodes stated below. Existing + * values redefine the safe memory requirements as stated in upstream + * device tree, in separate nodes for each bank. + */ + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0x3d800000>; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x40000000>; + }; + + memory@100000000 { + device_type = "memory"; + reg = <0x1 0x00000000 0x00000000>; + }; }; From d73efc6841c892c8dd06711aac97ac3de503bda8 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:48 +0530 Subject: [PATCH 15/80] ARM: dts: exynos7870-on7xelte: add properties to make S-BOOT happy Add properties in the DTSI file which is required for S-BOOT when used an external device tree when booting into U-Boot. S-BOOT is Samsung's proprietary bootloader, which chainloads U-Boot. Since this device has multiple bank nodes, add memory nodes for each RAM bank. This is the format S-BOOT recognizes, and (re)populates it with the correct bank sizes. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi b/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi index c7bd7103e70..01c3e95b0b3 100644 --- a/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi +++ b/arch/arm/dts/exynos7870-on7xelte-u-boot.dtsi @@ -4,6 +4,11 @@ */ / { + /* These properties are required by S-BOOT. */ + model_info-chip = <7870>; + model_info-hw_rev = <0>; + model_info-hw_rev_end = <255>; + chosen { #address-cells = <2>; #size-cells = <1>; @@ -18,4 +23,19 @@ format = "a8r8g8b8"; }; }; + + /* + * S-BOOT will populate the memory nodes stated below. Existing + * values redefine the safe memory requirements as stated in upstream + * device tree, in separate nodes for each bank. + */ + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0x3e400000>; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x80000000>; + }; }; From 11198fa347390eb449c2a0939f5f00cf510fe285 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 3 Feb 2026 18:38:49 +0530 Subject: [PATCH 16/80] doc: board: samsung: exynos-mobile: remove requirement of stub device tree Flashing U-Boot for Exynos 7870 requires creating a stub device tree, where certain properties and nodes are defined which are populated by the previous bootloader in the phones. Since these properties are now available in the U-Boot device tree, it's now possible to use the same blob generated by U-Boot in place of the stub, when creating boot images. Update the build documentation to reflect the same. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- .../samsung/exynos-mobile/exynos7870.rst | 40 ++----------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/doc/board/samsung/exynos-mobile/exynos7870.rst b/doc/board/samsung/exynos-mobile/exynos7870.rst index 37562e272b4..702b21244eb 100644 --- a/doc/board/samsung/exynos-mobile/exynos7870.rst +++ b/doc/board/samsung/exynos-mobile/exynos7870.rst @@ -6,47 +6,13 @@ Samsung Exynos 7870 Boards Preparation ----------- -Create the following device tree (named ``stub.dts``) -.. code-block:: devicetree - - /dts-v1/; - - / { - compatible = "samsung,exynos7870"; - #address-cells = <2>; - #size-cells = <1>; - - model_info-chip = <7870>; - model_info-hw_rev = <0>; - model_info-hw_rev_end = <255>; - - chosen { - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x0 0x80000000 0x0>; - }; - - memory@100000000 { - device_type = "memory"; - reg = <0x1 0x00000000 0x0>; - }; - }; - -The chosen node and memory ranges are populated by S-BOOT. A certain device -model may have multiple variants, with differing amounts of RAM and storage. The -RAM capacity information is graciously provided by S-BOOT's device tree -overlays. - -Compile it to a device tree blob, then pack it in the QCDT format [1]_ using -``dtbTool-exynos`` [2]_ by issuing the following commands: +Pack the device tree blob in the QCDT format [1]_ using ``dtbTool-exynos`` [2]_ +by issuing the following commands: .. prompt:: bash $ - dtc -I dts -O dtb -o stub.dtb stub.dts - dtbTool-exynos -o stub-dt.img stub.dtb + dtbTool-exynos -o stub-dt.img .output/u-boot.dtb Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image: From 7accb716c10c231e3785b47d02929919b3c5cd86 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Thu, 5 Feb 2026 09:07:49 +0100 Subject: [PATCH 17/80] gpio: stm32-gpio: prevent the use of the secure protected pins The hardware denies any access from the U-Boot non-secure world to the secure-protected pins. Hence, prevent any driver to request such a pin. Signed-off-by: Fabien Dessenne Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- drivers/gpio/stm32_gpio.c | 25 +++++++++++++++++++++++++ drivers/gpio/stm32_gpio_priv.h | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index b8eb55465d3..e354a4148ca 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -32,6 +32,9 @@ #define OTYPE_BITS(gpio_pin) (gpio_pin) #define OTYPE_MSK 1 +#define SECCFG_BITS(gpio_pin) (gpio_pin) +#define SECCFG_MSK 1 + static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs, int idx, int mode) @@ -89,6 +92,27 @@ static bool stm32_gpio_is_mapped(struct udevice *dev, int offset) return !!(priv->gpio_range & BIT(offset)); } +static int stm32_gpio_request(struct udevice *dev, unsigned int offset, const char *label) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + ulong drv_data = dev_get_driver_data(dev); + + if (!stm32_gpio_is_mapped(dev, offset)) + return -ENXIO; + + /* Deny request access if IO is secured */ + if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) && + ((readl(®s->seccfgr) >> SECCFG_BITS(offset)) & SECCFG_MSK)) { + dev_err(dev, "Failed to get secure IO %s %d @ %p\n", + uc_priv->bank_name, offset, regs); + return -EACCES; + } + + return 0; +} + static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) { struct stm32_gpio_priv *priv = dev_get_priv(dev); @@ -238,6 +262,7 @@ static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset, } static const struct dm_gpio_ops gpio_stm32_ops = { + .request = stm32_gpio_request, .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, .get_value = stm32_gpio_get_value, diff --git a/drivers/gpio/stm32_gpio_priv.h b/drivers/gpio/stm32_gpio_priv.h index 662a000fe73..d89e9b8ed60 100644 --- a/drivers/gpio/stm32_gpio_priv.h +++ b/drivers/gpio/stm32_gpio_priv.h @@ -51,6 +51,8 @@ enum stm32_gpio_af { STM32_GPIO_AF15 }; +#define STM32_GPIO_FLAG_SEC_CTRL BIT(0) + struct stm32_gpio_dsc { u8 port; u8 pin; @@ -74,6 +76,9 @@ struct stm32_gpio_regs { u32 bsrr; /* GPIO port bit set/reset */ u32 lckr; /* GPIO port configuration lock */ u32 afr[2]; /* GPIO alternate function */ + u32 brr; /* GPIO port bit reset */ + u32 rfu; /* Reserved */ + u32 seccfgr; /* GPIO secure configuration */ }; struct stm32_gpio_priv { From 04dcaadd4392d8b7498e6e80a977e0cd67074558 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Thu, 5 Feb 2026 09:07:50 +0100 Subject: [PATCH 18/80] pinctrl: pinctrl_stm32: prevent the use of the secure protected pins The hardware denies any access from the U-Boot non-secure world to the secure-protected pins. Hence, prevent any driver to configure such a pin. Identify the secure pins with "NO ACCESS" through the 'pinmux status -a' command. Use a driver data structure to identify which hardware versions support this feature. Signed-off-by: Fabien Dessenne Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- drivers/pinctrl/pinctrl_stm32.c | 83 ++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index fbf0271f08a..1758f9a909c 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #define PUPD_MASK 3 #define OTYPE_MSK 1 #define AFR_MASK 0xF +#define SECCFG_MSK 1 struct stm32_pinctrl_priv { struct hwspinlock hws; @@ -39,7 +41,12 @@ struct stm32_gpio_bank { struct list_head list; }; +struct stm32_pinctrl_data { + bool secure_control; +}; + #ifndef CONFIG_XPL_BUILD +static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx); static char pin_name[PINNAME_SIZE]; static const char * const pinmux_mode[GPIOF_COUNT] = { @@ -216,6 +223,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, if (!gpio_dev) return -ENODEV; + /* Check access protection */ + if (stm32_pinctrl_get_access(gpio_dev, gpio_idx)) { + snprintf(buf, size, "NO ACCESS"); + return 0; + } + mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label); dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", selector, gpio_idx, mode); @@ -252,6 +265,20 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, #endif +static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx) +{ + struct stm32_gpio_priv *priv = dev_get_priv(gpio_dev); + struct stm32_gpio_regs *regs = priv->regs; + ulong drv_data = dev_get_driver_data(gpio_dev); + + /* Deny request access if IO is secured */ + if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) && + ((readl(®s->seccfgr) >> gpio_idx) & SECCFG_MSK)) + return -EACCES; + + return 0; +} + static int stm32_pinctrl_probe(struct udevice *dev) { struct stm32_pinctrl_priv *priv = dev_get_priv(dev); @@ -279,6 +306,14 @@ static int stm32_gpio_config(ofnode node, int ret; u32 index; + /* Check access protection */ + ret = stm32_pinctrl_get_access(desc->dev, desc->offset); + if (ret) { + dev_err(desc->dev, "Failed to get secure IO %s %d @ %p\n", + uc_priv->bank_name, desc->offset, regs); + return ret; + } + if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 || ctl->pupd > 2 || ctl->speed > 3) return -EINVAL; @@ -414,8 +449,25 @@ static int stm32_pinctrl_bind(struct udevice *dev) { ofnode node; const char *name; + struct driver *drv; + const struct stm32_pinctrl_data *drv_data; + ulong gpio_data = 0; int ret; + drv = lists_driver_lookup_name("gpio_stm32"); + if (!drv) { + debug("Cannot find driver 'gpio_stm32'\n"); + return -ENOENT; + } + + drv_data = (const struct stm32_pinctrl_data *)dev_get_driver_data(dev); + if (!drv_data) { + debug("Cannot find driver data\n"); + return -EINVAL; + } + if (drv_data->secure_control) + gpio_data = STM32_GPIO_FLAG_SEC_CTRL; + dev_for_each_subnode(node, dev) { dev_dbg(dev, "bind %s\n", ofnode_get_name(node)); @@ -431,8 +483,7 @@ static int stm32_pinctrl_bind(struct udevice *dev) return -EINVAL; /* Bind each gpio node */ - ret = device_bind_driver_to_node(dev, "gpio_stm32", - name, node, NULL); + ret = device_bind_with_driver_data(dev, drv, name, gpio_data, node, NULL); if (ret) return ret; @@ -495,17 +546,25 @@ static struct pinctrl_ops stm32_pinctrl_ops = { #endif }; +static const struct stm32_pinctrl_data stm32_pinctrl_no_sec = { + .secure_control = false, +}; + +static const struct stm32_pinctrl_data stm32_pinctrl_with_sec = { + .secure_control = true, +}; + static const struct udevice_id stm32_pinctrl_ids[] = { - { .compatible = "st,stm32f429-pinctrl" }, - { .compatible = "st,stm32f469-pinctrl" }, - { .compatible = "st,stm32f746-pinctrl" }, - { .compatible = "st,stm32f769-pinctrl" }, - { .compatible = "st,stm32h743-pinctrl" }, - { .compatible = "st,stm32mp157-pinctrl" }, - { .compatible = "st,stm32mp157-z-pinctrl" }, - { .compatible = "st,stm32mp135-pinctrl" }, - { .compatible = "st,stm32mp257-pinctrl" }, - { .compatible = "st,stm32mp257-z-pinctrl" }, + { .compatible = "st,stm32f429-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32f469-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32f746-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32f769-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32h743-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32mp157-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32mp157-z-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32mp135-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, + { .compatible = "st,stm32mp257-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, + { .compatible = "st,stm32mp257-z-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, { } }; From 71433d2771611961c5ccdc4f335bc4d147c3b5d3 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 5 Feb 2026 09:50:24 +0100 Subject: [PATCH 19/80] stm32mp: stm32prog: Remove fsbl_nor_detected from stm32prog_data struct No more need to test if a fsbl partition is present on NOR when booting from serial or USB. Now MTD devices are automatically populated with partition information found in DT. Remove fsbl_nor_detected boolean from stm32prog_data struct and all code using it. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 8 -------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 10 ---------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 1 - arch/arm/mach-stm32mp/include/mach/stm32prog.h | 2 -- 4 files changed, 21 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 506ecac2ef0..24503bbe58c 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -187,11 +187,3 @@ U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog, " = address of flashlayout\n" " = size of flashlayout (optional for image with STM32 header)\n" ); - -bool stm32prog_get_fsbl_nor(void) -{ - if (stm32prog_data) - return stm32prog_data->fsbl_nor_detected; - - return false; -} diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 9acbc0689a9..835eaf48dfa 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1010,7 +1010,6 @@ static int treat_partition_list(struct stm32prog_data *data) INIT_LIST_HEAD(&data->dev[j].part_list); } - data->fsbl_nor_detected = false; for (i = 0; i < data->part_nb; i++) { part = &data->part_array[i]; part->alt_id = -1; @@ -1055,15 +1054,6 @@ static int treat_partition_list(struct stm32prog_data *data) stm32prog_err("Layout: too many device"); return -EINVAL; } - switch (part->target) { - case STM32PROG_NOR: - if (!data->fsbl_nor_detected && - !strncmp(part->name, "fsbl", 4)) - data->fsbl_nor_detected = true; - /* fallthrough */ - default: - break; - } part->dev = &data->dev[j]; if (!IS_SELECT(part)) part->dev->full_update = false; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index bf184c8a884..929e38700e1 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -167,7 +167,6 @@ struct stm32prog_data { struct stm32prog_dev_t dev[STM32PROG_MAX_DEV]; /* array of device */ int part_nb; /* nb of partition */ struct stm32prog_part_t *part_array; /* array of partition */ - bool fsbl_nor_detected; /* command internal information */ unsigned int phase; diff --git a/arch/arm/mach-stm32mp/include/mach/stm32prog.h b/arch/arm/mach-stm32mp/include/mach/stm32prog.h index 23d1adfbad9..c10bff09c84 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32prog.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32prog.h @@ -10,5 +10,3 @@ int stm32prog_write_medium_virt(struct dfu_entity *dfu, u64 offset, int stm32prog_read_medium_virt(struct dfu_entity *dfu, u64 offset, void *buf, long *len); int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size); - -bool stm32prog_get_fsbl_nor(void); From 5d5195073ca4913a7eb82e0354e45ba8504feb84 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 10 Feb 2026 15:57:35 +0100 Subject: [PATCH 20/80] stm32mp: fix array bounds checks Fix index check against array size. If that index is equal to the array size, we'll access one-past-the-end of the array. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-stm32mp/stm32mp2/cpu.c b/arch/arm/mach-stm32mp/stm32mp2/cpu.c index e081dc605b8..a8a6bcf8ab4 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/cpu.c +++ b/arch/arm/mach-stm32mp/stm32mp2/cpu.c @@ -148,7 +148,7 @@ static void setup_boot_mode(void) __func__, boot_ctx, boot_mode, instance, forced_mode); switch (boot_mode & TAMP_BOOT_DEVICE_MASK) { case BOOT_SERIAL_UART: - if (instance > ARRAY_SIZE(serial_addr)) + if (instance >= ARRAY_SIZE(serial_addr)) break; /* serial : search associated node in devicetree */ sprintf(cmd, "serial@%x", serial_addr[instance]); @@ -178,7 +178,7 @@ static void setup_boot_mode(void) break; case BOOT_FLASH_SD: case BOOT_FLASH_EMMC: - if (instance > ARRAY_SIZE(sdmmc_addr)) + if (instance >= ARRAY_SIZE(sdmmc_addr)) break; /* search associated sdmmc node in devicetree */ sprintf(cmd, "mmc@%x", sdmmc_addr[instance]); From d5cedabe8b55b4b58b8bd9a5c20de3a307be36d1 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 5 Feb 2026 17:20:49 +0100 Subject: [PATCH 21/80] stm32mp2: Update size of DDR entry in MMU table On 1GB board, in particular cases, a prefetch operation is done just above the 1GB boundary. The DDR size is 1GB (0x80000000 to 0xc0000000), there is an access on 0xc00017c0 (ie 0x800017c0). As beginning of DDR is protected by MMU until CONFIG_TEXT_BASE (0x80000000 to 0x84000000), it triggers the following IAC: E/TC:0 stm32_iac_itr:192 IAC exceptions [159:128]: 0x200 E/TC:0 stm32_iac_itr:197 IAC exception ID: 137 I/TC: DUMPING DATA FOR risaf@420d0000 I/TC: ===================================================== I/TC: Status register (IAESR0): 0x11 I/TC: ----------------------------------------------------- I/TC: Faulty address (IADDR0): 0xc00017c0 I/TC: ===================================================== E/TC:0 Panic at /usr/src/debug/optee-os-stm32mp/4.0.0-gitvalid.8> E/TC:0 TEE load address @ 0x82000000 E/TC:0 Call stack: E/TC:0 0x82007f30 E/TC:0 0x820444b4 E/TC:0 0x8202dc54 E/TC:0 0x82041fe0 E/TC:0 0x820143b8 By default, in MMU table, the DDR size is set to 4GB, but not all STM32MP2 based board embeds 4GB, some has only 1 or 2GB of DDR. The MMU table entry dedicated to DDR need to be updated with the real DDR size previously read from DT. After relocation, in enable_caches(), update the MMU table between the dcache_disable() / dcache_enable() with the real DDR size. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/cpu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/mach-stm32mp/stm32mp2/cpu.c b/arch/arm/mach-stm32mp/stm32mp2/cpu.c index a8a6bcf8ab4..178c6356b2b 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/cpu.c +++ b/arch/arm/mach-stm32mp/stm32mp2/cpu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -70,8 +71,21 @@ int mach_cpu_init(void) void enable_caches(void) { + struct mm_region *mem = mem_map; + /* deactivate the data cache, early enabled in arch_cpu_init() */ dcache_disable(); + + /* Parse mem_map and find DDR entry */ + while (mem->size) { + if (mem->phys == CONFIG_TEXT_BASE) { + /* update DDR entry with real DDR size */ + mem->size = gd->ram_size; + break; + } + mem++; + } + /* * Force the call of setup_all_pgtables() in mmu_setup() by clearing tlb_fillptr * to update the TLB location udpated in board_f.c::reserve_mmu From 32912d0908bbdb56a8863e835a2edc6e13c7159a Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 11 Feb 2026 15:32:22 +0100 Subject: [PATCH 22/80] board: st: common: Add support of stm32mp21xx-dk board Add board identifier for STM32MP21 discovery board = MB2059. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- board/st/common/cmd_stboard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c index b9d0abdba7d..d77046499a0 100644 --- a/board/st/common/cmd_stboard.c +++ b/board/st/common/cmd_stboard.c @@ -51,6 +51,7 @@ static bool check_stboard(u16 board) 0x1605, /* stm32mp25xx-dk */ 0x1635, 0x1936, /* stm32mp25xx-ev1 */ + 0x2059, /* stm32mp21xx-dk */ }; for (i = 0; i < ARRAY_SIZE(st_board_id); i++) From 6a6f2eb3e6a78abf76566df1e57b85a2a3d35ee2 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 11 Feb 2026 15:32:23 +0100 Subject: [PATCH 23/80] board: st: common: add uclass_get_device_by_driver()'s return value check class_get_device_by_driver()'s return value is not checked, in case of BSEC driver is not probed, dev is not set and used just after as parameter of misc_read() which leads to a Synchronous Abort. Add uclass_get_device_by_driver()'s return value check to fix it. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- board/st/common/cmd_stboard.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c index d77046499a0..58d9f205b92 100644 --- a/board/st/common/cmd_stboard.c +++ b/board/st/common/cmd_stboard.c @@ -92,6 +92,11 @@ static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc, DM_DRIVER_GET(stm32mp_bsec), &dev); + if (ret) { + puts("Can't get BSEC device\n"); + return CMD_RET_FAILURE; + } + ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), &otp, sizeof(otp)); From afa8f076db3e4ff322455e4b13b796f39c30eb14 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sat, 10 Jan 2026 20:56:10 +0100 Subject: [PATCH 24/80] arm: armv8: Flush TLB before enabling MMU Commit 9ebdbbc43e5f ("arm: armv8: invalidate dcache entries on dcache_enable") broke Apple Silicon machines in certain scenarios. If the MMU is currently not enabled we need to flush the TLB before we enable it to prevent stale TLB entries from becoming active again. So move the __asm_invalidate_tlb_all() back immediately before the mmu_setup() call. Fixes: 9ebdbbc43e5f ("arm: armv8: invalidate dcache entries on dcache_enable") Signed-off-by: Mark Kettenis Reviewed-by: Ilias Apalodimas --- arch/arm/cpu/armv8/cache_v8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 0309da6d397..39479df7b21 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -878,15 +878,16 @@ void flush_dcache_range(unsigned long start, unsigned long stop) void dcache_enable(void) { /* The data cache is not active unless the mmu is enabled */ - if (!mmu_status()) + if (!mmu_status()) { + __asm_invalidate_tlb_all(); mmu_setup(); + } /* Set up page tables only once (it is done also by mmu_setup()) */ if (!gd->arch.tlb_fillptr) setup_all_pgtables(); invalidate_dcache_all(); - __asm_invalidate_tlb_all(); set_sctlr(get_sctlr() | CR_C); } From 26048cdb4ce35b4119e82df2aafb1ebf3f611480 Mon Sep 17 00:00:00 2001 From: Devarsh Thakkar Date: Tue, 24 Feb 2026 19:15:57 +0530 Subject: [PATCH 25/80] arm: mach-k3: common: Clamp RAM end address to board-usable region in spl_enable_cache() commit ba20b2443c29 ("arm: mach-k3: common: Reserve video memory from end of the RAM") switched spl_enable_cache() to use gd->ram_top directly but omitted the board_get_usable_ram_top() call that limits RAM configuration and provides updated RAM end address per memory map used by board and impacts subsequent allocations and reservations. For e.g. here it impacts how high the TLB may be placed. On Verdin AM62 (512 MiB), the raw end of RAM (0xA0000000) is inside OP-TEE's region. board_get_usable_ram_top() in verdin-am62.c returns 0x9C000000 to keep relocations below it, but spl_enable_cache() never called it. commit 42b3ee7fa524 ("arm: mach-k3: am62x: Enable memory firewall support") then enforced the OP-TEE firewall, turning the silent corruption into a hard hang. Fix by calling board_get_usable_ram_top() after computing raw ram_top, consistent with setup_dest_addr() in board_f.c. A weak default is provided for boards that do not need to restrict the RAM top. Fixes: ba20b2443c29 ("arm: mach-k3: common: Reserve video memory from end of the RAM") Reported-by: Francesco Dolcini Link: https://lore.kernel.org/all/20260224102121.GB340942@francesco-nb/ Signed-off-by: Devarsh Thakkar Tested-by: Francesco Dolcini # Verdin AM62 512MB --- arch/arm/mach-k3/common.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 0a686efa131..2f3df5519c5 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -407,6 +407,11 @@ void k3_fix_rproc_clock(const char *path) path, a_core_frequency / 1000000, speed_grade); } +__weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size) +{ + return gd->ram_top; +} + void spl_enable_cache(void) { #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) @@ -420,6 +425,7 @@ void spl_enable_cache(void) gd->arch.tlb_size = PGTABLE_SIZE; gd->ram_top += get_effective_memsize(); + gd->ram_top = board_get_usable_ram_top(0); gd->relocaddr = gd->ram_top; ret = spl_reserve_video_from_ram_top(); From 0b2939464feef001e4d4b69578f29a7a4d572fcd Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Mon, 23 Feb 2026 13:40:04 -0700 Subject: [PATCH 26/80] boot: fit: validate FDT/DTO payload before fdt_open_into() boot_get_fdt_fit_into_buffer() calls fdt_open_into() for both the base FDT and overlay DTO blobs loaded from a FIT image. Those blobs come from FIT payload data. In the overlay path, fit_image_load() is called with FIT_LOAD_IGNORED, so the IH_TYPE_FLATDT header check in fit_image_load() is skipped. This leaves fdt_open_into() to consume header-derived offsets/sizes from unvalidated input. Validate the full blob against the payload length first with fdt_check_full(fdtsrcbuf, srclen), then proceed with fdt_totalsize() and fdt_open_into(). This fixes Coverity CID 644638 (TAINTED_SCALAR). Fixes: 5ebf0c55a23 ("image: fit: Apply overlays using aligned writable FDT copies") Link: https://lore.kernel.org/all/20260223195109.GG3233182@bill-the-cat/ Signed-off-by: James Hilliard Reviewed-by: Tom Rini --- boot/image-fit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boot/image-fit.c b/boot/image-fit.c index ddc64debb14..e7c7212195f 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -2390,6 +2390,14 @@ static int boot_get_fdt_fit_into_buffer(const void *src, ulong srclen, fdtsrcbuf = tmp; } + /* + * Source data comes from FIT payload. Validate the blob against + * payload length before fdt_open_into() trusts header offsets/sizes. + */ + err = fdt_check_full(fdtsrcbuf, srclen); + if (err < 0) + goto out; + newdstlen = ALIGN(fdt_totalsize(fdtsrcbuf) + extra, SZ_4K); min_dstlen = ALIGN(min_dstlen, SZ_4K); if (newdstlen < min_dstlen) From a44b36a044f2307a46d6b6a15f96144b6e437695 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:21 +0100 Subject: [PATCH 27/80] clk: stm32mp21: Add clock driver support Add clock driver support for STM32MP21 SoCs. Signed-off-by: Nicolas Le Bayon Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- drivers/clk/stm32/Kconfig | 9 + drivers/clk/stm32/Makefile | 1 + drivers/clk/stm32/clk-stm32mp21.c | 709 ++++++++++++++++++++++++++++++ include/stm32mp21_rcc.h | 651 +++++++++++++++++++++++++++ 4 files changed, 1370 insertions(+) create mode 100644 drivers/clk/stm32/clk-stm32mp21.c create mode 100644 include/stm32mp21_rcc.h diff --git a/drivers/clk/stm32/Kconfig b/drivers/clk/stm32/Kconfig index ea856be1662..4e488136eac 100644 --- a/drivers/clk/stm32/Kconfig +++ b/drivers/clk/stm32/Kconfig @@ -37,6 +37,15 @@ config CLK_STM32MP13 Enable the STM32 clock (RCC) driver. Enable support for manipulating STM32MP13's on-SoC clocks. +config CLK_STM32MP21 + bool "Enable RCC clock driver for STM32MP21" + depends on ARCH_STM32MP && CLK + default y if STM32MP21X + select CLK_STM32_CORE + help + Enable the STM32 clock (RCC) driver. Enable support for + manipulating STM32MP21's on-SoC clocks. + config CLK_STM32MP25 bool "Enable RCC clock driver for STM32MP25" depends on ARCH_STM32MP && CLK diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile index 56adb8a4bbb..0b849c52a3b 100644 --- a/drivers/clk/stm32/Makefile +++ b/drivers/clk/stm32/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_CLK_STM32F) += clk-stm32f.o obj-$(CONFIG_CLK_STM32H7) += clk-stm32h7.o obj-$(CONFIG_CLK_STM32MP1) += clk-stm32mp1.o obj-$(CONFIG_CLK_STM32MP13) += clk-stm32mp13.o +obj-$(CONFIG_CLK_STM32MP21) += clk-stm32mp21.o obj-$(CONFIG_CLK_STM32MP25) += clk-stm32mp25.o diff --git a/drivers/clk/stm32/clk-stm32mp21.c b/drivers/clk/stm32/clk-stm32mp21.c new file mode 100644 index 00000000000..ad990b6ad93 --- /dev/null +++ b/drivers/clk/stm32/clk-stm32mp21.c @@ -0,0 +1,709 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2026, STMicroelectronics - All Rights Reserved + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "clk-stm32-core.h" +#include "stm32mp21_rcc.h" + +/* Clock security definition */ +#define SECF_NONE -1 + +#define RCC_REG_SIZE 32 +#define RCC_SECCFGR(x) (((x) / RCC_REG_SIZE) * 0x4 + RCC_SECCFGR0) +#define RCC_CIDCFGR(x) ((x) * 0x8 + RCC_R0CIDCFGR) +#define RCC_SEMCR(x) ((x) * 0x8 + RCC_R0SEMCR) +#define RCC_CID1 1 + +/* Register: RIFSC_CIDCFGR */ +#define RCC_CIDCFGR_CFEN BIT(0) +#define RCC_CIDCFGR_SEM_EN BIT(1) +#define RCC_CIDCFGR_SEMWLC1_EN BIT(17) +#define RCC_CIDCFGR_SCID_MASK GENMASK(6, 4) + +/* Register: RIFSC_SEMCR */ +#define RCC_SEMCR_SEMCID_MASK GENMASK(6, 4) + +#define STM32MP21_RIFRCC_DBG_ID 73 +#define STM32MP21_RIFRCC_MCO1_ID 108 +#define STM32MP21_RIFRCC_MCO2_ID 109 +#define STM32MP21_RIFRCC_OSPI1_ID 110 + +#define SEC_RIFSC_FLAG BIT(31) +#define SEC_RIFRCC(_id) (STM32MP21_RIFRCC_##_id##_ID) +#define SEC_RIFSC(_id) ((_id) | SEC_RIFSC_FLAG) + +/* must match scmi clock order found in DT */ +enum { + IDX_HSE, + IDX_HSI, + IDX_MSI, + IDX_LSE, + IDX_LSI, + IDX_HSE_DIV2, + IDX_ICN_HS_MCU, + IDX_ICN_LS_MCU, + IDX_ICN_SDMMC, + IDX_ICN_DDR, + IDX_ICN_DISPLAY, + IDX_ICN_HSL, + IDX_ICN_NIC, + IDX_FLEXGEN_07, + IDX_FLEXGEN_08, + IDX_FLEXGEN_09, + IDX_FLEXGEN_10, + IDX_FLEXGEN_11, + IDX_FLEXGEN_12, + IDX_FLEXGEN_13, + IDX_FLEXGEN_14, + IDX_FLEXGEN_16, + IDX_FLEXGEN_17, + IDX_FLEXGEN_18, + IDX_FLEXGEN_19, + IDX_FLEXGEN_20, + IDX_FLEXGEN_21, + IDX_FLEXGEN_22, + IDX_FLEXGEN_23, + IDX_FLEXGEN_24, + IDX_FLEXGEN_25, + IDX_FLEXGEN_26, + IDX_FLEXGEN_27, + IDX_FLEXGEN_28, + IDX_FLEXGEN_29, + IDX_FLEXGEN_30, + IDX_FLEXGEN_31, + IDX_FLEXGEN_33, + IDX_FLEXGEN_36, + IDX_FLEXGEN_37, + IDX_FLEXGEN_38, + IDX_FLEXGEN_39, + IDX_FLEXGEN_40, + IDX_FLEXGEN_41, + IDX_FLEXGEN_42, + IDX_FLEXGEN_43, + IDX_FLEXGEN_44, + IDX_FLEXGEN_45, + IDX_FLEXGEN_46, + IDX_FLEXGEN_47, + IDX_FLEXGEN_48, + IDX_FLEXGEN_50, + IDX_FLEXGEN_51, + IDX_FLEXGEN_52, + IDX_FLEXGEN_53, + IDX_FLEXGEN_54, + IDX_FLEXGEN_55, + IDX_FLEXGEN_56, + IDX_FLEXGEN_57, + IDX_FLEXGEN_58, + IDX_FLEXGEN_61, + IDX_FLEXGEN_62, + IDX_FLEXGEN_63, + IDX_ICN_APB1, + IDX_ICN_APB2, + IDX_ICN_APB3, + IDX_ICN_APB4, + IDX_ICN_APB5, + IDX_ICN_APBDBG, + IDX_TIMG1, + IDX_TIMG2, +}; + +static const struct clk_parent_data adc1_src[] = { + { .index = IDX_FLEXGEN_46 }, + { .index = IDX_ICN_LS_MCU }, +}; + +static const struct clk_parent_data adc2_src[] = { + { .index = IDX_FLEXGEN_47 }, + { .index = IDX_ICN_LS_MCU }, + { .index = IDX_FLEXGEN_46 }, +}; + +static const struct clk_parent_data usb2phy1_src[] = { + { .index = IDX_FLEXGEN_57 }, + { .index = IDX_HSE_DIV2 }, +}; + +static const struct clk_parent_data usb2phy2_src[] = { + { .index = IDX_FLEXGEN_58 }, + { .index = IDX_HSE_DIV2 }, +}; + +static const struct clk_parent_data dts_src[] = { + { .index = IDX_HSI }, + { .index = IDX_HSE }, + { .index = IDX_MSI }, +}; + +static const struct clk_parent_data mco1_src[] = { + { .index = IDX_FLEXGEN_61 }, + { .name = "ck_obs0" }, +}; + +static const struct clk_parent_data mco2_src[] = { + { .index = IDX_FLEXGEN_62 }, + { .name = "ck_obs1" }, +}; + +enum enum_mux_cfg { + MUX_MCO1, + MUX_MCO2, + MUX_ADC1, + MUX_ADC2, + MUX_USB2PHY1, + MUX_USB2PHY2, + MUX_DTS, + MUX_NB +}; + +#define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\ + .num_parents = ARRAY_SIZE(src),\ + .parent_data = src,\ + .reg_off = (_offset),\ + .shift = (_shift),\ + .width = (_witdh),\ +} + +static const struct stm32_mux_cfg stm32mp21_muxes[MUX_NB] = { + MUX_CFG(MUX_ADC1, adc1_src, RCC_ADC1CFGR, 12, 1), + MUX_CFG(MUX_ADC2, adc2_src, RCC_ADC2CFGR, 12, 2), + MUX_CFG(MUX_DTS, dts_src, RCC_DTSCFGR, 12, 2), + MUX_CFG(MUX_MCO1, mco1_src, RCC_MCO1CFGR, 0, 1), + MUX_CFG(MUX_MCO2, mco2_src, RCC_MCO2CFGR, 0, 1), + MUX_CFG(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1), + MUX_CFG(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1), +}; + +enum enum_gate_cfg { + GATE_ADC1, + GATE_ADC2, + GATE_CRC, + GATE_CRYP1, + GATE_CRYP2, + GATE_CSI, + GATE_DBG, + GATE_DCMIPP, + GATE_DTS, + GATE_ETH1, + GATE_ETH1MAC, + GATE_ETH1RX, + GATE_ETH1STP, + GATE_ETH1TX, + GATE_ETH2, + GATE_ETH2MAC, + GATE_ETH2RX, + GATE_ETH2STP, + GATE_ETH2TX, + GATE_ETR, + GATE_FDCAN, + GATE_HASH1, + GATE_HASH2, + GATE_HDP, + GATE_I2C1, + GATE_I2C2, + GATE_I2C3, + GATE_I3C1, + GATE_I3C2, + GATE_I3C3, + GATE_IWDG1, + GATE_IWDG2, + GATE_IWDG3, + GATE_IWDG4, + GATE_LPTIM1, + GATE_LPTIM2, + GATE_LPTIM3, + GATE_LPTIM4, + GATE_LPTIM5, + GATE_LPUART1, + GATE_LTDC, + GATE_MCO1, + GATE_MCO2, + GATE_MDF1, + GATE_OSPI1, + GATE_PKA, + GATE_RNG1, + GATE_RNG2, + GATE_SAES, + GATE_SAI1, + GATE_SAI2, + GATE_SAI3, + GATE_SAI4, + GATE_SDMMC1, + GATE_SDMMC2, + GATE_SDMMC3, + GATE_SERC, + GATE_SPDIFRX, + GATE_SPI1, + GATE_SPI2, + GATE_SPI3, + GATE_SPI4, + GATE_SPI5, + GATE_SPI6, + GATE_STGEN, + GATE_STM, + GATE_TIM1, + GATE_TIM2, + GATE_TIM3, + GATE_TIM4, + GATE_TIM5, + GATE_TIM6, + GATE_TIM7, + GATE_TIM8, + GATE_TIM10, + GATE_TIM11, + GATE_TIM12, + GATE_TIM13, + GATE_TIM14, + GATE_TIM15, + GATE_TIM16, + GATE_TIM17, + GATE_TRACE, + GATE_UART4, + GATE_UART5, + GATE_UART7, + GATE_USART1, + GATE_USART2, + GATE_USART3, + GATE_USART6, + GATE_USBH, + GATE_USBOTG, + GATE_USB2PHY1, + GATE_USB2PHY2, + GATE_VREF, + GATE_WWDG1, + GATE_NB +}; + +#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\ + .reg_off = (_offset),\ + .bit_idx = (_bit_idx),\ + .set_clr = (_offset_clr),\ +} + +static const struct stm32_gate_cfg stm32mp21_gates[GATE_NB] = { + GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 8, 0), + GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 8, 0), + GATE_CFG(GATE_OSPI1, RCC_OSPI1CFGR, 1, 0), + GATE_CFG(GATE_DBG, RCC_DBGCFGR, 8, 0), + GATE_CFG(GATE_TRACE, RCC_DBGCFGR, 9, 0), + GATE_CFG(GATE_STM, RCC_STMCFGR, 1, 0), + GATE_CFG(GATE_ETR, RCC_ETRCFGR, 1, 0), + GATE_CFG(GATE_TIM1, RCC_TIM1CFGR, 1, 0), + GATE_CFG(GATE_TIM2, RCC_TIM2CFGR, 1, 0), + GATE_CFG(GATE_TIM3, RCC_TIM3CFGR, 1, 0), + GATE_CFG(GATE_TIM4, RCC_TIM4CFGR, 1, 0), + GATE_CFG(GATE_TIM5, RCC_TIM5CFGR, 1, 0), + GATE_CFG(GATE_TIM6, RCC_TIM6CFGR, 1, 0), + GATE_CFG(GATE_TIM7, RCC_TIM7CFGR, 1, 0), + GATE_CFG(GATE_TIM8, RCC_TIM8CFGR, 1, 0), + GATE_CFG(GATE_TIM10, RCC_TIM10CFGR, 1, 0), + GATE_CFG(GATE_TIM11, RCC_TIM11CFGR, 1, 0), + GATE_CFG(GATE_TIM12, RCC_TIM12CFGR, 1, 0), + GATE_CFG(GATE_TIM13, RCC_TIM13CFGR, 1, 0), + GATE_CFG(GATE_TIM14, RCC_TIM14CFGR, 1, 0), + GATE_CFG(GATE_TIM15, RCC_TIM15CFGR, 1, 0), + GATE_CFG(GATE_TIM16, RCC_TIM16CFGR, 1, 0), + GATE_CFG(GATE_TIM17, RCC_TIM17CFGR, 1, 0), + GATE_CFG(GATE_LPTIM1, RCC_LPTIM1CFGR, 1, 0), + GATE_CFG(GATE_LPTIM2, RCC_LPTIM2CFGR, 1, 0), + GATE_CFG(GATE_LPTIM3, RCC_LPTIM3CFGR, 1, 0), + GATE_CFG(GATE_LPTIM4, RCC_LPTIM4CFGR, 1, 0), + GATE_CFG(GATE_LPTIM5, RCC_LPTIM5CFGR, 1, 0), + GATE_CFG(GATE_SPI1, RCC_SPI1CFGR, 1, 0), + GATE_CFG(GATE_SPI2, RCC_SPI2CFGR, 1, 0), + GATE_CFG(GATE_SPI3, RCC_SPI3CFGR, 1, 0), + GATE_CFG(GATE_SPI4, RCC_SPI4CFGR, 1, 0), + GATE_CFG(GATE_SPI5, RCC_SPI5CFGR, 1, 0), + GATE_CFG(GATE_SPI6, RCC_SPI6CFGR, 1, 0), + GATE_CFG(GATE_SPDIFRX, RCC_SPDIFRXCFGR, 1, 0), + GATE_CFG(GATE_USART1, RCC_USART1CFGR, 1, 0), + GATE_CFG(GATE_USART2, RCC_USART2CFGR, 1, 0), + GATE_CFG(GATE_USART3, RCC_USART3CFGR, 1, 0), + GATE_CFG(GATE_UART4, RCC_UART4CFGR, 1, 0), + GATE_CFG(GATE_UART5, RCC_UART5CFGR, 1, 0), + GATE_CFG(GATE_USART6, RCC_USART6CFGR, 1, 0), + GATE_CFG(GATE_UART7, RCC_UART7CFGR, 1, 0), + GATE_CFG(GATE_LPUART1, RCC_LPUART1CFGR, 1, 0), + GATE_CFG(GATE_I2C1, RCC_I2C1CFGR, 1, 0), + GATE_CFG(GATE_I2C2, RCC_I2C2CFGR, 1, 0), + GATE_CFG(GATE_I2C3, RCC_I2C3CFGR, 1, 0), + GATE_CFG(GATE_SAI1, RCC_SAI1CFGR, 1, 0), + GATE_CFG(GATE_SAI2, RCC_SAI2CFGR, 1, 0), + GATE_CFG(GATE_SAI3, RCC_SAI3CFGR, 1, 0), + GATE_CFG(GATE_SAI4, RCC_SAI4CFGR, 1, 0), + GATE_CFG(GATE_MDF1, RCC_MDF1CFGR, 1, 0), + GATE_CFG(GATE_FDCAN, RCC_FDCANCFGR, 1, 0), + GATE_CFG(GATE_HDP, RCC_HDPCFGR, 1, 0), + GATE_CFG(GATE_ADC1, RCC_ADC1CFGR, 1, 0), + GATE_CFG(GATE_ADC2, RCC_ADC2CFGR, 1, 0), + GATE_CFG(GATE_ETH1MAC, RCC_ETH1CFGR, 1, 0), + GATE_CFG(GATE_ETH1STP, RCC_ETH1CFGR, 4, 0), + GATE_CFG(GATE_ETH1, RCC_ETH1CFGR, 5, 0), + GATE_CFG(GATE_ETH1TX, RCC_ETH1CFGR, 8, 0), + GATE_CFG(GATE_ETH1RX, RCC_ETH1CFGR, 10, 0), + GATE_CFG(GATE_ETH2MAC, RCC_ETH2CFGR, 1, 0), + GATE_CFG(GATE_ETH2STP, RCC_ETH2CFGR, 4, 0), + GATE_CFG(GATE_ETH2, RCC_ETH2CFGR, 5, 0), + GATE_CFG(GATE_ETH2TX, RCC_ETH2CFGR, 8, 0), + GATE_CFG(GATE_ETH2RX, RCC_ETH2CFGR, 10, 0), + GATE_CFG(GATE_USBH, RCC_USBHCFGR, 1, 0), + GATE_CFG(GATE_USB2PHY1, RCC_USB2PHY1CFGR, 1, 0), + GATE_CFG(GATE_USBOTG, RCC_OTGCFGR, 1, 0), + GATE_CFG(GATE_USB2PHY2, RCC_USB2PHY2CFGR, 1, 0), + GATE_CFG(GATE_STGEN, RCC_STGENCFGR, 1, 0), + GATE_CFG(GATE_SDMMC1, RCC_SDMMC1CFGR, 1, 0), + GATE_CFG(GATE_SDMMC2, RCC_SDMMC2CFGR, 1, 0), + GATE_CFG(GATE_SDMMC3, RCC_SDMMC3CFGR, 1, 0), + GATE_CFG(GATE_LTDC, RCC_LTDCCFGR, 1, 0), + GATE_CFG(GATE_CSI, RCC_CSICFGR, 1, 0), + GATE_CFG(GATE_DCMIPP, RCC_DCMIPPCFGR, 1, 0), + GATE_CFG(GATE_RNG1, RCC_RNG1CFGR, 1, 0), + GATE_CFG(GATE_RNG2, RCC_RNG2CFGR, 1, 0), + GATE_CFG(GATE_PKA, RCC_PKACFGR, 1, 0), + GATE_CFG(GATE_SAES, RCC_SAESCFGR, 1, 0), + GATE_CFG(GATE_HASH1, RCC_HASH1CFGR, 1, 0), + GATE_CFG(GATE_HASH2, RCC_HASH2CFGR, 1, 0), + GATE_CFG(GATE_CRYP1, RCC_CRYP1CFGR, 1, 0), + GATE_CFG(GATE_CRYP2, RCC_CRYP2CFGR, 1, 0), + GATE_CFG(GATE_IWDG1, RCC_IWDG1CFGR, 1, 0), + GATE_CFG(GATE_IWDG2, RCC_IWDG2CFGR, 1, 0), + GATE_CFG(GATE_IWDG3, RCC_IWDG3CFGR, 1, 0), + GATE_CFG(GATE_IWDG4, RCC_IWDG4CFGR, 1, 0), + GATE_CFG(GATE_WWDG1, RCC_WWDG1CFGR, 1, 0), + GATE_CFG(GATE_VREF, RCC_VREFCFGR, 1, 0), + GATE_CFG(GATE_DTS, RCC_DTSCFGR, 1, 0), + GATE_CFG(GATE_CRC, RCC_CRCCFGR, 1, 0), + GATE_CFG(GATE_SERC, RCC_SERCCFGR, 1, 0), + GATE_CFG(GATE_I3C1, RCC_I3C1CFGR, 1, 0), + GATE_CFG(GATE_I3C2, RCC_I3C2CFGR, 1, 0), + GATE_CFG(GATE_I3C3, RCC_I3C3CFGR, 1, 0), +}; + +static int stm32_rcc_get_access(struct udevice *dev, u32 index) +{ + fdt_addr_t rcc_base = dev_read_addr(dev->parent); + u32 seccfgr, cidcfgr, semcr; + int bit, cid; + + bit = index % RCC_REG_SIZE; + + seccfgr = readl(rcc_base + RCC_SECCFGR(index)); + if (seccfgr & BIT(bit)) + return -EACCES; + + cidcfgr = readl(rcc_base + RCC_CIDCFGR(index)); + if (!(cidcfgr & RCC_CIDCFGR_CFEN)) + /* CID filtering is turned off: access granted */ + return 0; + + if (!(cidcfgr & RCC_CIDCFGR_SEM_EN)) { + /* Static CID mode */ + cid = FIELD_GET(RCC_CIDCFGR_SCID_MASK, cidcfgr); + if (cid != RCC_CID1) + return -EACCES; + return 0; + } + + /* Pass-list with semaphore mode */ + if (!(cidcfgr & RCC_CIDCFGR_SEMWLC1_EN)) + return -EACCES; + + semcr = readl(rcc_base + RCC_SEMCR(index)); + + cid = FIELD_GET(RCC_SEMCR_SEMCID_MASK, semcr); + if (cid != RCC_CID1) + return -EACCES; + + return 0; +} + +static int stm32mp21_check_security(struct udevice *dev, void __iomem *base, + const struct clock_config *cfg) +{ + int ret = 0; + + if (cfg->sec_id != SECF_NONE) { + u32 index = (u32)cfg->sec_id; + + if (index & SEC_RIFSC_FLAG) + ret = stm32_rifsc_grant_access_by_id(dev_ofnode(dev), + index & ~SEC_RIFSC_FLAG); + else + ret = stm32_rcc_get_access(dev, index); + } + + return ret; +} + +#define STM32_COMPOSITE_NODIV(_id, _name, _flags, _sec_id, _gate_id, _mux_id)\ + STM32_COMPOSITE(_id, _name, _flags, _sec_id, _gate_id, _mux_id, NO_STM32_DIV) + +static const struct clock_config stm32mp21_clock_cfg[] = { + /* ADC */ + STM32_GATE(CK_BUS_ADC1, "ck_icn_p_adc1", IDX_ICN_LS_MCU, 0, GATE_ADC1, + SEC_RIFSC(58)), + STM32_COMPOSITE_NODIV(CK_KER_ADC1, "ck_ker_adc12", 0, SEC_RIFSC(58), + GATE_ADC1, MUX_ADC1), + STM32_GATE(CK_BUS_ADC2, "ck_icn_p_adc2", IDX_ICN_LS_MCU, 0, GATE_ADC2, SEC_RIFSC(59)), + STM32_COMPOSITE_NODIV(CK_KER_ADC2, "ck_ker_adc2", 0, SEC_RIFSC(59), GATE_ADC2, MUX_ADC2), + + /* CSI-HOST */ + STM32_GATE(CK_BUS_CSI, "ck_icn_p_csi", IDX_ICN_APB4, 0, GATE_CSI, SEC_RIFSC(86)), + STM32_GATE(CK_KER_CSI, "ck_ker_csi", IDX_FLEXGEN_29, 0, GATE_CSI, SEC_RIFSC(86)), + STM32_GATE(CK_KER_CSITXESC, "ck_ker_csitxesc", IDX_FLEXGEN_30, 0, GATE_CSI, + SEC_RIFSC(86)), + + /* CSI-PHY */ + STM32_GATE(CK_KER_CSIPHY, "ck_ker_csiphy", IDX_FLEXGEN_31, 0, GATE_CSI, + SEC_RIFSC(86)), + + /* DCMIPP */ + STM32_GATE(CK_BUS_DCMIPP, "ck_icn_p_dcmipp", IDX_ICN_APB4, 0, GATE_DCMIPP, + SEC_RIFSC(87)), + + /* CRC */ + STM32_GATE(CK_BUS_CRC, "ck_icn_p_crc", IDX_ICN_LS_MCU, 0, GATE_CRC, SEC_RIFSC(109)), + + /* CRYP */ + STM32_GATE(CK_BUS_CRYP1, "ck_icn_p_cryp1", IDX_ICN_LS_MCU, 0, GATE_CRYP1, + SEC_RIFSC(98)), + STM32_GATE(CK_BUS_CRYP2, "ck_icn_p_cryp2", IDX_ICN_LS_MCU, 0, GATE_CRYP2, + SEC_RIFSC(99)), + + /* DBG & TRACE*/ + /* Trace and debug clocks are managed by SCMI */ + + /* Display subsystem */ + /* LTDC */ + STM32_GATE(CK_BUS_LTDC, "ck_icn_p_ltdc", IDX_ICN_APB4, 0, GATE_LTDC, SEC_RIFSC(80)), + STM32_GATE(CK_KER_LTDC, "ck_ker_ltdc", IDX_FLEXGEN_27, CLK_SET_RATE_PARENT, GATE_LTDC, + SEC_RIFSC(80)), + + /* DTS */ + STM32_COMPOSITE_NODIV(CK_KER_DTS, "ck_ker_dts", 0, SEC_RIFSC(107), GATE_DTS, MUX_DTS), + + /* ETHERNET */ + STM32_GATE(CK_BUS_ETH1, "ck_icn_p_eth1", IDX_ICN_LS_MCU, 0, GATE_ETH1, SEC_RIFSC(60)), + STM32_GATE(CK_ETH1_STP, "ck_ker_eth1stp", IDX_ICN_LS_MCU, 0, GATE_ETH1STP, + SEC_RIFSC(60)), + STM32_GATE(CK_KER_ETH1, "ck_ker_eth1", IDX_FLEXGEN_54, 0, GATE_ETH1, SEC_RIFSC(60)), + STM32_GATE(CK_KER_ETH1, "ck_ker_eth1ptp", IDX_FLEXGEN_56, 0, GATE_ETH1, SEC_RIFSC(60)), + STM32_GATE(CK_ETH1_MAC, "ck_ker_eth1mac", IDX_ICN_LS_MCU, 0, GATE_ETH1MAC, + SEC_RIFSC(60)), + STM32_GATE(CK_ETH1_TX, "ck_ker_eth1tx", IDX_ICN_LS_MCU, 0, GATE_ETH1TX, SEC_RIFSC(60)), + STM32_GATE(CK_ETH1_RX, "ck_ker_eth1rx", IDX_ICN_LS_MCU, 0, GATE_ETH1RX, SEC_RIFSC(60)), + + STM32_GATE(CK_BUS_ETH2, "ck_icn_p_eth2", IDX_ICN_LS_MCU, 0, GATE_ETH2, SEC_RIFSC(61)), + STM32_GATE(CK_ETH2_STP, "ck_ker_eth2stp", IDX_ICN_LS_MCU, 0, GATE_ETH2STP, + SEC_RIFSC(61)), + STM32_GATE(CK_KER_ETH2, "ck_ker_eth2", IDX_FLEXGEN_54, 0, GATE_ETH2, SEC_RIFSC(61)), + STM32_GATE(CK_KER_ETH2, "ck_ker_eth2ptp", IDX_FLEXGEN_56, 0, GATE_ETH2, SEC_RIFSC(61)), + STM32_GATE(CK_ETH2_MAC, "ck_ker_eth2mac", IDX_ICN_LS_MCU, 0, GATE_ETH2MAC, + SEC_RIFSC(61)), + STM32_GATE(CK_ETH2_TX, "ck_ker_eth2tx", IDX_ICN_LS_MCU, 0, GATE_ETH2TX, SEC_RIFSC(61)), + STM32_GATE(CK_ETH2_RX, "ck_ker_eth2rx", IDX_ICN_LS_MCU, 0, GATE_ETH2RX, SEC_RIFSC(61)), + + /* FDCAN */ + STM32_GATE(CK_BUS_FDCAN, "ck_icn_p_fdcan", IDX_ICN_APB2, 0, GATE_FDCAN, SEC_RIFSC(56)), + STM32_GATE(CK_KER_FDCAN, "ck_ker_fdcan", IDX_FLEXGEN_26, 0, GATE_FDCAN, SEC_RIFSC(56)), + + /* HASH */ + STM32_GATE(CK_BUS_HASH1, "ck_icn_p_hash1", IDX_ICN_LS_MCU, 0, GATE_HASH1, SEC_RIFSC(96)), + STM32_GATE(CK_BUS_HASH2, "ck_icn_p_hash2", IDX_ICN_LS_MCU, 0, GATE_HASH2, SEC_RIFSC(97)), + + /* HDP */ + STM32_GATE(CK_BUS_HDP, "ck_icn_p_hdp", IDX_ICN_APB3, 0, GATE_HDP, SEC_RIFSC(57)), + + /* I2C */ + STM32_GATE(CK_KER_I2C1, "ck_ker_i2c1", IDX_FLEXGEN_13, 0, GATE_I2C1, SEC_RIFSC(41)), + STM32_GATE(CK_KER_I2C2, "ck_ker_i2c2", IDX_FLEXGEN_13, 0, GATE_I2C2, SEC_RIFSC(42)), + STM32_GATE(CK_KER_I2C3, "ck_ker_i2c3", IDX_FLEXGEN_38, 0, GATE_I2C3, SEC_RIFSC(43)), + + /* I3C */ + STM32_GATE(CK_KER_I3C1, "ck_ker_i3c1", IDX_FLEXGEN_14, 0, GATE_I3C1, SEC_RIFSC(114)), + STM32_GATE(CK_KER_I3C2, "ck_ker_i3c2", IDX_FLEXGEN_14, 0, GATE_I3C2, SEC_RIFSC(115)), + STM32_GATE(CK_KER_I3C3, "ck_ker_i3c3", IDX_FLEXGEN_36, 0, GATE_I3C3, SEC_RIFSC(116)), + + /* IWDG */ + STM32_GATE(CK_BUS_IWDG1, "ck_icn_p_iwdg1", IDX_ICN_APB3, 0, GATE_IWDG1, SEC_RIFSC(100)), + STM32_GATE(CK_BUS_IWDG2, "ck_icn_p_iwdg2", IDX_ICN_APB3, 0, GATE_IWDG2, SEC_RIFSC(101)), + STM32_GATE(CK_BUS_IWDG3, "ck_icn_p_iwdg3", IDX_ICN_APB3, 0, GATE_IWDG3, SEC_RIFSC(102)), + STM32_GATE(CK_BUS_IWDG4, "ck_icn_p_iwdg4", IDX_ICN_APB3, 0, GATE_IWDG4, SEC_RIFSC(103)), + + /* LPTIM */ + STM32_GATE(CK_KER_LPTIM1, "ck_ker_lptim1", IDX_FLEXGEN_07, 0, GATE_LPTIM1, + SEC_RIFSC(17)), + STM32_GATE(CK_KER_LPTIM2, "ck_ker_lptim2", IDX_FLEXGEN_07, 0, GATE_LPTIM2, + SEC_RIFSC(18)), + STM32_GATE(CK_KER_LPTIM3, "ck_ker_lptim3", IDX_FLEXGEN_40, 0, GATE_LPTIM3, + SEC_RIFSC(19)), + STM32_GATE(CK_KER_LPTIM4, "ck_ker_lptim4", IDX_FLEXGEN_41, 0, GATE_LPTIM4, + SEC_RIFSC(20)), + STM32_GATE(CK_KER_LPTIM5, "ck_ker_lptim5", IDX_FLEXGEN_42, 0, GATE_LPTIM5, + SEC_RIFSC(21)), + + /* LPUART */ + STM32_GATE(CK_KER_LPUART1, "ck_ker_lpuart1", IDX_FLEXGEN_39, 0, GATE_LPUART1, + SEC_RIFSC(40)), + + /* MCO1 & MCO2 */ + STM32_COMPOSITE_NODIV(CK_MCO1, "ck_mco1", 0, SEC_RIFRCC(MCO1), GATE_MCO1, MUX_MCO1), + STM32_COMPOSITE_NODIV(CK_MCO2, "ck_mco2", 0, SEC_RIFRCC(MCO2), GATE_MCO2, MUX_MCO2), + + /* MDF */ + STM32_GATE(CK_KER_MDF1, "ck_ker_mdf1", IDX_FLEXGEN_21, 0, GATE_MDF1, SEC_RIFSC(54)), + + /* PKA */ + STM32_GATE(CK_BUS_PKA, "ck_icn_p_pka", IDX_ICN_LS_MCU, 0, GATE_PKA, SEC_RIFSC(94)), + + /* RNG */ + STM32_GATE(CK_BUS_RNG1, "ck_icn_p_rng1", IDX_ICN_LS_MCU, CLK_IGNORE_UNUSED, GATE_RNG1, + SEC_RIFSC(92)), + STM32_GATE(CK_BUS_RNG2, "ck_icn_p_rng2", IDX_ICN_LS_MCU, CLK_IGNORE_UNUSED, GATE_RNG2, + SEC_RIFSC(93)), + + /* SAES */ + STM32_GATE(CK_BUS_SAES, "ck_icn_p_saes", IDX_ICN_LS_MCU, 0, GATE_SAES, SEC_RIFSC(95)), + + /* SAI [1..4] */ + STM32_GATE(CK_BUS_SAI1, "ck_icn_p_sai1", IDX_ICN_APB2, 0, GATE_SAI1, SEC_RIFSC(49)), + STM32_GATE(CK_BUS_SAI2, "ck_icn_p_sai2", IDX_ICN_APB2, 0, GATE_SAI2, SEC_RIFSC(50)), + STM32_GATE(CK_BUS_SAI3, "ck_icn_p_sai3", IDX_ICN_APB2, 0, GATE_SAI3, SEC_RIFSC(51)), + STM32_GATE(CK_BUS_SAI4, "ck_icn_p_sai4", IDX_ICN_APB2, 0, GATE_SAI4, SEC_RIFSC(52)), + STM32_GATE(CK_KER_SAI1, "ck_ker_sai1", IDX_FLEXGEN_22, 0, GATE_SAI1, SEC_RIFSC(49)), + STM32_GATE(CK_KER_SAI2, "ck_ker_sai2", IDX_FLEXGEN_23, 0, GATE_SAI2, SEC_RIFSC(50)), + STM32_GATE(CK_KER_SAI3, "ck_ker_sai3", IDX_FLEXGEN_24, 0, GATE_SAI3, SEC_RIFSC(51)), + STM32_GATE(CK_KER_SAI4, "ck_ker_sai4", IDX_FLEXGEN_25, 0, GATE_SAI4, SEC_RIFSC(52)), + + /* SDMMC */ + STM32_GATE(CK_KER_SDMMC1, "ck_ker_sdmmc1", IDX_FLEXGEN_51, 0, GATE_SDMMC1, + SEC_RIFSC(76)), + STM32_GATE(CK_KER_SDMMC2, "ck_ker_sdmmc2", IDX_FLEXGEN_52, 0, GATE_SDMMC2, + SEC_RIFSC(77)), + STM32_GATE(CK_KER_SDMMC3, "ck_ker_sdmmc3", IDX_FLEXGEN_53, 0, GATE_SDMMC3, + SEC_RIFSC(78)), + + /* SERC */ + STM32_GATE(CK_BUS_SERC, "ck_icn_p_serc", IDX_ICN_APB3, 0, GATE_SERC, SEC_RIFSC(110)), + + /* SPDIF */ + STM32_GATE(CK_KER_SPDIFRX, "ck_ker_spdifrx", IDX_FLEXGEN_12, 0, GATE_SPDIFRX, + SEC_RIFSC(30)), + + /* SPI */ + STM32_GATE(CK_KER_SPI1, "ck_ker_spi1", IDX_FLEXGEN_16, 0, GATE_SPI1, SEC_RIFSC(22)), + STM32_GATE(CK_KER_SPI2, "ck_ker_spi2", IDX_FLEXGEN_10, 0, GATE_SPI2, SEC_RIFSC(23)), + STM32_GATE(CK_KER_SPI3, "ck_ker_spi3", IDX_FLEXGEN_11, 0, GATE_SPI3, SEC_RIFSC(24)), + STM32_GATE(CK_KER_SPI4, "ck_ker_spi4", IDX_FLEXGEN_17, 0, GATE_SPI4, SEC_RIFSC(25)), + STM32_GATE(CK_KER_SPI5, "ck_ker_spi5", IDX_FLEXGEN_17, 0, GATE_SPI5, SEC_RIFSC(26)), + STM32_GATE(CK_KER_SPI6, "ck_ker_spi6", IDX_FLEXGEN_37, 0, GATE_SPI6, SEC_RIFSC(27)), + + /* STGEN */ + STM32_GATE(CK_KER_STGEN, "ck_ker_stgen", IDX_FLEXGEN_33, CLK_IGNORE_UNUSED, GATE_STGEN, + SEC_RIFSC(73)), + + /* Timers */ + STM32_GATE(CK_KER_TIM2, "ck_ker_tim2", IDX_TIMG1, 0, GATE_TIM2, SEC_RIFSC(1)), + STM32_GATE(CK_KER_TIM3, "ck_ker_tim3", IDX_TIMG1, 0, GATE_TIM3, SEC_RIFSC(2)), + STM32_GATE(CK_KER_TIM4, "ck_ker_tim4", IDX_TIMG1, 0, GATE_TIM4, SEC_RIFSC(3)), + STM32_GATE(CK_KER_TIM5, "ck_ker_tim5", IDX_TIMG1, 0, GATE_TIM5, SEC_RIFSC(4)), + STM32_GATE(CK_KER_TIM6, "ck_ker_tim6", IDX_TIMG1, 0, GATE_TIM6, SEC_RIFSC(5)), + STM32_GATE(CK_KER_TIM7, "ck_ker_tim7", IDX_TIMG1, 0, GATE_TIM7, SEC_RIFSC(6)), + STM32_GATE(CK_KER_TIM10, "ck_ker_tim10", IDX_TIMG1, 0, GATE_TIM10, SEC_RIFSC(8)), + STM32_GATE(CK_KER_TIM11, "ck_ker_tim11", IDX_TIMG1, 0, GATE_TIM11, SEC_RIFSC(9)), + STM32_GATE(CK_KER_TIM12, "ck_ker_tim12", IDX_TIMG1, 0, GATE_TIM12, SEC_RIFSC(10)), + STM32_GATE(CK_KER_TIM13, "ck_ker_tim13", IDX_TIMG1, 0, GATE_TIM13, SEC_RIFSC(11)), + STM32_GATE(CK_KER_TIM14, "ck_ker_tim14", IDX_TIMG1, 0, GATE_TIM14, SEC_RIFSC(12)), + + STM32_GATE(CK_KER_TIM1, "ck_ker_tim1", IDX_TIMG2, 0, GATE_TIM1, SEC_RIFSC(0)), + STM32_GATE(CK_KER_TIM8, "ck_ker_tim8", IDX_TIMG2, 0, GATE_TIM8, SEC_RIFSC(7)), + STM32_GATE(CK_KER_TIM15, "ck_ker_tim15", IDX_TIMG2, 0, GATE_TIM15, SEC_RIFSC(13)), + STM32_GATE(CK_KER_TIM16, "ck_ker_tim16", IDX_TIMG2, 0, GATE_TIM16, SEC_RIFSC(14)), + STM32_GATE(CK_KER_TIM17, "ck_ker_tim17", IDX_TIMG2, 0, GATE_TIM17, SEC_RIFSC(15)), + + /* UART/USART */ + STM32_GATE(CK_KER_USART2, "ck_ker_usart2", IDX_FLEXGEN_08, 0, GATE_USART2, + SEC_RIFSC(32)), + STM32_GATE(CK_KER_UART4, "ck_ker_uart4", IDX_FLEXGEN_08, 0, GATE_UART4, + SEC_RIFSC(34)), + STM32_GATE(CK_KER_USART3, "ck_ker_usart3", IDX_FLEXGEN_09, 0, GATE_USART3, + SEC_RIFSC(33)), + STM32_GATE(CK_KER_UART5, "ck_ker_uart5", IDX_FLEXGEN_09, 0, GATE_UART5, + SEC_RIFSC(35)), + STM32_GATE(CK_KER_USART1, "ck_ker_usart1", IDX_FLEXGEN_18, 0, GATE_USART1, + SEC_RIFSC(31)), + STM32_GATE(CK_KER_USART6, "ck_ker_usart6", IDX_FLEXGEN_19, 0, GATE_USART6, + SEC_RIFSC(36)), + STM32_GATE(CK_KER_UART7, "ck_ker_uart7", IDX_FLEXGEN_20, 0, GATE_UART7, + SEC_RIFSC(37)), + + /* USB2PHY1 */ + STM32_COMPOSITE_NODIV(CK_KER_USB2PHY1, "ck_ker_usb2phy1", 0, SEC_RIFSC(63), + GATE_USB2PHY1, MUX_USB2PHY1), + + /* USB2H */ + STM32_GATE(CK_BUS_USBHOHCI, "ck_icn_m_usbhohci", IDX_ICN_HSL, 0, GATE_USBH, + SEC_RIFSC(63)), + STM32_GATE(CK_BUS_USBHEHCI, "ck_icn_m_usbhehci", IDX_ICN_HSL, 0, GATE_USBH, + SEC_RIFSC(63)), + + /* USBOTG */ + STM32_GATE(CK_BUS_OTG, "ck_icn_m_otg", IDX_ICN_HSL, 0, GATE_USBOTG, + SEC_RIFSC(66)), + + /* USB2PHY2 */ + STM32_COMPOSITE_NODIV(CK_KER_USB2PHY2EN, "ck_ker_usb2phy2_en", 0, SEC_RIFSC(66), + GATE_USB2PHY2, MUX_USB2PHY2), + + /* VREF */ + STM32_GATE(CK_BUS_VREF, "ck_icn_p_vref", IDX_ICN_APB3, 0, RCC_VREFCFGR, + SEC_RIFSC(106)), + + /* WWDG */ + STM32_GATE(CK_BUS_WWDG1, "ck_icn_p_wwdg1", IDX_ICN_APB3, 0, GATE_WWDG1, + SEC_RIFSC(104)), +}; + +static const struct stm32_clock_match_data stm32mp21_data = { + .tab_clocks = stm32mp21_clock_cfg, + .num_clocks = ARRAY_SIZE(stm32mp21_clock_cfg), + .clock_data = &(const struct clk_stm32_clock_data) { + .num_gates = ARRAY_SIZE(stm32mp21_gates), + .gates = stm32mp21_gates, + .muxes = stm32mp21_muxes, + }, + .check_security = stm32mp21_check_security, + +}; + +static int stm32mp21_clk_probe(struct udevice *dev) +{ + fdt_addr_t base = dev_read_addr(dev->parent); + struct udevice *scmi; + + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* force SCMI probe to register all SCMI clocks */ + uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(scmi_clock), &scmi); + + stm32_rcc_init(dev, &stm32mp21_data); + + return 0; +} + +U_BOOT_DRIVER(stm32mp21_clock) = { + .name = "stm32mp21_clk", + .id = UCLASS_CLK, + .ops = &stm32_clk_ops, + .priv_auto = sizeof(struct stm32mp_rcc_priv), + .probe = stm32mp21_clk_probe, +}; diff --git a/include/stm32mp21_rcc.h b/include/stm32mp21_rcc.h new file mode 100644 index 00000000000..73863412720 --- /dev/null +++ b/include/stm32mp21_rcc.h @@ -0,0 +1,651 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */ +/* + * Copyright (C) STMicroelectronics 2023 - All Rights Reserved + * Author: Gabriel Fernandez for STMicroelectronics. + */ + +#ifndef STM32MP21_RCC_H +#define STM32MP21_RCC_H + +#define RCC_SECCFGR0 0x0 +#define RCC_SECCFGR1 0x4 +#define RCC_SECCFGR2 0x8 +#define RCC_SECCFGR3 0xC +#define RCC_PRIVCFGR0 0x10 +#define RCC_PRIVCFGR1 0x14 +#define RCC_PRIVCFGR2 0x18 +#define RCC_PRIVCFGR3 0x1C +#define RCC_RCFGLOCKR0 0x20 +#define RCC_RCFGLOCKR1 0x24 +#define RCC_RCFGLOCKR2 0x28 +#define RCC_RCFGLOCKR3 0x2C +#define RCC_R0CIDCFGR 0x30 +#define RCC_R0SEMCR 0x34 +#define RCC_R1CIDCFGR 0x38 +#define RCC_R1SEMCR 0x3C +#define RCC_R2CIDCFGR 0x40 +#define RCC_R2SEMCR 0x44 +#define RCC_R3CIDCFGR 0x48 +#define RCC_R3SEMCR 0x4C +#define RCC_R4CIDCFGR 0x50 +#define RCC_R4SEMCR 0x54 +#define RCC_R5CIDCFGR 0x58 +#define RCC_R5SEMCR 0x5C +#define RCC_R6CIDCFGR 0x60 +#define RCC_R6SEMCR 0x64 +#define RCC_R7CIDCFGR 0x68 +#define RCC_R7SEMCR 0x6C +#define RCC_R8CIDCFGR 0x70 +#define RCC_R8SEMCR 0x74 +#define RCC_R9CIDCFGR 0x78 +#define RCC_R9SEMCR 0x7C +#define RCC_R10CIDCFGR 0x80 +#define RCC_R10SEMCR 0x84 +#define RCC_R11CIDCFGR 0x88 +#define RCC_R11SEMCR 0x8C +#define RCC_R12CIDCFGR 0x90 +#define RCC_R12SEMCR 0x94 +#define RCC_R13CIDCFGR 0x98 +#define RCC_R13SEMCR 0x9C +#define RCC_R14CIDCFGR 0xA0 +#define RCC_R14SEMCR 0xA4 +#define RCC_R15CIDCFGR 0xA8 +#define RCC_R15SEMCR 0xAC +#define RCC_R16CIDCFGR 0xB0 +#define RCC_R16SEMCR 0xB4 +#define RCC_R17CIDCFGR 0xB8 +#define RCC_R17SEMCR 0xBC +#define RCC_R18CIDCFGR 0xC0 +#define RCC_R18SEMCR 0xC4 +#define RCC_R19CIDCFGR 0xC8 +#define RCC_R19SEMCR 0xCC +#define RCC_R20CIDCFGR 0xD0 +#define RCC_R20SEMCR 0xD4 +#define RCC_R21CIDCFGR 0xD8 +#define RCC_R21SEMCR 0xDC +#define RCC_R22CIDCFGR 0xE0 +#define RCC_R22SEMCR 0xE4 +#define RCC_R23CIDCFGR 0xE8 +#define RCC_R23SEMCR 0xEC +#define RCC_R24CIDCFGR 0xF0 +#define RCC_R24SEMCR 0xF4 +#define RCC_R25CIDCFGR 0xF8 +#define RCC_R25SEMCR 0xFC +#define RCC_R26CIDCFGR 0x100 +#define RCC_R26SEMCR 0x104 +#define RCC_R27CIDCFGR 0x108 +#define RCC_R27SEMCR 0x10C +#define RCC_R28CIDCFGR 0x110 +#define RCC_R28SEMCR 0x114 +#define RCC_R29CIDCFGR 0x118 +#define RCC_R29SEMCR 0x11C +#define RCC_R30CIDCFGR 0x120 +#define RCC_R30SEMCR 0x124 +#define RCC_R31CIDCFGR 0x128 +#define RCC_R31SEMCR 0x12C +#define RCC_R32CIDCFGR 0x130 +#define RCC_R32SEMCR 0x134 +#define RCC_R33CIDCFGR 0x138 +#define RCC_R33SEMCR 0x13C +#define RCC_R34CIDCFGR 0x140 +#define RCC_R34SEMCR 0x144 +#define RCC_R35CIDCFGR 0x148 +#define RCC_R35SEMCR 0x14C +#define RCC_R36CIDCFGR 0x150 +#define RCC_R36SEMCR 0x154 +#define RCC_R37CIDCFGR 0x158 +#define RCC_R37SEMCR 0x15C +#define RCC_R38CIDCFGR 0x160 +#define RCC_R38SEMCR 0x164 +#define RCC_R39CIDCFGR 0x168 +#define RCC_R39SEMCR 0x16C +#define RCC_R40CIDCFGR 0x170 +#define RCC_R40SEMCR 0x174 +#define RCC_R41CIDCFGR 0x178 +#define RCC_R41SEMCR 0x17C +#define RCC_R42CIDCFGR 0x180 +#define RCC_R42SEMCR 0x184 +#define RCC_R43CIDCFGR 0x188 +#define RCC_R43SEMCR 0x18C +#define RCC_R44CIDCFGR 0x190 +#define RCC_R44SEMCR 0x194 +#define RCC_R45CIDCFGR 0x198 +#define RCC_R45SEMCR 0x19C +#define RCC_R46CIDCFGR 0x1A0 +#define RCC_R46SEMCR 0x1A4 +#define RCC_R47CIDCFGR 0x1A8 +#define RCC_R47SEMCR 0x1AC +#define RCC_R48CIDCFGR 0x1B0 +#define RCC_R48SEMCR 0x1B4 +#define RCC_R49CIDCFGR 0x1B8 +#define RCC_R49SEMCR 0x1BC +#define RCC_R50CIDCFGR 0x1C0 +#define RCC_R50SEMCR 0x1C4 +#define RCC_R51CIDCFGR 0x1C8 +#define RCC_R51SEMCR 0x1CC +#define RCC_R52CIDCFGR 0x1D0 +#define RCC_R52SEMCR 0x1D4 +#define RCC_R53CIDCFGR 0x1D8 +#define RCC_R53SEMCR 0x1DC +#define RCC_R54CIDCFGR 0x1E0 +#define RCC_R54SEMCR 0x1E4 +#define RCC_R55CIDCFGR 0x1E8 +#define RCC_R55SEMCR 0x1EC +#define RCC_R56CIDCFGR 0x1F0 +#define RCC_R56SEMCR 0x1F4 +#define RCC_R57CIDCFGR 0x1F8 +#define RCC_R57SEMCR 0x1FC +#define RCC_R58CIDCFGR 0x200 +#define RCC_R58SEMCR 0x204 +#define RCC_R59CIDCFGR 0x208 +#define RCC_R59SEMCR 0x20C +#define RCC_R60CIDCFGR 0x210 +#define RCC_R60SEMCR 0x214 +#define RCC_R61CIDCFGR 0x218 +#define RCC_R61SEMCR 0x21C +#define RCC_R62CIDCFGR 0x220 +#define RCC_R62SEMCR 0x224 +#define RCC_R63CIDCFGR 0x228 +#define RCC_R63SEMCR 0x22C +#define RCC_R64CIDCFGR 0x230 +#define RCC_R64SEMCR 0x234 +#define RCC_R65CIDCFGR 0x238 +#define RCC_R65SEMCR 0x23C +#define RCC_R66CIDCFGR 0x240 +#define RCC_R66SEMCR 0x244 +#define RCC_R67CIDCFGR 0x248 +#define RCC_R67SEMCR 0x24C +#define RCC_R68CIDCFGR 0x250 +#define RCC_R68SEMCR 0x254 +#define RCC_R69CIDCFGR 0x258 +#define RCC_R69SEMCR 0x25C +#define RCC_R70CIDCFGR 0x260 +#define RCC_R70SEMCR 0x264 +#define RCC_R71CIDCFGR 0x268 +#define RCC_R71SEMCR 0x26C +#define RCC_R73CIDCFGR 0x278 +#define RCC_R73SEMCR 0x27C +#define RCC_R74CIDCFGR 0x280 +#define RCC_R74SEMCR 0x284 +#define RCC_R75CIDCFGR 0x288 +#define RCC_R75SEMCR 0x28C +#define RCC_R76CIDCFGR 0x290 +#define RCC_R76SEMCR 0x294 +#define RCC_R77CIDCFGR 0x298 +#define RCC_R77SEMCR 0x29C +#define RCC_R78CIDCFGR 0x2A0 +#define RCC_R78SEMCR 0x2A4 +#define RCC_R79CIDCFGR 0x2A8 +#define RCC_R79SEMCR 0x2AC +#define RCC_R83CIDCFGR 0x2C8 +#define RCC_R83SEMCR 0x2CC +#define RCC_R84CIDCFGR 0x2D0 +#define RCC_R84SEMCR 0x2D4 +#define RCC_R85CIDCFGR 0x2D8 +#define RCC_R85SEMCR 0x2DC +#define RCC_R86CIDCFGR 0x2E0 +#define RCC_R86SEMCR 0x2E4 +#define RCC_R87CIDCFGR 0x2E8 +#define RCC_R87SEMCR 0x2EC +#define RCC_R88CIDCFGR 0x2F0 +#define RCC_R88SEMCR 0x2F4 +#define RCC_R90CIDCFGR 0x300 +#define RCC_R90SEMCR 0x304 +#define RCC_R91CIDCFGR 0x308 +#define RCC_R91SEMCR 0x30C +#define RCC_R92CIDCFGR 0x310 +#define RCC_R92SEMCR 0x314 +#define RCC_R93CIDCFGR 0x318 +#define RCC_R93SEMCR 0x31C +#define RCC_R94CIDCFGR 0x320 +#define RCC_R94SEMCR 0x324 +#define RCC_R95CIDCFGR 0x328 +#define RCC_R95SEMCR 0x32C +#define RCC_R96CIDCFGR 0x330 +#define RCC_R96SEMCR 0x334 +#define RCC_R97CIDCFGR 0x338 +#define RCC_R97SEMCR 0x33C +#define RCC_R98CIDCFGR 0x340 +#define RCC_R98SEMCR 0x344 +#define RCC_R101CIDCFGR 0x358 +#define RCC_R101SEMCR 0x35C +#define RCC_R102CIDCFGR 0x360 +#define RCC_R102SEMCR 0x364 +#define RCC_R103CIDCFGR 0x368 +#define RCC_R103SEMCR 0x36C +#define RCC_R104CIDCFGR 0x370 +#define RCC_R104SEMCR 0x374 +#define RCC_R105CIDCFGR 0x378 +#define RCC_R105SEMCR 0x37C +#define RCC_R106CIDCFGR 0x380 +#define RCC_R106SEMCR 0x384 +#define RCC_R108CIDCFGR 0x390 +#define RCC_R108SEMCR 0x394 +#define RCC_R109CIDCFGR 0x398 +#define RCC_R109SEMCR 0x39C +#define RCC_R110CIDCFGR 0x3A0 +#define RCC_R110SEMCR 0x3A4 +#define RCC_R111CIDCFGR 0x3A8 +#define RCC_R111SEMCR 0x3AC +#define RCC_R112CIDCFGR 0x3B0 +#define RCC_R112SEMCR 0x3B4 +#define RCC_R113CIDCFGR 0x3B8 +#define RCC_R113SEMCR 0x3BC +#define RCC_GRSTCSETR 0x400 +#define RCC_C1RSTCSETR 0x404 +#define RCC_C2RSTCSETR 0x40C +#define RCC_HWRSTSCLRR 0x410 +#define RCC_C1HWRSTSCLRR 0x414 +#define RCC_C2HWRSTSCLRR 0x418 +#define RCC_C1BOOTRSTSSETR 0x41C +#define RCC_C1BOOTRSTSCLRR 0x420 +#define RCC_C2BOOTRSTSSETR 0x424 +#define RCC_C2BOOTRSTSCLRR 0x428 +#define RCC_C1SREQSETR 0x42C +#define RCC_C1SREQCLRR 0x430 +#define RCC_CPUBOOTCR 0x434 +#define RCC_STBYBOOTCR 0x438 +#define RCC_LEGBOOTCR 0x43C +#define RCC_BDCR 0x440 +#define RCC_RDCR 0x44C +#define RCC_C1MSRDCR 0x450 +#define RCC_PWRLPDLYCR 0x454 +#define RCC_C1CIESETR 0x458 +#define RCC_C1CIFCLRR 0x45C +#define RCC_C2CIESETR 0x460 +#define RCC_C2CIFCLRR 0x464 +#define RCC_IWDGC1FZSETR 0x468 +#define RCC_IWDGC1FZCLRR 0x46C +#define RCC_IWDGC1CFGSETR 0x470 +#define RCC_IWDGC1CFGCLRR 0x474 +#define RCC_IWDGC2FZSETR 0x478 +#define RCC_IWDGC2FZCLRR 0x47C +#define RCC_IWDGC2CFGSETR 0x480 +#define RCC_IWDGC2CFGCLRR 0x484 +#define RCC_MCO1CFGR 0x488 +#define RCC_MCO2CFGR 0x48C +#define RCC_OCENSETR 0x490 +#define RCC_OCENCLRR 0x494 +#define RCC_OCRDYR 0x498 +#define RCC_HSICFGR 0x49C +#define RCC_MSICFGR 0x4A0 +#define RCC_LSICR 0x4A4 +#define RCC_RTCDIVR 0x4A8 +#define RCC_APB1DIVR 0x4AC +#define RCC_APB2DIVR 0x4B0 +#define RCC_APB3DIVR 0x4B4 +#define RCC_APB4DIVR 0x4B8 +#define RCC_APB5DIVR 0x4BC +#define RCC_APBDBGDIVR 0x4C0 +#define RCC_TIMG1PRER 0x4C8 +#define RCC_TIMG2PRER 0x4CC +#define RCC_LSMCUDIVR 0x4D0 +#define RCC_DDRCPCFGR 0x4D4 +#define RCC_DDRCAPBCFGR 0x4D8 +#define RCC_DDRPHYCAPBCFGR 0x4DC +#define RCC_DDRPHYCCFGR 0x4E0 +#define RCC_DDRCFGR 0x4E4 +#define RCC_DDRITFCFGR 0x4E8 +#define RCC_SYSRAMCFGR 0x4F0 +#define RCC_SRAM1CFGR 0x4F8 +#define RCC_RETRAMCFGR 0x500 +#define RCC_BKPSRAMCFGR 0x504 +#define RCC_OSPI1CFGR 0x514 +#define RCC_FMCCFGR 0x51C +#define RCC_DBGCFGR 0x520 +#define RCC_STMCFGR 0x524 +#define RCC_ETRCFGR 0x528 +#define RCC_GPIOACFGR 0x52C +#define RCC_GPIOBCFGR 0x530 +#define RCC_GPIOCCFGR 0x534 +#define RCC_GPIODCFGR 0x538 +#define RCC_GPIOECFGR 0x53C +#define RCC_GPIOFCFGR 0x540 +#define RCC_GPIOGCFGR 0x544 +#define RCC_GPIOHCFGR 0x548 +#define RCC_GPIOICFGR 0x54C +#define RCC_GPIOZCFGR 0x558 +#define RCC_HPDMA1CFGR 0x55C +#define RCC_HPDMA2CFGR 0x560 +#define RCC_HPDMA3CFGR 0x564 +#define RCC_IPCC1CFGR 0x570 +#define RCC_RTCCFGR 0x578 +#define RCC_SYSCPU1CFGR 0x580 +#define RCC_BSECCFGR 0x584 +#define RCC_PLL2CFGR1 0x590 +#define RCC_PLL2CFGR2 0x594 +#define RCC_PLL2CFGR3 0x598 +#define RCC_PLL2CFGR4 0x59C +#define RCC_PLL2CFGR5 0x5A0 +#define RCC_PLL2CFGR6 0x5A8 +#define RCC_PLL2CFGR7 0x5AC +#define RCC_HSIFMONCR 0x5E0 +#define RCC_HSIFVALR 0x5E4 +#define RCC_MSIFMONCR 0x5E8 +#define RCC_MSIFVALR 0x5EC +#define RCC_TIM1CFGR 0x700 +#define RCC_TIM2CFGR 0x704 +#define RCC_TIM3CFGR 0x708 +#define RCC_TIM4CFGR 0x70C +#define RCC_TIM5CFGR 0x710 +#define RCC_TIM6CFGR 0x714 +#define RCC_TIM7CFGR 0x718 +#define RCC_TIM8CFGR 0x71C +#define RCC_TIM10CFGR 0x720 +#define RCC_TIM11CFGR 0x724 +#define RCC_TIM12CFGR 0x728 +#define RCC_TIM13CFGR 0x72C +#define RCC_TIM14CFGR 0x730 +#define RCC_TIM15CFGR 0x734 +#define RCC_TIM16CFGR 0x738 +#define RCC_TIM17CFGR 0x73C +#define RCC_LPTIM1CFGR 0x744 +#define RCC_LPTIM2CFGR 0x748 +#define RCC_LPTIM3CFGR 0x74C +#define RCC_LPTIM4CFGR 0x750 +#define RCC_LPTIM5CFGR 0x754 +#define RCC_SPI1CFGR 0x758 +#define RCC_SPI2CFGR 0x75C +#define RCC_SPI3CFGR 0x760 +#define RCC_SPI4CFGR 0x764 +#define RCC_SPI5CFGR 0x768 +#define RCC_SPI6CFGR 0x76C +#define RCC_SPDIFRXCFGR 0x778 +#define RCC_USART1CFGR 0x77C +#define RCC_USART2CFGR 0x780 +#define RCC_USART3CFGR 0x784 +#define RCC_UART4CFGR 0x788 +#define RCC_UART5CFGR 0x78C +#define RCC_USART6CFGR 0x790 +#define RCC_UART7CFGR 0x794 +#define RCC_LPUART1CFGR 0x7A0 +#define RCC_I2C1CFGR 0x7A4 +#define RCC_I2C2CFGR 0x7A8 +#define RCC_I2C3CFGR 0x7AC +#define RCC_SAI1CFGR 0x7C4 +#define RCC_SAI2CFGR 0x7C8 +#define RCC_SAI3CFGR 0x7CC +#define RCC_SAI4CFGR 0x7D0 +#define RCC_MDF1CFGR 0x7D8 +#define RCC_FDCANCFGR 0x7E0 +#define RCC_HDPCFGR 0x7E4 +#define RCC_ADC1CFGR 0x7E8 +#define RCC_ADC2CFGR 0x7EC +#define RCC_ETH1CFGR 0x7F0 +#define RCC_ETH2CFGR 0x7F4 +#define RCC_USBHCFGR 0x7FC +#define RCC_USB2PHY1CFGR 0x800 +#define RCC_OTGCFGR 0x808 +#define RCC_USB2PHY2CFGR 0x80C +#define RCC_STGENCFGR 0x824 +#define RCC_SDMMC1CFGR 0x830 +#define RCC_SDMMC2CFGR 0x834 +#define RCC_SDMMC3CFGR 0x838 +#define RCC_LTDCCFGR 0x840 +#define RCC_CSICFGR 0x858 +#define RCC_DCMIPPCFGR 0x85C +#define RCC_DCMIPSSICFGR 0x860 +#define RCC_RNG1CFGR 0x870 +#define RCC_RNG2CFGR 0x874 +#define RCC_PKACFGR 0x878 +#define RCC_SAESCFGR 0x87C +#define RCC_HASH1CFGR 0x880 +#define RCC_HASH2CFGR 0x884 +#define RCC_CRYP1CFGR 0x888 +#define RCC_CRYP2CFGR 0x88C +#define RCC_IWDG1CFGR 0x894 +#define RCC_IWDG2CFGR 0x898 +#define RCC_IWDG3CFGR 0x89C +#define RCC_IWDG4CFGR 0x8A0 +#define RCC_WWDG1CFGR 0x8A4 +#define RCC_VREFCFGR 0x8AC +#define RCC_DTSCFGR 0x8B0 +#define RCC_CRCCFGR 0x8B4 +#define RCC_SERCCFGR 0x8B8 +#define RCC_DDRPERFMCFGR 0x8C0 +#define RCC_I3C1CFGR 0x8C8 +#define RCC_I3C2CFGR 0x8CC +#define RCC_I3C3CFGR 0x8D0 +#define RCC_MUXSELCFGR 0x1000 +#define RCC_XBAR0CFGR 0x1018 +#define RCC_XBAR1CFGR 0x101C +#define RCC_XBAR2CFGR 0x1020 +#define RCC_XBAR3CFGR 0x1024 +#define RCC_XBAR4CFGR 0x1028 +#define RCC_XBAR5CFGR 0x102C +#define RCC_XBAR6CFGR 0x1030 +#define RCC_XBAR7CFGR 0x1034 +#define RCC_XBAR8CFGR 0x1038 +#define RCC_XBAR9CFGR 0x103C +#define RCC_XBAR10CFGR 0x1040 +#define RCC_XBAR11CFGR 0x1044 +#define RCC_XBAR12CFGR 0x1048 +#define RCC_XBAR13CFGR 0x104C +#define RCC_XBAR14CFGR 0x1050 +#define RCC_XBAR15CFGR 0x1054 +#define RCC_XBAR16CFGR 0x1058 +#define RCC_XBAR17CFGR 0x105C +#define RCC_XBAR18CFGR 0x1060 +#define RCC_XBAR19CFGR 0x1064 +#define RCC_XBAR20CFGR 0x1068 +#define RCC_XBAR21CFGR 0x106C +#define RCC_XBAR22CFGR 0x1070 +#define RCC_XBAR23CFGR 0x1074 +#define RCC_XBAR24CFGR 0x1078 +#define RCC_XBAR25CFGR 0x107C +#define RCC_XBAR26CFGR 0x1080 +#define RCC_XBAR27CFGR 0x1084 +#define RCC_XBAR28CFGR 0x1088 +#define RCC_XBAR29CFGR 0x108C +#define RCC_XBAR30CFGR 0x1090 +#define RCC_XBAR31CFGR 0x1094 +#define RCC_XBAR32CFGR 0x1098 +#define RCC_XBAR33CFGR 0x109C +#define RCC_XBAR34CFGR 0x10A0 +#define RCC_XBAR35CFGR 0x10A4 +#define RCC_XBAR36CFGR 0x10A8 +#define RCC_XBAR37CFGR 0x10AC +#define RCC_XBAR38CFGR 0x10B0 +#define RCC_XBAR39CFGR 0x10B4 +#define RCC_XBAR40CFGR 0x10B8 +#define RCC_XBAR41CFGR 0x10BC +#define RCC_XBAR42CFGR 0x10C0 +#define RCC_XBAR43CFGR 0x10C4 +#define RCC_XBAR44CFGR 0x10C8 +#define RCC_XBAR45CFGR 0x10CC +#define RCC_XBAR46CFGR 0x10D0 +#define RCC_XBAR47CFGR 0x10D4 +#define RCC_XBAR48CFGR 0x10D8 +#define RCC_XBAR49CFGR 0x10DC +#define RCC_XBAR50CFGR 0x10E0 +#define RCC_XBAR51CFGR 0x10E4 +#define RCC_XBAR52CFGR 0x10E8 +#define RCC_XBAR53CFGR 0x10EC +#define RCC_XBAR54CFGR 0x10F0 +#define RCC_XBAR55CFGR 0x10F4 +#define RCC_XBAR56CFGR 0x10F8 +#define RCC_XBAR57CFGR 0x10FC +#define RCC_XBAR58CFGR 0x1100 +#define RCC_XBAR59CFGR 0x1104 +#define RCC_XBAR60CFGR 0x1108 +#define RCC_XBAR61CFGR 0x110C +#define RCC_XBAR62CFGR 0x1110 +#define RCC_XBAR63CFGR 0x1114 +#define RCC_PREDIV0CFGR 0x1118 +#define RCC_PREDIV1CFGR 0x111C +#define RCC_PREDIV2CFGR 0x1120 +#define RCC_PREDIV3CFGR 0x1124 +#define RCC_PREDIV4CFGR 0x1128 +#define RCC_PREDIV5CFGR 0x112C +#define RCC_PREDIV6CFGR 0x1130 +#define RCC_PREDIV7CFGR 0x1134 +#define RCC_PREDIV8CFGR 0x1138 +#define RCC_PREDIV9CFGR 0x113C +#define RCC_PREDIV10CFGR 0x1140 +#define RCC_PREDIV11CFGR 0x1144 +#define RCC_PREDIV12CFGR 0x1148 +#define RCC_PREDIV13CFGR 0x114C +#define RCC_PREDIV14CFGR 0x1150 +#define RCC_PREDIV15CFGR 0x1154 +#define RCC_PREDIV16CFGR 0x1158 +#define RCC_PREDIV17CFGR 0x115C +#define RCC_PREDIV18CFGR 0x1160 +#define RCC_PREDIV19CFGR 0x1164 +#define RCC_PREDIV20CFGR 0x1168 +#define RCC_PREDIV21CFGR 0x116C +#define RCC_PREDIV22CFGR 0x1170 +#define RCC_PREDIV23CFGR 0x1174 +#define RCC_PREDIV24CFGR 0x1178 +#define RCC_PREDIV25CFGR 0x117C +#define RCC_PREDIV26CFGR 0x1180 +#define RCC_PREDIV27CFGR 0x1184 +#define RCC_PREDIV28CFGR 0x1188 +#define RCC_PREDIV29CFGR 0x118C +#define RCC_PREDIV30CFGR 0x1190 +#define RCC_PREDIV31CFGR 0x1194 +#define RCC_PREDIV32CFGR 0x1198 +#define RCC_PREDIV33CFGR 0x119C +#define RCC_PREDIV34CFGR 0x11A0 +#define RCC_PREDIV35CFGR 0x11A4 +#define RCC_PREDIV36CFGR 0x11A8 +#define RCC_PREDIV37CFGR 0x11AC +#define RCC_PREDIV38CFGR 0x11B0 +#define RCC_PREDIV39CFGR 0x11B4 +#define RCC_PREDIV40CFGR 0x11B8 +#define RCC_PREDIV41CFGR 0x11BC +#define RCC_PREDIV42CFGR 0x11C0 +#define RCC_PREDIV43CFGR 0x11C4 +#define RCC_PREDIV44CFGR 0x11C8 +#define RCC_PREDIV45CFGR 0x11CC +#define RCC_PREDIV46CFGR 0x11D0 +#define RCC_PREDIV47CFGR 0x11D4 +#define RCC_PREDIV48CFGR 0x11D8 +#define RCC_PREDIV49CFGR 0x11DC +#define RCC_PREDIV50CFGR 0x11E0 +#define RCC_PREDIV51CFGR 0x11E4 +#define RCC_PREDIV52CFGR 0x11E8 +#define RCC_PREDIV53CFGR 0x11EC +#define RCC_PREDIV54CFGR 0x11F0 +#define RCC_PREDIV55CFGR 0x11F4 +#define RCC_PREDIV56CFGR 0x11F8 +#define RCC_PREDIV57CFGR 0x11FC +#define RCC_PREDIV58CFGR 0x1200 +#define RCC_PREDIV59CFGR 0x1204 +#define RCC_PREDIV60CFGR 0x1208 +#define RCC_PREDIV61CFGR 0x120C +#define RCC_PREDIV62CFGR 0x1210 +#define RCC_PREDIV63CFGR 0x1214 +#define RCC_PREDIVSR1 0x1218 +#define RCC_PREDIVSR2 0x121C +#define RCC_FINDIV0CFGR 0x1224 +#define RCC_FINDIV1CFGR 0x1228 +#define RCC_FINDIV2CFGR 0x122C +#define RCC_FINDIV3CFGR 0x1230 +#define RCC_FINDIV4CFGR 0x1234 +#define RCC_FINDIV5CFGR 0x1238 +#define RCC_FINDIV6CFGR 0x123C +#define RCC_FINDIV7CFGR 0x1240 +#define RCC_FINDIV8CFGR 0x1244 +#define RCC_FINDIV9CFGR 0x1248 +#define RCC_FINDIV10CFGR 0x124C +#define RCC_FINDIV11CFGR 0x1250 +#define RCC_FINDIV12CFGR 0x1254 +#define RCC_FINDIV13CFGR 0x1258 +#define RCC_FINDIV14CFGR 0x125C +#define RCC_FINDIV15CFGR 0x1260 +#define RCC_FINDIV16CFGR 0x1264 +#define RCC_FINDIV17CFGR 0x1268 +#define RCC_FINDIV18CFGR 0x126C +#define RCC_FINDIV19CFGR 0x1270 +#define RCC_FINDIV20CFGR 0x1274 +#define RCC_FINDIV21CFGR 0x1278 +#define RCC_FINDIV22CFGR 0x127C +#define RCC_FINDIV23CFGR 0x1280 +#define RCC_FINDIV24CFGR 0x1284 +#define RCC_FINDIV25CFGR 0x1288 +#define RCC_FINDIV26CFGR 0x128C +#define RCC_FINDIV27CFGR 0x1290 +#define RCC_FINDIV28CFGR 0x1294 +#define RCC_FINDIV29CFGR 0x1298 +#define RCC_FINDIV30CFGR 0x129C +#define RCC_FINDIV31CFGR 0x12A0 +#define RCC_FINDIV32CFGR 0x12A4 +#define RCC_FINDIV33CFGR 0x12A8 +#define RCC_FINDIV34CFGR 0x12AC +#define RCC_FINDIV35CFGR 0x12B0 +#define RCC_FINDIV36CFGR 0x12B4 +#define RCC_FINDIV37CFGR 0x12B8 +#define RCC_FINDIV38CFGR 0x12BC +#define RCC_FINDIV39CFGR 0x12C0 +#define RCC_FINDIV40CFGR 0x12C4 +#define RCC_FINDIV41CFGR 0x12C8 +#define RCC_FINDIV42CFGR 0x12CC +#define RCC_FINDIV43CFGR 0x12D0 +#define RCC_FINDIV44CFGR 0x12D4 +#define RCC_FINDIV45CFGR 0x12D8 +#define RCC_FINDIV46CFGR 0x12DC +#define RCC_FINDIV47CFGR 0x12E0 +#define RCC_FINDIV48CFGR 0x12E4 +#define RCC_FINDIV49CFGR 0x12E8 +#define RCC_FINDIV50CFGR 0x12EC +#define RCC_FINDIV51CFGR 0x12F0 +#define RCC_FINDIV52CFGR 0x12F4 +#define RCC_FINDIV53CFGR 0x12F8 +#define RCC_FINDIV54CFGR 0x12FC +#define RCC_FINDIV55CFGR 0x1300 +#define RCC_FINDIV56CFGR 0x1304 +#define RCC_FINDIV57CFGR 0x1308 +#define RCC_FINDIV58CFGR 0x130C +#define RCC_FINDIV59CFGR 0x1310 +#define RCC_FINDIV60CFGR 0x1314 +#define RCC_FINDIV61CFGR 0x1318 +#define RCC_FINDIV62CFGR 0x131C +#define RCC_FINDIV63CFGR 0x1320 +#define RCC_FINDIVSR1 0x1324 +#define RCC_FINDIVSR2 0x1328 +#define RCC_FCALCOBS0CFGR 0x1340 +#define RCC_FCALCOBS1CFGR 0x1344 +#define RCC_FCALCREFCFGR 0x1348 +#define RCC_FCALCCR1 0x134C +#define RCC_FCALCCR2 0x1354 +#define RCC_FCALCSR 0x1358 +#define RCC_PLL4CFGR1 0x1360 +#define RCC_PLL4CFGR2 0x1364 +#define RCC_PLL4CFGR3 0x1368 +#define RCC_PLL4CFGR4 0x136C +#define RCC_PLL4CFGR5 0x1370 +#define RCC_PLL4CFGR6 0x1378 +#define RCC_PLL4CFGR7 0x137C +#define RCC_PLL5CFGR1 0x1388 +#define RCC_PLL5CFGR2 0x138C +#define RCC_PLL5CFGR3 0x1390 +#define RCC_PLL5CFGR4 0x1394 +#define RCC_PLL5CFGR5 0x1398 +#define RCC_PLL5CFGR6 0x13A0 +#define RCC_PLL5CFGR7 0x13A4 +#define RCC_PLL6CFGR1 0x13B0 +#define RCC_PLL6CFGR2 0x13B4 +#define RCC_PLL6CFGR3 0x13B8 +#define RCC_PLL6CFGR4 0x13BC +#define RCC_PLL6CFGR5 0x13C0 +#define RCC_PLL6CFGR6 0x13C8 +#define RCC_PLL6CFGR7 0x13CC +#define RCC_PLL7CFGR1 0x13D8 +#define RCC_PLL7CFGR2 0x13DC +#define RCC_PLL7CFGR3 0x13E0 +#define RCC_PLL7CFGR4 0x13E4 +#define RCC_PLL7CFGR5 0x13E8 +#define RCC_PLL7CFGR6 0x13F0 +#define RCC_PLL7CFGR7 0x13F4 +#define RCC_PLL8CFGR1 0x1400 +#define RCC_PLL8CFGR2 0x1404 +#define RCC_PLL8CFGR3 0x1408 +#define RCC_PLL8CFGR4 0x140C +#define RCC_PLL8CFGR5 0x1410 +#define RCC_PLL8CFGR6 0x1418 +#define RCC_PLL8CFGR7 0x141C +#define RCC_VERR 0xFFF4 +#define RCC_IDR 0xFFF8 +#define RCC_SIDR 0xFFFC + +#endif /* STM32MP21_RCC_H */ From 56356278331ee3934484ce8ee83aea892e3c0710 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:22 +0100 Subject: [PATCH 28/80] reset: stm32mp21: add stm32mp21 reset driver Implement STM32MP21 reset drivers using stm32-core-reset API. Signed-off-by: Gabriel Fernandez Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- drivers/reset/stm32/Kconfig | 7 ++ drivers/reset/stm32/Makefile | 1 + drivers/reset/stm32/stm32-reset-mp21.c | 136 +++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 drivers/reset/stm32/stm32-reset-mp21.c diff --git a/drivers/reset/stm32/Kconfig b/drivers/reset/stm32/Kconfig index fdd88a6bfae..1bafba516af 100644 --- a/drivers/reset/stm32/Kconfig +++ b/drivers/reset/stm32/Kconfig @@ -14,6 +14,13 @@ config RESET_STM32MP1 Support for reset controllers on STMicroelectronics STM32MP1 family SoCs. This reset driver is compatible with STM32MP13 and STM32MP15 SoCs. +config RESET_STM32MP21 + bool "Enable the STM32MP21 reset" + default y if STM32MP21X + help + Support for reset controllers on STMicroelectronics STM32MP21 family SoCs. + This reset driver is compatible with STM32MP21 SoCs. + config RESET_STM32MP25 bool "Enable the STM32MP25 reset" depends on STM32MP23X || STM32MP25X diff --git a/drivers/reset/stm32/Makefile b/drivers/reset/stm32/Makefile index c31ae524ba1..ac4d3c6fc8f 100644 --- a/drivers/reset/stm32/Makefile +++ b/drivers/reset/stm32/Makefile @@ -6,4 +6,5 @@ obj-y += stm32-reset-core.o obj-$(CONFIG_RESET_STM32) += stm32-reset.o obj-$(CONFIG_RESET_STM32MP1) += stm32-reset-mp1.o +obj-$(CONFIG_RESET_STM32MP21) += stm32-reset-mp21.o obj-$(CONFIG_RESET_STM32MP25) += stm32-reset-mp25.o diff --git a/drivers/reset/stm32/stm32-reset-mp21.c b/drivers/reset/stm32/stm32-reset-mp21.c new file mode 100644 index 00000000000..7d169d7582f --- /dev/null +++ b/drivers/reset/stm32/stm32-reset-mp21.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2026, STMicroelectronics - All Rights Reserved + * Author(s): Gabriel Fernandez, for STMicroelectronics. + */ + +#include +#include +#include +#include + +/* Reset clear offset for STM32MP RCC */ +#define RCC_CLR_OFFSET 0x4 + +/* Timeout for deassert */ +#define STM32_DEASSERT_TIMEOUT_US 10000 + +#define RESET(id, _offset, _bit_idx, _set_clr) \ + [id] = &(struct stm32_reset_cfg){ \ + .offset = (_offset), \ + .bit_idx = (_bit_idx), \ + .set_clr = (_set_clr), \ + } + +static const struct stm32_reset_cfg *stm32mp21_reset[] = { + RESET(TIM1_R, RCC_TIM1CFGR, 0, 0), + RESET(TIM2_R, RCC_TIM2CFGR, 0, 0), + RESET(TIM3_R, RCC_TIM3CFGR, 0, 0), + RESET(TIM4_R, RCC_TIM4CFGR, 0, 0), + RESET(TIM5_R, RCC_TIM5CFGR, 0, 0), + RESET(TIM6_R, RCC_TIM6CFGR, 0, 0), + RESET(TIM7_R, RCC_TIM7CFGR, 0, 0), + RESET(TIM8_R, RCC_TIM8CFGR, 0, 0), + RESET(TIM10_R, RCC_TIM10CFGR, 0, 0), + RESET(TIM11_R, RCC_TIM11CFGR, 0, 0), + RESET(TIM12_R, RCC_TIM12CFGR, 0, 0), + RESET(TIM13_R, RCC_TIM13CFGR, 0, 0), + RESET(TIM14_R, RCC_TIM14CFGR, 0, 0), + RESET(TIM15_R, RCC_TIM15CFGR, 0, 0), + RESET(TIM16_R, RCC_TIM16CFGR, 0, 0), + RESET(TIM17_R, RCC_TIM17CFGR, 0, 0), + RESET(LPTIM1_R, RCC_LPTIM1CFGR, 0, 0), + RESET(LPTIM2_R, RCC_LPTIM2CFGR, 0, 0), + RESET(LPTIM3_R, RCC_LPTIM3CFGR, 0, 0), + RESET(LPTIM4_R, RCC_LPTIM4CFGR, 0, 0), + RESET(LPTIM5_R, RCC_LPTIM5CFGR, 0, 0), + RESET(SPI1_R, RCC_SPI1CFGR, 0, 0), + RESET(SPI2_R, RCC_SPI2CFGR, 0, 0), + RESET(SPI3_R, RCC_SPI3CFGR, 0, 0), + RESET(SPI4_R, RCC_SPI4CFGR, 0, 0), + RESET(SPI5_R, RCC_SPI5CFGR, 0, 0), + RESET(SPI6_R, RCC_SPI6CFGR, 0, 0), + RESET(SPDIFRX_R, RCC_SPDIFRXCFGR, 0, 0), + RESET(USART1_R, RCC_USART1CFGR, 0, 0), + RESET(USART2_R, RCC_USART2CFGR, 0, 0), + RESET(USART3_R, RCC_USART3CFGR, 0, 0), + RESET(UART4_R, RCC_UART4CFGR, 0, 0), + RESET(UART5_R, RCC_UART5CFGR, 0, 0), + RESET(USART6_R, RCC_USART6CFGR, 0, 0), + RESET(UART7_R, RCC_UART7CFGR, 0, 0), + RESET(LPUART1_R, RCC_LPUART1CFGR, 0, 0), + RESET(I2C1_R, RCC_I2C1CFGR, 0, 0), + RESET(I2C2_R, RCC_I2C2CFGR, 0, 0), + RESET(I2C3_R, RCC_I2C3CFGR, 0, 0), + RESET(SAI1_R, RCC_SAI1CFGR, 0, 0), + RESET(SAI2_R, RCC_SAI2CFGR, 0, 0), + RESET(SAI3_R, RCC_SAI3CFGR, 0, 0), + RESET(SAI4_R, RCC_SAI4CFGR, 0, 0), + RESET(MDF1_R, RCC_MDF1CFGR, 0, 0), + RESET(FDCAN_R, RCC_FDCANCFGR, 0, 0), + RESET(HDP_R, RCC_HDPCFGR, 0, 0), + RESET(ADC1_R, RCC_ADC1CFGR, 0, 0), + RESET(ADC2_R, RCC_ADC2CFGR, 0, 0), + RESET(ETH1_R, RCC_ETH1CFGR, 0, 0), + RESET(ETH2_R, RCC_ETH2CFGR, 0, 0), + RESET(USBH_R, RCC_USBHCFGR, 0, 0), + RESET(USB2PHY1_R, RCC_USB2PHY1CFGR, 0, 0), + RESET(USB2PHY2_R, RCC_USB2PHY2CFGR, 0, 0), + RESET(SDMMC1_R, RCC_SDMMC1CFGR, 0, 0), + RESET(SDMMC1DLL_R, RCC_SDMMC1CFGR, 16, 0), + RESET(SDMMC2_R, RCC_SDMMC2CFGR, 0, 0), + RESET(SDMMC2DLL_R, RCC_SDMMC2CFGR, 16, 0), + RESET(SDMMC3_R, RCC_SDMMC3CFGR, 0, 0), + RESET(SDMMC3DLL_R, RCC_SDMMC3CFGR, 16, 0), + RESET(LTDC_R, RCC_LTDCCFGR, 0, 0), + RESET(CSI_R, RCC_CSICFGR, 0, 0), + RESET(DCMIPP_R, RCC_DCMIPPCFGR, 0, 0), + RESET(DCMIPSSI_R, RCC_DCMIPSSICFGR, 0, 0), + RESET(WWDG1_R, RCC_WWDG1CFGR, 0, 0), + RESET(VREF_R, RCC_VREFCFGR, 0, 0), + RESET(DTS_R, RCC_DTSCFGR, 0, 0), + RESET(CRC_R, RCC_CRCCFGR, 0, 0), + RESET(SERC_R, RCC_SERCCFGR, 0, 0), + RESET(I3C1_R, RCC_I3C1CFGR, 0, 0), + RESET(I3C2_R, RCC_I3C2CFGR, 0, 0), + RESET(IWDG2_KER_R, RCC_IWDGC1CFGSETR, 18, 1), + RESET(IWDG4_KER_R, RCC_IWDGC2CFGSETR, 18, 1), + RESET(RNG1_R, RCC_RNG1CFGR, 0, 0), + RESET(RNG2_R, RCC_RNG2CFGR, 0, 0), + RESET(PKA_R, RCC_PKACFGR, 0, 0), + RESET(SAES_R, RCC_SAESCFGR, 0, 0), + RESET(HASH1_R, RCC_HASH1CFGR, 0, 0), + RESET(HASH2_R, RCC_HASH2CFGR, 0, 0), + RESET(CRYP1_R, RCC_CRYP1CFGR, 0, 0), + RESET(CRYP2_R, RCC_CRYP2CFGR, 0, 0), + RESET(OTG_R, RCC_OTGCFGR, 0, 0), +}; + +static const struct stm32_reset_cfg *stm32_get_reset_line(struct reset_ctl *reset_ctl) +{ + unsigned long id = reset_ctl->id; + + if (id < ARRAY_SIZE(stm32mp21_reset)) + return stm32mp21_reset[id]; + + return NULL; +} + +static const struct stm32_reset_data stm32mp21_reset_data = { + .get_reset_line = stm32_get_reset_line, + .clear_offset = RCC_CLR_OFFSET, + .reset_us = STM32_DEASSERT_TIMEOUT_US, +}; + +static int stm32_reset_probe(struct udevice *dev) +{ + return stm32_reset_core_probe(dev, &stm32mp21_reset_data); +} + +U_BOOT_DRIVER(stm32mp21_rcc_reset) = { + .name = "stm32mp21_reset", + .id = UCLASS_RESET, + .probe = stm32_reset_probe, + .priv_auto = sizeof(struct stm32_reset_priv), + .ops = &stm32_reset_ops, +}; From 0ec3b313109da6086fc3f07d9dbcedb8dd5df2d5 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:23 +0100 Subject: [PATCH 29/80] stm32mp: syscon: Add STM32MP21 support Add "st,stm32mp21-syscfg" compatible. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/syscon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c index b00897e87ec..f2cfc9465a5 100644 --- a/arch/arm/mach-stm32mp/syscon.c +++ b/arch/arm/mach-stm32mp/syscon.c @@ -10,6 +10,7 @@ static const struct udevice_id stm32mp_syscon_ids[] = { { .compatible = "st,stm32mp157-syscfg", .data = STM32MP_SYSCON_SYSCFG }, + { .compatible = "st,stm32mp21-syscfg", .data = STM32MP_SYSCON_SYSCFG}, { .compatible = "st,stm32mp23-syscfg", .data = STM32MP_SYSCON_SYSCFG}, { .compatible = "st,stm32mp25-syscfg", .data = STM32MP_SYSCON_SYSCFG}, { } From 42fa38b925bbccf1d80f12a374594af9470e03fc Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:24 +0100 Subject: [PATCH 30/80] stm32mp: cmd_stm32key: add support of STM32MP21x Add cmd_stm32key support for STM32MP21x SoCs family. Signed-off-by: Yann Gautier Signed-off-by: Nicolas Le Bayon Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 70 +++++++++++++++------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index f5def4cd2dc..f1e0a3e817c 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2019-2024, STMicroelectronics - All Rights Reserved */ #include @@ -16,21 +16,21 @@ * Closed device: OTP0 * STM32MP15x: bit 6 of OTP0 * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device - * STM32MP25x: bit 0 of OTP18 + * STM32MP2xx: bit 0 of OTP18 */ #define STM32MP1_OTP_CLOSE_ID 0 #define STM32_OTP_STM32MP13X_CLOSE_MASK GENMASK(5, 0) #define STM32_OTP_STM32MP15X_CLOSE_MASK BIT(6) -#define STM32MP25_OTP_WORD8 8 -#define STM32_OTP_STM32MP25X_BOOTROM_CLOSE_MASK GENMASK(7, 0) -#define STM32MP25_OTP_CLOSE_ID 18 -#define STM32_OTP_STM32MP25X_CLOSE_MASK GENMASK(3, 0) -#define STM32_OTP_STM32MP25X_PROVISIONING_DONE_MASK GENMASK(7, 4) -#define STM32MP25_OTP_HWCONFIG 124 -#define STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK BIT(20) +#define STM32MP2X_OTP_WORD8 8 +#define STM32_OTP_STM32MP2X_BOOTROM_CLOSE_MASK GENMASK(7, 0) +#define STM32MP2X_OTP_CLOSE_ID 18 +#define STM32_OTP_STM32MP2X_CLOSE_MASK GENMASK(3, 0) +#define STM32_OTP_STM32MP2X_PROVISIONING_DONE_MASK GENMASK(7, 4) +#define STM32MP2X_OTP_HWCONFIG 124 +#define STM32_OTP_STM32MP2X_DISABLE_SCAN_MASK BIT(20) -#define STM32MP25_OTP_BOOTROM_CONF8 17 -#define STM32_OTP_STM32MP25X_OEM_KEY2_EN BIT(8) +#define STM32MP2X_OTP_BOOTROM_CONF8 17 +#define STM32_OTP_STM32MP2X_OEM_KEY2_EN BIT(8) /* PKH is the first element of the key list */ #define STM32KEY_PKH 0 @@ -69,7 +69,7 @@ const struct stm32key stm32mp15_list[] = { static int post_process_oem_key2(struct udevice *dev); -const struct stm32key stm32mp25_list[] = { +const struct stm32key stm32mp2x_list[] = { [STM32KEY_PKH] = { .name = "OEM-KEY1", .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M", @@ -138,23 +138,23 @@ const struct otp_close stm32mp15_close_state_otp[] = { } }; -const struct otp_close stm32mp25_close_state_otp[] = { +const struct otp_close stm32mp2x_close_state_otp[] = { { - .word = STM32MP25_OTP_WORD8, - .mask_wr = STM32_OTP_STM32MP25X_BOOTROM_CLOSE_MASK, + .word = STM32MP2X_OTP_WORD8, + .mask_wr = STM32_OTP_STM32MP2X_BOOTROM_CLOSE_MASK, .mask_rd = 0, .close_status_ops = NULL }, { - .word = STM32MP25_OTP_CLOSE_ID, - .mask_wr = STM32_OTP_STM32MP25X_CLOSE_MASK | - STM32_OTP_STM32MP25X_PROVISIONING_DONE_MASK, - .mask_rd = STM32_OTP_STM32MP25X_CLOSE_MASK, + .word = STM32MP2X_OTP_CLOSE_ID, + .mask_wr = STM32_OTP_STM32MP2X_CLOSE_MASK | + STM32_OTP_STM32MP2X_PROVISIONING_DONE_MASK, + .mask_rd = STM32_OTP_STM32MP2X_CLOSE_MASK, .close_status_ops = compare_any_bits }, { - .word = STM32MP25_OTP_HWCONFIG, - .mask_wr = STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK, + .word = STM32MP2X_OTP_HWCONFIG, + .mask_wr = STM32_OTP_STM32MP2X_DISABLE_SCAN_MASK, .mask_rd = 0, .close_status_ops = NULL }, @@ -171,8 +171,9 @@ static u8 get_key_nb(void) if (IS_ENABLED(CONFIG_STM32MP15X)) return ARRAY_SIZE(stm32mp15_list); - if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) - return ARRAY_SIZE(stm32mp25_list); + if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || + IS_ENABLED(CONFIG_STM32MP25X)) + return ARRAY_SIZE(stm32mp2x_list); } static const struct stm32key *get_key(u8 index) @@ -183,8 +184,9 @@ static const struct stm32key *get_key(u8 index) if (IS_ENABLED(CONFIG_STM32MP15X)) return &stm32mp15_list[index]; - if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) - return &stm32mp25_list[index]; + if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || + IS_ENABLED(CONFIG_STM32MP25X)) + return &stm32mp2x_list[index]; } static u8 get_otp_close_state_nb(void) @@ -195,8 +197,9 @@ static u8 get_otp_close_state_nb(void) if (IS_ENABLED(CONFIG_STM32MP15X)) return ARRAY_SIZE(stm32mp15_close_state_otp); - if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) - return ARRAY_SIZE(stm32mp25_close_state_otp); + if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || + IS_ENABLED(CONFIG_STM32MP25X)) + return ARRAY_SIZE(stm32mp2x_close_state_otp); } static const struct otp_close *get_otp_close_state(u8 index) @@ -207,8 +210,9 @@ static const struct otp_close *get_otp_close_state(u8 index) if (IS_ENABLED(CONFIG_STM32MP15X)) return &stm32mp15_close_state_otp[index]; - if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) - return &stm32mp25_close_state_otp[index]; + if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || + IS_ENABLED(CONFIG_STM32MP25X)) + return &stm32mp2x_close_state_otp[index]; } static int get_misc_dev(struct udevice **dev) @@ -352,14 +356,14 @@ static int post_process_oem_key2(struct udevice *dev) int ret; u32 val; - ret = misc_read(dev, STM32_BSEC_OTP(STM32MP25_OTP_BOOTROM_CONF8), &val, 4); + ret = misc_read(dev, STM32_BSEC_OTP(STM32MP2X_OTP_BOOTROM_CONF8), &val, 4); if (ret != 4) { - log_err("Error %d failed to read STM32MP25_OTP_BOOTROM_CONF8\n", ret); + log_err("Error %d failed to read STM32MP2X_OTP_BOOTROM_CONF8\n", ret); return -EIO; } - val |= STM32_OTP_STM32MP25X_OEM_KEY2_EN; - ret = misc_write(dev, STM32_BSEC_OTP(STM32MP25_OTP_BOOTROM_CONF8), &val, 4); + val |= STM32_OTP_STM32MP2X_OEM_KEY2_EN; + ret = misc_write(dev, STM32_BSEC_OTP(STM32MP2X_OTP_BOOTROM_CONF8), &val, 4); if (ret != 4) { log_err("Error %d failed to write OEM_KEY2_ENABLE\n", ret); return -EIO; From d557099fb0f1b1b8ae0a415e006c3d517874b8a6 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:25 +0100 Subject: [PATCH 31/80] ARM: stm32mp: Add STM32MP21 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STM32MP21 application processors (STM32 MPUs) based on a single Arm Cortex®-A35 core running up to 1.5 GHz and Cortex®-M33 core running at 300 MHz. It is pin-compatible with the STM32MP2 series in the VFBGA361 10×10 mm package: the STM32MP21 uses a subset of the STM32MP23 pinout, which itself is a subset of the STM32MP25. More details available here : https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/Kconfig | 27 +++ arch/arm/mach-stm32mp/Kconfig.21x | 37 ++++ arch/arm/mach-stm32mp/Makefile | 3 +- arch/arm/mach-stm32mp/include/mach/stm32.h | 12 +- .../arm/mach-stm32mp/include/mach/sys_proto.h | 22 ++ arch/arm/mach-stm32mp/stm32mp2/Makefile | 1 + arch/arm/mach-stm32mp/stm32mp2/arm64-mmu.c | 2 + arch/arm/mach-stm32mp/stm32mp2/cpu.c | 2 + arch/arm/mach-stm32mp/stm32mp2/rifsc.c | 1 + arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c | 192 ++++++++++++++++++ board/st/common/Kconfig | 2 +- board/st/stm32mp2/Kconfig | 14 ++ configs/stm32mp21_defconfig | 78 +++++++ include/configs/stm32mp21_common.h | 126 ++++++++++++ include/configs/stm32mp21_st_common.h | 51 +++++ 15 files changed, 564 insertions(+), 6 deletions(-) create mode 100644 arch/arm/mach-stm32mp/Kconfig.21x create mode 100644 arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c create mode 100644 configs/stm32mp21_defconfig create mode 100644 include/configs/stm32mp21_common.h create mode 100644 include/configs/stm32mp21_st_common.h diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 2716844b259..31b2746379d 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -84,6 +84,32 @@ config STM32MP15X STMicroelectronics MPU with core ARMv7 dual core A7 for STM32MP157/3, monocore for STM32MP151 +config STM32MP21X + bool "Support STMicroelectronics STM32MP21x Soc" + select ARM64 + select CLK_STM32MP21 + select OF_BOARD + select PINCTRL_STM32 + select STM32_RCC + select STM32_RESET + select STM32_SERIAL + select STM32MP_TAMP_NVMEM + select SYS_ARCH_TIMER + select TFABOOT + imply CLK_SCMI + imply CMD_NVEDIT_INFO + imply DM_REGULATOR + imply DM_REGULATOR_SCMI + imply OF_UPSTREAM + imply OPTEE + imply RESET_SCMI + imply SYSRESET_PSCI + imply TEE + imply VERSION_VARIABLE + help + Support of STMicroelectronics SOC STM32MP21X family + STMicroelectronics MPU with 1 A35 core and 1 M33 core + config STM32MP23X bool "Support STMicroelectronics STM32MP23x Soc" select ARM64 @@ -195,6 +221,7 @@ config MFD_STM32_TIMERS source "arch/arm/mach-stm32mp/Kconfig.13x" source "arch/arm/mach-stm32mp/Kconfig.15x" +source "arch/arm/mach-stm32mp/Kconfig.21x" source "arch/arm/mach-stm32mp/Kconfig.23x" source "arch/arm/mach-stm32mp/Kconfig.25x" source "arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig" diff --git a/arch/arm/mach-stm32mp/Kconfig.21x b/arch/arm/mach-stm32mp/Kconfig.21x new file mode 100644 index 00000000000..dbde3d75ad4 --- /dev/null +++ b/arch/arm/mach-stm32mp/Kconfig.21x @@ -0,0 +1,37 @@ +if STM32MP21X + +choice + prompt "STM32MP21X board select" + optional + +config TARGET_ST_STM32MP21X + bool "STMicroelectronics STM32MP21X boards" + imply BOOTSTAGE + imply CMD_BOOTSTAGE + help + target the STMicroelectronics board with SOC STM32MP21X + managed by board/st/stm32mp2 + The difference between board are managed with devicetree + +endchoice + +config TEXT_BASE + default 0x84000000 + +config PRE_CON_BUF_ADDR + default 0x84800000 + +config PRE_CON_BUF_SZ + default 4096 + +if DEBUG_UART + +# debug on USART2 by default +config DEBUG_UART_BASE + default 0x400e0000 + +endif + +source "board/st/stm32mp2/Kconfig" + +endif diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile index eeb5fdd7b45..853469f3c50 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile @@ -8,8 +8,9 @@ obj-y += syscon.o obj-y += bsec.o obj-y += soc.o -obj-$(CONFIG_STM32MP15X) += stm32mp1/ obj-$(CONFIG_STM32MP13X) += stm32mp1/ +obj-$(CONFIG_STM32MP15X) += stm32mp1/ +obj-$(CONFIG_STM32MP21X) += stm32mp2/ obj-$(CONFIG_STM32MP23X) += stm32mp2/ obj-$(CONFIG_STM32MP25X) += stm32mp2/ diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index 90f06a052d3..7f349f3b68d 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -165,16 +165,20 @@ enum forced_boot_mode { #endif /* __ASSEMBLY__ */ #endif /* CONFIG_STM32MP15X || CONFIG_STM32MP13X */ -#if defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) +#if defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) #define STM32_USART2_BASE 0x400E0000 #define STM32_USART3_BASE 0x400F0000 #define STM32_UART4_BASE 0x40100000 #define STM32_UART5_BASE 0x40110000 #define STM32_USART6_BASE 0x40220000 +#ifdef CONFIG_STM32MP25X #define STM32_UART9_BASE 0x402C0000 +#endif #define STM32_USART1_BASE 0x40330000 #define STM32_UART7_BASE 0x40370000 +#ifdef CONFIG_STM32MP25X #define STM32_UART8_BASE 0x40380000 +#endif #define STM32_RCC_BASE 0x44200000 #define STM32_TAMP_BASE 0x46010000 #define STM32_SDMMC1_BASE 0x48220000 @@ -194,7 +198,7 @@ enum forced_boot_mode { #define TAMP_FWU_BOOT_IDX_MASK GENMASK(3, 0) #define TAMP_FWU_BOOT_IDX_OFFSET 0 -#endif /* defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */ +#endif /* defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */ /* offset used for BSEC driver: misc_read and misc_write */ #define STM32_BSEC_SHADOW_OFFSET 0x0 @@ -218,14 +222,14 @@ enum forced_boot_mode { #define BSEC_OTP_MAC 57 #define BSEC_OTP_BOARD 60 #endif -#if defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) +#if defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) #define BSEC_OTP_SERIAL 5 #define BSEC_OTP_RPN 9 #define BSEC_OTP_REVID 102 #define BSEC_OTP_PKG 122 #define BSEC_OTP_BOARD 246 #define BSEC_OTP_MAC 247 -#endif /* defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */ +#endif /* defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */ #ifndef __ASSEMBLY__ #include diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h index 2a4837184fc..a875907ac3e 100644 --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h @@ -30,6 +30,20 @@ #define CPU_STM32MP131Fxx 0x05010EC8 #define CPU_STM32MP131Dxx 0x05010EC9 +/* ID for STM32MP21x = Device Part Number (RPN) (bit31:0) */ +#define CPU_STM32MP211Axx 0x40073E7D +#define CPU_STM32MP211Cxx 0x0007307D +#define CPU_STM32MP211Dxx 0xC0073E7D +#define CPU_STM32MP211Fxx 0x8007307D +#define CPU_STM32MP213Axx 0x40073E1D +#define CPU_STM32MP213Cxx 0x0007301D +#define CPU_STM32MP213Dxx 0xC0073E1D +#define CPU_STM32MP213Fxx 0x8007301D +#define CPU_STM32MP215Axx 0x40033E0D +#define CPU_STM32MP215Cxx 0x0003300D +#define CPU_STM32MP215Dxx 0xC0033E0D +#define CPU_STM32MP215Fxx 0x8003300D + /* ID for STM32MP23x = Device Part Number (RPN) (bit31:0) */ #define CPU_STM32MP235Cxx 0x00082182 #define CPU_STM32MP233Cxx 0x000B318E @@ -67,6 +81,7 @@ u32 get_cpu_type(void); #define CPU_DEV_STM32MP15 0x500 #define CPU_DEV_STM32MP13 0x501 +#define CPU_DEV_STM32MP21 0x503 #define CPU_DEV_STM32MP23 0x505 #define CPU_DEV_STM32MP25 0x505 @@ -102,6 +117,13 @@ u32 get_cpu_package(void); #define STM32MP15_PKG_AD_TFBGA257 1 #define STM32MP15_PKG_UNKNOWN 0 +/* package used for STM32MP21x */ +#define STM32MP21_PKG_CUSTOM 0 +#define STM32MP21_PKG_AL_VFBGA361 1 +#define STM32MP21_PKG_AN_VFBGA273 3 +#define STM32MP21_PKG_AO_VFBGA225 4 +#define STM32MP21_PKG_AM_TFBGA289 5 + /* package used for STM32MP23x */ #define STM32MP23_PKG_CUSTOM 0 #define STM32MP23_PKG_AL_VFBGA361 1 diff --git a/arch/arm/mach-stm32mp/stm32mp2/Makefile b/arch/arm/mach-stm32mp/stm32mp2/Makefile index 27fbf3ae728..b25af2e8934 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/Makefile +++ b/arch/arm/mach-stm32mp/stm32mp2/Makefile @@ -7,5 +7,6 @@ obj-y += cpu.o obj-y += arm64-mmu.o obj-y += rifsc.o obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o +obj-$(CONFIG_STM32MP21X) += stm32mp21x.o obj-$(CONFIG_STM32MP23X) += stm32mp23x.o obj-$(CONFIG_STM32MP25X) += stm32mp25x.o diff --git a/arch/arm/mach-stm32mp/stm32mp2/arm64-mmu.c b/arch/arm/mach-stm32mp/stm32mp2/arm64-mmu.c index 36c631ef0c2..4f418b65d38 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/arm64-mmu.c +++ b/arch/arm/mach-stm32mp/stm32mp2/arm64-mmu.c @@ -16,6 +16,7 @@ struct mm_region stm32mp2_mem_map[MP2_MEM_MAP_MAX] = { { +#if defined(CONFIG_STM32MP25X) /* PCIe */ .virt = 0x10000000UL, .phys = 0x10000000UL, @@ -24,6 +25,7 @@ struct mm_region stm32mp2_mem_map[MP2_MEM_MAP_MAX] = { PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { +#endif /* LPSRAMs, VDERAM, RETRAM, SRAMs, SYSRAM: alias1 */ .virt = 0x20000000UL, .phys = 0x20000000UL, diff --git a/arch/arm/mach-stm32mp/stm32mp2/cpu.c b/arch/arm/mach-stm32mp/stm32mp2/cpu.c index 178c6356b2b..5e2ecb93ee4 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/cpu.c +++ b/arch/arm/mach-stm32mp/stm32mp2/cpu.c @@ -142,8 +142,10 @@ static void setup_boot_mode(void) STM32_UART5_BASE, STM32_USART6_BASE, STM32_UART7_BASE, +#ifdef CONFIG_STM32MP25X STM32_UART8_BASE, STM32_UART9_BASE +#endif }; const u32 sdmmc_addr[] = { STM32_SDMMC1_BASE, diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c index f8f67af4449..cf8026088f3 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c +++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c @@ -367,6 +367,7 @@ static int stm32_rifsc_remove(struct udevice *bus) } static const struct udevice_id stm32_rifsc_ids[] = { + { .compatible = "st,stm32mp21-rifsc" }, { .compatible = "st,stm32mp25-rifsc" }, {}, }; diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c new file mode 100644 index 00000000000..40d0f329496 --- /dev/null +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2026, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY LOGC_ARCH + +#include +#include +#include +#include +#include + +/* SYSCFG register */ +#define SYSCFG_DEVICEID_OFFSET 0x6400 +#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0) +#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0 + +/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/ +#define REVID_SHIFT 0 +#define REVID_MASK GENMASK(5, 0) + +/* Device Part Number (RPN) = OTP9 */ +#define RPN_SHIFT 0 +#define RPN_MASK GENMASK(31, 0) + +/* Package = bit 0:2 of OTP122 => STM32MP21_PKG defines + * - 000: Custom package + * - 001: VFBGA361 => AL = 10x10, 361 balls pith 0.5mm + * - 011: VFBGA273 => AN = 11x11, 273 balls pith 0.5mm + * - 100: VFBGA225 => AO = 8x8, 225 balls pith 0.5mm + * - 101: TFBGA289 => AM = 14x14, 289 balls pith 0.8mm + * - others: Reserved + */ +#define PKG_SHIFT 0 +#define PKG_MASK GENMASK(2, 0) + +static u32 read_deviceid(void) +{ + void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + + return readl(syscfg + SYSCFG_DEVICEID_OFFSET); +} + +u32 get_cpu_dev(void) +{ + return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT; +} + +u32 get_cpu_rev(void) +{ + return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK); +} + +/* Get Device Part Number (RPN) from OTP */ +u32 get_cpu_type(void) +{ + return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); +} + +/* Get Package options from OTP */ +u32 get_cpu_package(void) +{ + return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); +} + +int get_eth_nb(void) +{ + int nb_eth; + + switch (get_cpu_type()) { + case CPU_STM32MP215Axx: + fallthrough; + case CPU_STM32MP215Cxx: + fallthrough; + case CPU_STM32MP215Dxx: + fallthrough; + case CPU_STM32MP215Fxx: + fallthrough; + case CPU_STM32MP213Axx: + fallthrough; + case CPU_STM32MP213Cxx: + fallthrough; + case CPU_STM32MP213Dxx: + fallthrough; + case CPU_STM32MP213Fxx: + nb_eth = 2; /* dual ETH */ + break; + case CPU_STM32MP211Axx: + fallthrough; + case CPU_STM32MP211Cxx: + fallthrough; + case CPU_STM32MP211Dxx: + fallthrough; + case CPU_STM32MP211Fxx: + nb_eth = 1; /* single ETH */ + break; + default: + nb_eth = 0; + break; + } + + return nb_eth; +} + +void get_soc_name(char name[SOC_NAME_SIZE]) +{ + char *cpu_s, *cpu_r, *package; + + cpu_s = "????"; + cpu_r = "?"; + package = "??"; + if (get_cpu_dev() == CPU_DEV_STM32MP21) { + switch (get_cpu_type()) { + case CPU_STM32MP215Fxx: + cpu_s = "215F"; + break; + case CPU_STM32MP215Dxx: + cpu_s = "215D"; + break; + case CPU_STM32MP215Cxx: + cpu_s = "215C"; + break; + case CPU_STM32MP215Axx: + cpu_s = "215A"; + break; + case CPU_STM32MP213Fxx: + cpu_s = "213F"; + break; + case CPU_STM32MP213Dxx: + cpu_s = "213D"; + break; + case CPU_STM32MP213Cxx: + cpu_s = "213C"; + break; + case CPU_STM32MP213Axx: + cpu_s = "213A"; + break; + case CPU_STM32MP211Fxx: + cpu_s = "211F"; + break; + case CPU_STM32MP211Dxx: + cpu_s = "211D"; + break; + case CPU_STM32MP211Cxx: + cpu_s = "211C"; + break; + case CPU_STM32MP211Axx: + cpu_s = "211A"; + break; + default: + cpu_s = "21??"; + break; + } + /* REVISION */ + switch (get_cpu_rev()) { + case OTP_REVID_1: + cpu_r = "A"; + break; + case OTP_REVID_1_1: + cpu_r = "Z"; + break; + case OTP_REVID_2: + cpu_r = "B"; + break; + default: + break; + } + /* PACKAGE */ + switch (get_cpu_package()) { + case STM32MP25_PKG_CUSTOM: + package = "XX"; + break; + case STM32MP21_PKG_AL_VFBGA361: + package = "AL"; + break; + case STM32MP21_PKG_AN_VFBGA273: + package = "AN"; + break; + case STM32MP21_PKG_AO_VFBGA225: + package = "AO"; + break; + case STM32MP21_PKG_AM_TFBGA289: + package = "AM"; + break; + default: + break; + } + } + + snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s", cpu_s, package, cpu_r); +} diff --git a/board/st/common/Kconfig b/board/st/common/Kconfig index 94ec806949b..3d00f3f3331 100644 --- a/board/st/common/Kconfig +++ b/board/st/common/Kconfig @@ -1,7 +1,7 @@ config CMD_STBOARD bool "stboard - command for OTP board information" depends on ARCH_STM32MP - default y if TARGET_ST_STM32MP13X || TARGET_ST_STM32MP15X || TARGET_ST_STM32MP23X || TARGET_ST_STM32MP25X + default y if TARGET_ST_STM32MP13X || TARGET_ST_STM32MP15X || TARGET_ST_STM32MP21X || TARGET_ST_STM32MP23X || TARGET_ST_STM32MP25X help This compile the stboard command to read and write the board in the OTP. diff --git a/board/st/stm32mp2/Kconfig b/board/st/stm32mp2/Kconfig index e88c71a278e..d8882f113b6 100644 --- a/board/st/stm32mp2/Kconfig +++ b/board/st/stm32mp2/Kconfig @@ -1,3 +1,17 @@ +if TARGET_ST_STM32MP21X + +config SYS_BOARD + default "stm32mp2" + +config SYS_VENDOR + default "st" + +config SYS_CONFIG_NAME + default "stm32mp21_st_common" + +source "board/st/common/Kconfig" +endif + if TARGET_ST_STM32MP23X config SYS_BOARD diff --git a/configs/stm32mp21_defconfig b/configs/stm32mp21_defconfig new file mode 100644 index 00000000000..8ad31292579 --- /dev/null +++ b/configs/stm32mp21_defconfig @@ -0,0 +1,78 @@ +CONFIG_ARM=y +CONFIG_ARCH_STM32MP=y +CONFIG_SYS_MALLOC_F_LEN=0x600000 +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x90000000 +CONFIG_ENV_OFFSET=0x900000 +CONFIG_ENV_SECT_SIZE=0x40000 +CONFIG_DEFAULT_DEVICE_TREE="st/stm32mp215f-dk" +CONFIG_SYS_BOOTM_LEN=0x2000000 +CONFIG_SYS_LOAD_ADDR=0x84000000 +CONFIG_STM32MP21X=y +CONFIG_DDR_CACHEABLE_SIZE=0x10000000 +CONFIG_CMD_STM32KEY=y +CONFIG_TARGET_ST_STM32MP21X=y +CONFIG_SYS_MEMTEST_START=0x84000000 +CONFIG_SYS_MEMTEST_END=0x88000000 +CONFIG_API=y +CONFIG_SYS_MMC_MAX_DEVICE=3 +CONFIG_FIT=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_BOOTDELAY=1 +CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" +CONFIG_SYS_PROMPT="STM32MP> " +# CONFIG_CMD_BDI is not set +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_ADTIMG=y +# CONFIG_CMD_ELF is not set +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_CLK=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADB is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_RNG=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_LOG=y +CONFIG_CMD_UBI=y +CONFIG_OF_LIVE=y +CONFIG_OF_UPSTREAM_BUILD_VENDOR=y +CONFIG_OF_UPSTREAM_VENDOR="st" +CONFIG_ENV_IS_NOWHERE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_IS_IN_UBI=y +CONFIG_ENV_UBI_PART="UBI" +CONFIG_ENV_UBI_VOLUME="uboot_config" +CONFIG_NO_NET=y +CONFIG_SYS_64BIT_LBA=y +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=y +CONFIG_GPIO_HOG=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_STM32F7=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_STM32_SDMMC2=y +CONFIG_MTD=y +CONFIG_USE_SYS_MAX_FLASH_BANKS=y +CONFIG_SPI_FLASH=y +CONFIG_PINCONF=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +# CONFIG_STM32MP1_DDR is not set +CONFIG_DM_RNG=y +CONFIG_SERIAL_RX_BUFFER=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +# CONFIG_OPTEE_TA_AVB is not set +CONFIG_WDT=y +CONFIG_WDT_STM32MP=y +CONFIG_WDT_ARM_SMC=y +# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set +CONFIG_ERRNO_STR=y diff --git a/include/configs/stm32mp21_common.h b/include/configs/stm32mp21_common.h new file mode 100644 index 00000000000..e5129b13b3e --- /dev/null +++ b/include/configs/stm32mp21_common.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */ +/* + * Copyright (C) 2026, STMicroelectronics - All Rights Reserved + * + * Configuration settings for the STM32MP21x CPU + */ + +#ifndef __CONFIG_STM32MP21_COMMMON_H +#define __CONFIG_STM32MP21_COMMMON_H +#include +#include + +/* + * Configuration of the external SRAM memory used by U-Boot + */ +#define CFG_SYS_SDRAM_BASE STM32_DDR_BASE + +/* + * For booting Linux, use the first 256 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_SYS_BOOTMAPSZ SZ_256M + +/*****************************************************************************/ +#ifdef CONFIG_DISTRO_DEFAULTS +/*****************************************************************************/ + +#ifdef CONFIG_NET +#define BOOT_TARGET_PXE(func) func(PXE, pxe, na) +#else +#define BOOT_TARGET_PXE(func) +#endif + +#ifdef CONFIG_CMD_MMC +#define BOOT_TARGET_MMC0(func) func(MMC, mmc, 0) +#define BOOT_TARGET_MMC1(func) func(MMC, mmc, 1) +#define BOOT_TARGET_MMC2(func) func(MMC, mmc, 2) +#else +#define BOOT_TARGET_MMC0(func) +#define BOOT_TARGET_MMC1(func) +#define BOOT_TARGET_MMC2(func) +#endif + +#ifdef CONFIG_CMD_UBIFS +#define BOOT_TARGET_UBIFS(func) func(UBIFS, ubifs, 0, UBI, boot) +#else +#define BOOT_TARGET_UBIFS(func) +#endif + +#ifdef CONFIG_CMD_USB +#define BOOT_TARGET_USB(func) func(USB, usb, 0) +#else +#define BOOT_TARGET_USB(func) +#endif + +#define BOOT_TARGET_DEVICES(func) \ + BOOT_TARGET_MMC1(func) \ + BOOT_TARGET_UBIFS(func) \ + BOOT_TARGET_MMC0(func) \ + BOOT_TARGET_MMC2(func) \ + BOOT_TARGET_USB(func) \ + BOOT_TARGET_PXE(func) + +/* + * default bootcmd for stm32mp21: + * for serial/usb: execute the stm32prog command + * for mmc boot (eMMC, SD card), distro boot on the same mmc device + * for NAND or SPI-NAND boot, distro boot with UBIFS on UBI partition + * for other boot, use the default distro order in ${boot_targets} + */ +#define STM32MP_BOOTCMD "bootcmd_stm32mp=" \ + "echo \"Boot over ${boot_device}${boot_instance}!\";" \ + "if test ${boot_device} = serial || test ${boot_device} = usb;" \ + "then stm32prog ${boot_device} ${boot_instance}; " \ + "else " \ + "run env_check;" \ + "if test ${boot_device} = mmc;" \ + "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ + "if test ${boot_device} = nand ||" \ + " test ${boot_device} = spi-nand ;" \ + "then env set boot_targets ubifs0; fi;" \ + "run distro_bootcmd;" \ + "fi;\0" + +#ifndef STM32MP_BOARD_EXTRA_ENV +#define STM32MP_BOARD_EXTRA_ENV +#endif + +#define STM32MP_EXTRA \ + "env_check=if env info -p -d -q; then env save; fi\0" \ + "boot_net_usb_start=true\0" +/* + * memory layout for 96MB uncompressed/compressed kernel, + * 1M fdt, 1M script, 1M pxe and 1M for overlay + * and the ramdisk at the end. + */ +#define __KERNEL_COMP_ADDR_R __stringify(0x84000000) +#define __KERNEL_COMP_SIZE_R __stringify(0x04000000) +#define __KERNEL_ADDR_R __stringify(0x8a000000) +#define __FDT_ADDR_R __stringify(0x90000000) +#define __SCRIPT_ADDR_R __stringify(0x90100000) +#define __PXEFILE_ADDR_R __stringify(0x90200000) +#define __FDTOVERLAY_ADDR_R __stringify(0x90300000) +#define __RAMDISK_ADDR_R __stringify(0x90400000) + +#define STM32MP_MEM_LAYOUT \ + "kernel_addr_r=" __KERNEL_ADDR_R "\0" \ + "fdt_addr_r=" __FDT_ADDR_R "\0" \ + "scriptaddr=" __SCRIPT_ADDR_R "\0" \ + "pxefile_addr_r=" __PXEFILE_ADDR_R "\0" \ + "fdtoverlay_addr_r=" __FDTOVERLAY_ADDR_R "\0" \ + "ramdisk_addr_r=" __RAMDISK_ADDR_R "\0" \ + "kernel_comp_addr_r=" __KERNEL_COMP_ADDR_R "\0" \ + "kernel_comp_size=" __KERNEL_COMP_SIZE_R "\0" + +#include +#define CFG_EXTRA_ENV_SETTINGS \ + STM32MP_MEM_LAYOUT \ + STM32MP_BOOTCMD \ + BOOTENV \ + STM32MP_EXTRA \ + STM32MP_BOARD_EXTRA_ENV + +#endif + +#endif /* __CONFIG_STM32MP21_COMMMON_H */ diff --git a/include/configs/stm32mp21_st_common.h b/include/configs/stm32mp21_st_common.h new file mode 100644 index 00000000000..c601f2d7fb6 --- /dev/null +++ b/include/configs/stm32mp21_st_common.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */ +/* + * Copyright (C) 2026, STMicroelectronics - All Rights Reserved + * + * Configuration settings for the STMicroelectonics STM32MP21x boards + */ + +#ifndef __CONFIG_STM32MP21_ST_COMMON_H__ +#define __CONFIG_STM32MP21_ST_COMMON_H__ + +#define STM32MP_BOARD_EXTRA_ENV \ + "usb_pgood_delay=2000\0" \ + "console=ttySTM0\0" + +#include + +#ifdef CFG_EXTRA_ENV_SETTINGS +/* + * default bootcmd for stm32mp21 STMicroelectronics boards: + * for serial/usb: execute the stm32prog command + * for mmc boot (eMMC, SD card), distro boot on the same mmc device + * for nand or spi-nand boot, distro boot with ubifs on UBI partition or + * sdcard + * for nor boot, distro boot on SD card = mmc0 ONLY ! + */ +#define ST_STM32MP21_BOOTCMD "bootcmd_stm32mp=" \ + "echo \"Boot over ${boot_device}${boot_instance}!\";" \ + "if test ${boot_device} = serial || test ${boot_device} = usb;" \ + "then stm32prog ${boot_device} ${boot_instance}; " \ + "else " \ + "run env_check;" \ + "if test ${boot_device} = mmc;" \ + "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ + "if test ${boot_device} = nand ||" \ + " test ${boot_device} = spi-nand ;" \ + "then env set boot_targets ubifs0 mmc0; fi;" \ + "if test ${boot_device} = nor;" \ + "then env set boot_targets mmc0; fi;" \ + "run distro_bootcmd;" \ + "fi;\0" + +#undef CFG_EXTRA_ENV_SETTINGS +#define CFG_EXTRA_ENV_SETTINGS \ + STM32MP_MEM_LAYOUT \ + ST_STM32MP21_BOOTCMD \ + BOOTENV \ + STM32MP_EXTRA \ + STM32MP_BOARD_EXTRA_ENV + +#endif +#endif From ec3fc57da456d29d336d694f8a28f6cfb05d8cb1 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:26 +0100 Subject: [PATCH 32/80] ARM: dts: stm32: Add stm32mp215f-dk-u-boot Add U-Boot specific file for stm32mp215f-dk board Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/dts/stm32mp215f-dk-u-boot.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 arch/arm/dts/stm32mp215f-dk-u-boot.dtsi diff --git a/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi b/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi new file mode 100644 index 00000000000..e4b44af6df9 --- /dev/null +++ b/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) STMicroelectronics 2026 - All Rights Reserved + */ + +/ { + config { + u-boot,boot-led = "led-blue"; + u-boot,mmc-env-partition = "u-boot-env"; + }; +}; From 5af044da9bf98685b4e516facd7b468e54243f28 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 3 Feb 2026 17:49:27 +0100 Subject: [PATCH 33/80] ARM: dts: stm32: Add bootph-all in stm32mp215f-dk-u-boot.dtsi Add temporarily bootph-all property in usart2 and syscfg nodes to allows stm32mp215f-dk board to boot. When DT kernel series [1] will be merged and synchronized in U-Boot this patch will be reverted. [1] https://lore.kernel.org/linux-arm-kernel/20260203-upstream_uboot_properties-v6-0-0a2280e84d31@foss.st.com/ Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/dts/stm32mp215f-dk-u-boot.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi b/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi index e4b44af6df9..0046b22db7a 100644 --- a/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi +++ b/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi @@ -9,3 +9,11 @@ u-boot,mmc-env-partition = "u-boot-env"; }; }; + +&syscfg { + bootph-all; +}; + +&usart2 { + bootph-all; +}; From 4aac418854a3d865759bfac9110a662e4668bb1c Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 4 Feb 2026 11:16:06 +0100 Subject: [PATCH 34/80] stm32mp2: Migrate duplicated code into stm32mp2x.c Same code is duplicated into stm32mp25x.c, stm32mp23x.c and stm32mp21x.c. Migrate read_deviceid(), get_cpu_dev(), get_cpu_rev(), get_cpu_type() and get_cpu_package() into new stm32mp2x.c. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/Makefile | 1 + arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c | 44 ---------------- arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c | 44 ---------------- arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c | 46 ----------------- arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c | 56 +++++++++++++++++++++ 5 files changed, 57 insertions(+), 134 deletions(-) create mode 100644 arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c diff --git a/arch/arm/mach-stm32mp/stm32mp2/Makefile b/arch/arm/mach-stm32mp/stm32mp2/Makefile index b25af2e8934..8f2e641dcab 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/Makefile +++ b/arch/arm/mach-stm32mp/stm32mp2/Makefile @@ -6,6 +6,7 @@ obj-y += cpu.o obj-y += arm64-mmu.o obj-y += rifsc.o +obj-y += stm32mp2x.o obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o obj-$(CONFIG_STM32MP21X) += stm32mp21x.o obj-$(CONFIG_STM32MP23X) += stm32mp23x.o diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c index 40d0f329496..7b5d79d3497 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c @@ -11,19 +11,6 @@ #include #include -/* SYSCFG register */ -#define SYSCFG_DEVICEID_OFFSET 0x6400 -#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0) -#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0 - -/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/ -#define REVID_SHIFT 0 -#define REVID_MASK GENMASK(5, 0) - -/* Device Part Number (RPN) = OTP9 */ -#define RPN_SHIFT 0 -#define RPN_MASK GENMASK(31, 0) - /* Package = bit 0:2 of OTP122 => STM32MP21_PKG defines * - 000: Custom package * - 001: VFBGA361 => AL = 10x10, 361 balls pith 0.5mm @@ -32,37 +19,6 @@ * - 101: TFBGA289 => AM = 14x14, 289 balls pith 0.8mm * - others: Reserved */ -#define PKG_SHIFT 0 -#define PKG_MASK GENMASK(2, 0) - -static u32 read_deviceid(void) -{ - void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); - - return readl(syscfg + SYSCFG_DEVICEID_OFFSET); -} - -u32 get_cpu_dev(void) -{ - return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT; -} - -u32 get_cpu_rev(void) -{ - return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK); -} - -/* Get Device Part Number (RPN) from OTP */ -u32 get_cpu_type(void) -{ - return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); -} - -/* Get Package options from OTP */ -u32 get_cpu_package(void) -{ - return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); -} int get_eth_nb(void) { diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c index 022db60811a..e4e5812760c 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c @@ -11,19 +11,6 @@ #include #include -/* SYSCFG register */ -#define SYSCFG_DEVICEID_OFFSET 0x6400 -#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0) -#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0 - -/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/ -#define REVID_SHIFT 0 -#define REVID_MASK GENMASK(5, 0) - -/* Device Part Number (RPN) = OTP9 */ -#define RPN_SHIFT 0 -#define RPN_MASK GENMASK(31, 0) - /* Package = bit 0:2 of OTP122 => STM32MP23_PKG defines * - 000: Custom package * - 011: TFBGA361 => AL = 10x10, 361 balls pith 0.5mm @@ -31,37 +18,6 @@ * - 101: TFBGA436 => AI = 18x18, 436 balls pith 0.5mm * - others: Reserved */ -#define PKG_SHIFT 0 -#define PKG_MASK GENMASK(2, 0) - -static u32 read_deviceid(void) -{ - void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); - - return readl(syscfg + SYSCFG_DEVICEID_OFFSET); -} - -u32 get_cpu_dev(void) -{ - return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT; -} - -u32 get_cpu_rev(void) -{ - return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK); -} - -/* Get Device Part Number (RPN) from OTP */ -u32 get_cpu_type(void) -{ - return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); -} - -/* Get Package options from OTP */ -u32 get_cpu_package(void) -{ - return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); -} int get_eth_nb(void) { diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c index bf1f3d3c5a7..e0d54f4ecc8 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c @@ -6,24 +6,9 @@ #define LOG_CATEGORY LOGC_ARCH #include -#include #include -#include #include -/* SYSCFG register */ -#define SYSCFG_DEVICEID_OFFSET 0x6400 -#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0) -#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0 - -/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/ -#define REVID_SHIFT 0 -#define REVID_MASK GENMASK(5, 0) - -/* Device Part Number (RPN) = OTP9 */ -#define RPN_SHIFT 0 -#define RPN_MASK GENMASK(31, 0) - /* Package = bit 0:2 of OTP122 => STM32MP25_PKG defines * - 000: Custom package * - 001: VFBGA361 => AL = 10x10, 361 balls pith 0.5mm @@ -31,37 +16,6 @@ * - 101: TFBGA436 => AI = 18x18, 436 balls pith 0.5mm * - others: Reserved */ -#define PKG_SHIFT 0 -#define PKG_MASK GENMASK(2, 0) - -static u32 read_deviceid(void) -{ - void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); - - return readl(syscfg + SYSCFG_DEVICEID_OFFSET); -} - -u32 get_cpu_dev(void) -{ - return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT; -} - -u32 get_cpu_rev(void) -{ - return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK); -} - -/* Get Device Part Number (RPN) from OTP */ -u32 get_cpu_type(void) -{ - return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); -} - -/* Get Package options from OTP */ -u32 get_cpu_package(void) -{ - return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); -} int get_eth_nb(void) { diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c new file mode 100644 index 00000000000..551601a12a9 --- /dev/null +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2026, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY LOGC_ARCH + +#include +#include +#include +#include + +/* SYSCFG register */ +#define SYSCFG_DEVICEID_OFFSET 0x6400 +#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0) +#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0 + +/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/ +#define REVID_SHIFT 0 +#define REVID_MASK GENMASK(5, 0) + +/* Device Part Number (RPN) = OTP9 */ +#define RPN_SHIFT 0 +#define RPN_MASK GENMASK(31, 0) + +#define PKG_SHIFT 0 +#define PKG_MASK GENMASK(2, 0) + +static u32 read_deviceid(void) +{ + void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + + return readl(syscfg + SYSCFG_DEVICEID_OFFSET); +} + +u32 get_cpu_dev(void) +{ + return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT; +} + +u32 get_cpu_rev(void) +{ + return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK); +} + +/* Get Device Part Number (RPN) from OTP */ +u32 get_cpu_type(void) +{ + return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); +} + +/* Get Package options from OTP */ +u32 get_cpu_package(void) +{ + return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); +} From ab965d31a26610a5ede267f1962956c9deb9e913 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 4 Feb 2026 11:16:07 +0100 Subject: [PATCH 35/80] stm32mp2: Add check on syscon_get_first_range() return value syscon_get_first_range()'s return value is used as base address to perform a read, without any checks. In case stmp32mp_syscon is not binded, syscon_get_first_range() returns -ENODEV which leads to a "Synchronous abort". Add syscon_get_first_range() check on return value. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c index 551601a12a9..40fceac402c 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c @@ -9,6 +9,7 @@ #include #include #include +#include /* SYSCFG register */ #define SYSCFG_DEVICEID_OFFSET 0x6400 @@ -30,6 +31,12 @@ static u32 read_deviceid(void) { void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + if (IS_ERR(syscfg)) { + pr_err("Error, can't get SYSCON range (%ld)\n", PTR_ERR(syscfg)); + + return PTR_ERR(syscfg); + } + return readl(syscfg + SYSCFG_DEVICEID_OFFSET); } From ac7f28523cd4fc5c01bc4a99e0ed856b32d1cf8d Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 4 Feb 2026 11:16:08 +0100 Subject: [PATCH 36/80] stm32mp1: Add check on syscon_get_first_range() return value syscon_get_first_range()'s return value is used as base address to perform a read, without any checks. In case stmp32mp_syscon is not binded, syscon_get_first_range() returns -ENODEV which leads to a "Synchronous abort". Add syscon_get_first_range() check on return value. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c b/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c index 79b2f2d0bba..6d2d69f3442 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c +++ b/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c @@ -17,6 +17,7 @@ #include #include #include +#include #include /* RCC register */ @@ -231,6 +232,12 @@ static u32 read_idc(void) { void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + if (IS_ERR(syscfg)) { + pr_err("Error, can't get SYSCON range (%ld)\n", PTR_ERR(syscfg)); + + return PTR_ERR(syscfg); + } + return readl(syscfg + SYSCFG_IDC_OFFSET); } From dcb304943e21c24f8e170d40370286f8d30c2687 Mon Sep 17 00:00:00 2001 From: Thomas Bourgoin Date: Wed, 4 Feb 2026 11:20:46 +0100 Subject: [PATCH 37/80] stm32mp: cmd_stm32key: add support of STM32MP21x SoC Update stm32key to support stm32mp21 OTP mapping. Create a new list of key to support the following differences : - STM32MP21x SoC support 128b and 25b FSBL encryption keys. - OEM-KEY1 and OEM-KEY2 used for authentication are in different OTP from STM32MP25 and STM32MP23. stm32key is compatible with platform STM32MP2 (aarch64) Hence, use unsigned long to handle argument addr of function read_key_value() instead of u32. Signed-off-by: Thomas Bourgoin Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 97 +++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index f1e0a3e817c..1ceb640e6b2 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -40,7 +40,7 @@ struct stm32key { char *desc; u16 start; u8 size; - int (*post_process)(struct udevice *dev); + int (*post_process)(struct udevice *dev, const struct stm32key *key); }; const struct stm32key stm32mp13_list[] = { @@ -67,7 +67,56 @@ const struct stm32key stm32mp15_list[] = { } }; -static int post_process_oem_key2(struct udevice *dev); +static int post_process_oem_key2(struct udevice *dev, const struct stm32key *key); +static int post_process_edmk_128b(struct udevice *dev, const struct stm32key *key); + +const struct stm32key stm32mp21_list[] = { + [STM32KEY_PKH] = { + .name = "OEM-KEY1", + .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M", + .start = 152, + .size = 8, + }, + { + .name = "OEM-KEY2", + .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLM", + .start = 160, + .size = 8, + .post_process = post_process_oem_key2, + }, + { + .name = "FIP-EDMK", + .desc = "Encryption/Decryption Master Key for FIP", + .start = 260, + .size = 8, + }, + { + .name = "EDMK1-128b", + .desc = "Encryption/Decryption Master 128b Key for FSBLA or M", + .start = 356, + .size = 4, + .post_process = post_process_edmk_128b, + }, + { + .name = "EDMK1-256b", + .desc = "Encryption/Decryption Master 256b Key for FSBLA or M", + .start = 356, + .size = 8, + }, + { + .name = "EDMK2-128b", + .desc = "Encryption/Decryption Master 128b Key for FSBLM", + .start = 348, + .size = 4, + .post_process = post_process_edmk_128b, + }, + { + .name = "EDMK2-256b", + .desc = "Encryption/Decryption Master 256b Key for FSBLM", + .start = 348, + .size = 8, + }, +}; const struct stm32key stm32mp2x_list[] = { [STM32KEY_PKH] = { @@ -171,8 +220,10 @@ static u8 get_key_nb(void) if (IS_ENABLED(CONFIG_STM32MP15X)) return ARRAY_SIZE(stm32mp15_list); - if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || - IS_ENABLED(CONFIG_STM32MP25X)) + if (IS_ENABLED(CONFIG_STM32MP21X)) + return ARRAY_SIZE(stm32mp21_list); + + if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) return ARRAY_SIZE(stm32mp2x_list); } @@ -184,8 +235,10 @@ static const struct stm32key *get_key(u8 index) if (IS_ENABLED(CONFIG_STM32MP15X)) return &stm32mp15_list[index]; - if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || - IS_ENABLED(CONFIG_STM32MP25X)) + if (IS_ENABLED(CONFIG_STM32MP21X)) + return &stm32mp21_list[index]; + + if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) return &stm32mp2x_list[index]; } @@ -237,7 +290,8 @@ static void read_key_value(const struct stm32key *key, unsigned long addr) } } -static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked) +static int read_key_otp(struct udevice *dev, const struct stm32key *key, + bool print, bool *locked) { int i, word, ret; int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0; @@ -351,7 +405,7 @@ static int write_close_status(struct udevice *dev) return 0; } -static int post_process_oem_key2(struct udevice *dev) +static int post_process_oem_key2(struct udevice *dev, const struct stm32key *key) { int ret; u32 val; @@ -372,6 +426,31 @@ static int post_process_oem_key2(struct udevice *dev) return 0; } +static int post_process_edmk_128b(struct udevice *dev, const struct stm32key *key) +{ + int ret, word, start_otp; + u32 val; + + start_otp = key->start + key->size; + + /* On MP21, when using a 128bit key, program 0xffffffff and lock the unused OTPs. */ + for (word = start_otp; word < (start_otp + 4); word++) { + val = GENMASK(31, 0); + ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4); + if (ret != 4) + log_warning("Fuse %s OTP padding %i failed, continue\n", key->name, word); + + val = BSEC_LOCK_PERM; + ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4); + if (ret != 4) { + log_err("Failed to lock unused OTP : %d\n", word); + return ret; + } + } + + return 0; +} + static int fuse_key_value(struct udevice *dev, const struct stm32key *key, unsigned long addr, bool print) { @@ -550,7 +629,7 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con return CMD_RET_FAILURE; if (key->post_process) { - if (key->post_process(dev)) { + if (key->post_process(dev, key)) { printf("Error: %s for post process\n", key->name); return CMD_RET_FAILURE; } From cbd3977207f3844ce640f57e31eca73a1c8ddae0 Mon Sep 17 00:00:00 2001 From: Thomas Bourgoin Date: Wed, 4 Feb 2026 11:20:47 +0100 Subject: [PATCH 38/80] stm32mp: cmd_stm32key: add support of OTP key format 2 Add support of OTP key format 2 used by OP-TEE. Key formats are describes in the STM32MPUs references manuals section OTP mapping. Signed-off-by: Thomas Bourgoin Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 35 ++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 1ceb640e6b2..cd539a626d1 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -41,6 +41,7 @@ struct stm32key { u16 start; u8 size; int (*post_process)(struct udevice *dev, const struct stm32key *key); + u32 (*key_format)(u32 value); }; const struct stm32key stm32mp13_list[] = { @@ -69,6 +70,8 @@ const struct stm32key stm32mp15_list[] = { static int post_process_oem_key2(struct udevice *dev, const struct stm32key *key); static int post_process_edmk_128b(struct udevice *dev, const struct stm32key *key); +static u32 format1(u32 value); +static u32 format2(u32 value); const struct stm32key stm32mp21_list[] = { [STM32KEY_PKH] = { @@ -268,6 +271,24 @@ static const struct otp_close *get_otp_close_state(u8 index) return &stm32mp2x_close_state_otp[index]; } +/* + * Define format wrappers based on reference manual formats + * ex for key from NIST vector AES_ECB_256b_test0: + * key (bytes) : f9 e8 38 9f ... ef 94 4b e0 + * format 1 (le32) : 0xf9e8389f ... 0xef944be0 + * format 2 (le32) : 0x9f38e8f9 ... 0xe04b94ef + */ + +static u32 format1(u32 value) +{ + return __be32_to_cpu(value); +} + +static u32 __maybe_unused format2(u32 value) +{ + return __le32_to_cpu(value); +} + static int get_misc_dev(struct udevice **dev) { int ret; @@ -282,10 +303,15 @@ static int get_misc_dev(struct udevice **dev) static void read_key_value(const struct stm32key *key, unsigned long addr) { int i; + u32 (*format)(u32) = format1; + + /* Use key_format function pointer if defined */ + if (key->key_format) + format = key->key_format; for (i = 0; i < key->size; i++) { printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i, - (u32)addr, __be32_to_cpu(*(u32 *)addr)); + (u32)addr, format(*(u32 *)addr)); addr += 4; } } @@ -456,9 +482,14 @@ static int fuse_key_value(struct udevice *dev, const struct stm32key *key, unsig { u32 word, val; int i, ret; + u32 (*format)(u32) = format1; + + /* Use key_format function pointer if defined */ + if (key->key_format) + format = key->key_format; for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) { - val = __be32_to_cpu(*(u32 *)addr); + val = format(*(u32 *)addr); if (print) printf("Fuse %s OTP %i : %08x\n", key->name, word, val); From d8a0db45367acd94c022f2d1380857e98959c7b2 Mon Sep 17 00:00:00 2001 From: Thomas Bourgoin Date: Wed, 4 Feb 2026 11:20:48 +0100 Subject: [PATCH 39/80] stm32mp: cmd_stm32key: add support of remoteproc firmware encryption key Add support of RPROC-FW-KEY for STM32MP25, STM32MP23 and STM32MP21. Signed-off-by: Thomas Bourgoin Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index cd539a626d1..7a82152faf3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -93,6 +93,13 @@ const struct stm32key stm32mp21_list[] = { .start = 260, .size = 8, }, + { + .name = "RPROC-FW-ENC-KEY", + .desc = "Encryption/Decryption Key for remote processor firmware", + .start = 332, + .size = 8, + .key_format = format2, + }, { .name = "EDMK1-128b", .desc = "Encryption/Decryption Master 128b Key for FSBLA or M", @@ -141,6 +148,13 @@ const struct stm32key stm32mp2x_list[] = { .start = 260, .size = 8, }, + { + .name = "RPROC-FW-ENC-KEY", + .desc = "Encryption/Decryption Key for remote processor firmware", + .start = 336, + .size = 8, + .key_format = format2, + }, { .name = "EDMK1", .desc = "Encryption/Decryption Master Key for FSBLA or M", @@ -284,7 +298,7 @@ static u32 format1(u32 value) return __be32_to_cpu(value); } -static u32 __maybe_unused format2(u32 value) +static u32 format2(u32 value) { return __le32_to_cpu(value); } From c258621b5ef6c1a759198b603e9bb30a928ca2ef Mon Sep 17 00:00:00 2001 From: Gwenael Treuveur Date: Wed, 4 Feb 2026 11:20:49 +0100 Subject: [PATCH 40/80] stm32mp: cmd_stm32key: add support of remoteproc firmware public key Add support of RPROC-FW-PKH for STM32MP25, STM32MP23 and STM32MP21. Signed-off-by: Gwenael Treuveur Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 7a82152faf3..d1432ba1e23 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -87,6 +87,13 @@ const struct stm32key stm32mp21_list[] = { .size = 8, .post_process = post_process_oem_key2, }, + { + .name = "RPROC-FW-PKH", + .desc = "Hash of the Public Key for remote processor firmware", + .start = 180, + .size = 8, + .key_format = format2, + }, { .name = "FIP-EDMK", .desc = "Encryption/Decryption Master Key for FIP", @@ -142,6 +149,13 @@ const struct stm32key stm32mp2x_list[] = { .size = 8, .post_process = post_process_oem_key2, }, + { + .name = "RPROC-FW-PKH", + .desc = "Hash of the Public Key for remote processor firmware", + .start = 176, + .size = 8, + .key_format = format2, + }, { .name = "FIP-EDMK", .desc = "Encryption/Decryption Master Key for FIP", From bd6fd26f150c655d36735285cb900445a2b399a3 Mon Sep 17 00:00:00 2001 From: Thomas Bourgoin Date: Wed, 4 Feb 2026 11:20:50 +0100 Subject: [PATCH 41/80] stm32mp: cmd_stm32key: add support of ADAC public key hash Add support of ADAC-PKH for STM32MP21. Signed-off-by: Thomas Bourgoin Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index d1432ba1e23..4610841f825 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -94,6 +94,13 @@ const struct stm32key stm32mp21_list[] = { .size = 8, .key_format = format2, }, + { + .name = "ADAC-ROTPKH", + .desc = "Authenticated Debug Access Control Root Of Trust Public Key Hash", + .start = 238, + .size = 8, + .key_format = format2, + }, { .name = "FIP-EDMK", .desc = "Encryption/Decryption Master Key for FIP", From 20727a083f46bb5f664f9da624254ad38e88f400 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 4 Feb 2026 11:20:51 +0100 Subject: [PATCH 42/80] configs: stm32mp25: Enable CMD_STM32KEY Enable CONFIG_CMD_STM32KEY flag to enable usage of command stm32key. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- configs/stm32mp25_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/stm32mp25_defconfig b/configs/stm32mp25_defconfig index 234a6a8abdc..99b22a68fda 100644 --- a/configs/stm32mp25_defconfig +++ b/configs/stm32mp25_defconfig @@ -9,6 +9,7 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x84000000 CONFIG_STM32MP25X=y CONFIG_DDR_CACHEABLE_SIZE=0x10000000 +CONFIG_CMD_STM32KEY=y CONFIG_MFD_STM32_TIMERS=y CONFIG_ENV_OFFSET_REDUND=0x940000 CONFIG_TARGET_ST_STM32MP25X=y From 5f92eef2f994256c77bcba0649084e358524da10 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Tue, 10 Feb 2026 11:26:03 +0100 Subject: [PATCH 43/80] ARM: stm32mp: Do not acquire RIFSC semaphore if CID filtering is disabled If the CID filtering is enabled, the semaphore mode is disabled as well. To avoid an incorrect behavior and error trace, add a check of CID filtering state before acquiring the semaphore. Signed-off-by: Gatien Chevallier Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/rifsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c index cf8026088f3..01ffc9f2798 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c +++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c @@ -208,7 +208,7 @@ int stm32_rifsc_grant_access_by_id(ofnode device_node, u32 id) * If the peripheral is in semaphore mode, take the semaphore so that * the CID1 has the ownership. */ - if (cid_reg_value & CIDCFGR_SEMEN && + if (cid_reg_value & CIDCFGR_CFEN && cid_reg_value & CIDCFGR_SEMEN && (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) { err = stm32_rifsc_acquire_semaphore(rifsc_base, id); if (err) { From 9d3a9080c9fb57186dd90be4cfa8ac9759f0d823 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Tue, 10 Feb 2026 11:26:04 +0100 Subject: [PATCH 44/80] ARM: stm32mp: Fix CID and semaphore check Peripheral holding CID0 cannot be accessed, remove this completely incorrect check. While there, fix and simplify the semaphore checking that should be performed when the CID filtering is enabled. Signed-off-by: Gatien Chevallier Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/rifsc.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c index 01ffc9f2798..0ef086bb956 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c +++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c @@ -141,27 +141,10 @@ static int rifsc_check_access(void *base, u32 id) cid_reg_value = readl(base + RIFSC_RISC_PER0_CIDCFGR(id)); sem_reg_value = readl(base + RIFSC_RISC_PER0_SEMCR(id)); - /* - * First check conditions for semaphore mode, which doesn't take into - * account static CID. - */ - if (cid_reg_value & CIDCFGR_SEMEN) + /* Skip cid check if CID filtering isn't enabled */ + if (!(cid_reg_value & CIDCFGR_CFEN)) goto skip_cid_check; - /* - * Skip cid check if CID filtering isn't enabled or filtering is enabled on CID0, which - * corresponds to whatever CID. - */ - if (!(cid_reg_value & CIDCFGR_CFEN) || - FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) == RIF_CID0) - goto skip_cid_check; - - /* Coherency check with the CID configuration */ - if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) { - log_debug("Invalid CID configuration for peripheral %d\n", id); - return -EACCES; - } - /* Check semaphore accesses */ if (cid_reg_value & CIDCFGR_SEMEN) { if (!(FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) { @@ -173,6 +156,9 @@ static int rifsc_check_access(void *base, u32 id) log_debug("Semaphore unavailable for peripheral %d\n", id); return -EACCES; } + } else if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) { + log_debug("Invalid CID configuration for peripheral %d\n", id); + return -EACCES; } skip_cid_check: From c61d6f67f46f05149182b33c3c0ba5d9b6b46889 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Tue, 10 Feb 2026 11:26:05 +0100 Subject: [PATCH 45/80] ARM: stm32mp: Check secure state first Secure state must be checked before handling semaphores, otherwise it can cause an IAC. Signed-off-by: Gatien Chevallier Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/mach-stm32mp/stm32mp2/rifsc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c index 0ef086bb956..9db8b9efc64 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c +++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c @@ -141,6 +141,12 @@ static int rifsc_check_access(void *base, u32 id) cid_reg_value = readl(base + RIFSC_RISC_PER0_CIDCFGR(id)); sem_reg_value = readl(base + RIFSC_RISC_PER0_SEMCR(id)); + /* Check security configuration */ + if (sec_reg_value & BIT(reg_offset)) { + log_debug("Invalid security configuration for peripheral %d\n", id); + return -EACCES; + } + /* Skip cid check if CID filtering isn't enabled */ if (!(cid_reg_value & CIDCFGR_CFEN)) goto skip_cid_check; @@ -162,12 +168,6 @@ static int rifsc_check_access(void *base, u32 id) } skip_cid_check: - /* Check security configuration */ - if (sec_reg_value & BIT(reg_offset)) { - log_debug("Invalid security configuration for peripheral %d\n", id); - return -EACCES; - } - return 0; } From ae1e081f83fb4b4d79e32f1bdcea3e47519ce05c Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Mon, 23 Feb 2026 19:55:23 +0530 Subject: [PATCH 46/80] phy: samsung: add enum for variants based on SoCs The variant enum is used to uniquely identify which SoC the PHY block belongs to. It is initially set in the match table, along with the compatible string, it gets copied to driver data struct during probe. SoC specific functions must only be called if the respective variant enum is set. Add switch-case blocks wherever required. Reviewed-by: Mattijs Korpershoek Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/phy/phy-exynos-usbdrd.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-exynos-usbdrd.c b/drivers/phy/phy-exynos-usbdrd.c index db5815ed184..4ab8da2a08f 100644 --- a/drivers/phy/phy-exynos-usbdrd.c +++ b/drivers/phy/phy-exynos-usbdrd.c @@ -66,6 +66,10 @@ #define KHZ 1000 #define MHZ (KHZ * KHZ) +enum exynos_usbdrd_phy_variant { + EXYNOS850_USBDRD_PHY, +}; + /** * struct exynos_usbdrd_phy - driver data for Exynos USB PHY * @reg_phy: USB PHY controller register memory base @@ -73,6 +77,7 @@ * @core_clk: core clock for phy (ref clock) * @reg_pmu: regmap for PMU block * @extrefclk: frequency select settings when using 'separate reference clocks' + * @variant: ID to uniquely distinguish USB PHY variant */ struct exynos_usbdrd_phy { void __iomem *reg_phy; @@ -80,6 +85,7 @@ struct exynos_usbdrd_phy { struct clk *core_clk; struct regmap *reg_pmu; u32 extrefclk; + enum exynos_usbdrd_phy_variant variant; }; static void exynos_usbdrd_phy_isol(struct regmap *reg_pmu, bool isolate) @@ -254,7 +260,13 @@ static int exynos_usbdrd_phy_init(struct phy *phy) if (ret) return ret; - exynos850_usbdrd_utmi_init(phy); + switch (phy_drd->variant) { + case EXYNOS850_USBDRD_PHY: + exynos850_usbdrd_utmi_init(phy); + break; + default: + dev_err(phy->dev, "Failed to recognize phy variant\n"); + } clk_disable_unprepare(phy_drd->clk); @@ -270,7 +282,13 @@ static int exynos_usbdrd_phy_exit(struct phy *phy) if (ret) return ret; - exynos850_usbdrd_utmi_exit(phy); + switch (phy_drd->variant) { + case EXYNOS850_USBDRD_PHY: + exynos850_usbdrd_utmi_exit(phy); + break; + default: + dev_err(phy->dev, "Failed to recognize phy variant\n"); + } clk_disable_unprepare(phy_drd->clk); @@ -359,6 +377,8 @@ static int exynos_usbdrd_phy_probe(struct udevice *dev) return err; } + phy_drd->variant = dev_get_driver_data(dev); + return 0; } @@ -372,6 +392,7 @@ static const struct phy_ops exynos_usbdrd_phy_ops = { static const struct udevice_id exynos_usbdrd_phy_of_match[] = { { .compatible = "samsung,exynos850-usbdrd-phy", + .data = EXYNOS850_USBDRD_PHY, }, { } }; From e4001865ff387b928ea3d422d673dcc7389f8665 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Mon, 23 Feb 2026 19:55:24 +0530 Subject: [PATCH 47/80] phy: samsung: add support for exynos7870 USB PHY The USB PHY used by the Exynos7870 SoC has a single USB 2.0 interface. Add its dedicated variant enum, compatible, and init/exit functions. The PHY enable bit of Exynos7870's PHY is different in contrast to that of Exynos850 and most Exynos PHYs. To allow this change, a simple if condition is added in exynos_usbdrd_phy_isol() which changes the bitmask. Since the variant enum is required, the function argument is changed to accept the driver data itself. Reviewed-by: Mattijs Korpershoek Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/phy/phy-exynos-usbdrd.c | 246 ++++++++++++++++++++++++++++++-- 1 file changed, 238 insertions(+), 8 deletions(-) diff --git a/drivers/phy/phy-exynos-usbdrd.c b/drivers/phy/phy-exynos-usbdrd.c index 4ab8da2a08f..c5eed29a2c8 100644 --- a/drivers/phy/phy-exynos-usbdrd.c +++ b/drivers/phy/phy-exynos-usbdrd.c @@ -21,6 +21,7 @@ /* Offset of PMU register controlling USB PHY output isolation */ #define EXYNOS_USBDRD_PHY_CONTROL 0x0704 #define EXYNOS_PHY_ENABLE BIT(0) +#define EXYNOS7870_PHY_ENABLE BIT(1) /* Exynos USB PHY registers */ #define EXYNOS5_FSEL_9MHZ6 0x0 @@ -32,6 +33,88 @@ #define EXYNOS5_FSEL_26MHZ 0x6 #define EXYNOS5_FSEL_50MHZ 0x7 +/* Exynos5: USB DRD PHY registers */ +#define EXYNOS5_DRD_LINKSYSTEM 0x04 +#define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27) +#define LINKSYSTEM_FORCE_VBUSVALID BIT(8) +#define LINKSYSTEM_FORCE_BVALID BIT(7) +#define LINKSYSTEM_FLADJ GENMASK(6, 1) + +#define EXYNOS5_DRD_PHYUTMI 0x08 +#define PHYUTMI_UTMI_SUSPEND_COM_N BIT(12) +#define PHYUTMI_UTMI_L1_SUSPEND_COM_N BIT(11) +#define PHYUTMI_VBUSVLDEXTSEL BIT(10) +#define PHYUTMI_VBUSVLDEXT BIT(9) +#define PHYUTMI_TXBITSTUFFENH BIT(8) +#define PHYUTMI_TXBITSTUFFEN BIT(7) +#define PHYUTMI_OTGDISABLE BIT(6) +#define PHYUTMI_IDPULLUP BIT(5) +#define PHYUTMI_DRVVBUS BIT(4) +#define PHYUTMI_DPPULLDOWN BIT(3) +#define PHYUTMI_DMPULLDOWN BIT(2) +#define PHYUTMI_FORCESUSPEND BIT(1) +#define PHYUTMI_FORCESLEEP BIT(0) + +#define EXYNOS5_DRD_PHYCLKRST 0x10 +#define PHYCLKRST_EN_UTMISUSPEND BIT(31) +#define PHYCLKRST_SSC_REFCLKSEL GENMASK(30, 23) +#define PHYCLKRST_SSC_RANGE GENMASK(22, 21) +#define PHYCLKRST_SSC_EN BIT(20) +#define PHYCLKRST_REF_SSP_EN BIT(19) +#define PHYCLKRST_REF_CLKDIV2 BIT(18) +#define PHYCLKRST_MPLL_MULTIPLIER GENMASK(17, 11) +#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF 0x19 +#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF 0x32 +#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF 0x68 +#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF 0x7d +#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF 0x02 +#define PHYCLKRST_FSEL_PIPE GENMASK(10, 8) +#define PHYCLKRST_FSEL_UTMI GENMASK(7, 5) +#define PHYCLKRST_FSEL_PAD_100MHZ 0x27 +#define PHYCLKRST_FSEL_PAD_24MHZ 0x2a +#define PHYCLKRST_FSEL_PAD_20MHZ 0x31 +#define PHYCLKRST_FSEL_PAD_19_2MHZ 0x38 +#define PHYCLKRST_RETENABLEN BIT(4) +#define PHYCLKRST_REFCLKSEL GENMASK(3, 2) +#define PHYCLKRST_REFCLKSEL_PAD_REFCLK 0x2 +#define PHYCLKRST_REFCLKSEL_EXT_REFCLK 0x3 +#define PHYCLKRST_PORTRESET BIT(1) +#define PHYCLKRST_COMMONONN BIT(0) + +#define EXYNOS5_DRD_PHYPARAM0 0x1c +#define PHYPARAM0_REF_USE_PAD BIT(31) +#define PHYPARAM0_REF_LOSLEVEL GENMASK(30, 26) +#define PHYPARAM0_REF_LOSLEVEL_VAL 0x9 +#define PHYPARAM0_TXVREFTUNE GENMASK(25, 22) +#define PHYPARAM0_TXRISETUNE GENMASK(21, 20) +#define PHYPARAM0_TXRESTUNE GENMASK(19, 18) +#define PHYPARAM0_TXPREEMPPULSETUNE BIT(17) +#define PHYPARAM0_TXPREEMPAMPTUNE GENMASK(16, 15) +#define PHYPARAM0_TXHSXVTUNE GENMASK(14, 13) +#define PHYPARAM0_TXFSLSTUNE GENMASK(12, 9) +#define PHYPARAM0_SQRXTUNE GENMASK(8, 6) +#define PHYPARAM0_OTGTUNE GENMASK(5, 3) +#define PHYPARAM0_COMPDISTUNE GENMASK(2, 0) + +#define EXYNOS5_DRD_LINKPORT 0x44 +#define LINKPORT_HOST_U3_PORT_DISABLE BIT(8) +#define LINKPORT_HOST_U2_PORT_DISABLE BIT(7) +#define LINKPORT_HOST_PORT_OVCR_U3 BIT(5) +#define LINKPORT_HOST_PORT_OVCR_U2 BIT(4) +#define LINKPORT_HOST_PORT_OVCR_U3_SEL BIT(3) +#define LINKPORT_HOST_PORT_OVCR_U2_SEL BIT(2) + +/* Exynos7870: USB DRD PHY registers */ +#define EXYNOS7870_DRD_HSPHYCTRL 0x54 +#define HSPHYCTRL_PHYSWRSTALL BIT(31) +#define HSPHYCTRL_SIDDQ BIT(6) +#define HSPHYCTRL_PHYSWRST BIT(0) + +#define EXYNOS7870_DRD_HSPHYPLLTUNE 0x70 +#define HSPHYPLLTUNE_PLL_B_TUNE BIT(6) +#define HSPHYPLLTUNE_PLL_I_TUNE GENMASK(5, 4) +#define HSPHYPLLTUNE_PLL_P_TUNE GENMASK(3, 0) + /* Exynos850: USB DRD PHY registers */ #define EXYNOS850_DRD_LINKCTRL 0x04 #define LINKCTRL_FORCE_QACT BIT(8) @@ -67,6 +150,7 @@ #define MHZ (KHZ * KHZ) enum exynos_usbdrd_phy_variant { + EXYNOS7870_USBDRD_PHY, EXYNOS850_USBDRD_PHY, }; @@ -88,16 +172,20 @@ struct exynos_usbdrd_phy { enum exynos_usbdrd_phy_variant variant; }; -static void exynos_usbdrd_phy_isol(struct regmap *reg_pmu, bool isolate) +static void exynos_usbdrd_phy_isol(struct exynos_usbdrd_phy *phy_drd, + bool isolate) { - unsigned int val; + unsigned int mask = EXYNOS_PHY_ENABLE, val; - if (!reg_pmu) + if (!phy_drd->reg_pmu) return; - val = isolate ? 0 : EXYNOS_PHY_ENABLE; - regmap_update_bits(reg_pmu, EXYNOS_USBDRD_PHY_CONTROL, - EXYNOS_PHY_ENABLE, val); + if (phy_drd->variant == EXYNOS7870_USBDRD_PHY) + mask = EXYNOS7870_PHY_ENABLE; + + val = isolate ? 0 : mask; + regmap_update_bits(phy_drd->reg_pmu, EXYNOS_USBDRD_PHY_CONTROL, + mask, val); } /* @@ -138,6 +226,111 @@ static unsigned int exynos_rate_to_clk(unsigned long rate, u32 *reg) return 0; } +static void exynos7870_usbdrd_utmi_init(struct phy *phy) +{ + struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev); + void __iomem *regs_base = phy_drd->reg_phy; + u32 reg; + + reg = readl(regs_base + EXYNOS5_DRD_PHYCLKRST); + /* Use PADREFCLK as ref clock */ + reg &= ~PHYCLKRST_REFCLKSEL; + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_PAD_REFCLK); + /* Select ref clock rate */ + reg &= ~PHYCLKRST_FSEL_UTMI; + reg &= ~PHYCLKRST_FSEL_PIPE; + reg |= FIELD_PREP(PHYCLKRST_FSEL_UTMI, phy_drd->extrefclk); + /* Enable suspend and reset the port */ + reg |= PHYCLKRST_EN_UTMISUSPEND; + reg |= PHYCLKRST_COMMONONN; + reg |= PHYCLKRST_PORTRESET; + writel(reg, regs_base + EXYNOS5_DRD_PHYCLKRST); + udelay(10); + + /* Clear the port reset bit */ + reg &= ~PHYCLKRST_PORTRESET; + writel(reg, regs_base + EXYNOS5_DRD_PHYCLKRST); + + /* Change PHY PLL tune value */ + reg = readl(regs_base + EXYNOS7870_DRD_HSPHYPLLTUNE); + if (phy_drd->extrefclk == EXYNOS5_FSEL_24MHZ) + reg |= HSPHYPLLTUNE_PLL_B_TUNE; + else + reg &= ~HSPHYPLLTUNE_PLL_B_TUNE; + reg &= ~HSPHYPLLTUNE_PLL_P_TUNE; + reg |= FIELD_PREP(HSPHYPLLTUNE_PLL_P_TUNE, 14); + writel(reg, regs_base + EXYNOS7870_DRD_HSPHYPLLTUNE); + + /* High-Speed PHY control */ + reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL); + reg &= ~HSPHYCTRL_SIDDQ; + reg &= ~HSPHYCTRL_PHYSWRST; + reg &= ~HSPHYCTRL_PHYSWRSTALL; + writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL); + udelay(500); + + reg = readl(regs_base + EXYNOS5_DRD_LINKSYSTEM); + /* + * Setting the Frame length Adj value[6:1] to default 0x20 + * See xHCI 1.0 spec, 5.2.4 + */ + reg |= LINKSYSTEM_XHCI_VERSION_CONTROL; + reg &= ~LINKSYSTEM_FLADJ; + reg |= FIELD_PREP(LINKSYSTEM_FLADJ, 0x20); + /* Set VBUSVALID signal as the VBUS pad is not used */ + reg |= LINKSYSTEM_FORCE_BVALID; + reg |= LINKSYSTEM_FORCE_VBUSVALID; + writel(reg, regs_base + EXYNOS5_DRD_LINKSYSTEM); + + reg = readl(regs_base + EXYNOS5_DRD_PHYUTMI); + /* Release force_sleep & force_suspend */ + reg &= ~PHYUTMI_FORCESLEEP; + reg &= ~PHYUTMI_FORCESUSPEND; + /* DP/DM pull down control */ + reg &= ~PHYUTMI_DMPULLDOWN; + reg &= ~PHYUTMI_DPPULLDOWN; + reg &= ~PHYUTMI_DRVVBUS; + /* Set DP-pull up as the VBUS pad is not used */ + reg |= PHYUTMI_VBUSVLDEXTSEL; + reg |= PHYUTMI_VBUSVLDEXT; + /* Disable OTG block and VBUS valid comparator */ + reg |= PHYUTMI_OTGDISABLE; + writel(reg, regs_base + EXYNOS5_DRD_PHYUTMI); + + /* Configure OVC IO usage */ + reg = readl(regs_base + EXYNOS5_DRD_LINKPORT); + reg |= LINKPORT_HOST_PORT_OVCR_U3_SEL | LINKPORT_HOST_PORT_OVCR_U2_SEL; + writel(reg, regs_base + EXYNOS5_DRD_LINKPORT); + + /* High-Speed PHY swrst */ + reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL); + reg |= HSPHYCTRL_PHYSWRST; + writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL); + udelay(20); + + /* Clear the PHY swrst bit */ + reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL); + reg &= ~HSPHYCTRL_PHYSWRST; + writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL); + + reg = readl(regs_base + EXYNOS5_DRD_PHYPARAM0); + reg &= ~(PHYPARAM0_TXVREFTUNE | PHYPARAM0_TXRISETUNE | + PHYPARAM0_TXRESTUNE | PHYPARAM0_TXPREEMPPULSETUNE | + PHYPARAM0_TXPREEMPAMPTUNE | PHYPARAM0_TXHSXVTUNE | + PHYPARAM0_TXFSLSTUNE | PHYPARAM0_SQRXTUNE | + PHYPARAM0_OTGTUNE | PHYPARAM0_COMPDISTUNE); + reg |= FIELD_PREP_CONST(PHYPARAM0_TXVREFTUNE, 14) | + FIELD_PREP_CONST(PHYPARAM0_TXRISETUNE, 1) | + FIELD_PREP_CONST(PHYPARAM0_TXRESTUNE, 3) | + FIELD_PREP_CONST(PHYPARAM0_TXPREEMPAMPTUNE, 0) | + FIELD_PREP_CONST(PHYPARAM0_TXHSXVTUNE, 0) | + FIELD_PREP_CONST(PHYPARAM0_TXFSLSTUNE, 3) | + FIELD_PREP_CONST(PHYPARAM0_SQRXTUNE, 6) | + FIELD_PREP_CONST(PHYPARAM0_OTGTUNE, 2) | + FIELD_PREP_CONST(PHYPARAM0_COMPDISTUNE, 3); + writel(reg, regs_base + EXYNOS5_DRD_PHYPARAM0); +} + static void exynos850_usbdrd_utmi_init(struct phy *phy) { struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev); @@ -225,6 +418,33 @@ static void exynos850_usbdrd_utmi_init(struct phy *phy) writel(reg, regs_base + EXYNOS850_DRD_HSP); } +static void exynos7870_usbdrd_utmi_exit(struct phy *phy) +{ + struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev); + void __iomem *regs_base = phy_drd->reg_phy; + u32 reg; + + /* + * Disable the VBUS signal and the ID pull-up resistor. + * Enable force-suspend and force-sleep modes. + */ + reg = readl(regs_base + EXYNOS5_DRD_PHYUTMI); + reg &= ~(PHYUTMI_DRVVBUS | PHYUTMI_VBUSVLDEXT | PHYUTMI_VBUSVLDEXTSEL); + reg &= ~PHYUTMI_IDPULLUP; + reg |= PHYUTMI_FORCESUSPEND | PHYUTMI_FORCESLEEP; + writel(reg, regs_base + EXYNOS5_DRD_PHYUTMI); + + /* Power down PHY analog blocks */ + reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL); + reg |= HSPHYCTRL_SIDDQ; + writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL); + + /* Clear VBUSVALID signal as the VBUS pad is not used */ + reg = readl(regs_base + EXYNOS5_DRD_LINKSYSTEM); + reg &= ~(LINKSYSTEM_FORCE_BVALID | LINKSYSTEM_FORCE_VBUSVALID); + writel(reg, regs_base + EXYNOS5_DRD_LINKSYSTEM); +} + static void exynos850_usbdrd_utmi_exit(struct phy *phy) { struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev); @@ -261,6 +481,9 @@ static int exynos_usbdrd_phy_init(struct phy *phy) return ret; switch (phy_drd->variant) { + case EXYNOS7870_USBDRD_PHY: + exynos7870_usbdrd_utmi_init(phy); + break; case EXYNOS850_USBDRD_PHY: exynos850_usbdrd_utmi_init(phy); break; @@ -283,6 +506,9 @@ static int exynos_usbdrd_phy_exit(struct phy *phy) return ret; switch (phy_drd->variant) { + case EXYNOS7870_USBDRD_PHY: + exynos7870_usbdrd_utmi_exit(phy); + break; case EXYNOS850_USBDRD_PHY: exynos850_usbdrd_utmi_exit(phy); break; @@ -307,7 +533,7 @@ static int exynos_usbdrd_phy_power_on(struct phy *phy) return ret; /* Power-on PHY */ - exynos_usbdrd_phy_isol(phy_drd->reg_pmu, false); + exynos_usbdrd_phy_isol(phy_drd, false); return 0; } @@ -319,7 +545,7 @@ static int exynos_usbdrd_phy_power_off(struct phy *phy) dev_dbg(phy->dev, "Request to power_off usbdrd_phy phy\n"); /* Power-off the PHY */ - exynos_usbdrd_phy_isol(phy_drd->reg_pmu, true); + exynos_usbdrd_phy_isol(phy_drd, true); clk_disable_unprepare(phy_drd->core_clk); @@ -390,6 +616,10 @@ static const struct phy_ops exynos_usbdrd_phy_ops = { }; static const struct udevice_id exynos_usbdrd_phy_of_match[] = { + { + .compatible = "samsung,exynos7870-usbdrd-phy", + .data = EXYNOS7870_USBDRD_PHY, + }, { .compatible = "samsung,exynos850-usbdrd-phy", .data = EXYNOS850_USBDRD_PHY, From db0fe21bd38f27f570ce16670ccad567efd596f4 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 24 Feb 2026 21:07:09 +0530 Subject: [PATCH 48/80] board: samsung: exynos-mobile: use blkmap for booting from userdata subpartitions Some distributions tend to provide a single combined image with EFS and the system root filesystem. Flashing it as-is in a single partition (usually done in userdata partition as it is the largest) is not bootable as U-Boot does not understand subpartitions. Use blkmap to map the userdata partition into its own block device. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- board/samsung/exynos-mobile/exynos-mobile.c | 45 +++++++++++++++++++ board/samsung/exynos-mobile/exynos-mobile.env | 5 +++ configs/exynos-mobile_defconfig | 4 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index 1f61f28de5f..c5e1b186ae3 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -184,6 +184,45 @@ static void exynos_env_setup(void) env_set("fdtfile", buf); } +static int exynos_blk_env_setup(void) +{ + const char *blk_ifname; + int blk_dev = 0; + struct blk_desc *blk_desc; + struct disk_partition info = {0}; + unsigned long largest_part_start = 0, largest_part_size = 0; + int i; + + blk_ifname = "mmc"; + blk_desc = blk_get_dev(blk_ifname, blk_dev); + if (!blk_desc) { + log_err("%s: required mmc device not available\n", __func__); + return -ENODEV; + } + + for (i = 1; i < CONFIG_EFI_PARTITION_ENTRIES_NUMBERS; i++) { + if (part_get_info(blk_desc, i, &info)) + continue; + + if (info.start > largest_part_size) { + largest_part_start = info.start; + largest_part_size = info.size; + } + } + + if (largest_part_size) { + env_set("blkmap_blk_ifname", blk_ifname); + env_set_ulong("blkmap_blk_dev", blk_dev); + env_set_ulong("blkmap_blk_nr", largest_part_start); + env_set_hex("blkmap_size_r", largest_part_size); + } else { + log_warning("%s: no qualified partition for blkmap, skipping\n", + __func__); + } + + return 0; +} + static int exynos_fastboot_setup(void) { struct blk_desc *blk_dev; @@ -297,7 +336,13 @@ int board_init(void) int misc_init_r(void) { + int ret; + exynos_env_setup(); + ret = exynos_blk_env_setup(); + if (ret) + return ret; + return exynos_fastboot_setup(); } diff --git a/board/samsung/exynos-mobile/exynos-mobile.env b/board/samsung/exynos-mobile/exynos-mobile.env index aa2e89afbac..33f767319b5 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.env +++ b/board/samsung/exynos-mobile/exynos-mobile.env @@ -2,6 +2,11 @@ stdin=serial,button-kbd stdout=serial,vidconsole stderr=serial,vidconsole +blkmapcmd=blkmap create root; + blkmap map root 0 ${blkmap_size_r} linear ${blkmap_blk_ifname} ${blkmap_blk_dev} ${blkmap_blk_nr} + +preboot=run blkmapcmd + bootdelay=0 bootcmd=bootefi bootmgr; pause; bootmenu diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index c7d206f94ac..cee468d9c24 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -12,6 +12,7 @@ CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_ARMV8_CNTFRQ_BROKEN=y # CONFIG_PSCI_RESET is not set CONFIG_BUTTON_CMD=y +CONFIG_USE_PREBOOT=y CONFIG_SAVE_PREV_BL_FDT_ADDR=y CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y CONFIG_SYS_PBSIZE=1024 @@ -24,8 +25,9 @@ CONFIG_CMD_POWEROFF=y CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y CONFIG_OF_UPSTREAM=y -CONFIG_OF_BOARD=y CONFIG_OF_UPSTREAM_BUILD_VENDOR=y +CONFIG_OF_BOARD=y +CONFIG_BLKMAP=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y CONFIG_CLK_EXYNOS7870=y From 0e61fc5364dc6b4af88b44ea2e1aa9d84c9f1ca7 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 24 Feb 2026 21:07:10 +0530 Subject: [PATCH 49/80] board: samsung: exynos-mobile: add EFI capsule update support Add support for EFI capsule updates via U-Boot's DFU. This flashes the boot partition with the new image provided in the capsule. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- board/samsung/exynos-mobile/exynos-mobile.c | 24 +++++++++++++++++++++ configs/exynos-mobile_defconfig | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index c5e1b186ae3..6b2b1523663 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -24,6 +26,19 @@ DECLARE_GLOBAL_DATA_PTR; #define lmb_alloc(size, addr) \ lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) +struct efi_fw_image fw_images[] = { + { + .fw_name = u"UBOOT_BOOT_PARTITION", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = NULL, + .images = fw_images, + .num_images = ARRAY_SIZE(fw_images), +}; + /* * The memory mapping includes all DRAM banks, along with the * peripheral block, and a sentinel at the end. This is filled in @@ -191,6 +206,7 @@ static int exynos_blk_env_setup(void) struct blk_desc *blk_desc; struct disk_partition info = {0}; unsigned long largest_part_start = 0, largest_part_size = 0; + static char dfu_string[32]; int i; blk_ifname = "mmc"; @@ -204,6 +220,14 @@ static int exynos_blk_env_setup(void) if (part_get_info(blk_desc, i, &info)) continue; + if (!update_info.dfu_string && + !strncasecmp(info.name, "boot", strlen("boot"))) { + snprintf(dfu_string, sizeof(dfu_string), + "mmc %d=u-boot.bin part %d %d", blk_dev, + blk_dev, i); + update_info.dfu_string = dfu_string; + } + if (info.start > largest_part_size) { largest_part_start = info.start; largest_part_size = info.size; diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index cee468d9c24..9a4b6a52362 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -11,6 +11,10 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_ARMV8_CNTFRQ_BROKEN=y # CONFIG_PSCI_RESET is not set +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_ON_DISK_EARLY=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_BUTTON_CMD=y CONFIG_USE_PREBOOT=y CONFIG_SAVE_PREV_BL_FDT_ADDR=y @@ -31,6 +35,8 @@ CONFIG_BLKMAP=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y CONFIG_CLK_EXYNOS7870=y +CONFIG_DFU_MMC=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000 CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0xdead0000 CONFIG_FASTBOOT_FLASH=y From 336dd39b956e5f7e078da1d2b689415a41484067 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 24 Feb 2026 21:07:11 +0530 Subject: [PATCH 50/80] configs: exynos-mobile: add DEFAULT_DEVICE_TREE option Add a default fallback device tree in order to allow a successful build without mentioning the DEVICE_TREE= make flag. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- configs/exynos-mobile_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index 9a4b6a52362..bff4e6c6fb7 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x16000 CONFIG_TARGET_EXYNOS_MOBILE=y CONFIG_NR_DRAM_BANKS=3 +CONFIG_DEFAULT_DEVICE_TREE="exynos/exynos7870-a2corelte" CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_ARMV8_CNTFRQ_BROKEN=y From 3ee1408eeb7352d770bbf063df85fa23cd6b79a4 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 10 Feb 2026 16:12:14 +0800 Subject: [PATCH 51/80] firmware: scmi: Validate device tree node before setup channel SCMI base protocol device does not have a device tree, it should use and need to use the agent base channel. For scmi_base.[x], there is no real device tree node for it. ofnode_null() is assigned as the device tree node for scmi base protocol device: commit 7eb4eb541c14 ("firmware: scmi: install base protocol to SCMI agent") However with recent update in commit 0535e46d55d7 ("scripts/dtc: Update to upstream version v1.7.2-35-g52f07dcca47c"), SPL panic in fdt_check_node_offset_()->fdt_next_tag(), because offset is -1 and SPL_OF_LIBFDT_ASSUME_MASK is 0xFF. So add a check in x_get_channel() to validate the protocol devices' ofnode. Reported-by: Ye Li Closes: https://lore.kernel.org/u-boot/939a9696-27fa-45a1-b428-feffe21ac6d5@oss.nxp.com/ Signed-off-by: Peng Fan --- drivers/firmware/scmi/mailbox_agent.c | 2 +- drivers/firmware/scmi/optee_agent.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c index 16a82f55ab7..cda94565de5 100644 --- a/drivers/firmware/scmi/mailbox_agent.c +++ b/drivers/firmware/scmi/mailbox_agent.c @@ -101,7 +101,7 @@ static int scmi_mbox_get_channel(struct udevice *dev, struct scmi_mbox_channel *chan; int ret; - if (!dev_read_prop(protocol, "shmem", NULL)) { + if (!dev_has_ofnode(protocol) || !dev_read_prop(protocol, "shmem", NULL)) { /* Uses agent base channel */ *channel = container_of(base_chan, struct scmi_channel, ref); diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c index 631625d715b..7170bd1e682 100644 --- a/drivers/firmware/scmi/optee_agent.c +++ b/drivers/firmware/scmi/optee_agent.c @@ -331,7 +331,8 @@ static int scmi_optee_get_channel(struct udevice *dev, u32 channel_id; int ret; - if (dev_read_u32(protocol, "linaro,optee-channel-id", &channel_id)) { + if (!dev_has_ofnode(protocol) || + dev_read_u32(protocol, "linaro,optee-channel-id", &channel_id)) { /* Uses agent base channel */ *channel = container_of(base_chan, struct scmi_channel, ref); From 6ee82240de63b085325b4f4ce4874240724f9dbe Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 10 Feb 2026 16:12:15 +0800 Subject: [PATCH 52/80] power: domain: Validate device tree node in dev_power_domain_ctrl Similar to pinctrl_select_state(), add dev_has_ofnode() check before doing the real work. Device(scmi_base.0) does not have a real device node, ofnode_null() is assigned as the device tree node for scmi base protocol device: 'commit 7eb4eb541c14 ("firmware: scmi: install base protocol to SCMI agent")' However with recent update in 'commit 0535e46d55d7 ("scripts/dtc: Update to upstream version v1.7.2-35-g52f07dcca47c")', SPL panic in fdt_check_node_offset_()->fdt_next_tag(), because offset is -1 and SPL_OF_LIBFDT_ASSUME_MASK is 0xFF. So need to validate device tree node. Reported-by: Ye Li Closes: https://lore.kernel.org/u-boot/939a9696-27fa-45a1-b428-feffe21ac6d5@oss.nxp.com/ Signed-off-by: Peng Fan --- drivers/power/domain/power-domain-uclass.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index d9fa8ad4bd2..cea68945cbd 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -180,6 +180,9 @@ static int dev_power_domain_ctrl(struct udevice *dev, bool on) struct power_domain pd; int i, count, ret = 0; + if (!dev_has_ofnode(dev)) + return 0; + count = dev_count_phandle_with_args(dev, "power-domains", "#power-domain-cells", 0); for (i = 0; i < count; i++) { From efc9be77d851b98b38afcfb4e46d17703057efad Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 10 Feb 2026 16:12:16 +0800 Subject: [PATCH 53/80] iommu: Validate device tree node in dev_iommu_enable Similar to pinctrl_select_state(), add dev_has_ofnode() check before doing the real work. Device(scmi_base.0) does not have a real device node, ofnode_null() is assigned as the device tree node for scmi base protocol device: 'commit 7eb4eb541c14 ("firmware: scmi: install base protocol to SCMI agent")' However with recent update in 'commit 0535e46d55d7 ("scripts/dtc: Update to upstream version v1.7.2-35-g52f07dcca47c")', SPL panic in fdt_check_node_offset_()->fdt_next_tag(), because offset is -1 and SPL_OF_LIBFDT_ASSUME_MASK is 0xFF. So need to validate device tree node. Reported-by: Ye Li Closes: https://lore.kernel.org/u-boot/939a9696-27fa-45a1-b428-feffe21ac6d5@oss.nxp.com/ Signed-off-by: Peng Fan --- drivers/iommu/iommu-uclass.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c index bb31cd519d2..31b40e5713a 100644 --- a/drivers/iommu/iommu-uclass.c +++ b/drivers/iommu/iommu-uclass.c @@ -79,6 +79,9 @@ int dev_iommu_enable(struct udevice *dev) const struct iommu_ops *ops; int i, count, ret = 0; + if (!dev_has_ofnode(dev)) + return 0; + count = dev_count_phandle_with_args(dev, "iommus", "#iommu-cells", 0); for (i = 0; i < count; i++) { From 437ea9f8be5afaebe2d8cbab6242f1182857f21e Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 24 Feb 2026 12:31:07 -0600 Subject: [PATCH 54/80] Gitlab: Fix TEST_PY_TEST_SPEC for qemu-x86_64 in sjg-lab With the change to regularize the usage of TEST_PY_TEST_SPEC in the sjg-lab stanza with commit c7f360f20d84 ("Gitlab: Rework sjg-lab calling test.py to be closer to test.py stage") the leading "and " part of the usage under qemu-x86_64 wasn't removed when it should have been. Do so now. Fixes: c7f360f20d84 ("Gitlab: Rework sjg-lab calling test.py to be closer to test.py stage") Reviewed-by: Simon Glass Signed-off-by: Tom Rini --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08d01c41f35..245e422d72f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -795,5 +795,5 @@ vf2: qemu-x86_64: variables: ROLE: qemu-x86_64 - TEST_PY_TEST_SPEC: "and not sleep" + TEST_PY_TEST_SPEC: "not sleep" <<: *sjg_lab_dfn From 3768968b1ea7abd587df1fcc3f9a528203fccb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Mon, 16 Feb 2026 12:30:16 +0100 Subject: [PATCH 55/80] efi_loader: fix specific LoadImage() return code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the LoadImage() UEFI function is called with both its SourceBuffer and DevicePath input arguments equal to NULL, it must return EFI_NOT_FOUND [1]. However, it does return EFI_INVALID_PARAMETER instead; fix it. Link: https://uefi.org/specs/UEFI/2.11/07_Services_Boot_Services.html#efi-boot-services-loadimage [1] Reported-by: Sathisha Shivaramappa Signed-off-by: Vincent Stehlé Cc: Heinrich Schuchardt Cc: Ilias Apalodimas Cc: Tom Rini --- lib/efi_loader/efi_boottime.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index b424d924896..de57823bd44 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2096,8 +2096,12 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy, EFI_ENTRY("%d, %p, %pD, %p, %zu, %p", boot_policy, parent_image, file_path, source_buffer, source_size, image_handle); - if (!image_handle || (!source_buffer && !file_path) || - !efi_search_obj(parent_image) || + if (!source_buffer && !file_path) { + ret = EFI_NOT_FOUND; + goto error; + } + + if (!image_handle || !efi_search_obj(parent_image) || /* The parent image handle must refer to a loaded image */ !parent_image->type) { ret = EFI_INVALID_PARAMETER; From 02b74a786354db961f3e057f671d60fad9a17515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Mon, 16 Feb 2026 12:30:17 +0100 Subject: [PATCH 56/80] efi_selftest: test specific LoadImage() case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test calling the LoadImage() UEFI function with both its SourceBuffer and DevicePath input arguments equal to NULL. This test can be run on the sandbox with the following command: ./u-boot -T -c "setenv efi_selftest load image from file; \ bootefi selftest" Signed-off-by: Vincent Stehlé Cc: Heinrich Schuchardt Cc: Ilias Apalodimas Cc: Tom Rini --- lib/efi_selftest/efi_selftest_loadimage.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/efi_selftest/efi_selftest_loadimage.c b/lib/efi_selftest/efi_selftest_loadimage.c index 967eaa58c69..0e8fc6216f0 100644 --- a/lib/efi_selftest/efi_selftest_loadimage.c +++ b/lib/efi_selftest/efi_selftest_loadimage.c @@ -562,6 +562,13 @@ static int execute(void) return EFI_ST_FAILURE; } + ret = boottime->load_image(false, handle_image, NULL, NULL, 0, + &handle); + if (ret != EFI_NOT_FOUND) { + efi_st_error("Unexpected load_image return value\n"); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; } From 89f6b9020db0960e219fc56d0d32aba82e42332a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Thu, 19 Feb 2026 19:44:00 +0100 Subject: [PATCH 57/80] efi_selftest: cosmetic: fix spelling in comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a few UEFI function names, as well as a typo. Signed-off-by: Vincent Stehlé Cc: Heinrich Schuchardt Cc: Ilias Apalodimas Cc: Tom Rini Reviewed-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- lib/efi_selftest/efi_selftest_manageprotocols.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c index 097b2ae3545..31ea67748a5 100644 --- a/lib/efi_selftest/efi_selftest_manageprotocols.c +++ b/lib/efi_selftest/efi_selftest_manageprotocols.c @@ -6,7 +6,7 @@ * * This unit test checks the following protocol services: * InstallProtocolInterface, UninstallProtocolInterface, - * InstallMultipleProtocolsInterfaces, UninstallMultipleProtocolsInterfaces, + * InstallMultipleProtocolInterfaces, UninstallMultipleProtocolInterfaces, * HandleProtocol, ProtocolsPerHandle, * LocateHandle, LocateHandleBuffer. */ @@ -189,7 +189,7 @@ static int execute(void) } /* - * Test error handling in UninstallMultipleProtocols + * Test error handling in UninstallMultipleProtocolInterfaces * * These are the installed protocol interfaces on handle 2: * @@ -240,7 +240,7 @@ static int execute(void) efi_st_error("LocateHandleBuffer failed to locate new handle\n"); return EFI_ST_FAILURE; } - /* Clear the buffer, we are reusing it it the next step. */ + /* Clear the buffer, we are reusing it in the next step. */ boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0); /* @@ -289,7 +289,7 @@ static int execute(void) } /* - * Test UninstallMultipleProtocols + * Test UninstallMultipleProtocolInterfaces */ ret = boottime->uninstall_multiple_protocol_interfaces( handle2, From 080b4f099558212703a772d3ca74c0521cf5a7e8 Mon Sep 17 00:00:00 2001 From: Padmarao Begari Date: Wed, 26 Nov 2025 16:06:41 +0100 Subject: [PATCH 58/80] ufs: Disable UTP command timeout in slow mode When the UFS controller is operating in slow (PWM) mode, the driver is disabled the timeout for UTP send commands. In high-speed mode, the timeout remains enabled to detect stalled or failed transfers. This change ensures reliable operation in slow mode, where command completion may take longer and timeouts are not required. Signed-off-by: Padmarao Begari Signed-off-by: Michal Simek Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/e6deb9086afab9d2bdd53db8ecbc7db93af5204d.1764169598.git.michal.simek@amd.com Signed-off-by: Neil Armstrong --- drivers/ufs/ufs-uclass.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c index 3c8e4299259..7a80a9d5664 100644 --- a/drivers/ufs/ufs-uclass.c +++ b/drivers/ufs/ufs-uclass.c @@ -917,11 +917,13 @@ static int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) enabled_intr_status = intr_status & hba->intr_mask; ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); - if (get_timer(start) > QUERY_REQ_TIMEOUT) { - dev_err(hba->dev, - "Timedout waiting for UTP response\n"); - - return -ETIMEDOUT; + if (hba->max_pwr_info.info.pwr_rx != SLOWAUTO_MODE && + hba->max_pwr_info.info.pwr_tx != SLOWAUTO_MODE) { + if (get_timer(start) > QUERY_REQ_TIMEOUT) { + dev_err(hba->dev, + "Timedout waiting for UTP response\n"); + return -ETIMEDOUT; + } } if (enabled_intr_status & UFSHCD_ERROR_MASK) { From 25f142543196e5b5f0f9c916f15671dcd26eb2f7 Mon Sep 17 00:00:00 2001 From: Igor Belwon Date: Sat, 11 Oct 2025 21:10:04 +0200 Subject: [PATCH 59/80] phy: Add MediaTek UFS PHY Driver This UFS M-PHY driver can be used on recent MediaTek SoCs as the primary PHY for the UFS controller. Signed-off-by: Igor Belwon Link: https://patch.msgid.link/20251011-mtk-ufs-uboot-v1-1-a05f991ee150@mentallysanemainliners.org Signed-off-by: Neil Armstrong --- drivers/phy/Kconfig | 10 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-mtk-ufs.c | 190 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 drivers/phy/phy-mtk-ufs.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 87729b479bd..09810b62b51 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -282,6 +282,16 @@ config PHY_MTK_TPHY multi-ports is first version, otherwise is second veriosn, so you can easily distinguish them by banks layout. +config PHY_MTK_UFS + tristate "MediaTek UFS M-PHY driver" + depends on ARCH_MEDIATEK + depends on PHY + help + Support for UFS M-PHY on MediaTek chipsets. + Enable this to provide vendor-specific probing, + initialization, power on and power off flow of + specified M-PHYs. + config PHY_NPCM_USB bool "Nuvoton NPCM USB PHY support" depends on PHY diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 5a6df0ecfeb..83102349669 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o obj-$(CONFIG_PHY_EXYNOS_USBDRD) += phy-exynos-usbdrd.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o +obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o obj-$(CONFIG_$(PHASE_)PHY_IMX8MQ_USB) += phy-imx8mq-usb.o obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o diff --git a/drivers/phy/phy-mtk-ufs.c b/drivers/phy/phy-mtk-ufs.c new file mode 100644 index 00000000000..1eda3df858d --- /dev/null +++ b/drivers/phy/phy-mtk-ufs.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * Author: Stanley Chu + * + * Copyright (c) 2025, Igor Belwon + */ + +#include "dm/ofnode.h" +#include "dm/read.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* mphy register and offsets */ +#define MP_GLB_DIG_8C 0x008C +#define FRC_PLL_ISO_EN BIT(8) +#define PLL_ISO_EN BIT(9) +#define FRC_FRC_PWR_ON BIT(10) +#define PLL_PWR_ON BIT(11) + +#define MP_LN_DIG_RX_9C 0xA09C +#define FSM_DIFZ_FRC BIT(18) + +#define MP_LN_DIG_RX_AC 0xA0AC +#define FRC_RX_SQ_EN BIT(0) +#define RX_SQ_EN BIT(1) + +#define MP_LN_RX_44 0xB044 +#define FRC_CDR_PWR_ON BIT(17) +#define CDR_PWR_ON BIT(18) +#define FRC_CDR_ISO_EN BIT(19) +#define CDR_ISO_EN BIT(20) + +#define UFSPHY_CLKS_CNT 2 + +struct mtk_ufs_phy { + struct udevice *dev; + void __iomem *mmio; + + struct clk *unipro_clk; + struct clk *mp_clk; +}; + +static void ufs_mtk_phy_set_active(struct mtk_ufs_phy *phy) +{ + /* release DA_MP_PLL_PWR_ON */ + setbits_le32(phy->mmio + MP_GLB_DIG_8C, PLL_PWR_ON); + clrbits_le32(phy->mmio + MP_GLB_DIG_8C, FRC_FRC_PWR_ON); + + /* release DA_MP_PLL_ISO_EN */ + clrbits_le32(phy->mmio + MP_GLB_DIG_8C, PLL_ISO_EN); + clrbits_le32(phy->mmio + MP_GLB_DIG_8C, FRC_PLL_ISO_EN); + + /* release DA_MP_CDR_PWR_ON */ + setbits_le32(phy->mmio + MP_LN_RX_44, CDR_PWR_ON); + clrbits_le32(phy->mmio + MP_LN_RX_44, FRC_CDR_PWR_ON); + + /* release DA_MP_CDR_ISO_EN */ + clrbits_le32(phy->mmio + MP_LN_RX_44, CDR_ISO_EN); + clrbits_le32(phy->mmio + MP_LN_RX_44, FRC_CDR_ISO_EN); + + /* release DA_MP_RX0_SQ_EN */ + setbits_le32(phy->mmio + MP_LN_DIG_RX_AC, RX_SQ_EN); + clrbits_le32(phy->mmio + MP_LN_DIG_RX_AC, FRC_RX_SQ_EN); + + /* delay 1us to wait DIFZ stable */ + udelay(1); + + /* release DIFZ */ + clrbits_le32(phy->mmio + MP_LN_DIG_RX_9C, FSM_DIFZ_FRC); +} + +static int mtk_phy_power_on(struct phy *phy) +{ + struct mtk_ufs_phy *ufs_phy = dev_get_priv(phy->dev); + int ret; + + ret = clk_enable(ufs_phy->mp_clk); + if (ret < 0) { + dev_err(phy->dev, "failed to enable mp_clk\n"); + return ret; + } + + ret = clk_enable(ufs_phy->unipro_clk); + if (ret < 0) { + dev_err(phy->dev, "failed to enable unipro_clk %d\n", ret); + clk_disable(ufs_phy->unipro_clk); + return ret; + } + + ufs_mtk_phy_set_active(ufs_phy); + + return 0; +} + +static int mtk_phy_power_off(struct phy *phy) +{ + struct mtk_ufs_phy *ufs_phy = dev_get_priv(phy->dev); + + /* Set PHY to Deep Hibernate mode */ + setbits_le32(ufs_phy->mmio + MP_LN_DIG_RX_9C, FSM_DIFZ_FRC); + + /* force DA_MP_RX0_SQ_EN */ + setbits_le32(ufs_phy->mmio + MP_LN_DIG_RX_AC, FRC_RX_SQ_EN); + clrbits_le32(ufs_phy->mmio + MP_LN_DIG_RX_AC, RX_SQ_EN); + + /* force DA_MP_CDR_ISO_EN */ + setbits_le32(ufs_phy->mmio + MP_LN_RX_44, FRC_CDR_ISO_EN); + setbits_le32(ufs_phy->mmio + MP_LN_RX_44, CDR_ISO_EN); + + /* force DA_MP_CDR_PWR_ON */ + setbits_le32(ufs_phy->mmio + MP_LN_RX_44, FRC_CDR_PWR_ON); + clrbits_le32(ufs_phy->mmio + MP_LN_RX_44, CDR_PWR_ON); + + /* force DA_MP_PLL_ISO_EN */ + setbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, FRC_PLL_ISO_EN); + setbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, PLL_ISO_EN); + + /* force DA_MP_PLL_PWR_ON */ + setbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, FRC_FRC_PWR_ON); + clrbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, PLL_PWR_ON); + + return 0; +} + +static const struct phy_ops mtk_ufs_phy_ops = { + .power_on = mtk_phy_power_on, + .power_off = mtk_phy_power_off, +}; + +static int mtk_ufs_phy_probe(struct udevice *dev) +{ + struct mtk_ufs_phy *phy = dev_get_priv(dev); + fdt_addr_t addr; + int ret; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -ENOMEM; + + phy->dev = dev; + phy->mmio = map_sysmem(addr, 0); + + phy->mp_clk = devm_clk_get(dev, "mp"); + if (IS_ERR(phy->mp_clk)) { + ret = PTR_ERR(phy->mp_clk); + dev_err(dev, "Failed to get mp clock (ret=%d)\n", ret); + return ret; + } + + phy->unipro_clk = devm_clk_get(dev, "unipro"); + if (IS_ERR(phy->unipro_clk)) { + ret = PTR_ERR(phy->unipro_clk); + dev_err(dev, "Failed to get unipro clock (ret=%d)\n", ret); + return ret; + } + + return 0; +} + +static const struct udevice_id mtk_ufs_phy_id_table[] = { + {.compatible = "mediatek,mt8183-ufsphy"}, + {}, +}; + +U_BOOT_DRIVER(mtk_ufs_phy) = { + .name = "mtk-ufs_phy", + .id = UCLASS_PHY, + .of_match = mtk_ufs_phy_id_table, + .ops = &mtk_ufs_phy_ops, + .probe = mtk_ufs_phy_probe, + .priv_auto = sizeof(struct mtk_ufs_phy), +}; From 47905f28468e3524cb5f775f52928cdcc568815a Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Tue, 3 Feb 2026 10:21:26 +0100 Subject: [PATCH 60/80] drivers: ufs: remove unused ufs_post_bind() declaration Commit 067c1b033282 ("ufs: Call ufs_scsi_bind() from uclass .post_bind") inlined ufs_scsi_bind() into ufs_post_bind() as trivial device_bind_driver() call. ufs_scsi_bind() is no longer referenced anywhere in the codebase, so drop its declaration from include/ufs.h. Drivers used to include to include prototype of ufs_scsi_bind() function, so we can now safely remove such includes. Fixes: 067c1b033282 ("ufs: Call ufs_scsi_bind() from uclass .post_bind") Signed-off-by: Julien Stephan Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20260203-cleanup-ufs-header-v1-1-4c10424485f0@baylibre.com Signed-off-by: Neil Armstrong --- drivers/ufs/cdns-platform.c | 1 - drivers/ufs/ufs-amd-versal2.c | 1 - drivers/ufs/ufs-pci.c | 1 - drivers/ufs/ufs-qcom.c | 1 - drivers/ufs/ufs-renesas-rcar-gen5.c | 1 - drivers/ufs/ufs-renesas.c | 1 - drivers/ufs/ufs-rockchip.c | 1 - drivers/ufs/ufshcd-dwc.c | 1 - include/ufs.h | 9 --------- 9 files changed, 17 deletions(-) diff --git a/drivers/ufs/cdns-platform.c b/drivers/ufs/cdns-platform.c index 87d9c5bad79..40883a187b0 100644 --- a/drivers/ufs/cdns-platform.c +++ b/drivers/ufs/cdns-platform.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ufs/ufs-amd-versal2.c b/drivers/ufs/ufs-amd-versal2.c index dd62c9819ba..6c949b2ca76 100644 --- a/drivers/ufs/ufs-amd-versal2.c +++ b/drivers/ufs/ufs-amd-versal2.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ufs/ufs-pci.c b/drivers/ufs/ufs-pci.c index 5b9c72a695d..e1e010d027c 100644 --- a/drivers/ufs/ufs-pci.c +++ b/drivers/ufs/ufs-pci.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "ufs.h" diff --git a/drivers/ufs/ufs-qcom.c b/drivers/ufs/ufs-qcom.c index ee43958d5d8..dc40ee62daf 100644 --- a/drivers/ufs/ufs-qcom.c +++ b/drivers/ufs/ufs-qcom.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/drivers/ufs/ufs-renesas-rcar-gen5.c b/drivers/ufs/ufs-renesas-rcar-gen5.c index cc53e91449c..a21ae3f390e 100644 --- a/drivers/ufs/ufs-renesas-rcar-gen5.c +++ b/drivers/ufs/ufs-renesas-rcar-gen5.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ufs/ufs-renesas.c b/drivers/ufs/ufs-renesas.c index 5652309911e..a206e3c6d58 100644 --- a/drivers/ufs/ufs-renesas.c +++ b/drivers/ufs/ufs-renesas.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ufs/ufs-rockchip.c b/drivers/ufs/ufs-rockchip.c index 0384244387d..643a6ffb9bc 100644 --- a/drivers/ufs/ufs-rockchip.c +++ b/drivers/ufs/ufs-rockchip.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "ufs.h" #include "unipro.h" diff --git a/drivers/ufs/ufshcd-dwc.c b/drivers/ufs/ufshcd-dwc.c index 3f62e59a060..98422d742a0 100644 --- a/drivers/ufs/ufshcd-dwc.c +++ b/drivers/ufs/ufshcd-dwc.c @@ -7,7 +7,6 @@ */ #include #include -#include #include #include #include diff --git a/include/ufs.h b/include/ufs.h index 702b8359dbd..f6e27d90e43 100644 --- a/include/ufs.h +++ b/include/ufs.h @@ -20,13 +20,4 @@ int ufs_probe(void); */ int ufs_probe_dev(int index); -/* - * ufs_scsi_bind() - Create a new scsi device as a child of the UFS device and - * bind it to the ufs_scsi driver - * @ufs_dev: UFS device - * @scsi_devp: Pointer to scsi device - * - * Return: 0 if Ok, -ve on error - */ -int ufs_scsi_bind(struct udevice *ufs_dev, struct udevice **scsi_devp); #endif From 8d24789abed0822fbe41a2f9d72cf19650159dc6 Mon Sep 17 00:00:00 2001 From: Stefan Eichenberger Date: Fri, 14 Mar 2025 11:06:49 +0100 Subject: [PATCH 61/80] common/memsize.c: Fix get_ram_size() original data restore The get_ram_size() function fails to restore the original RAM data when the data cache is enabled. This issue was observed on an AM625 R5 SPL with 512MB of RAM and is a regression that became visible with commit bc07851897bd ("board: ti: Pull redundant DDR functions to a common location and Fixup DDR size when ECC is enabled"). Observed boot failure messages: Warning: Did not detect image signing certificate. Skipping authentication to prevent boot failure. This will fail on Security Enforcing(HS-SE) devices Authentication passed Starting ATF on ARM64 core... The system then hangs. This indicates that without a data cache flush, data in the cache is not coherent with RAM, preventing the system from booting. This was verified by printing the content of this address when the issue occurs. Add a data cache flush after each restore operation to resolve this issue. Fixes: bc07851897bd ("board: ti: Pull redundant DDR functions to a common location and Fixup DDR size when ECC is enabled") Fixes: 1c64b98c1ec4 ("common/memsize.c: Fix get_ram_size() when cache is enabled") Signed-off-by: Stefan Eichenberger Reviewed-by: Emanuele Ghidoli Tested-by: Francesco Dolcini # Toradex Verdin AM62 --- common/memsize.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/memsize.c b/common/memsize.c index 3c3ae6f1eba..1abf3fc47d7 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -85,6 +85,8 @@ long get_ram_size(long *base, long maxsize) addr = base + cnt; sync(); *addr = save[--i]; + if (dcache_en) + dcache_flush_invalidate(addr); } return (0); } @@ -93,6 +95,8 @@ long get_ram_size(long *base, long maxsize) addr = base + cnt; /* pointer arith! */ val = *addr; *addr = save[--i]; + if (dcache_en) + dcache_flush_invalidate(addr); if (val != ~cnt) { size = cnt * sizeof(long); /* @@ -104,6 +108,8 @@ long get_ram_size(long *base, long maxsize) cnt <<= 1) { addr = base + cnt; *addr = save[--i]; + if (dcache_en) + dcache_flush_invalidate(addr); } /* warning: don't restore save_base in this case, * it is already done in the loop because @@ -115,6 +121,8 @@ long get_ram_size(long *base, long maxsize) } } *base = save_base; + if (dcache_en) + dcache_flush_invalidate(base); return (maxsize); } From 39e1ccc777563d8c769531f1dfce24d38d023086 Mon Sep 17 00:00:00 2001 From: Romain Gantois Date: Tue, 17 Feb 2026 10:27:52 +0100 Subject: [PATCH 62/80] dm: core: Don't allow ofnode_to_fdt() to return NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ofnode_to_fdt() function may return a NULL pointer in multiple cases. Or, this function's return value is often passed directly to functions such as fdt_getprop() which end up dereferencing it, thus causing a NULL pointer exception. Don't allow ofnode_to_fdt() to return NULL, to avoid a NULL pointer dereference. Reviewed-by: Raphaël Gallais-Pou Signed-off-by: Romain Gantois Reviewed-by: Simon Glass --- drivers/core/ofnode.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index cf1cf8abfbe..3a36b6fdd03 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -164,15 +164,20 @@ void *ofnode_lookup_fdt(ofnode node) void *ofnode_to_fdt(ofnode node) { + void *fdt; + #ifdef OF_CHECKS if (of_live_active()) - return NULL; + panic("%s called with live tree in use!\n", __func__); #endif if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && ofnode_valid(node)) - return ofnode_lookup_fdt(node); + fdt = ofnode_lookup_fdt(node); + else + fdt = (void *)gd->fdt_blob; - /* Use the control FDT by default */ - return (void *)gd->fdt_blob; + assert(fdt); + + return fdt; } /** From e15b78bcf72bae42c7d198dfac5317c1058b8c26 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 16 Feb 2026 12:28:39 -0500 Subject: [PATCH 63/80] drivers: cpu: fix syntax error in Kconfig documentation Replace then -> they so that the sentence makes sense. Signed-off-by: Hugo Villeneuve Reviewed-by: Quentin Schulz --- drivers/cpu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index 4cc3679c009..6a96be94de4 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -3,7 +3,7 @@ config CPU help This allows drivers to be provided for CPUs and their type to be specified in the board's device tree. For boards which support - multiple CPUs, then normally have to be set up in U-Boot so that + multiple CPUs, they normally have to be set up in U-Boot so that they can work correctly in the OS. This provides a framework for finding out information about available CPUs and making changes. From 8353239dabb8079a10fd34167922302288a6a1bd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 13 Feb 2026 06:39:09 -0700 Subject: [PATCH 64/80] menu: Move shortcut-key handling to bootmenu_loop() The bootmenu_conv_key() function is shared with expo subsystem for key input. Adding alphanumeric-to-BKEY_SHORTCUT conversion there causes expo to swallow typed characters instead of inserting them as text, since BKEY_SHORTCUT falls in the range that expo treats as a command key rather than passing through. Move the shortcut-key detection into bootmenu_loop() where it is only used in the bootmenu context. Fixes: 8c986521c3c9 ("cmd: bootmenu: permit to select bootmenu entry with a shortcut") Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- common/menu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/common/menu.c b/common/menu.c index ae5afa14766..02df3b8f133 100644 --- a/common/menu.c +++ b/common/menu.c @@ -556,11 +556,6 @@ enum bootmenu_key bootmenu_conv_key(int ichar) case ' ': key = BKEY_SPACE; break; - case 'A' ... 'Z': - case 'a' ... 'z': - case '0' ... '9': - key = BKEY_SHORTCUT; - break; default: key = BKEY_NONE; break; @@ -591,8 +586,10 @@ enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, key = bootmenu_conv_key(c); - if (key == BKEY_SHORTCUT) + if (key == BKEY_NONE && isalnum(c)) { + key = BKEY_SHORTCUT; cch->shortcut_key = bootmenu_conv_shortcut_key(menu, c); + } return key; } From 4284306d22c5b6d64ecd62b462551d9d313c8104 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 13 Feb 2026 19:47:34 -0700 Subject: [PATCH 65/80] kbuild: unexport sub_make_done to fix child make invocations The exported sub_make_done variable leaks into the environment of all child processes. When make targets like tcheck spawn independent make invocations with O=, those child makes inherit sub_make_done=1, skip the KBUILD_OUTPUT setup and try to build in the source tree. There is a workaround that resets sub_make_done to 0 for specific test targets, but this isn't great since it has tolist every target that spawns independent make invocations. Instead, unexport sub_make_done once we are in the final make invocation. The direct sub-make already has the value in its environment from the export, and no further propagation is needed. This also allows the per-target workaround to be removed. Fixes: 27529f1cb02d ("kbuild: skip parsing pre sub-make code for recursion") Signed-off-by: Simon Glass --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 5df869213b6..fdaba4895fe 100644 --- a/Makefile +++ b/Makefile @@ -194,6 +194,10 @@ endif # sub_make_done # We process the rest of the Makefile if this is the final invocation of make ifeq ($(need-sub-make),) +# Do not propagate sub_make_done to non-submake children (e.g. test scripts +# that invoke make separately with O= need to process the KBUILD_OUTPUT block) +unexport sub_make_done + # Do not print "Entering directory ...", # but we want to display it when entering to the output directory # so that IDEs/editors are able to understand relative filenames. @@ -2737,10 +2741,6 @@ help: @echo 'Execute "make" or "make all" to build all targets marked with [*] ' @echo 'For further info see the ./README file' -ifneq ($(filter tests pcheck qcheck tcheck,$(MAKECMDGOALS)),) -export sub_make_done := 0 -endif - tests check: $(srctree)/test/run From f473a453b0c03d0042b4422de1d822274d2e2d4e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 15 Feb 2026 15:04:55 +0100 Subject: [PATCH 66/80] kbuild: Drop phandle from diff between base DT and U-Boot augmented DT if DEVICE_TREE_DEBUG=1 Remove the "phandle = <0x..>;" properties from the DT diff between unpatched base DT and U-Boot augmented DT if DEVICE_TREE_DEBUG=1. The phandle numbers are only generated by DTC, but not referenced anywhere in the DT, because the original references are specifically not replaced by phandle numbers when recent DTC is invoked with the -I dts -O dts flags . The phandle number are therefore only a noise in the diff, filter them out. Signed-off-by: Marek Vasut Tested-by: Quentin Schulz Reviewed-by: Quentin Schulz --- scripts/Makefile.lib | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 377a4700b94..7386353e0cc 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -437,6 +437,8 @@ cmd_dtc_diff = \ $(DTC) -s -O dts -o $@.full.dts -b 0 \ -i $(dir $<) -i $(u_boot_dtsi_loc) $(DTC_FLAGS) $(dtc-tmp) || \ (echo "Check $(shell pwd)/$(pre-tmp) for errors" && false); \ + sed -i '/\ = <0x[0-9a-f]\+>;/ d' $@.clean.dts; \ + sed -i '/\ = <0x[0-9a-f]\+>;/ d' $@.full.dts; \ (diff -Naru $@.clean.dts $@.full.dts > $@.diff || true) dtn-tmp = $(subst $(comma),_,$(dot-target).dtn.tmp) From 3e91c6a36a14b38d066186e68f43c6ffe650c3c3 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 4 Mar 2026 11:34:36 -0600 Subject: [PATCH 67/80] Revert "kbuild: unexport sub_make_done to fix child make invocations" This unfortunately introduces failure to build in other cases: $ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- O=build \ microchip_mpfs_generic_defconfig GEN Makefile # # configuration written to .config # $ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- O=build HOSTCC scripts/basic/fixdep GEN Makefile HOSTCC scripts/kconfig/conf.o YACC scripts/kconfig/zconf.tab.[ch] LEX scripts/kconfig/zconf.lex.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --syncconfig Kconfig *** *** Configuration file ".config" not found! *** *** Please run some configurator (e.g. "make oldconfig" or *** "make menuconfig" or "make xconfig"). *** make[4]: *** [/stuff/u-boot/scripts/kconfig/Makefile:75: syncconfig] Error 1 make[3]: *** [/stuff/u-boot/Makefile:702: syncconfig] Error 2 make[2]: *** [../Makefile:189: __sub-make] Error 2 make[1]: *** No rule to make target 'include/config/auto.conf', needed by 'include/config/uboot.release'. Stop. make: *** [Makefile:189: __sub-make] Error 2 This reverts commit 4284306d22c5b6d64ecd62b462551d9d313c8104. Reported-by: Conor Dooley Signed-off-by: Tom Rini --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index fdaba4895fe..5df869213b6 100644 --- a/Makefile +++ b/Makefile @@ -194,10 +194,6 @@ endif # sub_make_done # We process the rest of the Makefile if this is the final invocation of make ifeq ($(need-sub-make),) -# Do not propagate sub_make_done to non-submake children (e.g. test scripts -# that invoke make separately with O= need to process the KBUILD_OUTPUT block) -unexport sub_make_done - # Do not print "Entering directory ...", # but we want to display it when entering to the output directory # so that IDEs/editors are able to understand relative filenames. @@ -2741,6 +2737,10 @@ help: @echo 'Execute "make" or "make all" to build all targets marked with [*] ' @echo 'For further info see the ./README file' +ifneq ($(filter tests pcheck qcheck tcheck,$(MAKECMDGOALS)),) +export sub_make_done := 0 +endif + tests check: $(srctree)/test/run From 35d9b9c70ea4998aebc723273dca123dd1c3953f Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 27 Feb 2026 01:50:46 +0000 Subject: [PATCH 68/80] tools/atmelimage: add const qualifier to fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More strict checks in GCC 15 expose a new warning: tools/atmelimage.c: In function ‘atmel_find_pmecc_parameter_in_token’: tools/atmelimage.c:64:31: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 64 | param = strstr(token, "="); | ^ cc1: all warnings being treated as errors Add 'const' qualifier to variable 'param' to prevent build failing due to -Werror. Signed-off-by: Daniel Golle --- tools/atmelimage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/atmelimage.c b/tools/atmelimage.c index 6a2d9d8feab..770f7a0de4e 100644 --- a/tools/atmelimage.c +++ b/tools/atmelimage.c @@ -55,7 +55,7 @@ static const char * const configs[] = { static int atmel_find_pmecc_parameter_in_token(const char *token) { size_t pos; - char *param; + const char *param; debug("token: '%s'\n", token); From bdc5f6531a40cc54c0e017843fd09d15e3e5aa07 Mon Sep 17 00:00:00 2001 From: Philip Molloy Date: Thu, 26 Feb 2026 11:11:46 +0000 Subject: [PATCH 69/80] MAINTAINERS: Update ARM SC5xx After years of developing the ADI ADSP platform, Timesys was purchased by another company and is no longer contracted to maintain the platform. Utsav is leaving ADI after contributing to ADSP SoCs for the last 3 years. He is a founding member of the in-house team supporting the chips. Linux support at ADI has been consolidated. Use the company-wide mailing list and git repository. Signed-off-by: Philip Molloy Reviewed-by: Greg Malysa --- MAINTAINERS | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f8d4f6ee8b2..920da147e6c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -626,15 +626,12 @@ S: Supported F: arch/arm/dts/am335x-sancloud* ARM SC5XX -M: Nathan Barrett-Morrison M: Greg Malysa -M: Ian Roberts M: Vasileios Bimpikas -M: Utsav Agarwal M: Arturs Artamonovs -L: adsp-linux@analog.com +L: linux@analog.com S: Supported -T: git https://github.com/analogdevicesinc/lnxdsp-u-boot +T: git https://github.com/analogdevicesinc/u-boot F: arch/arm/dts/sc5* F: arch/arm/include/asm/arch-adi/ F: arch/arm/mach-sc5xx/ From 15e2bacc308d1ea2f50c53f8116fd15ba6c4af6e Mon Sep 17 00:00:00 2001 From: Philip Molloy Date: Thu, 26 Feb 2026 11:11:50 +0000 Subject: [PATCH 70/80] treewide: Remove Timesys from ADI ADSP maintenance After years of developing the ADI ADSP platform, Timesys was purchased by another company and is no longer contracted to maintain the platform. Signed-off-by: Philip Molloy Reviewed-by: Greg Malysa --- arch/arm/include/asm/arch-adi/sc5xx/sc5xx.h | 4 +--- arch/arm/include/asm/arch-adi/sc5xx/soc.h | 4 +--- arch/arm/include/asm/arch-adi/sc5xx/spl.h | 4 +--- arch/arm/mach-sc5xx/Kconfig | 5 +---- arch/arm/mach-sc5xx/Makefile | 5 +---- arch/arm/mach-sc5xx/config.mk | 5 +---- arch/arm/mach-sc5xx/init/Makefile | 5 +---- arch/arm/mach-sc5xx/init/clkinit.c | 4 +--- arch/arm/mach-sc5xx/init/clkinit.h | 4 +--- arch/arm/mach-sc5xx/init/dmcinit.c | 4 +--- arch/arm/mach-sc5xx/init/dmcinit.h | 4 +--- arch/arm/mach-sc5xx/init/mem/is43tr16512bl.h | 4 +--- arch/arm/mach-sc5xx/init/mem/mt41k128m16jt.h | 4 +--- arch/arm/mach-sc5xx/init/mem/mt41k512m16ha.h | 4 +--- arch/arm/mach-sc5xx/init/mem/mt47h128m16rt.h | 4 +--- arch/arm/mach-sc5xx/rcu.c | 3 +-- arch/arm/mach-sc5xx/sc57x.c | 4 +--- arch/arm/mach-sc5xx/sc58x.c | 4 +--- arch/arm/mach-sc5xx/sc59x.c | 4 +--- arch/arm/mach-sc5xx/sc59x_64.c | 4 +--- arch/arm/mach-sc5xx/soc.c | 4 +--- arch/arm/mach-sc5xx/spl.c | 4 +--- drivers/clk/adi/Kconfig | 5 +---- drivers/clk/adi/Makefile | 5 +---- drivers/clk/adi/clk-adi-pll.c | 2 +- drivers/clk/adi/clk-adi-sc57x.c | 2 +- drivers/clk/adi/clk-adi-sc58x.c | 2 +- drivers/clk/adi/clk-adi-sc594.c | 2 +- drivers/clk/adi/clk-adi-sc598.c | 2 +- drivers/clk/adi/clk-shared.c | 2 +- drivers/clk/adi/clk.h | 2 +- drivers/dma/adi_dma.c | 5 +---- drivers/gpio/adp5588_gpio.c | 4 +--- drivers/gpio/gpio-adi-adsp.c | 3 +-- drivers/i2c/adi_i2c.c | 4 +--- drivers/mmc/adi_sdhci.c | 4 +--- drivers/net/dwc_eth_qos_adi.c | 3 +-- drivers/pinctrl/pinctrl-adi-adsp.c | 3 +-- drivers/remoteproc/adi_sc5xx_rproc.c | 4 +--- drivers/serial/serial_adi_uart4.c | 4 +--- drivers/spi/adi_spi3.c | 6 +----- drivers/timer/adi_sc5xx_timer.c | 3 +-- drivers/usb/musb-new/sc5xx.c | 2 +- drivers/watchdog/adi_wdt.c | 4 +--- include/dt-bindings/clock/adi-sc5xx-clock.h | 4 +--- include/dt-bindings/pinctrl/adi-adsp.h | 4 +--- 46 files changed, 46 insertions(+), 126 deletions(-) diff --git a/arch/arm/include/asm/arch-adi/sc5xx/sc5xx.h b/arch/arm/include/asm/arch-adi/sc5xx/sc5xx.h index 683e3d412ce..c80de67d7ae 100644 --- a/arch/arm/include/asm/arch-adi/sc5xx/sc5xx.h +++ b/arch/arm/include/asm/arch-adi/sc5xx/sc5xx.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef ARCH_ADI_SC5XX_SC5XX_H #define ARCH_ADI_SC5XX_SC5XX_H diff --git a/arch/arm/include/asm/arch-adi/sc5xx/soc.h b/arch/arm/include/asm/arch-adi/sc5xx/soc.h index 430dbe2dae4..065d272acab 100644 --- a/arch/arm/include/asm/arch-adi/sc5xx/soc.h +++ b/arch/arm/include/asm/arch-adi/sc5xx/soc.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef BOARD_ADI_COMMON_SOC_H diff --git a/arch/arm/include/asm/arch-adi/sc5xx/spl.h b/arch/arm/include/asm/arch-adi/sc5xx/spl.h index c215e6b892a..077667daa10 100644 --- a/arch/arm/include/asm/arch-adi/sc5xx/spl.h +++ b/arch/arm/include/asm/arch-adi/sc5xx/spl.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef ARCH_ADI_SC5XX_SPL_H #define ARCH_ADI_SC5XX_SPL_H diff --git a/arch/arm/mach-sc5xx/Kconfig b/arch/arm/mach-sc5xx/Kconfig index ec1d5539dc9..1486656b36b 100644 --- a/arch/arm/mach-sc5xx/Kconfig +++ b/arch/arm/mach-sc5xx/Kconfig @@ -2,10 +2,7 @@ # # (C) Copyright 2022 - Analog Devices, Inc. # -# Written and/or maintained by Timesys Corporation -# -# Contact: Nathan Barrett-Morrison -# Contact: Greg Malysa +# Written by Timesys Corporation # # All 32-bit platforms require SYS_ARM_CACHE_WRITETHROUGH diff --git a/arch/arm/mach-sc5xx/Makefile b/arch/arm/mach-sc5xx/Makefile index 47b28200a03..4aaf94f6b9f 100644 --- a/arch/arm/mach-sc5xx/Makefile +++ b/arch/arm/mach-sc5xx/Makefile @@ -2,10 +2,7 @@ # # (C) Copyright 2022 - Analog Devices, Inc. # -# Written and/or maintained by Timesys Corporation -# -# Contact: Nathan Barrett-Morrison -# Contact: Greg Malysa +# Written by Timesys Corporation # obj-y += soc.o init/ diff --git a/arch/arm/mach-sc5xx/config.mk b/arch/arm/mach-sc5xx/config.mk index b4eb1c42810..85889f54e89 100644 --- a/arch/arm/mach-sc5xx/config.mk +++ b/arch/arm/mach-sc5xx/config.mk @@ -2,10 +2,7 @@ # # (C) Copyright 2022 - Analog Devices, Inc. # -# Written and/or maintained by Timesys Corporation -# -# Contact: Nathan Barrett-Morrison -# Contact: Greg Malysa +# Written by Timesys Corporation # ifdef CONFIG_XPL_BUILD diff --git a/arch/arm/mach-sc5xx/init/Makefile b/arch/arm/mach-sc5xx/init/Makefile index 9d4920fe076..6f99bdaeb72 100644 --- a/arch/arm/mach-sc5xx/init/Makefile +++ b/arch/arm/mach-sc5xx/init/Makefile @@ -2,10 +2,7 @@ # # (C) Copyright 2022 - Analog Devices, Inc. # -# Written and/or maintained by Timesys Corporation -# -# Contact: Nathan Barrett-Morrison -# Contact: Greg Malysa +# Written by Timesys Corporation # obj-y += dmcinit.o clkinit.o diff --git a/arch/arm/mach-sc5xx/init/clkinit.c b/arch/arm/mach-sc5xx/init/clkinit.c index ae53cd61efd..3dcba33bd1b 100644 --- a/arch/arm/mach-sc5xx/init/clkinit.c +++ b/arch/arm/mach-sc5xx/init/clkinit.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/init/clkinit.h b/arch/arm/mach-sc5xx/init/clkinit.h index b05f4325bfc..035a766d266 100644 --- a/arch/arm/mach-sc5xx/init/clkinit.h +++ b/arch/arm/mach-sc5xx/init/clkinit.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef CLKINIT_H_ diff --git a/arch/arm/mach-sc5xx/init/dmcinit.c b/arch/arm/mach-sc5xx/init/dmcinit.c index 30b77aee459..2bf2cc53a9f 100644 --- a/arch/arm/mach-sc5xx/init/dmcinit.c +++ b/arch/arm/mach-sc5xx/init/dmcinit.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/init/dmcinit.h b/arch/arm/mach-sc5xx/init/dmcinit.h index 46ff729282d..6ddabdbf325 100644 --- a/arch/arm/mach-sc5xx/init/dmcinit.h +++ b/arch/arm/mach-sc5xx/init/dmcinit.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef DMCINIT_H_ diff --git a/arch/arm/mach-sc5xx/init/mem/is43tr16512bl.h b/arch/arm/mach-sc5xx/init/mem/is43tr16512bl.h index a5838370555..0cb1184c236 100644 --- a/arch/arm/mach-sc5xx/init/mem/is43tr16512bl.h +++ b/arch/arm/mach-sc5xx/init/mem/is43tr16512bl.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef IS43TR16512BL_H diff --git a/arch/arm/mach-sc5xx/init/mem/mt41k128m16jt.h b/arch/arm/mach-sc5xx/init/mem/mt41k128m16jt.h index 882777521b8..7c1381e5a18 100644 --- a/arch/arm/mach-sc5xx/init/mem/mt41k128m16jt.h +++ b/arch/arm/mach-sc5xx/init/mem/mt41k128m16jt.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef MT41K128M16JT_H diff --git a/arch/arm/mach-sc5xx/init/mem/mt41k512m16ha.h b/arch/arm/mach-sc5xx/init/mem/mt41k512m16ha.h index 5735b87871c..21e3f44ccb5 100644 --- a/arch/arm/mach-sc5xx/init/mem/mt41k512m16ha.h +++ b/arch/arm/mach-sc5xx/init/mem/mt41k512m16ha.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef MT41K512M16HA_H diff --git a/arch/arm/mach-sc5xx/init/mem/mt47h128m16rt.h b/arch/arm/mach-sc5xx/init/mem/mt47h128m16rt.h index 5ada7f2985b..b0d012818cf 100644 --- a/arch/arm/mach-sc5xx/init/mem/mt47h128m16rt.h +++ b/arch/arm/mach-sc5xx/init/mem/mt47h128m16rt.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #ifndef MT47H128M16RT_H diff --git a/arch/arm/mach-sc5xx/rcu.c b/arch/arm/mach-sc5xx/rcu.c index 49357501a93..c9911be91d6 100644 --- a/arch/arm/mach-sc5xx/rcu.c +++ b/arch/arm/mach-sc5xx/rcu.c @@ -2,9 +2,8 @@ /* * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Ian Roberts */ #include diff --git a/arch/arm/mach-sc5xx/sc57x.c b/arch/arm/mach-sc5xx/sc57x.c index b0587686d73..02b04cd1b2f 100644 --- a/arch/arm/mach-sc5xx/sc57x.c +++ b/arch/arm/mach-sc5xx/sc57x.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/sc58x.c b/arch/arm/mach-sc5xx/sc58x.c index 0f892774309..c981cafd986 100644 --- a/arch/arm/mach-sc5xx/sc58x.c +++ b/arch/arm/mach-sc5xx/sc58x.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/sc59x.c b/arch/arm/mach-sc5xx/sc59x.c index 174c6f5c445..675f8c7d69a 100644 --- a/arch/arm/mach-sc5xx/sc59x.c +++ b/arch/arm/mach-sc5xx/sc59x.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/sc59x_64.c b/arch/arm/mach-sc5xx/sc59x_64.c index 001747f223d..a8402075d0a 100644 --- a/arch/arm/mach-sc5xx/sc59x_64.c +++ b/arch/arm/mach-sc5xx/sc59x_64.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/soc.c b/arch/arm/mach-sc5xx/soc.c index 8f13127a660..cf8ff0dc3af 100644 --- a/arch/arm/mach-sc5xx/soc.c +++ b/arch/arm/mach-sc5xx/soc.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/arch/arm/mach-sc5xx/spl.c b/arch/arm/mach-sc5xx/spl.c index 68e0310f5af..c529829420d 100644 --- a/arch/arm/mach-sc5xx/spl.c +++ b/arch/arm/mach-sc5xx/spl.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/drivers/clk/adi/Kconfig b/drivers/clk/adi/Kconfig index 5745bedf88c..94cf744305f 100644 --- a/drivers/clk/adi/Kconfig +++ b/drivers/clk/adi/Kconfig @@ -2,10 +2,7 @@ # # (C) Copyright 2022 - Analog Devices, Inc. # -# Written and/or maintained by Timesys Corporation -# -# Contact: Nathan Barrett-Morrison -# Contact: Greg Malysa +# Written by Timesys Corporation # config COMMON_CLK_ADI_SHARED diff --git a/drivers/clk/adi/Makefile b/drivers/clk/adi/Makefile index f3f1fd92e5f..b7664fe1da0 100644 --- a/drivers/clk/adi/Makefile +++ b/drivers/clk/adi/Makefile @@ -2,10 +2,7 @@ # # (C) Copyright 2022 - Analog Devices, Inc. # -# Written and/or maintained by Timesys Corporation -# -# Contact: Nathan Barrett-Morrison -# Contact: Greg Malysa +# Written by Timesys Corporation # obj-$(CONFIG_COMMON_CLK_ADI_SHARED) += clk-shared.o clk-adi-pll.o diff --git a/drivers/clk/adi/clk-adi-pll.c b/drivers/clk/adi/clk-adi-pll.c index 372baa9c11b..34818cb1af0 100644 --- a/drivers/clk/adi/clk-adi-pll.c +++ b/drivers/clk/adi/clk-adi-pll.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa * diff --git a/drivers/clk/adi/clk-adi-sc57x.c b/drivers/clk/adi/clk-adi-sc57x.c index b17563f0444..3eeb3109bd6 100644 --- a/drivers/clk/adi/clk-adi-sc57x.c +++ b/drivers/clk/adi/clk-adi-sc57x.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa * diff --git a/drivers/clk/adi/clk-adi-sc58x.c b/drivers/clk/adi/clk-adi-sc58x.c index 05a0feddec7..776e4748c42 100644 --- a/drivers/clk/adi/clk-adi-sc58x.c +++ b/drivers/clk/adi/clk-adi-sc58x.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa * diff --git a/drivers/clk/adi/clk-adi-sc594.c b/drivers/clk/adi/clk-adi-sc594.c index c80bbf9728d..6749c6d0382 100644 --- a/drivers/clk/adi/clk-adi-sc594.c +++ b/drivers/clk/adi/clk-adi-sc594.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa * diff --git a/drivers/clk/adi/clk-adi-sc598.c b/drivers/clk/adi/clk-adi-sc598.c index d4a16ac9603..05176f2fa85 100644 --- a/drivers/clk/adi/clk-adi-sc598.c +++ b/drivers/clk/adi/clk-adi-sc598.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa * diff --git a/drivers/clk/adi/clk-shared.c b/drivers/clk/adi/clk-shared.c index dcadcafa9d2..afd5f46c845 100644 --- a/drivers/clk/adi/clk-shared.c +++ b/drivers/clk/adi/clk-shared.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa */ diff --git a/drivers/clk/adi/clk.h b/drivers/clk/adi/clk.h index f230205c311..acd4e384746 100644 --- a/drivers/clk/adi/clk.h +++ b/drivers/clk/adi/clk.h @@ -2,7 +2,7 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa * diff --git a/drivers/dma/adi_dma.c b/drivers/dma/adi_dma.c index 28afe488db0..9244ba22068 100644 --- a/drivers/dma/adi_dma.c +++ b/drivers/dma/adi_dma.c @@ -4,11 +4,8 @@ * * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa - * Contact: Ian Roberts * */ #include diff --git a/drivers/gpio/adp5588_gpio.c b/drivers/gpio/adp5588_gpio.c index 36304e48893..a5b2ccfea17 100644 --- a/drivers/gpio/adp5588_gpio.c +++ b/drivers/gpio/adp5588_gpio.c @@ -5,10 +5,8 @@ * * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * * Based on Michael Hennerich's Linux driver: * Michael Hennerich diff --git a/drivers/gpio/gpio-adi-adsp.c b/drivers/gpio/gpio-adi-adsp.c index 0ce00572e08..af54354fa76 100644 --- a/drivers/gpio/gpio-adi-adsp.c +++ b/drivers/gpio/gpio-adi-adsp.c @@ -2,10 +2,9 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa - * Additional Contact: Nathan Barrett-Morrison */ #include diff --git a/drivers/i2c/adi_i2c.c b/drivers/i2c/adi_i2c.c index 4cddcfa6b7f..c80a1517b5f 100644 --- a/drivers/i2c/adi_i2c.c +++ b/drivers/i2c/adi_i2c.c @@ -2,12 +2,10 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Converted to driver model by Nathan Barrett-Morrison * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa */ #include diff --git a/drivers/mmc/adi_sdhci.c b/drivers/mmc/adi_sdhci.c index f58897b5218..2bcd16ec3ba 100644 --- a/drivers/mmc/adi_sdhci.c +++ b/drivers/mmc/adi_sdhci.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * * Based on Rockchip's sdhci.c file */ diff --git a/drivers/net/dwc_eth_qos_adi.c b/drivers/net/dwc_eth_qos_adi.c index fee50a88156..b578225eaad 100644 --- a/drivers/net/dwc_eth_qos_adi.c +++ b/drivers/net/dwc_eth_qos_adi.c @@ -2,10 +2,9 @@ /** * (C) Copyright 2024 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa - * Additional Contact: Nathan Barrett-Morrison */ #include diff --git a/drivers/pinctrl/pinctrl-adi-adsp.c b/drivers/pinctrl/pinctrl-adi-adsp.c index debf434212d..e39f88c8b26 100644 --- a/drivers/pinctrl/pinctrl-adi-adsp.c +++ b/drivers/pinctrl/pinctrl-adi-adsp.c @@ -2,10 +2,9 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Author: Greg Malysa - * Additional Contact: Nathan Barrett-Morrison * * dm pinctrl implementation for ADI ADSP SoCs * diff --git a/drivers/remoteproc/adi_sc5xx_rproc.c b/drivers/remoteproc/adi_sc5xx_rproc.c index 86acd1b98c7..b96603263a5 100644 --- a/drivers/remoteproc/adi_sc5xx_rproc.c +++ b/drivers/remoteproc/adi_sc5xx_rproc.c @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * * Analog Devices SC5xx remoteproc driver for loading code onto SHARC cores */ diff --git a/drivers/serial/serial_adi_uart4.c b/drivers/serial/serial_adi_uart4.c index 45f8315d0a0..24b2071d705 100644 --- a/drivers/serial/serial_adi_uart4.c +++ b/drivers/serial/serial_adi_uart4.c @@ -2,12 +2,10 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Converted to driver model by Nathan Barrett-Morrison * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * */ diff --git a/drivers/spi/adi_spi3.c b/drivers/spi/adi_spi3.c index 2125d25561a..bc66dfbfdd6 100644 --- a/drivers/spi/adi_spi3.c +++ b/drivers/spi/adi_spi3.c @@ -2,14 +2,10 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Converted to driver model by Nathan Barrett-Morrison * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa - * Contact: Ian Roberts - * Contact: Piotr Wojtaszczyk * */ diff --git a/drivers/timer/adi_sc5xx_timer.c b/drivers/timer/adi_sc5xx_timer.c index 11c098434a8..d9aef3da11e 100644 --- a/drivers/timer/adi_sc5xx_timer.c +++ b/drivers/timer/adi_sc5xx_timer.c @@ -2,12 +2,11 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Converted to driver model by Nathan Barrett-Morrison * * Author: Greg Malysa - * Additional Contact: Nathan Barrett-Morrison * * dm timer implementation for ADI ADSP-SC5xx SoCs * diff --git a/drivers/usb/musb-new/sc5xx.c b/drivers/usb/musb-new/sc5xx.c index 16201480b43..991846818a2 100644 --- a/drivers/usb/musb-new/sc5xx.c +++ b/drivers/usb/musb-new/sc5xx.c @@ -4,7 +4,7 @@ * * ADI SC5XX MUSB "glue layer" * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Loosely ported from Linux driver: * Author: Nathan Barrett-Morrison diff --git a/drivers/watchdog/adi_wdt.c b/drivers/watchdog/adi_wdt.c index 6f5b3d5d042..7d7cf98b55e 100644 --- a/drivers/watchdog/adi_wdt.c +++ b/drivers/watchdog/adi_wdt.c @@ -2,12 +2,10 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * * Converted to driver model by Nathan Barrett-Morrison * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * * adi_wtd.c - driver for ADI on-chip watchdog * diff --git a/include/dt-bindings/clock/adi-sc5xx-clock.h b/include/dt-bindings/clock/adi-sc5xx-clock.h index 4a5373d1141..94ab225d3b7 100644 --- a/include/dt-bindings/clock/adi-sc5xx-clock.h +++ b/include/dt-bindings/clock/adi-sc5xx-clock.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * */ diff --git a/include/dt-bindings/pinctrl/adi-adsp.h b/include/dt-bindings/pinctrl/adi-adsp.h index 7dc8a1ef5c4..afe68e836e7 100644 --- a/include/dt-bindings/pinctrl/adi-adsp.h +++ b/include/dt-bindings/pinctrl/adi-adsp.h @@ -2,10 +2,8 @@ /* * (C) Copyright 2022 - Analog Devices, Inc. * - * Written and/or maintained by Timesys Corporation + * Written by Timesys Corporation * - * Contact: Nathan Barrett-Morrison - * Contact: Greg Malysa * */ From 0b429f7c6b9de24eb4b8d8ddab74b0020994c405 Mon Sep 17 00:00:00 2001 From: Raphael Gallais-Pou Date: Thu, 5 Feb 2026 00:35:40 +0100 Subject: [PATCH 71/80] video: stm32: dsi: add .of_to_plat callback Drivers should extract device-tree data before probing via the .of_to_plat hook. Implement it for stm32_dsi driver. By doing so, it also solve a variable shadowing in stm32_dsi_probe() where &clk was used as peripheral clock and ref clock. For readability some struct have been renamed such as: * struct stm32_dsi_priv *dsi -> struct stm32_dsi_priv *priv * struct clk clk -> struct clk pclk Signed-off-by: Raphael Gallais-Pou Reviewed-by: Patrick Delaunay --- drivers/video/stm32/stm32_dsi.c | 168 +++++++++++++++++--------------- 1 file changed, 91 insertions(+), 77 deletions(-) diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c index 438ed41e8d5..65a91f5cff7 100644 --- a/drivers/video/stm32/stm32_dsi.c +++ b/drivers/video/stm32/stm32_dsi.c @@ -84,42 +84,48 @@ enum dsi_color { /* Timeout for regulator on/off, pll lock/unlock & fifo empty */ #define TIMEOUT_US 200000 -struct stm32_dsi_priv { +struct stm32_dsi_plat { struct mipi_dsi_device device; void __iomem *base; struct udevice *panel; + struct udevice *vdd_reg; + struct udevice *dsi_host; + struct reset_ctl rst; + struct clk pclk; + struct clk refclk; +}; + +struct stm32_dsi_priv { u32 pllref_clk; u32 hw_version; int lane_min_kbps; int lane_max_kbps; - struct udevice *vdd_reg; - struct udevice *dsi_host; }; -static inline void dsi_write(struct stm32_dsi_priv *dsi, u32 reg, u32 val) +static inline void dsi_write(void __iomem *base, u32 reg, u32 val) { - writel(val, dsi->base + reg); + writel(val, base + reg); } -static inline u32 dsi_read(struct stm32_dsi_priv *dsi, u32 reg) +static inline u32 dsi_read(void __iomem *base, u32 reg) { - return readl(dsi->base + reg); + return readl(base + reg); } -static inline void dsi_set(struct stm32_dsi_priv *dsi, u32 reg, u32 mask) +static inline void dsi_set(void __iomem *base, u32 reg, u32 mask) { - dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); + dsi_write(base, reg, dsi_read(base, reg) | mask); } -static inline void dsi_clear(struct stm32_dsi_priv *dsi, u32 reg, u32 mask) +static inline void dsi_clear(void __iomem *base, u32 reg, u32 mask) { - dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); + dsi_write(base, reg, dsi_read(base, reg) & ~mask); } -static inline void dsi_update_bits(struct stm32_dsi_priv *dsi, u32 reg, +static inline void dsi_update_bits(void __iomem *base, u32 reg, u32 mask, u32 val) { - dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); + dsi_write(base, reg, (dsi_read(base, reg) & ~mask) | val); } static enum dsi_color dsi_color_from_mipi(u32 fmt) @@ -210,14 +216,14 @@ static int dsi_phy_init(void *priv_data) { struct mipi_dsi_device *device = priv_data; struct udevice *dev = device->dev; - struct stm32_dsi_priv *dsi = dev_get_priv(dev); + struct stm32_dsi_plat *dsi = dev_get_plat(dev); u32 val; int ret; dev_dbg(dev, "Initialize DSI physical layer\n"); /* Enable the regulator */ - dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); + dsi_set(dsi->base, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS, TIMEOUT_US); if (ret) { @@ -226,7 +232,7 @@ static int dsi_phy_init(void *priv_data) } /* Enable the DSI PLL & wait for its lock */ - dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN); + dsi_set(dsi->base, DSI_WRPCR, WRPCR_PLLEN); ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS, TIMEOUT_US); if (ret) { @@ -241,7 +247,7 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) { struct mipi_dsi_device *device = priv_data; struct udevice *dev = device->dev; - struct stm32_dsi_priv *dsi = dev_get_priv(dev); + struct stm32_dsi_plat *dsi = dev_get_plat(dev); dev_dbg(dev, "Set mode %p enable %ld\n", dsi, mode_flags & MIPI_DSI_MODE_VIDEO); @@ -256,9 +262,9 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) */ if (mode_flags & MIPI_DSI_MODE_VIDEO) - dsi_set(dsi, DSI_WCR, WCR_DSIEN); + dsi_set(dsi->base, DSI_WCR, WCR_DSIEN); else - dsi_clear(dsi, DSI_WCR, WCR_DSIEN); + dsi_clear(dsi->base, DSI_WCR, WCR_DSIEN); } static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, @@ -266,32 +272,33 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, { struct mipi_dsi_device *device = priv_data; struct udevice *dev = device->dev; - struct stm32_dsi_priv *dsi = dev_get_priv(dev); + struct stm32_dsi_plat *plat = dev_get_plat(dev); + struct stm32_dsi_priv *priv = dev_get_priv(dev); int idf, ndiv, odf, pll_in_khz, pll_out_khz; int ret, bpp; u32 val; /* Update lane capabilities according to hw version */ - dsi->lane_min_kbps = LANE_MIN_KBPS; - dsi->lane_max_kbps = LANE_MAX_KBPS; - if (dsi->hw_version == HWVER_131) { - dsi->lane_min_kbps *= 2; - dsi->lane_max_kbps *= 2; + priv->lane_min_kbps = LANE_MIN_KBPS; + priv->lane_max_kbps = LANE_MAX_KBPS; + if (priv->hw_version == HWVER_131) { + priv->lane_min_kbps *= 2; + priv->lane_max_kbps *= 2; } - pll_in_khz = dsi->pllref_clk / 1000; + pll_in_khz = priv->pllref_clk / 1000; /* Compute requested pll out */ bpp = mipi_dsi_pixel_format_to_bpp(format); pll_out_khz = (timings->pixelclock.typ / 1000) * bpp / lanes; /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ pll_out_khz = (pll_out_khz * 12) / 10; - if (pll_out_khz > dsi->lane_max_kbps) { - pll_out_khz = dsi->lane_max_kbps; + if (pll_out_khz > priv->lane_max_kbps) { + pll_out_khz = priv->lane_max_kbps; dev_warn(dev, "Warning max phy mbps is used\n"); } - if (pll_out_khz < dsi->lane_min_kbps) { - pll_out_khz = dsi->lane_min_kbps; + if (pll_out_khz < priv->lane_min_kbps) { + pll_out_khz = priv->lane_min_kbps; dev_warn(dev, "Warning min phy mbps is used\n"); } @@ -299,7 +306,7 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, idf = 0; ndiv = 0; odf = 0; - ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, + ret = dsi_pll_get_params(priv, pll_in_khz, pll_out_khz, &idf, &ndiv, &odf); if (ret) { dev_err(dev, "Warning dsi_pll_get_params(): bad params\n"); @@ -310,18 +317,18 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); /* Set the PLL division factors */ - dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, + dsi_update_bits(plat->base, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16)); /* Compute uix4 & set the bit period in high-speed mode */ val = 4000000 / pll_out_khz; - dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val); + dsi_update_bits(plat->base, DSI_WPCR0, WPCR0_UIX4, val); /* Select video mode by resetting DSIM bit */ - dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM); + dsi_clear(plat->base, DSI_WCFGR, WCFGR_DSIM); /* Select the color coding */ - dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX, + dsi_update_bits(plat->base, DSI_WCFGR, WCFGR_COLMUX, dsi_color_from_mipi(format) << 1); *lane_mbps = pll_out_khz / 1000; @@ -340,27 +347,27 @@ static const struct mipi_dsi_phy_ops dsi_stm_phy_ops = { static int stm32_dsi_attach(struct udevice *dev) { - struct stm32_dsi_priv *priv = dev_get_priv(dev); - struct mipi_dsi_device *device = &priv->device; + struct stm32_dsi_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *device = &plat->device; struct mipi_dsi_panel_plat *mplat; struct display_timing timings; int ret; - ret = uclass_first_device_err(UCLASS_PANEL, &priv->panel); + ret = uclass_first_device_err(UCLASS_PANEL, &plat->panel); if (ret) { dev_err(dev, "panel device error %d\n", ret); return ret; } - mplat = dev_get_plat(priv->panel); - mplat->device = &priv->device; + mplat = dev_get_plat(plat->panel); + mplat->device = &plat->device; device->lanes = mplat->lanes; device->format = mplat->format; device->mode_flags = mplat->mode_flags; - ret = panel_get_display_timing(priv->panel, &timings); + ret = panel_get_display_timing(plat->panel, &timings); if (ret) { - ret = ofnode_decode_display_timing(dev_ofnode(priv->panel), + ret = ofnode_decode_display_timing(dev_ofnode(plat->panel), 0, &timings); if (ret) { dev_err(dev, "decode display timing error %d\n", ret); @@ -368,13 +375,13 @@ static int stm32_dsi_attach(struct udevice *dev) } } - ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host); + ret = uclass_get_device(UCLASS_DSI_HOST, 0, &plat->dsi_host); if (ret) { dev_err(dev, "No video dsi host detected %d\n", ret); return ret; } - ret = dsi_host_init(priv->dsi_host, device, &timings, 2, + ret = dsi_host_init(plat->dsi_host, device, &timings, 2, &dsi_stm_phy_ops); if (ret) { dev_err(dev, "failed to initialize mipi dsi host\n"); @@ -386,17 +393,17 @@ static int stm32_dsi_attach(struct udevice *dev) static int stm32_dsi_set_backlight(struct udevice *dev, int percent) { - struct stm32_dsi_priv *priv = dev_get_priv(dev); + struct stm32_dsi_plat *plat = dev_get_plat(dev); int ret; - ret = panel_enable_backlight(priv->panel); + ret = panel_enable_backlight(plat->panel); if (ret) { dev_err(dev, "panel %s enable backlight error %d\n", - priv->panel->name, ret); + plat->panel->name, ret); return ret; } - ret = dsi_host_enable(priv->dsi_host); + ret = dsi_host_enable(plat->dsi_host); if (ret) { dev_err(dev, "failed to enable mipi dsi host\n"); return ret; @@ -417,66 +424,71 @@ static int stm32_dsi_bind(struct udevice *dev) return dm_scan_fdt_dev(dev); } -static int stm32_dsi_probe(struct udevice *dev) +static int stm32_dsi_of_to_plat(struct udevice *dev) { - struct stm32_dsi_priv *priv = dev_get_priv(dev); - struct mipi_dsi_device *device = &priv->device; - struct reset_ctl rst; - struct clk clk; + struct stm32_dsi_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *device = &plat->device; int ret; device->dev = dev; - priv->base = dev_read_addr_ptr(dev); - if (!priv->base) { + plat->base = dev_read_addr_ptr(dev); + if (!plat->base) { dev_err(dev, "dsi dt register address error\n"); return -EINVAL; } ret = device_get_supply_regulator(dev, "phy-dsi-supply", - &priv->vdd_reg); + &plat->vdd_reg); if (ret && ret != -ENOENT) { dev_err(dev, "Warning: cannot get phy dsi supply\n"); return -ENODEV; } if (ret != -ENOENT) { - ret = regulator_set_enable(priv->vdd_reg, true); + ret = regulator_set_enable(plat->vdd_reg, true); if (ret) return ret; } - ret = clk_get_by_name(device->dev, "pclk", &clk); + ret = clk_get_by_name(device->dev, "pclk", &plat->pclk); if (ret) { dev_err(dev, "peripheral clock get error %d\n", ret); - goto err_reg; + return ret; } - ret = clk_enable(&clk); + ret = clk_get_by_name(dev, "ref", &plat->refclk); + if (ret) { + dev_err(dev, "pll reference clock get error %d\n", ret); + return ret; + } + + ret = reset_get_by_index(device->dev, 0, &plat->rst); + if (ret) + dev_err(dev, "missing dsi hardware reset\n"); + + return ret; +} + +static int stm32_dsi_probe(struct udevice *dev) +{ + struct stm32_dsi_plat *plat = dev_get_plat(dev); + struct stm32_dsi_priv *priv = dev_get_priv(dev); + int ret; + + ret = clk_enable(&plat->pclk); if (ret) { dev_err(dev, "peripheral clock enable error %d\n", ret); goto err_reg; } - ret = clk_get_by_name(dev, "ref", &clk); - if (ret) { - dev_err(dev, "pll reference clock get error %d\n", ret); - goto err_clk; - } - - priv->pllref_clk = (unsigned int)clk_get_rate(&clk); - - ret = reset_get_by_index(device->dev, 0, &rst); - if (ret) { - dev_err(dev, "missing dsi hardware reset\n"); - goto err_clk; - } + priv->pllref_clk = (unsigned int)clk_get_rate(&plat->refclk); /* Reset */ - reset_deassert(&rst); + reset_deassert(&plat->rst); /* check hardware version */ - priv->hw_version = dsi_read(priv, DSI_VERSION) & VERSION; + priv->hw_version = dsi_read(plat->base, DSI_VERSION) & VERSION; if (priv->hw_version != HWVER_130 && priv->hw_version != HWVER_131) { dev_err(dev, "DSI version 0x%x not supported\n", priv->hw_version); @@ -489,9 +501,9 @@ static int stm32_dsi_probe(struct udevice *dev) return 0; err_clk: - clk_disable(&clk); + clk_disable(&plat->pclk); err_reg: - regulator_set_enable(priv->vdd_reg, false); + regulator_set_enable(plat->vdd_reg, false); return ret; } @@ -512,6 +524,8 @@ U_BOOT_DRIVER(stm32_dsi) = { .of_match = stm32_dsi_ids, .bind = stm32_dsi_bind, .probe = stm32_dsi_probe, + .of_to_plat = stm32_dsi_of_to_plat, .ops = &stm32_dsi_ops, + .plat_auto = sizeof(struct stm32_dsi_plat), .priv_auto = sizeof(struct stm32_dsi_priv), }; From 8ee2e262d13eca993a1ee553d802bdaf765296be Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Mon, 9 Mar 2026 10:12:51 +0900 Subject: [PATCH 72/80] MAINTAINERS: update SPI NOR reviewer Tudor Ambarus will step down as SPI NOR reviewer. I would like to take this role. Signed-off-by: Takahiro Kuwano Acked-by: Tudor Ambarus --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 920da147e6c..d2040fee252 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1754,7 +1754,7 @@ F: drivers/mtd/nand/spi/ SPI-NOR M: Vignesh R -R: Tudor Ambarus +R: Takahiro Kuwano S: Maintained F: drivers/mtd/spi/ F: include/spi_flash.h From d62f1c98c5e78f4092510992f8174c284e3d1778 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 27 Feb 2026 17:28:29 +0530 Subject: [PATCH 73/80] arm: mach-k3: arm64-mmu: add mapping for PCIe 4 GB Address Windows The PCIe Controllers in the K3 SoCs have 4 GB Address Windows in the 64-bit address space to map System (CPU) Addresses to PCIe Bus Addresses. The physical addresses for these Address Windows across PCIe instances across SoCs is as follows: +--------+----------------+----------------+----------------+----------------+ | SoC | PCIe0 | PCIe1 | PCIe2 | PCIe3 | +--------+----------------+----------------+----------------+----------------+ | AM64 | 0x6_0000_0000 | NA | NA | NA | | J722S | 0x6_0000_0000 | NA | NA | NA | | AM68 | NA | 0x41_0000_0000 | NA | NA | | J7200 | NA | 0x41_0000_0000 | NA | NA | | J721S2 | NA | 0x41_0000_0000 | NA | NA | | J742S2 | 0x40_0000_0000 | 0x41_0000_0000 | NA | NA | | AM69 | 0x40_0000_0000 | 0x41_0000_0000 | 0x42_0000_0000 | 0x43_0000_0000 | | J721E | 0x40_0000_0000 | 0x41_0000_0000 | 0x42_0000_0000 | 0x43_0000_0000 | | J784S4 | 0x40_0000_0000 | 0x41_0000_0000 | 0x42_0000_0000 | 0x43_0000_0000 | +--------+----------------+----------------+----------------+----------------+ Two regions for a 1:1 mapping from virtual addresses to physical addresses catering to all of the above will be required, which are: 1. For AM64 and J722S SoCs => Start: 0x6_0000_0000 Size: 0x1_0000_0000 2. For AM68, AM69, J7200, J721E, J721S2, J742S2 and J784S4 SoCs => Start: 0x40_0000_0000 Size: 0x4_0000_0000 Since the 'Flash Peripherals' region from 0x5_0000_0000 to 0x8_7FFF_FFFF includes the mapping for AM64 and J722S SoCs, only the second region mentioned above needs to be added. Hence, add the region to support 64-bit address space for PCIe. Signed-off-by: Siddharth Vadapalli Fixes: 79f3e77133bd ("Subtree merge tag 'v6.16-dts' of dts repo [1] into dts/upstream") --- arch/arm/mach-k3/arm64/arm64-mmu.c | 16 ++++++++++++++++ arch/arm/mach-k3/include/mach/k3-ddr.h | 11 +++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-k3/arm64/arm64-mmu.c b/arch/arm/mach-k3/arm64/arm64-mmu.c index f999af143fb..e032755db0d 100644 --- a/arch/arm/mach-k3/arm64/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64/arm64-mmu.c @@ -29,6 +29,22 @@ struct mm_region k3_mem_map[K3_MEM_MAP_LEN] = { .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { /* + * PCIe 4 GB Address Window for AM64 and J722S SoCs starts + * from 0x6_0000_0000 and has a size of 0x1_0000_0000. + * Since this is already enabled by the 'Flash Peripherals' + * region above, we don't need to add it again. + * + * The PCIe 4 GB Address Windows for AM68, AM69, J7200, J721E, + * J721S2, J742S2 and J784S4 SoCs are enabled by the following + * region. + */ + .virt = 0x4000000000UL, + .phys = 0x4000000000UL, + .size = 0x400000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN }, [K3_MEM_MAP_FIRST_BANK_IDX] = { /* First DRAM Bank of size 2G */ .virt = CFG_SYS_SDRAM_BASE, .phys = CFG_SYS_SDRAM_BASE, diff --git a/arch/arm/mach-k3/include/mach/k3-ddr.h b/arch/arm/mach-k3/include/mach/k3-ddr.h index 207e60b2763..6ac7f682fb8 100644 --- a/arch/arm/mach-k3/include/mach/k3-ddr.h +++ b/arch/arm/mach-k3/include/mach/k3-ddr.h @@ -8,11 +8,14 @@ #include -/* We need 3 extra entries for: - * SoC peripherals, flash and the sentinel value. +/* We need 4 extra entries for: + * 1. SoC peripherals + * 2. Flash + * 3. PCIe 4GB Windows for AM68, AM69, J7200, J721E, J721S2, J742S2 and J784S4 SoCs + * 4. Sentinel value */ -#define K3_MEM_MAP_LEN ((CONFIG_NR_DRAM_BANKS) + 3) -#define K3_MEM_MAP_FIRST_BANK_IDX 2 +#define K3_MEM_MAP_LEN ((CONFIG_NR_DRAM_BANKS) + 4) +#define K3_MEM_MAP_FIRST_BANK_IDX 3 int dram_init(void); int dram_init_banksize(void); From 068d05ad5f82a58316e895fd1497cf10898b3beb Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 27 Feb 2026 17:28:30 +0530 Subject: [PATCH 74/80] pci: pcie_cdns_ti: enable PCIe root-complex mode for J784S4 SoC The PCIe Controllers on the J784S4 SoC support Root-Complex mode of operation. Hence, enable it. Signed-off-by: Siddharth Vadapalli Fixes: 79f3e77133bd ("Subtree merge tag 'v6.16-dts' of dts repo [1] into dts/upstream") --- drivers/pci/pcie_cdns_ti.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/pcie_cdns_ti.c b/drivers/pci/pcie_cdns_ti.c index 38804f1c09c..63d249c2506 100644 --- a/drivers/pci/pcie_cdns_ti.c +++ b/drivers/pci/pcie_cdns_ti.c @@ -860,6 +860,12 @@ static const struct pcie_cdns_ti_data j722s_pcie_rc_data = { .max_lanes = 1, }; +static const struct pcie_cdns_ti_data j784s4_pcie_rc_data = { + .mode = PCIE_MODE_RC, + .quirk_detect_quiet_flag = true, + .max_lanes = 4, +}; + static const struct udevice_id pcie_cdns_ti_ids[] = { { .compatible = "ti,j7200-pcie-host", @@ -873,6 +879,10 @@ static const struct udevice_id pcie_cdns_ti_ids[] = { .compatible = "ti,j722s-pcie-host", .data = (ulong)&j722s_pcie_rc_data, }, + { + .compatible = "ti,j784s4-pcie-host", + .data = (ulong)&j784s4_pcie_rc_data, + }, {}, }; From 724952ac41c144a8528a273aeed23422b1e2330e Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 27 Feb 2026 17:28:31 +0530 Subject: [PATCH 75/80] configs: {am69_sk, j784s4_evm}_a72_defconfig: enable PCIe Root-Complex mode The PCIe Controllers on the J784S4 and AM69 SoCs support Root-Complex mode of operation. PCIe0 instance of PCIe on both of the SoCs is brought out on the Starter-Kit (AM69) and EVM (J784S4) boards. Hence, enable the configs required for Root-Complex mode of operation. Signed-off-by: Siddharth Vadapalli Fixes: 79f3e77133bd ("Subtree merge tag 'v6.16-dts' of dts repo [1] into dts/upstream") --- configs/j784s4_evm_a72_defconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configs/j784s4_evm_a72_defconfig b/configs/j784s4_evm_a72_defconfig index f440b18c6fc..1d2043aeba0 100644 --- a/configs/j784s4_evm_a72_defconfig +++ b/configs/j784s4_evm_a72_defconfig @@ -28,6 +28,8 @@ CONFIG_SPL_FS_FAT=y CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y +CONFIG_SYS_PCI_64BIT=y +CONFIG_PCI=y CONFIG_EFI_SET_TIME=y CONFIG_BOOTSTD_FULL=y CONFIG_BOOTCOMMAND="run envboot; bootflow scan -lb" @@ -56,6 +58,7 @@ CONFIG_SPL_YMODEM_SUPPORT=y CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_MTD=y +CONFIG_CMD_PCI=y CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_EFIDEBUG=y CONFIG_OF_CONTROL=y @@ -123,6 +126,9 @@ CONFIG_MUX_MMIO=y CONFIG_PHY_TI_DP83867=y CONFIG_PHY_FIXED=y CONFIG_TI_AM65_CPSW_NUSS=y +CONFIG_NVME_PCI=y +CONFIG_PCI_CONFIG_HOST_BRIDGE=y +CONFIG_PCIE_CDNS_TI=y CONFIG_PCI_ENDPOINT=y CONFIG_PCIE_CDNS_TI_EP=y CONFIG_PHY=y From 430874ce20c78c4d2f427dac34860642f044c5fd Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 27 Feb 2026 17:28:32 +0530 Subject: [PATCH 76/80] configs: am64x_evm_a53_defconfig: enable 64-bit addressing for PCIe The PCIe0 instance of PCIe on the AM64x SoC uses the 4 GB Address Window starting from 0x6_0000_0000 to map System Addresses to PCIe Bus Addresses. Hence, enable CONFIG_SYS_PCI_64BIT. Signed-off-by: Siddharth Vadapalli Fixes: 79f3e77133bd ("Subtree merge tag 'v6.16-dts' of dts repo [1] into dts/upstream") --- configs/am64x_evm_a53_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/am64x_evm_a53_defconfig b/configs/am64x_evm_a53_defconfig index e576012b3f6..3a35df830e3 100644 --- a/configs/am64x_evm_a53_defconfig +++ b/configs/am64x_evm_a53_defconfig @@ -31,6 +31,7 @@ CONFIG_SPL_FS_FAT=y CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y +CONFIG_SYS_PCI_64BIT=y CONFIG_PCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_BOOTSTD_FULL=y From b04d709459073c6dc48cafd8eed9d14f552fdaa7 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 27 Feb 2026 17:28:33 +0530 Subject: [PATCH 77/80] configs: j7200_evm_a72_defconfig: enable 64-bit addressing for PCIe The PCIe1 instance of PCIe on the J7200 SoC uses the 4 GB Address Window starting from 0x41_0000_0000 to map System Addresses to PCIe Bus Addresses. Hence, enable CONFIG_SYS_PCI_64BIT. Signed-off-by: Siddharth Vadapalli Fixes: 79f3e77133bd ("Subtree merge tag 'v6.16-dts' of dts repo [1] into dts/upstream") --- configs/j7200_evm_a72_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig index 27a9db72fb5..5c5abd94eb0 100644 --- a/configs/j7200_evm_a72_defconfig +++ b/configs/j7200_evm_a72_defconfig @@ -30,6 +30,7 @@ CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y # CONFIG_PSCI_RESET is not set +CONFIG_SYS_PCI_64BIT=y CONFIG_PCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_BOOTSTD_FULL=y From f0bb3940b132d039a249815d34eea6fae5be60d6 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 27 Feb 2026 17:28:34 +0530 Subject: [PATCH 78/80] configs: j722s_evm_a53_defconfig: enable 64-bit addressing for PCIe The PCIe0 instance of PCIe on the J722S SoC uses the 4 GB Address Window starting from 0x6_0000_0000 to map System Addresses to PCIe Bus Addresses. Hence, enable CONFIG_SYS_PCI_64BIT. Signed-off-by: Siddharth Vadapalli Fixes: 79f3e77133bd ("Subtree merge tag 'v6.16-dts' of dts repo [1] into dts/upstream") --- configs/j722s_evm_a53_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/j722s_evm_a53_defconfig b/configs/j722s_evm_a53_defconfig index e84670c75ed..dc4b6b93803 100644 --- a/configs/j722s_evm_a53_defconfig +++ b/configs/j722s_evm_a53_defconfig @@ -27,6 +27,7 @@ CONFIG_SPL_FS_FAT=y CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y +CONFIG_SYS_PCI_64BIT=y CONFIG_PCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_BOOTSTD_FULL=y From 2092322b31cc8b1f8c9e2e238d1043ae0637b241 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Mar 2026 18:20:09 -0700 Subject: [PATCH 79/80] boot: Add fit_config_get_hash_list() to build signed node list The hashed-nodes property in a FIT signature node lists which FDT paths are included in the signature hash. It is intended as a hint so should not be used for verification. Add a function to build the node list from scratch by iterating the configuration's image references. Skip properties known not to be image references. For each image, collect the path plus all hash and cipher subnodes. Use the new function in fit_config_check_sig() instead of reading 'hashed-nodes'. Update the test_vboot kernel@ test case: fit_check_sign now catches the attack at signature-verification time (the @-suffixed node is hashed instead of the real one, causing a mismatch) rather than at fit_check_format() time. Update the docs to cover this. The FIT spec can be updated separately. Signed-off-by: Simon Glass Closes: https://lore.kernel.org/u-boot/20260302220937.3682128-1-trini@konsulko.com/ Reported-by: Apple Security Engineering and Architecture (SEAR) Tested-by: Tom Rini --- boot/image-fit-sig.c | 227 +++++++++++++++++++++++++++++------- doc/usage/fit/signature.rst | 19 ++- test/py/tests/test_vboot.py | 8 +- 3 files changed, 201 insertions(+), 53 deletions(-) diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c index f23e9d5d0b0..f426ead13c0 100644 --- a/boot/image-fit-sig.c +++ b/boot/image-fit-sig.c @@ -18,6 +18,7 @@ DECLARE_GLOBAL_DATA_PTR; #include #define IMAGE_MAX_HASHED_NODES 100 +#define FIT_MAX_HASH_PATH_BUF 4096 /** * fit_region_make_list() - Make a list of image regions @@ -229,6 +230,179 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, return 0; } +/** + * fit_config_add_hash() - Add hash nodes for one image to the node list + * + * Adds the image path, all its hash-* subnode paths, and its cipher + * subnode path (if present) to the packed buffer. + * + * @fit: FIT blob + * @image_noffset: Image node offset (e.g. /images/kernel-1) + * @node_inc: Array of path pointers to fill + * @count: Pointer to current count (updated on return) + * @max_nodes: Maximum entries in @node_inc + * @buf: Buffer for packed path strings + * @buf_used: Pointer to bytes used in @buf (updated on return) + * @buf_len: Total size of @buf + * Return: 0 on success, -ve on error + */ +static int fit_config_add_hash(const void *fit, int image_noffset, + char **node_inc, int *count, int max_nodes, + char *buf, int *buf_used, int buf_len) +{ + int noffset, hash_count, ret, len; + + if (*count >= max_nodes) + return -ENOSPC; + + ret = fdt_get_path(fit, image_noffset, buf + *buf_used, + buf_len - *buf_used); + if (ret < 0) + return -ENOENT; + len = strlen(buf + *buf_used) + 1; + node_inc[(*count)++] = buf + *buf_used; + *buf_used += len; + + /* Add all this image's hash subnodes */ + hash_count = 0; + for (noffset = fdt_first_subnode(fit, image_noffset); + noffset >= 0; + noffset = fdt_next_subnode(fit, noffset)) { + const char *name = fit_get_name(fit, noffset, NULL); + + if (strncmp(name, FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME))) + continue; + if (*count >= max_nodes) + return -ENOSPC; + ret = fdt_get_path(fit, noffset, buf + *buf_used, + buf_len - *buf_used); + if (ret < 0) + return -ENOENT; + len = strlen(buf + *buf_used) + 1; + node_inc[(*count)++] = buf + *buf_used; + *buf_used += len; + hash_count++; + } + + if (!hash_count) { + printf("No hash nodes in image '%s'\n", + fdt_get_name(fit, image_noffset, NULL)); + return -ENOMSG; + } + + /* Add this image's cipher node if present */ + noffset = fdt_subnode_offset(fit, image_noffset, FIT_CIPHER_NODENAME); + if (noffset != -FDT_ERR_NOTFOUND) { + if (noffset < 0) + return -EIO; + if (*count >= max_nodes) + return -ENOSPC; + ret = fdt_get_path(fit, noffset, buf + *buf_used, + buf_len - *buf_used); + if (ret < 0) + return -ENOENT; + len = strlen(buf + *buf_used) + 1; + node_inc[(*count)++] = buf + *buf_used; + *buf_used += len; + } + + return 0; +} + +/** + * fit_config_get_hash_list() - Build the list of nodes to hash + * + * Works through every image referenced by the configuration and collects the + * node paths: root + config + all referenced images with their hash and + * cipher subnodes. + * + * Properties known not to be image references (description, compatible, + * default, load-only) are skipped, so any new image type is covered by default. + * + * @fit: FIT blob + * @conf_noffset: Configuration node offset + * @node_inc: Array to fill with path string pointers + * @max_nodes: Size of @node_inc array + * @buf: Buffer for packed null-terminated path strings + * @buf_len: Size of @buf + * Return: number of entries in @node_inc, or -ve on error + */ +static int fit_config_get_hash_list(const void *fit, int conf_noffset, + char **node_inc, int max_nodes, + char *buf, int buf_len) +{ + const char *conf_name; + int image_count; + int prop_offset; + int used = 0; + int count = 0; + int ret, len; + + conf_name = fit_get_name(fit, conf_noffset, NULL); + + /* Always include the root node and the configuration node */ + if (max_nodes < 2) + return -ENOSPC; + + len = 2; /* "/" + nul */ + if (len > buf_len) + return -ENOSPC; + strcpy(buf, "/"); + node_inc[count++] = buf; + used += len; + + len = snprintf(buf + used, buf_len - used, "%s/%s", FIT_CONFS_PATH, + conf_name) + 1; + if (used + len > buf_len) + return -ENOSPC; + node_inc[count++] = buf + used; + used += len; + + /* Process each image referenced by the config */ + image_count = 0; + fdt_for_each_property_offset(prop_offset, fit, conf_noffset) { + const char *prop_name; + int img_count, i; + + fdt_getprop_by_offset(fit, prop_offset, &prop_name, NULL); + if (!prop_name) + continue; + + /* Skip properties that are not image references */ + if (!strcmp(prop_name, FIT_DESC_PROP) || + !strcmp(prop_name, FIT_COMPAT_PROP) || + !strcmp(prop_name, FIT_DEFAULT_PROP)) + continue; + + img_count = fdt_stringlist_count(fit, conf_noffset, prop_name); + for (i = 0; i < img_count; i++) { + int noffset; + + noffset = fit_conf_get_prop_node_index(fit, + conf_noffset, + prop_name, i); + if (noffset < 0) + continue; + + ret = fit_config_add_hash(fit, noffset, node_inc, + &count, max_nodes, buf, &used, + buf_len); + if (ret < 0) + return ret; + + image_count++; + } + } + + if (!image_count) { + printf("No images in config '%s'\n", conf_name); + return -ENOMSG; + } + + return count; +} + /** * fit_config_check_sig() - Check the signature of a config * @@ -269,20 +443,16 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, FIT_DATA_POSITION_PROP, FIT_DATA_OFFSET_PROP, }; - - const char *prop, *end, *name; + char *node_inc[IMAGE_MAX_HASHED_NODES]; + char hash_buf[FIT_MAX_HASH_PATH_BUF]; struct image_sign_info info; const uint32_t *strings; - const char *config_name; uint8_t *fit_value; int fit_value_len; - bool found_config; int max_regions; - int i, prop_len; char path[200]; int count; - config_name = fit_get_name(fit, conf_noffset, NULL); debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, key_blob, fit_get_name(fit, noffset, NULL), fit_get_name(key_blob, required_keynode, NULL)); @@ -297,45 +467,12 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, return -1; } - /* Count the number of strings in the property */ - prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len); - end = prop ? prop + prop_len : prop; - for (name = prop, count = 0; name < end; name++) - if (!*name) - count++; - if (!count) { - *err_msgp = "Can't get hashed-nodes property"; - return -1; - } - - if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') { - *err_msgp = "hashed-nodes property must be null-terminated"; - return -1; - } - - /* Add a sanity check here since we are using the stack */ - if (count > IMAGE_MAX_HASHED_NODES) { - *err_msgp = "Number of hashed nodes exceeds maximum"; - return -1; - } - - /* Create a list of node names from those strings */ - char *node_inc[count]; - - debug("Hash nodes (%d):\n", count); - found_config = false; - for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) { - debug(" '%s'\n", name); - node_inc[i] = (char *)name; - if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) && - name[sizeof(FIT_CONFS_PATH) - 1] == '/' && - !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) { - debug(" (found config node %s)", config_name); - found_config = true; - } - } - if (!found_config) { - *err_msgp = "Selected config not in hashed nodes"; + /* Build the node list from the config, ignoring hashed-nodes */ + count = fit_config_get_hash_list(fit, conf_noffset, + node_inc, IMAGE_MAX_HASHED_NODES, + hash_buf, sizeof(hash_buf)); + if (count < 0) { + *err_msgp = "Failed to build hash node list"; return -1; } diff --git a/doc/usage/fit/signature.rst b/doc/usage/fit/signature.rst index e5b5a8432e9..da08cc75c3a 100644 --- a/doc/usage/fit/signature.rst +++ b/doc/usage/fit/signature.rst @@ -353,20 +353,27 @@ meantime. Details ------- The signature node contains a property ('hashed-nodes') which lists all the -nodes that the signature was made over. The image is walked in order and each -tag processed as follows: +nodes that the signature was made over. The signer (mkimage) writes this +property as a record of what was included in the hash. During verification, +however, U-Boot does not read 'hashed-nodes'. Instead it rebuilds the node +list from the configuration's own image references (kernel, fdt, ramdisk, +etc.), since 'hashed-nodes' is not itself covered by the signature. The +rebuilt list always includes the root node, the configuration node, each +referenced image node and its hash/cipher subnodes. + +The image is walked in order and each tag processed as follows: DTB_BEGIN_NODE The tag and the following name are included in the signature - if the node or its parent are present in 'hashed-nodes' + if the node or its parent are present in the node list DTB_END_NODE The tag is included in the signature if the node or its parent - are present in 'hashed-nodes' + are present in the node list DTB_PROPERTY The tag, the length word, the offset in the string table, and - the data are all included if the current node is present in 'hashed-nodes' + the data are all included if the current node is present in the node list and the property name is not 'data'. DTB_END @@ -374,7 +381,7 @@ DTB_END DTB_NOP The tag is included in the signature if the current node is present - in 'hashed-nodes' + in the node list In addition, the signature contains a property 'hashed-strings' which contains the offset and length in the string table of the strings that are to be diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 7a7f9c379de..19f3f981379 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -362,10 +362,14 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required, shutil.copyfile(fit, efit) vboot_evil.add_evil_node(fit, efit, evil_kernel, 'kernel@') - msg = 'Signature checking prevents use of unit addresses (@) in nodes' + # fit_check_sign catches this via signature mismatch (the @ + # node is hashed instead of the real one) utils.run_and_log_expect_exception( ubman, [fit_check_sign, '-f', efit, '-k', dtb], - 1, msg) + 1, 'Failed to verify required signature') + + # bootm catches it earlier, at fit_check_format() time + msg = 'Signature checking prevents use of unit addresses (@) in nodes' run_bootm(sha_algo, 'evil kernel@', msg, False, efit) # Create a new properly signed fit and replace header bytes From ba7bf918dafcd093ad733b07ba490baeb20cf5da Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 9 Mar 2026 13:52:04 -0600 Subject: [PATCH 80/80] Prepare v2026.04-rc4 Signed-off-by: Tom Rini --- Makefile | 2 +- doc/develop/release_cycle.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5df869213b6..bbe0c366729 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION = 2026 PATCHLEVEL = 04 SUBLEVEL = -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = # *DOCUMENTATION* diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index 0544929df84..74834f5bd87 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -77,7 +77,7 @@ For the next scheduled release, release candidates were made on: * U-Boot |next_ver|-rc3 was released on Mon 23 February 2026. -.. * U-Boot |next_ver|-rc4 was released on Mon 09 March 2026. +* U-Boot |next_ver|-rc4 was released on Mon 09 March 2026. .. * U-Boot |next_ver|-rc5 was released on Mon 23 March 2026.