summaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-stm32mp')
-rw-r--r--arch/arm/mach-stm32mp/Kconfig11
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32key.c286
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig2
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c6
-rw-r--r--arch/arm/mach-stm32mp/include/mach/etzpc.h32
-rw-r--r--arch/arm/mach-stm32mp/include/mach/rif.h26
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32.h16
-rw-r--r--arch/arm/mach-stm32mp/include/mach/sys_proto.h24
-rw-r--r--arch/arm/mach-stm32mp/stm32mp1/Makefile3
-rw-r--r--arch/arm/mach-stm32mp/stm32mp1/etzpc.c194
-rw-r--r--arch/arm/mach-stm32mp/stm32mp1/fdt.c258
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/Makefile1
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/cpu.c170
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/rifsc.c364
-rw-r--r--arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c31
15 files changed, 1093 insertions, 331 deletions
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index 002da2e3d3b..58250901101 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -52,6 +52,7 @@ config STM32MP13X
select STM32_SERIAL
select SYS_ARCH_TIMER
imply CMD_NVEDIT_INFO
+ imply OF_UPSTREAM
help
support of STMicroelectronics SOC STM32MP13x family
STMicroelectronics MPU with core ARMv7
@@ -73,6 +74,7 @@ config STM32MP15X
select SUPPORT_SPL
select SYS_ARCH_TIMER
imply CMD_NVEDIT_INFO
+ imply OF_UPSTREAM
help
support of STMicroelectronics SOC STM32MP15x family
STM32MP157, STM32MP153 or STM32MP151
@@ -94,6 +96,7 @@ config STM32MP25X
imply CMD_NVEDIT_INFO
imply DM_REGULATOR
imply DM_REGULATOR_SCMI
+ imply OF_UPSTREAM
imply OPTEE
imply RESET_SCMI
imply SYSRESET_PSCI
@@ -127,14 +130,6 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
Partition on the second MMC to load U-Boot from when the MMC is being
used in raw mode
-config STM32_ETZPC
- bool "STM32 Extended TrustZone Protection"
- depends on STM32MP15X || STM32MP13X
- default y
- imply BOOTP_SERVERIP
- help
- Say y to enable STM32 Extended TrustZone Protection
-
config STM32_ECDSA_VERIFY
bool "STM32 ECDSA verification via the ROM API"
depends on SPL_ECDSA_VERIFY
diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c
index 040a70f581c..6bfa67859e1 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32key.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32key.c
@@ -14,12 +14,23 @@
/*
* Closed device: OTP0
- * STM32MP15x: bit 6 of OPT0
+ * STM32MP15x: bit 6 of OTP0
* STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device
+ * STM32MP25x: bit 0 of OTP18
*/
-#define STM32_OTP_CLOSE_ID 0
-#define STM32_OTP_STM32MP13X_CLOSE_MASK 0x3F
-#define STM32_OTP_STM32MP15X_CLOSE_MASK BIT(6)
+#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 STM32MP25_OTP_BOOTROM_CONF8 17
+#define STM32_OTP_STM32MP25X_OEM_KEY2_EN BIT(8)
/* PKH is the first element of the key list */
#define STM32KEY_PKH 0
@@ -27,8 +38,9 @@
struct stm32key {
char *name;
char *desc;
- u8 start;
+ u16 start;
u8 size;
+ int (*post_process)(struct udevice *dev);
};
const struct stm32key stm32mp13_list[] = {
@@ -55,6 +67,99 @@ const struct stm32key stm32mp15_list[] = {
}
};
+static int post_process_oem_key2(struct udevice *dev);
+
+const struct stm32key stm32mp25_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 = 144,
+ .size = 8,
+ },
+ {
+ .name = "OEM-KEY2",
+ .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLM",
+ .start = 152,
+ .size = 8,
+ .post_process = post_process_oem_key2,
+ },
+ {
+ .name = "FIP-EDMK",
+ .desc = "Encryption/Decryption Master Key for FIP",
+ .start = 260,
+ .size = 8,
+ },
+ {
+ .name = "EDMK1",
+ .desc = "Encryption/Decryption Master Key for FSBLA or M",
+ .start = 364,
+ .size = 4,
+ },
+ {
+ .name = "EDMK2",
+ .desc = "Encryption/Decryption Master Key for FSBLM",
+ .start = 360,
+ .size = 4,
+ }
+};
+
+struct otp_close {
+ u32 word;
+ u32 mask_wr;
+ u32 mask_rd;
+ bool (*close_status_ops)(u32 value, u32 mask);
+};
+
+static bool compare_mask_exact(u32 value, u32 mask)
+{
+ return ((value & mask) == mask);
+}
+
+static bool compare_any_bits(u32 value, u32 mask)
+{
+ return ((value & mask) != 0);
+}
+
+const struct otp_close stm32mp13_close_state_otp[] = {
+ {
+ .word = STM32MP1_OTP_CLOSE_ID,
+ .mask_wr = STM32_OTP_STM32MP13X_CLOSE_MASK,
+ .mask_rd = STM32_OTP_STM32MP13X_CLOSE_MASK,
+ .close_status_ops = compare_mask_exact,
+ }
+};
+
+const struct otp_close stm32mp15_close_state_otp[] = {
+ {
+ .word = STM32MP1_OTP_CLOSE_ID,
+ .mask_wr = STM32_OTP_STM32MP15X_CLOSE_MASK,
+ .mask_rd = STM32_OTP_STM32MP15X_CLOSE_MASK,
+ .close_status_ops = compare_mask_exact,
+ }
+};
+
+const struct otp_close stm32mp25_close_state_otp[] = {
+ {
+ .word = STM32MP25_OTP_WORD8,
+ .mask_wr = STM32_OTP_STM32MP25X_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,
+ .close_status_ops = compare_any_bits
+ },
+ {
+ .word = STM32MP25_OTP_HWCONFIG,
+ .mask_wr = STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK,
+ .mask_rd = 0,
+ .close_status_ops = NULL
+ },
+};
+
/* index of current selected key in stm32key list, 0 = PKH by default */
static u8 stm32key_index;
@@ -65,6 +170,9 @@ static u8 get_key_nb(void)
if (IS_ENABLED(CONFIG_STM32MP15X))
return ARRAY_SIZE(stm32mp15_list);
+
+ if (IS_ENABLED(CONFIG_STM32MP25X))
+ return ARRAY_SIZE(stm32mp25_list);
}
static const struct stm32key *get_key(u8 index)
@@ -74,15 +182,33 @@ static const struct stm32key *get_key(u8 index)
if (IS_ENABLED(CONFIG_STM32MP15X))
return &stm32mp15_list[index];
+
+ if (IS_ENABLED(CONFIG_STM32MP25X))
+ return &stm32mp25_list[index];
}
-static u32 get_otp_close_mask(void)
+static u8 get_otp_close_state_nb(void)
{
if (IS_ENABLED(CONFIG_STM32MP13X))
- return STM32_OTP_STM32MP13X_CLOSE_MASK;
+ return ARRAY_SIZE(stm32mp13_close_state_otp);
if (IS_ENABLED(CONFIG_STM32MP15X))
- return STM32_OTP_STM32MP15X_CLOSE_MASK;
+ return ARRAY_SIZE(stm32mp15_close_state_otp);
+
+ if (IS_ENABLED(CONFIG_STM32MP25X))
+ return ARRAY_SIZE(stm32mp25_close_state_otp);
+}
+
+static const struct otp_close *get_otp_close_state(u8 index)
+{
+ if (IS_ENABLED(CONFIG_STM32MP13X))
+ return &stm32mp13_close_state_otp[index];
+
+ if (IS_ENABLED(CONFIG_STM32MP15X))
+ return &stm32mp15_close_state_otp[index];
+
+ if (IS_ENABLED(CONFIG_STM32MP25X))
+ return &stm32mp25_close_state_otp[index];
}
static int get_misc_dev(struct udevice **dev)
@@ -96,13 +222,13 @@ static int get_misc_dev(struct udevice **dev)
return ret;
}
-static void read_key_value(const struct stm32key *key, u32 addr)
+static void read_key_value(const struct stm32key *key, unsigned long addr)
{
int i;
for (i = 0; i < key->size; i++) {
printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i,
- addr, __be32_to_cpu(*(u32 *)addr));
+ (u32)addr, __be32_to_cpu(*(u32 *)addr));
addr += 4;
}
}
@@ -157,26 +283,42 @@ static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool pr
static int read_close_status(struct udevice *dev, bool print, bool *closed)
{
- int word, ret, result;
- u32 val, lock, mask;
- bool status;
+ int ret, result, i;
+ const struct otp_close *otp_close = NULL;
+ u32 otp_close_nb = get_otp_close_state_nb();
+ u32 val, lock, mask, word = 0;
+ bool status = true;
+ bool tested_once = false;
result = 0;
- word = STM32_OTP_CLOSE_ID;
- ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
- if (ret < 0)
- result = ret;
- if (ret != 4)
- val = 0x0;
-
- ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
- if (ret < 0)
- result = ret;
- if (ret != 4)
- lock = BSEC_LOCK_ERROR;
-
- mask = get_otp_close_mask();
- status = (val & mask) == mask;
+ for (i = 0; status && (i < otp_close_nb); i++) {
+ otp_close = get_otp_close_state(i);
+
+ if (!otp_close->close_status_ops)
+ continue;
+
+ mask = otp_close->mask_rd;
+ word = otp_close->word;
+
+ ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
+ if (ret < 0)
+ result = ret;
+ if (ret != 4)
+ val = 0x0;
+
+ ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
+ if (ret < 0)
+ result = ret;
+ if (ret != 4)
+ lock = BSEC_LOCK_ERROR;
+
+ status = otp_close->close_status_ops(val, mask);
+ tested_once = true;
+ }
+
+ if (!tested_once)
+ status = false;
+
if (closed)
*closed = status;
if (print)
@@ -185,7 +327,49 @@ static int read_close_status(struct udevice *dev, bool print, bool *closed)
return result;
}
-static int fuse_key_value(struct udevice *dev, const struct stm32key *key, u32 addr, bool print)
+static int write_close_status(struct udevice *dev)
+{
+ int i;
+ u32 val, word, ret;
+ const struct otp_close *otp_close = NULL;
+ u32 otp_num = get_otp_close_state_nb();
+
+ for (i = 0; i < otp_num; i++) {
+ otp_close = get_otp_close_state(i);
+ val = otp_close->mask_wr;
+ word = otp_close->word;
+ ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
+ if (ret != 4) {
+ log_err("Error: can't update OTP %d\n", word);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+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);
+ if (ret != 4) {
+ log_err("Error %d failed to read STM32MP25_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);
+ if (ret != 4) {
+ log_err("Error %d failed to write OEM_KEY2_ENABLE\n", ret);
+ return -EIO;
+ }
+
+ 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;
@@ -229,7 +413,7 @@ static int confirm_prog(void)
static void display_key_info(const struct stm32key *key)
{
printf("%s : %s\n", key->name, key->desc);
- printf("\tOTP%d..%d\n", key->start, key->start + key->size);
+ printf("\tOTP%d..%d\n", key->start, key->start + key->size - 1);
}
static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
@@ -272,7 +456,7 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *con
{
const struct stm32key *key;
struct udevice *dev;
- u32 addr;
+ unsigned long addr;
int ret, i;
int result;
@@ -310,7 +494,7 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *con
return CMD_RET_USAGE;
key = get_key(stm32key_index);
- printf("Read %s at 0x%08x\n", key->name, addr);
+ printf("Read %s at 0x%08x\n", key->name, (u32)addr);
read_key_value(key, addr);
return CMD_RET_SUCCESS;
@@ -320,7 +504,7 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con
{
const struct stm32key *key = get_key(stm32key_index);
struct udevice *dev;
- u32 addr;
+ unsigned long addr;
int ret;
bool yes = false, lock;
@@ -361,6 +545,13 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con
if (fuse_key_value(dev, key, addr, !yes))
return CMD_RET_FAILURE;
+ if (key->post_process) {
+ if (key->post_process(dev)) {
+ printf("Error: %s for post process\n", key->name);
+ return CMD_RET_FAILURE;
+ }
+ }
+
printf("%s updated !\n", key->name);
return CMD_RET_SUCCESS;
@@ -371,7 +562,6 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co
const struct stm32key *key;
bool yes, lock, closed;
struct udevice *dev;
- u32 val;
int ret;
yes = false;
@@ -407,12 +597,8 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co
if (!yes && !confirm_prog())
return CMD_RET_FAILURE;
- val = get_otp_close_mask();
- ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4);
- if (ret != 4) {
- printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID);
+ if (write_close_status(dev))
return CMD_RET_FAILURE;
- }
printf("Device is closed !\n");
@@ -432,3 +618,25 @@ U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Manage key on STM32", stm32key_help_text,
U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read),
U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse),
U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close));
+
+/*
+ * Check the "closed" state in product life cycle, when product secrets have
+ * been provisioned into the device, by SSP tools for example.
+ * On closed devices, authentication is mandatory.
+ */
+bool stm32mp_is_closed(void)
+{
+ struct udevice *dev;
+ bool closed;
+ int ret;
+
+ ret = get_misc_dev(&dev);
+ if (ret)
+ return false;
+
+ ret = read_close_status(dev, false, &closed);
+ if (ret)
+ return false;
+
+ return closed;
+}
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig
index 589276282e4..490097e98be 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig
@@ -27,6 +27,8 @@ config CMD_STM32PROG_USB
config CMD_STM32PROG_SERIAL
bool "support stm32prog over UART"
depends on CMD_STM32PROG
+ imply DISABLE_CONSOLE
+ imply SILENT_CONSOLE
default y
help
activate the command "stm32prog serial" for STM32MP soc family
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
index 353aecc09de..5b027fad048 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
@@ -13,6 +13,7 @@
#include <part.h>
#include <tee.h>
#include <asm/arch/stm32mp1_smc.h>
+#include <asm/arch/sys_proto.h>
#include <asm/global_data.h>
#include <dm/device_compat.h>
#include <dm/uclass.h>
@@ -1156,7 +1157,8 @@ static int create_gpt_partitions(struct stm32prog_data *data)
/* partition UUID */
uuid_bin = NULL;
- if (!rootfs_found && !strcmp(part->name, "rootfs")) {
+ if (!rootfs_found && (!strcmp(part->name, "rootfs") ||
+ !strcmp(part->name, "rootfs-a"))) {
mmc_id = part->dev_id;
rootfs_found = true;
if (mmc_id < ARRAY_SIZE(uuid_mmc))
@@ -1357,7 +1359,7 @@ static int dfu_init_entities(struct stm32prog_data *data)
alt_nb = 1; /* number of virtual = CMD*/
- if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP) && !stm32mp_is_closed()) {
/* OTP_SIZE_SMC = 0 if SMC is not supported */
otp_size = OTP_SIZE_SMC;
/* check if PTA BSEC is supported */
diff --git a/arch/arm/mach-stm32mp/include/mach/etzpc.h b/arch/arm/mach-stm32mp/include/mach/etzpc.h
new file mode 100644
index 00000000000..fd697c3e2ac
--- /dev/null
+++ b/arch/arm/mach-stm32mp/include/mach/etzpc.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef MACH_ETZPC_H
+#define MACH_ETZPC_H
+
+#include <linux/types.h>
+
+/**
+ * stm32_etzpc_check_access - Check ETZPC accesses for given device node
+ *
+ * @device_node Node of the device for which the accesses are checked
+ *
+ * @returns 0 on success (if access is granted), -EINVAL if access is denied.
+ * Else, returns an appropriate negative ERRNO value
+ */
+int stm32_etzpc_check_access(ofnode device_node);
+
+/**
+ * stm32_etzpc_check_access_by_id - Check ETZPC accesses for given id
+ *
+ * @device_node Node of the device to get a reference on ETZPC
+ * @id ID of the resource to check
+ *
+ * @returns 0 on success (if access is granted), -EINVAL if access is denied.
+ * Else, returns an appropriate negative ERRNO value
+ */
+int stm32_etzpc_check_access_by_id(ofnode device_node, u32 id);
+
+#endif /* MACH_ETZPC_H*/
diff --git a/arch/arm/mach-stm32mp/include/mach/rif.h b/arch/arm/mach-stm32mp/include/mach/rif.h
new file mode 100644
index 00000000000..10b22108120
--- /dev/null
+++ b/arch/arm/mach-stm32mp/include/mach/rif.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef MACH_RIF_H
+#define MACH_RIF_H
+
+#include <linux/types.h>
+
+/**
+ * stm32_rifsc_check_access - Check RIF accesses for given device node
+ *
+ * @device_node Node of the device for which the accesses are checked
+ */
+int stm32_rifsc_check_access(ofnode device_node);
+
+/**
+ * stm32_rifsc_check_access - Check RIF accesses for given id
+ *
+ * @device_node Node of the device to get a reference on RIFSC
+ * @id ID of the resource to check
+ */
+int stm32_rifsc_check_access_by_id(ofnode device_node, u32 id);
+
+#endif /* MACH_RIF_H*/
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 6eb85ba7233..a9ac49bc5d2 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -42,6 +42,9 @@ enum boot_device {
BOOT_FLASH_SPINAND = 0x70,
BOOT_FLASH_SPINAND_1 = 0x71,
+
+ BOOT_FLASH_HYPERFLASH = 0x80,
+ BOOT_FLASH_HYPERFLASH_1 = 0x81
};
#define TAMP_BOOT_MODE_MASK GENMASK(15, 8)
@@ -158,8 +161,20 @@ enum forced_boot_mode {
#endif /* CONFIG_STM32MP15X || CONFIG_STM32MP13X */
#ifdef 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
+#define STM32_UART9_BASE 0x402C0000
+#define STM32_USART1_BASE 0x40330000
+#define STM32_UART7_BASE 0x40370000
+#define STM32_UART8_BASE 0x40380000
#define STM32_RCC_BASE 0x44200000
#define STM32_TAMP_BASE 0x46010000
+#define STM32_SDMMC1_BASE 0x48220000
+#define STM32_SDMMC2_BASE 0x48230000
+#define STM32_SDMMC3_BASE 0x48240000
#define STM32_DDR_BASE 0x80000000
@@ -197,6 +212,7 @@ enum forced_boot_mode {
#ifdef 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
diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
index 2a65efc0a50..19073668497 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -58,6 +58,7 @@ u32 get_cpu_type(void);
/* return CPU_DEV constants */
u32 get_cpu_dev(void);
+/* Silicon revision = REV_ID[15:0] of Device Version */
#define CPU_REV1 0x1000
#define CPU_REV1_1 0x1001
#define CPU_REV1_2 0x1003
@@ -65,7 +66,15 @@ u32 get_cpu_dev(void);
#define CPU_REV2_1 0x2001
#define CPU_REV2_2 0x2003
-/* return Silicon revision = REV_ID[15:0] of Device Version */
+/* OTP revision ID = 6 bits : 3 for Major / 3 for Minor */
+#define OTP_REVID_1 0b001000
+#define OTP_REVID_1_1 0b001001
+#define OTP_REVID_1_2 0b001010
+#define OTP_REVID_2 0b010000
+#define OTP_REVID_2_1 0b010001
+#define OTP_REVID_2_2 0b010010
+
+/* return SoC revision = Silicon revision (STM32MP1) or OTP revision ID (STM32MP2)*/
u32 get_cpu_rev(void);
/* Get Package options from OTP */
@@ -80,9 +89,9 @@ u32 get_cpu_package(void);
/* package used for STM32MP25x */
#define STM32MP25_PKG_CUSTOM 0
-#define STM32MP25_PKG_AL_TBGA361 3
-#define STM32MP25_PKG_AK_TBGA424 4
-#define STM32MP25_PKG_AI_TBGA436 5
+#define STM32MP25_PKG_AL_VFBGA361 1
+#define STM32MP25_PKG_AK_VFBGA424 3
+#define STM32MP25_PKG_AI_TFBGA436 5
#define STM32MP25_PKG_UNKNOWN 7
/* Get SOC name */
@@ -111,3 +120,10 @@ u32 get_otp(int index, int shift, int mask);
uintptr_t get_stm32mp_rom_api_table(void);
uintptr_t get_stm32mp_bl2_dtb(void);
+
+/* helper function: check "closed" state in product "Life Cycle" */
+#ifdef CONFIG_CMD_STM32KEY
+bool stm32mp_is_closed(void);
+#else
+static inline bool stm32mp_is_closed(void) { return false; }
+#endif
diff --git a/arch/arm/mach-stm32mp/stm32mp1/Makefile b/arch/arm/mach-stm32mp/stm32mp1/Makefile
index db160c24cbc..1f4ada3ac70 100644
--- a/arch/arm/mach-stm32mp/stm32mp1/Makefile
+++ b/arch/arm/mach-stm32mp/stm32mp1/Makefile
@@ -4,6 +4,7 @@
#
obj-y += cpu.o
+obj-y += etzpc.o
obj-$(CONFIG_STM32MP13X) += stm32mp13x.o
obj-$(CONFIG_STM32MP15X) += stm32mp15x.o
@@ -15,5 +16,5 @@ else
obj-$(CONFIG_ARMV7_PSCI) += psci.o
endif
-obj-$(CONFIG_$(XPL_)STM32MP15_PWR) += pwr_regulator.o
+obj-$(CONFIG_$(PHASE_)STM32MP15_PWR) += pwr_regulator.o
obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o
diff --git a/arch/arm/mach-stm32mp/stm32mp1/etzpc.c b/arch/arm/mach-stm32mp/stm32mp1/etzpc.c
new file mode 100644
index 00000000000..7013bf97167
--- /dev/null
+++ b/arch/arm/mach-stm32mp/stm32mp1/etzpc.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#define LOG_CATEGORY UCLASS_NOP
+
+#include <dm.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <linux/bitfield.h>
+#include <mach/etzpc.h>
+
+/* ETZPC peripheral as firewall bus */
+/* ETZPC registers */
+#define ETZPC_DECPROT 0x10
+#define ETZPC_HWCFGR 0x3F0
+
+/* ETZPC miscellaneous */
+#define ETZPC_PROT_MASK GENMASK(1, 0)
+#define ETZPC_PROT_A7NS 0x3
+#define ETZPC_DECPROT_SHIFT 1
+
+#define IDS_PER_DECPROT_REGS 16
+
+#define ETZPC_HWCFGR_NUM_PER_SEC GENMASK(15, 8)
+#define ETZPC_HWCFGR_NUM_AHB_SEC GENMASK(23, 16)
+
+/*
+ * struct stm32_etzpc_plat: Information about ETZPC device
+ *
+ * @base: Base address of ETZPC
+ * @max_entries: Number of securable peripherals in ETZPC
+ */
+struct stm32_etzpc_plat {
+ void *base;
+ unsigned int max_entries;
+};
+
+static int etzpc_parse_feature_domain(ofnode node, struct ofnode_phandle_args *args)
+{
+ int ret;
+
+ ret = ofnode_parse_phandle_with_args(node, "access-controllers",
+ "#access-controller-cells", 0,
+ 0, args);
+ if (ret) {
+ log_debug("failed to parse access-controller (%d)\n", ret);
+ return ret;
+ }
+
+ if (args->args_count != 1) {
+ log_debug("invalid domain args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int etzpc_check_access(void *base, u32 id)
+{
+ u32 reg_offset, offset, sec_val;
+
+ /* Check access configuration, 16 peripherals per register */
+ reg_offset = ETZPC_DECPROT + 0x4 * (id / IDS_PER_DECPROT_REGS);
+ offset = (id % IDS_PER_DECPROT_REGS) << ETZPC_DECPROT_SHIFT;
+
+ /* Verify peripheral is non-secure and attributed to cortex A7 */
+ sec_val = (readl(base + reg_offset) >> offset) & ETZPC_PROT_MASK;
+ if (sec_val != ETZPC_PROT_A7NS) {
+ log_debug("Invalid bus configuration: reg_offset %#x, value %d\n",
+ reg_offset, sec_val);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+int stm32_etzpc_check_access_by_id(ofnode device_node, u32 id)
+{
+ struct stm32_etzpc_plat *plat;
+ struct ofnode_phandle_args args;
+ struct udevice *dev;
+ int err;
+
+ err = etzpc_parse_feature_domain(device_node, &args);
+ if (err)
+ return err;
+
+ if (id == -1U)
+ id = args.args[0];
+
+ err = uclass_get_device_by_ofnode(UCLASS_NOP, args.node, &dev);
+ if (err || dev->driver != DM_DRIVER_GET(stm32_etzpc)) {
+ log_err("No device found\n");
+ return -EINVAL;
+ }
+
+ plat = dev_get_plat(dev);
+
+ if (id >= plat->max_entries) {
+ dev_err(dev, "Invalid sys bus ID for %s\n", ofnode_get_name(device_node));
+ return -EINVAL;
+ }
+
+ return etzpc_check_access(plat->base, id);
+}
+
+int stm32_etzpc_check_access(ofnode device_node)
+{
+ return stm32_etzpc_check_access_by_id(device_node, -1U);
+}
+
+static int stm32_etzpc_bind(struct udevice *dev)
+{
+ struct stm32_etzpc_plat *plat = dev_get_plat(dev);
+ struct ofnode_phandle_args args;
+ u32 nb_per, nb_master;
+ int ret = 0, err = 0;
+ ofnode node, parent;
+
+ plat->base = dev_read_addr_ptr(dev);
+ if (!plat->base) {
+ dev_err(dev, "can't get registers base address\n");
+ return -ENOENT;
+ }
+
+ /* Get number of etzpc entries*/
+ nb_per = FIELD_GET(ETZPC_HWCFGR_NUM_PER_SEC,
+ readl(plat->base + ETZPC_HWCFGR));
+ nb_master = FIELD_GET(ETZPC_HWCFGR_NUM_AHB_SEC,
+ readl(plat->base + ETZPC_HWCFGR));
+ plat->max_entries = nb_per + nb_master;
+
+ parent = dev_ofnode(dev);
+ for (node = ofnode_first_subnode(parent);
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ const char *node_name = ofnode_get_name(node);
+
+ if (!ofnode_is_enabled(node))
+ continue;
+
+ err = etzpc_parse_feature_domain(node, &args);
+ if (err) {
+ dev_err(dev, "%s failed to parse child on bus (%d)\n", node_name, err);
+ continue;
+ }
+
+ if (!ofnode_equal(args.node, parent)) {
+ dev_err(dev, "%s phandle to %s\n",
+ node_name, ofnode_get_name(args.node));
+ continue;
+ }
+
+ if (args.args[0] >= plat->max_entries) {
+ dev_err(dev, "Invalid sys bus ID for %s\n", node_name);
+ return -EINVAL;
+ }
+
+ err = etzpc_check_access(plat->base, args.args[0]);
+ if (err) {
+ dev_info(dev, "%s not allowed on bus (%d)\n", node_name, err);
+ continue;
+ }
+
+ err = lists_bind_fdt(dev, node, NULL, NULL,
+ gd->flags & GD_FLG_RELOC ? false : true);
+ if (err) {
+ ret = err;
+ dev_err(dev, "%s failed to bind on bus (%d)\n", node_name, ret);
+ }
+ }
+
+ if (ret)
+ dev_err(dev, "Some child failed to bind (%d)\n", ret);
+
+ return ret;
+}
+
+static const struct udevice_id stm32_etzpc_ids[] = {
+ { .compatible = "st,stm32-etzpc" },
+ {},
+};
+
+U_BOOT_DRIVER(stm32_etzpc) = {
+ .name = "stm32_etzpc",
+ .id = UCLASS_NOP,
+ .of_match = stm32_etzpc_ids,
+ .bind = stm32_etzpc_bind,
+ .plat_auto = sizeof(struct stm32_etzpc_plat),
+};
diff --git a/arch/arm/mach-stm32mp/stm32mp1/fdt.c b/arch/arm/mach-stm32mp/stm32mp1/fdt.c
index e1e4dc04e01..72474fa73f6 100644
--- a/arch/arm/mach-stm32mp/stm32mp1/fdt.c
+++ b/arch/arm/mach-stm32mp/stm32mp1/fdt.c
@@ -14,20 +14,6 @@
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
#include <linux/io.h>
-#define ETZPC_DECPROT(n) (STM32_ETZPC_BASE + 0x10 + 4 * (n))
-#define ETZPC_DECPROT_NB 6
-
-#define DECPROT_MASK 0x03
-#define NB_PROT_PER_REG 0x10
-#define DECPROT_NB_BITS 2
-
-#define DECPROT_SECURED 0x00
-#define DECPROT_WRITE_SECURE 0x01
-#define DECPROT_MCU_ISOLATION 0x02
-#define DECPROT_NON_SECURED 0x03
-
-#define ETZPC_RESERVED 0xffffffff
-
#define STM32MP13_FDCAN_BASE 0x4400F000
#define STM32MP13_ADC1_BASE 0x48003000
#define STM32MP13_TSC_BASE 0x5000B000
@@ -42,204 +28,6 @@
#define STM32MP15_GPU_BASE 0x59000000
#define STM32MP15_DSI_BASE 0x5a000000
-static const u32 stm32mp13_ip_addr[] = {
- 0x50025000, /* 0 VREFBUF APB3 */
- 0x50021000, /* 1 LPTIM2 APB3 */
- 0x50022000, /* 2 LPTIM3 APB3 */
- STM32MP13_LTDC_BASE, /* 3 LTDC APB4 */
- STM32MP13_DCMIPP_BASE, /* 4 DCMIPP APB4 */
- 0x5A006000, /* 5 USBPHYCTRL APB4 */
- 0x5A003000, /* 6 DDRCTRLPHY APB4 */
- ETZPC_RESERVED, /* 7 Reserved*/
- ETZPC_RESERVED, /* 8 Reserved*/
- ETZPC_RESERVED, /* 9 Reserved*/
- 0x5C006000, /* 10 TZC APB5 */
- 0x58001000, /* 11 MCE APB5 */
- 0x5C000000, /* 12 IWDG1 APB5 */
- 0x5C008000, /* 13 STGENC APB5 */
- ETZPC_RESERVED, /* 14 Reserved*/
- ETZPC_RESERVED, /* 15 Reserved*/
- 0x4C000000, /* 16 USART1 APB6 */
- 0x4C001000, /* 17 USART2 APB6 */
- 0x4C002000, /* 18 SPI4 APB6 */
- 0x4C003000, /* 19 SPI5 APB6 */
- 0x4C004000, /* 20 I2C3 APB6 */
- 0x4C005000, /* 21 I2C4 APB6 */
- 0x4C006000, /* 22 I2C5 APB6 */
- 0x4C007000, /* 23 TIM12 APB6 */
- 0x4C008000, /* 24 TIM13 APB6 */
- 0x4C009000, /* 25 TIM14 APB6 */
- 0x4C00A000, /* 26 TIM15 APB6 */
- 0x4C00B000, /* 27 TIM16 APB6 */
- 0x4C00C000, /* 28 TIM17 APB6 */
- ETZPC_RESERVED, /* 29 Reserved*/
- ETZPC_RESERVED, /* 30 Reserved*/
- ETZPC_RESERVED, /* 31 Reserved*/
- STM32MP13_ADC1_BASE, /* 32 ADC1 AHB2 */
- 0x48004000, /* 33 ADC2 AHB2 */
- 0x49000000, /* 34 OTG AHB2 */
- ETZPC_RESERVED, /* 35 Reserved*/
- ETZPC_RESERVED, /* 36 Reserved*/
- STM32MP13_TSC_BASE, /* 37 TSC AHB4 */
- ETZPC_RESERVED, /* 38 Reserved*/
- ETZPC_RESERVED, /* 39 Reserved*/
- 0x54004000, /* 40 RNG AHB5 */
- 0x54003000, /* 41 HASH AHB5 */
- STM32MP13_CRYP_BASE, /* 42 CRYPT AHB5 */
- 0x54005000, /* 43 SAES AHB5 */
- 0x54006000, /* 44 PKA AHB5 */
- 0x54000000, /* 45 BKPSRAM AHB5 */
- ETZPC_RESERVED, /* 46 Reserved*/
- ETZPC_RESERVED, /* 47 Reserved*/
- 0x5800A000, /* 48 ETH1 AHB6 */
- STM32MP13_ETH2_BASE, /* 49 ETH2 AHB6 */
- 0x58005000, /* 50 SDMMC1 AHB6 */
- 0x58007000, /* 51 SDMMC2 AHB6 */
- ETZPC_RESERVED, /* 52 Reserved*/
- ETZPC_RESERVED, /* 53 Reserved*/
- 0x58002000, /* 54 FMC AHB6 */
- 0x58003000, /* 55 QSPI AHB6 */
- ETZPC_RESERVED, /* 56 Reserved*/
- ETZPC_RESERVED, /* 57 Reserved*/
- ETZPC_RESERVED, /* 58 Reserved*/
- ETZPC_RESERVED, /* 59 Reserved*/
- 0x30000000, /* 60 SRAM1 MLAHB */
- 0x30004000, /* 61 SRAM2 MLAHB */
- 0x30006000, /* 62 SRAM3 MLAHB */
- ETZPC_RESERVED, /* 63 Reserved*/
- ETZPC_RESERVED, /* 64 Reserved*/
- ETZPC_RESERVED, /* 65 Reserved*/
- ETZPC_RESERVED, /* 66 Reserved*/
- ETZPC_RESERVED, /* 67 Reserved*/
- ETZPC_RESERVED, /* 68 Reserved*/
- ETZPC_RESERVED, /* 69 Reserved*/
- ETZPC_RESERVED, /* 70 Reserved*/
- ETZPC_RESERVED, /* 71 Reserved*/
- ETZPC_RESERVED, /* 72 Reserved*/
- ETZPC_RESERVED, /* 73 Reserved*/
- ETZPC_RESERVED, /* 74 Reserved*/
- ETZPC_RESERVED, /* 75 Reserved*/
- ETZPC_RESERVED, /* 76 Reserved*/
- ETZPC_RESERVED, /* 77 Reserved*/
- ETZPC_RESERVED, /* 78 Reserved*/
- ETZPC_RESERVED, /* 79 Reserved*/
- ETZPC_RESERVED, /* 80 Reserved*/
- ETZPC_RESERVED, /* 81 Reserved*/
- ETZPC_RESERVED, /* 82 Reserved*/
- ETZPC_RESERVED, /* 83 Reserved*/
- ETZPC_RESERVED, /* 84 Reserved*/
- ETZPC_RESERVED, /* 85 Reserved*/
- ETZPC_RESERVED, /* 86 Reserved*/
- ETZPC_RESERVED, /* 87 Reserved*/
- ETZPC_RESERVED, /* 88 Reserved*/
- ETZPC_RESERVED, /* 89 Reserved*/
- ETZPC_RESERVED, /* 90 Reserved*/
- ETZPC_RESERVED, /* 91 Reserved*/
- ETZPC_RESERVED, /* 92 Reserved*/
- ETZPC_RESERVED, /* 93 Reserved*/
- ETZPC_RESERVED, /* 94 Reserved*/
- ETZPC_RESERVED, /* 95 Reserved*/
-};
-
-static const u32 stm32mp15_ip_addr[] = {
- 0x5c008000, /* 00 stgenc */
- 0x54000000, /* 01 bkpsram */
- 0x5c003000, /* 02 iwdg1 */
- 0x5c000000, /* 03 usart1 */
- 0x5c001000, /* 04 spi6 */
- 0x5c002000, /* 05 i2c4 */
- ETZPC_RESERVED, /* 06 reserved */
- 0x54003000, /* 07 rng1 */
- 0x54002000, /* 08 hash1 */
- STM32MP15_CRYP1_BASE, /* 09 cryp1 */
- 0x5a003000, /* 0A ddrctrl */
- 0x5a004000, /* 0B ddrphyc */
- 0x5c009000, /* 0C i2c6 */
- ETZPC_RESERVED, /* 0D reserved */
- ETZPC_RESERVED, /* 0E reserved */
- ETZPC_RESERVED, /* 0F reserved */
- 0x40000000, /* 10 tim2 */
- 0x40001000, /* 11 tim3 */
- 0x40002000, /* 12 tim4 */
- 0x40003000, /* 13 tim5 */
- 0x40004000, /* 14 tim6 */
- 0x40005000, /* 15 tim7 */
- 0x40006000, /* 16 tim12 */
- 0x40007000, /* 17 tim13 */
- 0x40008000, /* 18 tim14 */
- 0x40009000, /* 19 lptim1 */
- 0x4000a000, /* 1A wwdg1 */
- 0x4000b000, /* 1B spi2 */
- 0x4000c000, /* 1C spi3 */
- 0x4000d000, /* 1D spdifrx */
- 0x4000e000, /* 1E usart2 */
- 0x4000f000, /* 1F usart3 */
- 0x40010000, /* 20 uart4 */
- 0x40011000, /* 21 uart5 */
- 0x40012000, /* 22 i2c1 */
- 0x40013000, /* 23 i2c2 */
- 0x40014000, /* 24 i2c3 */
- 0x40015000, /* 25 i2c5 */
- 0x40016000, /* 26 cec */
- 0x40017000, /* 27 dac */
- 0x40018000, /* 28 uart7 */
- 0x40019000, /* 29 uart8 */
- ETZPC_RESERVED, /* 2A reserved */
- ETZPC_RESERVED, /* 2B reserved */
- 0x4001c000, /* 2C mdios */
- ETZPC_RESERVED, /* 2D reserved */
- ETZPC_RESERVED, /* 2E reserved */
- ETZPC_RESERVED, /* 2F reserved */
- 0x44000000, /* 30 tim1 */
- 0x44001000, /* 31 tim8 */
- ETZPC_RESERVED, /* 32 reserved */
- 0x44003000, /* 33 usart6 */
- 0x44004000, /* 34 spi1 */
- 0x44005000, /* 35 spi4 */
- 0x44006000, /* 36 tim15 */
- 0x44007000, /* 37 tim16 */
- 0x44008000, /* 38 tim17 */
- 0x44009000, /* 39 spi5 */
- 0x4400a000, /* 3A sai1 */
- 0x4400b000, /* 3B sai2 */
- 0x4400c000, /* 3C sai3 */
- 0x4400d000, /* 3D dfsdm */
- STM32MP15_FDCAN_BASE, /* 3E tt_fdcan */
- ETZPC_RESERVED, /* 3F reserved */
- 0x50021000, /* 40 lptim2 */
- 0x50022000, /* 41 lptim3 */
- 0x50023000, /* 42 lptim4 */
- 0x50024000, /* 43 lptim5 */
- 0x50027000, /* 44 sai4 */
- 0x50025000, /* 45 vrefbuf */
- 0x4c006000, /* 46 dcmi */
- 0x4c004000, /* 47 crc2 */
- 0x48003000, /* 48 adc */
- 0x4c002000, /* 49 hash2 */
- 0x4c003000, /* 4A rng2 */
- STM32MP15_CRYP2_BASE, /* 4B cryp2 */
- ETZPC_RESERVED, /* 4C reserved */
- ETZPC_RESERVED, /* 4D reserved */
- ETZPC_RESERVED, /* 4E reserved */
- ETZPC_RESERVED, /* 4F reserved */
- ETZPC_RESERVED, /* 50 sram1 */
- ETZPC_RESERVED, /* 51 sram2 */
- ETZPC_RESERVED, /* 52 sram3 */
- ETZPC_RESERVED, /* 53 sram4 */
- ETZPC_RESERVED, /* 54 retram */
- 0x49000000, /* 55 otg */
- 0x48004000, /* 56 sdmmc3 */
- 0x48005000, /* 57 dlybsd3 */
- 0x48000000, /* 58 dma1 */
- 0x48001000, /* 59 dma2 */
- 0x48002000, /* 5A dmamux */
- 0x58002000, /* 5B fmc */
- 0x58003000, /* 5C qspi */
- 0x58004000, /* 5D dlybq */
- 0x5800a000, /* 5E eth */
- ETZPC_RESERVED, /* 5F reserved */
-};
-
/* fdt helper */
static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr)
{
@@ -263,46 +51,6 @@ static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr)
return false;
}
-static int stm32_fdt_fixup_etzpc(void *fdt, int soc_node)
-{
- const u32 *array;
- int array_size, i;
- int offset, shift;
- u32 addr, status, decprot[ETZPC_DECPROT_NB];
-
- if (IS_ENABLED(CONFIG_STM32MP13X)) {
- array = stm32mp13_ip_addr;
- array_size = ARRAY_SIZE(stm32mp13_ip_addr);
- }
-
- if (IS_ENABLED(CONFIG_STM32MP15X)) {
- array = stm32mp15_ip_addr;
- array_size = ARRAY_SIZE(stm32mp15_ip_addr);
- }
-
- for (i = 0; i < ETZPC_DECPROT_NB; i++)
- decprot[i] = readl(ETZPC_DECPROT(i));
-
- for (i = 0; i < array_size; i++) {
- offset = i / NB_PROT_PER_REG;
- shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS;
- status = (decprot[offset] >> shift) & DECPROT_MASK;
- addr = array[i];
-
- log_debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status);
-
- if (addr == ETZPC_RESERVED ||
- status == DECPROT_NON_SECURED)
- continue;
-
- if (fdt_disable_subnode_by_address(fdt, soc_node, addr))
- log_notice("ETZPC: 0x%08x node disabled, decprot %d=%d\n",
- addr, i, status);
- }
-
- return 0;
-}
-
/* deactivate all the cpu except core 0 */
static void stm32_fdt_fixup_cpu(void *blob, char *name)
{
@@ -481,12 +229,6 @@ int ft_system_setup(void *blob, struct bd_info *bd)
if (soc < 0)
return soc;
- if (CONFIG_IS_ENABLED(STM32_ETZPC)) {
- ret = stm32_fdt_fixup_etzpc(blob, soc);
- if (ret)
- return ret;
- }
-
/* MPUs Part Numbers and name*/
cpu = get_cpu_type();
get_soc_name(name);
diff --git a/arch/arm/mach-stm32mp/stm32mp2/Makefile b/arch/arm/mach-stm32mp/stm32mp2/Makefile
index b579ce5a800..5dbf75daa76 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/Makefile
+++ b/arch/arm/mach-stm32mp/stm32mp2/Makefile
@@ -5,5 +5,6 @@
obj-y += cpu.o
obj-y += arm64-mmu.o
+obj-y += rifsc.o
obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o
obj-$(CONFIG_STM32MP25X) += stm32mp25x.o
diff --git a/arch/arm/mach-stm32mp/stm32mp2/cpu.c b/arch/arm/mach-stm32mp/stm32mp2/cpu.c
index 9530aa8534b..c3b87d7f981 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/cpu.c
+++ b/arch/arm/mach-stm32mp/stm32mp2/cpu.c
@@ -24,7 +24,7 @@
* early TLB into the .data section so that it not get cleared
* with 16kB alignment
*/
-#define EARLY_TLB_SIZE 0xA000
+#define EARLY_TLB_SIZE 0x10000
u8 early_tlb[EARLY_TLB_SIZE] __section(".data") __aligned(0x4000);
/*
@@ -55,6 +55,19 @@ int arch_cpu_init(void)
return 0;
}
+int mach_cpu_init(void)
+{
+ u32 boot_mode;
+
+ boot_mode = get_bootmode();
+
+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) &&
+ (boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART)
+ gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
+
+ return 0;
+}
+
void enable_caches(void)
{
/* deactivate the data cache, early enabled in arch_cpu_init() */
@@ -67,14 +80,6 @@ void enable_caches(void)
dcache_enable();
}
-int arch_misc_init(void)
-{
- setup_serial_number();
- setup_mac_address();
-
- return 0;
-}
-
/*
* Force data-section, as .bss will not be valid
* when save_boot_params is invoked.
@@ -97,3 +102,150 @@ void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
save_boot_params_ret();
}
+
+u32 get_bootmode(void)
+{
+ /* read bootmode from TAMP backup register */
+ return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
+ TAMP_BOOT_MODE_SHIFT;
+}
+
+static void setup_boot_mode(void)
+{
+ const u32 serial_addr[] = {
+ STM32_USART1_BASE,
+ STM32_USART2_BASE,
+ STM32_USART3_BASE,
+ STM32_UART4_BASE,
+ STM32_UART5_BASE,
+ STM32_USART6_BASE,
+ STM32_UART7_BASE,
+ STM32_UART8_BASE,
+ STM32_UART9_BASE
+ };
+ const u32 sdmmc_addr[] = {
+ STM32_SDMMC1_BASE,
+ STM32_SDMMC2_BASE,
+ STM32_SDMMC3_BASE
+ };
+ char cmd[60];
+ u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
+ u32 boot_mode =
+ (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
+ unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
+ u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
+ struct udevice *dev;
+
+ log_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
+ __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))
+ break;
+ /* serial : search associated node in devicetree */
+ sprintf(cmd, "serial@%x", serial_addr[instance]);
+ if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) {
+ /* restore console on error */
+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL))
+ gd->flags &= ~(GD_FLG_SILENT |
+ GD_FLG_DISABLE_CONSOLE);
+ log_err("uart%d = %s not found in device tree!\n",
+ instance + 1, cmd);
+ break;
+ }
+ sprintf(cmd, "%d", dev_seq(dev));
+ env_set("boot_device", "serial");
+ env_set("boot_instance", cmd);
+
+ /* restore console on uart when not used */
+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && gd->cur_serial_dev != dev) {
+ gd->flags &= ~(GD_FLG_SILENT |
+ GD_FLG_DISABLE_CONSOLE);
+ log_info("serial boot with console enabled!\n");
+ }
+ break;
+ case BOOT_SERIAL_USB:
+ env_set("boot_device", "usb");
+ env_set("boot_instance", "0");
+ break;
+ case BOOT_FLASH_SD:
+ case BOOT_FLASH_EMMC:
+ if (instance > ARRAY_SIZE(sdmmc_addr))
+ break;
+ /* search associated sdmmc node in devicetree */
+ sprintf(cmd, "mmc@%x", sdmmc_addr[instance]);
+ if (uclass_get_device_by_name(UCLASS_MMC, cmd, &dev)) {
+ printf("mmc%d = %s not found in device tree!\n",
+ instance, cmd);
+ break;
+ }
+ sprintf(cmd, "%d", dev_seq(dev));
+ env_set("boot_device", "mmc");
+ env_set("boot_instance", cmd);
+ break;
+ case BOOT_FLASH_NAND:
+ env_set("boot_device", "nand");
+ env_set("boot_instance", "0");
+ break;
+ case BOOT_FLASH_SPINAND:
+ env_set("boot_device", "spi-nand");
+ env_set("boot_instance", "0");
+ break;
+ case BOOT_FLASH_NOR:
+ env_set("boot_device", "nor");
+ if (IS_ENABLED(CONFIG_SYS_MAX_FLASH_BANKS))
+ sprintf(cmd, "%d", CONFIG_SYS_MAX_FLASH_BANKS);
+ else
+ sprintf(cmd, "%d", 0);
+ env_set("boot_instance", cmd);
+ break;
+ case BOOT_FLASH_HYPERFLASH:
+ env_set("boot_device", "nor");
+ env_set("boot_instance", "0");
+ break;
+ default:
+ env_set("boot_device", "invalid");
+ env_set("boot_instance", "");
+ log_err("unexpected boot mode = %x\n", boot_mode);
+ break;
+ }
+
+ switch (forced_mode) {
+ case BOOT_FASTBOOT:
+ log_info("Enter fastboot!\n");
+ env_set("preboot", "env set preboot; fastboot 0");
+ break;
+ case BOOT_STM32PROG:
+ env_set("boot_device", "usb");
+ env_set("boot_instance", "0");
+ break;
+ case BOOT_UMS_MMC0:
+ case BOOT_UMS_MMC1:
+ case BOOT_UMS_MMC2:
+ log_info("Enter UMS!\n");
+ instance = forced_mode - BOOT_UMS_MMC0;
+ sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
+ env_set("preboot", cmd);
+ break;
+ case BOOT_RECOVERY:
+ env_set("preboot", "env set preboot; run altbootcmd");
+ break;
+ case BOOT_NORMAL:
+ break;
+ default:
+ log_debug("unexpected forced boot mode = %x\n", forced_mode);
+ break;
+ }
+
+ /* clear TAMP for next reboot */
+ clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
+}
+
+int arch_misc_init(void)
+{
+ setup_boot_mode();
+ setup_serial_number();
+ setup_mac_address();
+
+ return 0;
+}
diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
new file mode 100644
index 00000000000..50dececf77b
--- /dev/null
+++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
@@ -0,0 +1,364 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#define LOG_CATEGORY UCLASS_NOP
+
+#include <dm.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <linux/bitfield.h>
+#include <mach/rif.h>
+
+/* RIFSC offset register */
+#define RIFSC_RISC_SECCFGR0(id) (0x10 + 0x4 * (id))
+#define RIFSC_RISC_PER0_CIDCFGR(id) (0x100 + 0x8 * (id))
+#define RIFSC_RISC_PER0_SEMCR(id) (0x104 + 0x8 * (id))
+
+/*
+ * SEMCR register
+ */
+#define SEMCR_MUTEX BIT(0)
+
+/* RIFSC miscellaneous */
+#define RIFSC_RISC_SCID_MASK GENMASK(6, 4)
+#define RIFSC_RISC_SEMWL_MASK GENMASK(23, 16)
+
+#define IDS_PER_RISC_SEC_PRIV_REGS 32
+
+/*
+ * CIDCFGR register fields
+ */
+#define CIDCFGR_CFEN BIT(0)
+#define CIDCFGR_SEMEN BIT(1)
+
+#define SEMWL_SHIFT 16
+
+#define STM32MP25_RIFSC_ENTRIES 178
+
+/* Compartiment IDs */
+#define RIF_CID0 0x0
+#define RIF_CID1 0x1
+
+/*
+ * struct stm32_rifsc_plat: Information about RIFSC device
+ *
+ * @base: Base address of RIFSC
+ */
+struct stm32_rifsc_plat {
+ void *base;
+};
+
+/*
+ * struct stm32_rifsc_child_plat: Information about each child
+ *
+ * @domain_id: Domain id
+ */
+struct stm32_rifsc_child_plat {
+ u32 domain_id;
+};
+
+static bool stm32_rif_is_semaphore_available(void *base, u32 id)
+{
+ void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
+
+ return !(readl(addr) & SEMCR_MUTEX);
+}
+
+static int stm32_rif_acquire_semaphore(void *base, u32 id)
+{
+ void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
+
+ /* Check that the semaphore is available */
+ if (!stm32_rif_is_semaphore_available(base, id))
+ return -EACCES;
+
+ setbits_le32(addr, SEMCR_MUTEX);
+
+ /* Check that CID1 has the semaphore */
+ if (stm32_rif_is_semaphore_available(base, id) ||
+ FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) != RIF_CID1))
+ return -EACCES;
+
+ return 0;
+}
+
+static int stm32_rif_release_semaphore(void *base, u32 id)
+{
+ void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
+
+ if (stm32_rif_is_semaphore_available(base, id))
+ return 0;
+
+ clrbits_le32(addr, SEMCR_MUTEX);
+
+ /* Ok if another compartment takes the semaphore before the check */
+ if (!stm32_rif_is_semaphore_available(base, id) &&
+ FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) == RIF_CID1))
+ return -EACCES;
+
+ return 0;
+}
+
+static int rifsc_parse_access_controller(ofnode node, struct ofnode_phandle_args *args)
+{
+ int ret;
+
+ ret = ofnode_parse_phandle_with_args(node, "access-controllers",
+ "#access-controller-cells", 0,
+ 0, args);
+ if (ret) {
+ log_debug("failed to parse access-controller (%d)\n", ret);
+ return ret;
+ }
+
+ if (args->args_count != 1) {
+ log_debug("invalid domain args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args[0] >= STM32MP25_RIFSC_ENTRIES) {
+ log_err("Invalid sys bus ID for %s\n", ofnode_get_name(node));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rifsc_check_access(void *base, u32 id)
+{
+ u32 reg_offset, reg_id, sec_reg_value, cid_reg_value, sem_reg_value;
+
+ /*
+ * RIFSC_RISC_PRIVCFGRx and RIFSC_RISC_SECCFGRx both handle configuration access for
+ * 32 peripherals. On the other hand, there is one _RIFSC_RISC_PERx_CIDCFGR register
+ * per peripheral
+ */
+ reg_id = id / IDS_PER_RISC_SEC_PRIV_REGS;
+ reg_offset = id % IDS_PER_RISC_SEC_PRIV_REGS;
+ sec_reg_value = readl(base + RIFSC_RISC_SECCFGR0(reg_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);
+ return -EACCES;
+ }
+
+ /* Check semaphore accesses */
+ if (cid_reg_value & CIDCFGR_SEMEN) {
+ if (!(FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
+ log_debug("Not in semaphore whitelist for peripheral %d\n", id);
+ return -EACCES;
+ }
+ if (!stm32_rif_is_semaphore_available(base, id) &&
+ !(FIELD_GET(RIFSC_RISC_SCID_MASK, sem_reg_value) & BIT(RIF_CID1))) {
+ 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);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+int stm32_rifsc_check_access_by_id(ofnode device_node, u32 id)
+{
+ struct ofnode_phandle_args args;
+ int err;
+
+ if (id >= STM32MP25_RIFSC_ENTRIES)
+ return -EINVAL;
+
+ err = rifsc_parse_access_controller(device_node, &args);
+ if (err)
+ return err;
+
+ return rifsc_check_access((void *)ofnode_get_addr(args.node), id);
+}
+
+int stm32_rifsc_check_access(ofnode device_node)
+{
+ struct ofnode_phandle_args args;
+ int err;
+
+ err = rifsc_parse_access_controller(device_node, &args);
+ if (err)
+ return err;
+
+ return rifsc_check_access((void *)ofnode_get_addr(args.node), args.args[0]);
+}
+
+static int stm32_rifsc_child_pre_probe(struct udevice *dev)
+{
+ struct stm32_rifsc_plat *plat = dev_get_plat(dev->parent);
+ struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
+ u32 cid_reg_value;
+ int err;
+ u32 id = child_plat->domain_id;
+
+ cid_reg_value = readl(plat->base + RIFSC_RISC_PER0_CIDCFGR(id));
+
+ /*
+ * If the peripheral is in semaphore mode, take the semaphore so that
+ * the CID1 has the ownership.
+ */
+ if (cid_reg_value & CIDCFGR_SEMEN &&
+ (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
+ err = stm32_rif_acquire_semaphore(plat->base, id);
+ if (err) {
+ dev_err(dev, "Couldn't acquire RIF semaphore for peripheral %d (%d)\n",
+ id, err);
+ return err;
+ }
+ dev_dbg(dev, "Acquiring semaphore for peripheral %d\n", id);
+ }
+
+ return 0;
+}
+
+static int stm32_rifsc_child_post_remove(struct udevice *dev)
+{
+ struct stm32_rifsc_plat *plat = dev_get_plat(dev->parent);
+ struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
+ u32 cid_reg_value;
+ int err;
+ u32 id = child_plat->domain_id;
+
+ cid_reg_value = readl(plat->base + RIFSC_RISC_PER0_CIDCFGR(id));
+
+ /*
+ * If the peripheral is in semaphore mode, release the semaphore so that
+ * there's no ownership.
+ */
+ if (cid_reg_value & CIDCFGR_SEMEN &&
+ (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
+ err = stm32_rif_release_semaphore(plat->base, id);
+ if (err)
+ dev_err(dev, "Couldn't release rif semaphore for peripheral %d (%d)\n",
+ id, err);
+ }
+
+ return 0;
+}
+
+static int stm32_rifsc_child_post_bind(struct udevice *dev)
+{
+ struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
+ struct ofnode_phandle_args args;
+ int ret;
+
+ if (!dev_has_ofnode(dev))
+ return -EPERM;
+
+ ret = rifsc_parse_access_controller(dev_ofnode(dev), &args);
+ if (ret)
+ return ret;
+
+ child_plat->domain_id = args.args[0];
+
+ return 0;
+}
+
+static int stm32_rifsc_bind(struct udevice *dev)
+{
+ struct stm32_rifsc_plat *plat = dev_get_plat(dev);
+ struct ofnode_phandle_args args;
+ int ret = 0, err = 0;
+ ofnode node;
+
+ plat->base = dev_read_addr_ptr(dev);
+ if (!plat->base) {
+ dev_err(dev, "can't get registers base address\n");
+ return -ENOENT;
+ }
+
+ for (node = ofnode_first_subnode(dev_ofnode(dev));
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ const char *node_name = ofnode_get_name(node);
+
+ if (!ofnode_is_enabled(node))
+ continue;
+
+ err = rifsc_parse_access_controller(node, &args);
+ if (err) {
+ dev_dbg(dev, "%s failed to parse child on bus (%d)\n", node_name, err);
+ continue;
+ }
+
+ err = rifsc_check_access(plat->base, args.args[0]);
+ if (err) {
+ dev_info(dev, "%s not allowed on bus (%d)\n", node_name, err);
+ continue;
+ }
+
+ err = lists_bind_fdt(dev, node, NULL, NULL,
+ gd->flags & GD_FLG_RELOC ? false : true);
+ if (err && !ret) {
+ ret = err;
+ dev_err(dev, "%s failed to bind on bus (%d)\n", node_name, ret);
+ }
+ }
+
+ if (ret)
+ dev_err(dev, "Some child failed to bind (%d)\n", ret);
+
+ return ret;
+}
+
+static int stm32_rifsc_remove(struct udevice *bus)
+{
+ struct udevice *dev;
+
+ /* Deactivate all child devices not yet removed */
+ for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev))
+ if (device_active(dev))
+ stm32_rifsc_child_post_remove(dev);
+
+ return 0;
+}
+
+static const struct udevice_id stm32_rifsc_ids[] = {
+ { .compatible = "st,stm32mp25-rifsc" },
+ {},
+};
+
+U_BOOT_DRIVER(stm32_rifsc) = {
+ .name = "stm32_rifsc",
+ .id = UCLASS_NOP,
+ .of_match = stm32_rifsc_ids,
+ .bind = stm32_rifsc_bind,
+ .remove = stm32_rifsc_remove,
+ .child_post_bind = stm32_rifsc_child_post_bind,
+ .child_pre_probe = stm32_rifsc_child_pre_probe,
+ .child_post_remove = stm32_rifsc_child_post_remove,
+ .plat_auto = sizeof(struct stm32_rifsc_plat),
+ .per_child_plat_auto = sizeof(struct stm32_rifsc_child_plat),
+ .flags = DM_FLAG_OS_PREPARE,
+};
diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c
index 7f896a0d65d..12b43ea5cdf 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c
+++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp25x.c
@@ -15,8 +15,10 @@
#define SYSCFG_DEVICEID_OFFSET 0x6400
#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0)
#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0
-#define SYSCFG_DEVICEID_REV_ID_MASK GENMASK(31, 16)
-#define SYSCFG_DEVICEID_REV_ID_SHIFT 16
+
+/* 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
@@ -24,8 +26,8 @@
/* Package = bit 0:2 of OTP122 => STM32MP25_PKG defines
* - 000: Custom package
- * - 011: TFBGA361 => AL = 10x10, 361 balls pith 0.5mm
- * - 100: TFBGA424 => AK = 14x14, 424 balls pith 0.5mm
+ * - 001: VFBGA361 => AL = 10x10, 361 balls pith 0.5mm
+ * - 011: VFBGA424 => AK = 14x14, 424 balls pith 0.5mm
* - 101: TFBGA436 => AI = 18x18, 436 balls pith 0.5mm
* - others: Reserved
*/
@@ -46,7 +48,7 @@ u32 get_cpu_dev(void)
u32 get_cpu_rev(void)
{
- return (read_deviceid() & SYSCFG_DEVICEID_REV_ID_MASK) >> SYSCFG_DEVICEID_REV_ID_SHIFT;
+ return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK);
}
/* Get Device Part Number (RPN) from OTP */
@@ -164,12 +166,21 @@ void get_soc_name(char name[SOC_NAME_SIZE])
}
/* REVISION */
switch (get_cpu_rev()) {
- case CPU_REV1:
+ case OTP_REVID_1:
cpu_r = "A";
break;
- case CPU_REV2:
+ case OTP_REVID_1_1:
+ cpu_r = "Z";
+ break;
+ case OTP_REVID_2:
cpu_r = "B";
break;
+ case OTP_REVID_2_1:
+ cpu_r = "Y";
+ break;
+ case OTP_REVID_2_2:
+ cpu_r = "X";
+ break;
default:
break;
}
@@ -178,13 +189,13 @@ void get_soc_name(char name[SOC_NAME_SIZE])
case STM32MP25_PKG_CUSTOM:
package = "XX";
break;
- case STM32MP25_PKG_AL_TBGA361:
+ case STM32MP25_PKG_AL_VFBGA361:
package = "AL";
break;
- case STM32MP25_PKG_AK_TBGA424:
+ case STM32MP25_PKG_AK_VFBGA424:
package = "AK";
break;
- case STM32MP25_PKG_AI_TBGA436:
+ case STM32MP25_PKG_AI_TFBGA436:
package = "AI";
break;
default: