summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2026-02-25 08:48:54 -0600
committerTom Rini <trini@konsulko.com>2026-02-25 08:48:54 -0600
commit78ea226ddb2aa56cd6d8c034ff34df74d210edd5 (patch)
tree225214277e78fff7f031d461ba207323fe451b8a /arch
parent0b2939464feef001e4d4b69578f29a7a4d572fcd (diff)
parentc61d6f67f46f05149182b33c3c0ba5d9b6b46889 (diff)
Merge tag 'u-boot-stm32-20260224' of https://source.denx.de/u-boot/custodians/u-boot-stm
STM32 update: _ Add STM32MP21 support (board, machine, cmd_stm32key, cmd_stboard, rifsc) _ pinctrl: stm32 : various update _ stm32prog: clean stm32prog_data struct _ stm32mp2: Fix array bound check in setup_boot_mode() _ stm32mp2: Update dynamically DDR size in MMU table _ rifsc: various fixes
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/dts/stm32mp215f-dk-u-boot.dtsi19
-rw-r--r--arch/arm/mach-stm32mp/Kconfig27
-rw-r--r--arch/arm/mach-stm32mp/Kconfig.21x37
-rw-r--r--arch/arm/mach-stm32mp/Makefile3
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32key.c225
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c8
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c10
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h1
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32.h12
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32prog.h2
-rw-r--r--arch/arm/mach-stm32mp/include/mach/sys_proto.h22
-rw-r--r--arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c7
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/Makefile2
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/arm64-mmu.c2
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/cpu.c20
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/rifsc.c37
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c148
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c44
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c46
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c63
-rw-r--r--arch/arm/mach-stm32mp/syscon.c1
21 files changed, 555 insertions, 181 deletions
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..0046b22db7a
--- /dev/null
+++ b/arch/arm/dts/stm32mp215f-dk-u-boot.dtsi
@@ -0,0 +1,19 @@
+// 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";
+ };
+};
+
+&syscfg {
+ bootph-all;
+};
+
+&usart2 {
+ bootph-all;
+};
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/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c
index f5def4cd2dc..4610841f825 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 <command.h>
@@ -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
@@ -40,7 +40,8 @@ struct stm32key {
char *desc;
u16 start;
u8 size;
- int (*post_process)(struct udevice *dev);
+ int (*post_process)(struct udevice *dev, const struct stm32key *key);
+ u32 (*key_format)(u32 value);
};
const struct stm32key stm32mp13_list[] = {
@@ -67,9 +68,81 @@ 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);
+static u32 format1(u32 value);
+static u32 format2(u32 value);
-const struct stm32key stm32mp25_list[] = {
+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 = "RPROC-FW-PKH",
+ .desc = "Hash of the Public Key for remote processor firmware",
+ .start = 180,
+ .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",
+ .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",
+ .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] = {
.name = "OEM-KEY1",
.desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M",
@@ -84,12 +157,26 @@ const struct stm32key stm32mp25_list[] = {
.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",
.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",
.start = 364,
@@ -138,23 +225,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 +258,11 @@ static u8 get_key_nb(void)
if (IS_ENABLED(CONFIG_STM32MP15X))
return ARRAY_SIZE(stm32mp15_list);
+ if (IS_ENABLED(CONFIG_STM32MP21X))
+ return ARRAY_SIZE(stm32mp21_list);
+
if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X))
- return ARRAY_SIZE(stm32mp25_list);
+ return ARRAY_SIZE(stm32mp2x_list);
}
static const struct stm32key *get_key(u8 index)
@@ -183,8 +273,11 @@ static const struct stm32key *get_key(u8 index)
if (IS_ENABLED(CONFIG_STM32MP15X))
return &stm32mp15_list[index];
+ if (IS_ENABLED(CONFIG_STM32MP21X))
+ return &stm32mp21_list[index];
+
if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X))
- return &stm32mp25_list[index];
+ return &stm32mp2x_list[index];
}
static u8 get_otp_close_state_nb(void)
@@ -195,8 +288,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 +301,27 @@ 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];
+}
+
+/*
+ * 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 format2(u32 value)
+{
+ return __le32_to_cpu(value);
}
static int get_misc_dev(struct udevice **dev)
@@ -225,15 +338,21 @@ 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;
}
}
-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;
@@ -347,19 +466,19 @@ 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;
- 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;
@@ -368,14 +487,44 @@ 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)
{
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);
@@ -546,7 +695,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;
}
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,
" <addr> = address of flashlayout\n"
" <size> = 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/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 <asm/types.h>
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);
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/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 <dm/device.h>
#include <dm/uclass.h>
#include <linux/bitfield.h>
+#include <linux/err.h>
#include <malloc.h>
/* 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);
}
diff --git a/arch/arm/mach-stm32mp/stm32mp2/Makefile b/arch/arm/mach-stm32mp/stm32mp2/Makefile
index 27fbf3ae728..8f2e641dcab 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/Makefile
+++ b/arch/arm/mach-stm32mp/stm32mp2/Makefile
@@ -6,6 +6,8 @@
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
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 e081dc605b8..5e2ecb93ee4 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/cpu.c
+++ b/arch/arm/mach-stm32mp/stm32mp2/cpu.c
@@ -15,6 +15,7 @@
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
+#include <asm/armv8/mmu.h>
#include <asm/system.h>
#include <dm/device.h>
#include <dm/lists.h>
@@ -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
@@ -128,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,
@@ -148,7 +164,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 +194,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]);
diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
index f8f67af4449..9db8b9efc64 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
+++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
@@ -141,27 +141,16 @@ 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)
- 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);
+ /* 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;
+
/* Check semaphore accesses */
if (cid_reg_value & CIDCFGR_SEMEN) {
if (!(FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
@@ -173,15 +162,12 @@ static int rifsc_check_access(void *base, u32 id)
log_debug("Semaphore unavailable for peripheral %d\n", id);
return -EACCES;
}
- }
-
-skip_cid_check:
- /* Check security configuration */
- if (sec_reg_value & BIT(reg_offset)) {
- log_debug("Invalid security configuration for peripheral %d\n", id);
+ } 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:
return 0;
}
@@ -208,7 +194,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) {
@@ -367,6 +353,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..7b5d79d3497
--- /dev/null
+++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp21x.c
@@ -0,0 +1,148 @@
+// 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 <log.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/stm32.h>
+#include <asm/arch/sys_proto.h>
+
+/* 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
+ */
+
+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/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 <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
-/* 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 <log.h>
-#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
-/* 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..40fceac402c
--- /dev/null
+++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp2x.c
@@ -0,0 +1,63 @@
+// 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 <log.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/err.h>
+
+/* 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);
+
+ 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);
+}
+
+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);
+}
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},
{ }