diff options
Diffstat (limited to 'arch/arm/mach-stm32mp')
-rw-r--r-- | arch/arm/mach-stm32mp/Kconfig | 34 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/Kconfig.13x | 5 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/Kconfig.23x | 37 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/cmd_stm32key.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/include/mach/stm32.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/include/mach/sys_proto.h | 53 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/include/mach/timers.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/stm32mp1/cpu.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/stm32mp1/spl.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c | 204 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/stm32mp2/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c | 191 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/timers.c | 34 |
14 files changed, 566 insertions, 33 deletions
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 09b7d5123ae..ba4694f2964 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -40,16 +40,19 @@ choice config STM32MP13X bool "Support STMicroelectronics STM32MP13x Soc" select ARCH_EARLY_INIT_R - select ARM_SMCCC + select ARM_SMCCC if TFABOOT + select ARCH_SUPPORT_PSCI if !TFABOOT + select BINMAN if !TFABOOT select CPU_V7A select CPU_V7_HAS_NONSEC select CPU_V7_HAS_VIRT - select OF_BOARD + select OF_BOARD if TFABOOT select OF_BOARD_SETUP select PINCTRL_STM32 select STM32_RCC select STM32_RESET select STM32_SERIAL + select SUPPORT_SPL if !TFABOOT select SYS_ARCH_TIMER imply CMD_NVEDIT_INFO imply OF_UPSTREAM @@ -81,6 +84,32 @@ config STM32MP15X STMicroelectronics MPU with core ARMv7 dual core A7 for STM32MP157/3, monocore for STM32MP151 +config STM32MP23X + bool "Support STMicroelectronics STM32MP23x Soc" + select ARM64 + select CLK_STM32MP25 + 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 STM32MP23x family + STMicroelectronics MPU with 2 * A53 core and 1 M33 core + config STM32MP25X bool "Support STMicroelectronics STM32MP25x Soc" select ARM64 @@ -165,6 +194,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.23x" source "arch/arm/mach-stm32mp/Kconfig.25x" source "arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig" diff --git a/arch/arm/mach-stm32mp/Kconfig.13x b/arch/arm/mach-stm32mp/Kconfig.13x index bc8b3f8cf77..6a45c4e4132 100644 --- a/arch/arm/mach-stm32mp/Kconfig.13x +++ b/arch/arm/mach-stm32mp/Kconfig.13x @@ -20,10 +20,11 @@ config TARGET_ST_STM32MP13X endchoice config TEXT_BASE - default 0xC0000000 + default 0xC0000000 if TFABOOT + default 0xC0100000 if !TFABOOT config PRE_CON_BUF_ADDR - default 0xC0800000 + default 0xC2FFF000 config PRE_CON_BUF_SZ default 4096 diff --git a/arch/arm/mach-stm32mp/Kconfig.23x b/arch/arm/mach-stm32mp/Kconfig.23x new file mode 100644 index 00000000000..2859210c77c --- /dev/null +++ b/arch/arm/mach-stm32mp/Kconfig.23x @@ -0,0 +1,37 @@ +if STM32MP23X + +choice + prompt "STM32MP23x board select" + optional + +config TARGET_ST_STM32MP23X + bool "STMicroelectronics STM32MP23x boards" + imply BOOTSTAGE + imply CMD_BOOTSTAGE + help + target the STMicroelectronics board with SOC STM32MP23x + 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 ecd49fe668d..eeb5fdd7b45 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile @@ -10,6 +10,7 @@ obj-y += soc.o obj-$(CONFIG_STM32MP15X) += stm32mp1/ obj-$(CONFIG_STM32MP13X) += stm32mp1/ +obj-$(CONFIG_STM32MP23X) += stm32mp2/ obj-$(CONFIG_STM32MP25X) += stm32mp2/ obj-$(CONFIG_MFD_STM32_TIMERS) += timers.o diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 6bfa67859e1..f5def4cd2dc 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -171,7 +171,7 @@ static u8 get_key_nb(void) if (IS_ENABLED(CONFIG_STM32MP15X)) return ARRAY_SIZE(stm32mp15_list); - if (IS_ENABLED(CONFIG_STM32MP25X)) + if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) return ARRAY_SIZE(stm32mp25_list); } @@ -183,7 +183,7 @@ static const struct stm32key *get_key(u8 index) if (IS_ENABLED(CONFIG_STM32MP15X)) return &stm32mp15_list[index]; - if (IS_ENABLED(CONFIG_STM32MP25X)) + if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) return &stm32mp25_list[index]; } @@ -195,7 +195,7 @@ static u8 get_otp_close_state_nb(void) if (IS_ENABLED(CONFIG_STM32MP15X)) return ARRAY_SIZE(stm32mp15_close_state_otp); - if (IS_ENABLED(CONFIG_STM32MP25X)) + if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) return ARRAY_SIZE(stm32mp25_close_state_otp); } @@ -207,7 +207,7 @@ 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_STM32MP25X)) + if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)) return &stm32mp25_close_state_otp[index]; } diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index dfba57e7dc4..2bf50c755cb 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -156,6 +156,8 @@ enum forced_boot_mode { #endif #ifdef CONFIG_STM32MP13X +#define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4) +#define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5) #define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(31) #define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(30) #endif @@ -163,7 +165,7 @@ enum forced_boot_mode { #endif /* __ASSEMBLY__ */ #endif /* CONFIG_STM32MP15X || CONFIG_STM32MP13X */ -#ifdef CONFIG_STM32MP25X +#if defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) #define STM32_USART2_BASE 0x400E0000 #define STM32_USART3_BASE 0x400F0000 #define STM32_UART4_BASE 0x40100000 @@ -188,7 +190,7 @@ enum forced_boot_mode { /* TAMP registers zone 3 RIF 1 (RW) at 96*/ #define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(96) -#endif /* STM32MP25X */ +#endif /* defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */ /* offset used for BSEC driver: misc_read and misc_write */ #define STM32_BSEC_SHADOW_OFFSET 0x0 @@ -212,14 +214,14 @@ enum forced_boot_mode { #define BSEC_OTP_MAC 57 #define BSEC_OTP_BOARD 60 #endif -#ifdef CONFIG_STM32MP25X +#if 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 +#endif /* defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */ #ifndef __ASSEMBLY__ #include <asm/types.h> diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h index 19073668497..2a4837184fc 100644 --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h @@ -30,29 +30,44 @@ #define CPU_STM32MP131Fxx 0x05010EC8 #define CPU_STM32MP131Dxx 0x05010EC9 +/* ID for STM32MP23x = Device Part Number (RPN) (bit31:0) */ +#define CPU_STM32MP235Cxx 0x00082182 +#define CPU_STM32MP233Cxx 0x000B318E +#define CPU_STM32MP231Cxx 0x000B31EF +#define CPU_STM32MP235Axx 0x40082F82 +#define CPU_STM32MP233Axx 0x400B3F8E +#define CPU_STM32MP231Axx 0x400B3FEF +#define CPU_STM32MP235Fxx 0x80082182 +#define CPU_STM32MP233Fxx 0x800B318E +#define CPU_STM32MP231Fxx 0x800B31EF +#define CPU_STM32MP235Dxx 0xC0082F82 +#define CPU_STM32MP233Dxx 0xC00B3F8E +#define CPU_STM32MP231Dxx 0xC00B3FEF + /* ID for STM32MP25x = Device Part Number (RPN) (bit31:0) */ -#define CPU_STM32MP257Cxx 0x00002000 -#define CPU_STM32MP255Cxx 0x00082000 -#define CPU_STM32MP253Cxx 0x000B2004 -#define CPU_STM32MP251Cxx 0x000B3065 -#define CPU_STM32MP257Axx 0x40002E00 -#define CPU_STM32MP255Axx 0x40082E00 -#define CPU_STM32MP253Axx 0x400B2E04 -#define CPU_STM32MP251Axx 0x400B3E65 -#define CPU_STM32MP257Fxx 0x80002000 -#define CPU_STM32MP255Fxx 0x80082000 -#define CPU_STM32MP253Fxx 0x800B2004 -#define CPU_STM32MP251Fxx 0x800B3065 -#define CPU_STM32MP257Dxx 0xC0002E00 -#define CPU_STM32MP255Dxx 0xC0082E00 -#define CPU_STM32MP253Dxx 0xC00B2E04 -#define CPU_STM32MP251Dxx 0xC00B3E65 +#define CPU_STM32MP257Cxx 0x00002000 +#define CPU_STM32MP255Cxx 0x00082000 +#define CPU_STM32MP253Cxx 0x000B2004 +#define CPU_STM32MP251Cxx 0x000B3065 +#define CPU_STM32MP257Axx 0x40002E00 +#define CPU_STM32MP255Axx 0x40082E00 +#define CPU_STM32MP253Axx 0x400B2E04 +#define CPU_STM32MP251Axx 0x400B3E65 +#define CPU_STM32MP257Fxx 0x80002000 +#define CPU_STM32MP255Fxx 0x80082000 +#define CPU_STM32MP253Fxx 0x800B2004 +#define CPU_STM32MP251Fxx 0x800B3065 +#define CPU_STM32MP257Dxx 0xC0002E00 +#define CPU_STM32MP255Dxx 0xC0082E00 +#define CPU_STM32MP253Dxx 0xC00B2E04 +#define CPU_STM32MP251Dxx 0xC00B3E65 /* return CPU_STMP32MP...Xxx constants */ u32 get_cpu_type(void); #define CPU_DEV_STM32MP15 0x500 #define CPU_DEV_STM32MP13 0x501 +#define CPU_DEV_STM32MP23 0x505 #define CPU_DEV_STM32MP25 0x505 /* return CPU_DEV constants */ @@ -87,6 +102,12 @@ u32 get_cpu_package(void); #define STM32MP15_PKG_AD_TFBGA257 1 #define STM32MP15_PKG_UNKNOWN 0 +/* package used for STM32MP23x */ +#define STM32MP23_PKG_CUSTOM 0 +#define STM32MP23_PKG_AL_VFBGA361 1 +#define STM32MP23_PKG_AK_VFBGA424 3 +#define STM32MP23_PKG_AJ_TFBGA361 7 + /* package used for STM32MP25x */ #define STM32MP25_PKG_CUSTOM 0 #define STM32MP25_PKG_AL_VFBGA361 1 diff --git a/arch/arm/mach-stm32mp/include/mach/timers.h b/arch/arm/mach-stm32mp/include/mach/timers.h index a84465bb28e..8209dd84911 100644 --- a/arch/arm/mach-stm32mp/include/mach/timers.h +++ b/arch/arm/mach-stm32mp/include/mach/timers.h @@ -29,6 +29,10 @@ #define TIM_DMAR 0x4C /* DMA register for transfer */ #define TIM_TISEL 0x68 /* Input Selection */ +#define TIM_HWCFGR2 0x3EC /* hardware configuration 2 Reg (MP25) */ +#define TIM_HWCFGR1 0x3F0 /* hardware configuration 1 Reg (MP25) */ +#define TIM_IPIDR 0x3F8 /* IP identification Reg (MP25) */ + #define TIM_CR1_CEN BIT(0) /* Counter Enable */ #define TIM_CR1_ARPE BIT(7) #define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12)) @@ -40,11 +44,16 @@ #define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */ #define TIM_BDTR_MOE BIT(15) /* Main Output Enable */ #define TIM_EGR_UG BIT(0) /* Update Generation */ +#define TIM_HWCFGR2_CNT_WIDTH GENMASK(15, 8) /* Counter width */ +#define TIM_HWCFGR1_NB_OF_DT GENMASK(7, 4) /* Complementary outputs & dead-time generators */ #define MAX_TIM_PSC 0xFFFF +#define STM32MP25_TIM_IPIDR 0x00120002 + struct stm32_timers_plat { void __iomem *base; + u32 ipidr; }; struct stm32_timers_priv { diff --git a/arch/arm/mach-stm32mp/stm32mp1/cpu.c b/arch/arm/mach-stm32mp/stm32mp1/cpu.c index 8c09d91de05..e0c6f8ba937 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/cpu.c +++ b/arch/arm/mach-stm32mp/stm32mp1/cpu.c @@ -28,7 +28,9 @@ * early TLB into the .data section so that it not get cleared * with 16kB allignment (see TTBR0_BASE_ADDR_MASK) */ +#if (!IS_ENABLED(CONFIG_XPL_BUILD) || !IS_ENABLED(CONFIG_STM32MP13X)) u8 early_tlb[PGTABLE_SIZE] __section(".data") __aligned(0x4000); +#endif u32 get_bootmode(void) { @@ -95,18 +97,19 @@ void dram_bank_mmu_setup(int bank) */ static void early_enable_caches(void) { +#if (!IS_ENABLED(CONFIG_XPL_BUILD) || !IS_ENABLED(CONFIG_STM32MP13X)) /* I-cache is already enabled in start.S: cpu_init_cp15 */ - if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) return; #if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) - gd->arch.tlb_size = PGTABLE_SIZE; - gd->arch.tlb_addr = (unsigned long)&early_tlb; + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = (unsigned long)&early_tlb; #endif /* enable MMU (default configuration) */ dcache_enable(); +#endif } /* diff --git a/arch/arm/mach-stm32mp/stm32mp1/spl.c b/arch/arm/mach-stm32mp/stm32mp1/spl.c index 9c4fafbf478..e63bdaaf42f 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/spl.c +++ b/arch/arm/mach-stm32mp/stm32mp1/spl.c @@ -220,10 +220,11 @@ void board_init_f(ulong dummy) * activate cache on DDR only when DDR is fully initialized * to avoid speculative access and issue in get_ram_size() */ - if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) + if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !IS_ENABLED(CONFIG_STM32MP13X)) { mmu_set_region_dcache_behaviour(STM32_DDR_BASE, CONFIG_DDR_CACHEABLE_SIZE, DCACHE_DEFAULT_OPTION); + } } void spl_board_prepare_for_boot(void) diff --git a/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c b/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c index 4a811065fc3..79b2f2d0bba 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c +++ b/arch/arm/mach-stm32mp/stm32mp1/stm32mp13x.c @@ -6,11 +6,59 @@ #define LOG_CATEGORY LOGC_ARCH #include <config.h> +#include <cpu_func.h> #include <log.h> #include <syscon.h> #include <asm/io.h> +#include <asm/system.h> +#include <asm/arch/bsec.h> #include <asm/arch/stm32.h> #include <asm/arch/sys_proto.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <linux/bitfield.h> +#include <malloc.h> + +/* RCC register */ +#define RCC_TZCR (STM32_RCC_BASE + 0x00) +#define RCC_BDCR (STM32_RCC_BASE + 0x400) +#define RCC_DBGCFGR (STM32_RCC_BASE + 0x468) +#define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x740) +#define RCC_MP_AHB6ENSETR (STM32_RCC_BASE + 0x780) + +#define RCC_BDCR_VSWRST BIT(31) +#define RCC_BDCR_RTCSRC GENMASK(17, 16) + +#define RCC_DBGCFGR_DBGCKEN BIT(8) + +/* DBGMCU register */ +#define DBGMCU_APB4FZ1 (STM32_DBGMCU_BASE + 0x2c) +#define DBGMCU_APB4FZ1_IWDG2 BIT(2) + +/* Security register */ +#define ETZPC_TZMA1_SIZE (STM32_ETZPC_BASE + 0x04) +#define ETZPC_DECPROT0 (STM32_ETZPC_BASE + 0x10) + +#define TZC_ACTION (STM32_TZC_BASE + 0x004) +#define TZC_GATE_KEEPER (STM32_TZC_BASE + 0x008) +#define TZC_REGION_BASE(n) (STM32_TZC_BASE + 0x100 + (0x20 * (n))) +#define TZC_REGION_TOP(n) (STM32_TZC_BASE + 0x108 + (0x20 * (n))) +#define TZC_REGION_ATTRIBUTE(n) (STM32_TZC_BASE + 0x110 + (0x20 * (n))) +#define TZC_REGION_ID_ACCESS(n) (STM32_TZC_BASE + 0x114 + (0x20 * (n))) + +#define TAMP_CR1 (STM32_TAMP_BASE + 0x00) + +#define PWR_CR1 (STM32_PWR_BASE + 0x00) +#define PWR_CR1_DBP BIT(8) + +/* boot interface from Bootrom + * - boot instance = bit 31:16 + * - boot device = bit 15:0 + */ +#define BOOTROM_MODE_MASK GENMASK(15, 0) +#define BOOTROM_MODE_SHIFT 0 +#define BOOTROM_INSTANCE_MASK GENMASK(31, 16) +#define BOOTROM_INSTANCE_SHIFT 16 /* SYSCFG register */ #define SYSCFG_IDC_OFFSET 0x380 @@ -23,6 +71,162 @@ #define RPN_SHIFT 0 #define RPN_MASK GENMASK(11, 0) +static void security_init(void) +{ + /* Disable the backup domain write protection */ + /* the protection is enable at each reset by hardware */ + /* And must be disable by software */ + setbits_le32(PWR_CR1, PWR_CR1_DBP); + + while (!(readl(PWR_CR1) & PWR_CR1_DBP)) + ; + + /* If RTC clock isn't enable so this is a cold boot then we need + * to reset the backup domain + */ + if (!(readl(RCC_BDCR) & RCC_BDCR_RTCSRC)) { + setbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); + while (!(readl(RCC_BDCR) & RCC_BDCR_VSWRST)) + ; + clrbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); + } + + /* allow non secure access in Write/Read for all peripheral */ + writel(0, ETZPC_DECPROT0); + + /* Open SYSRAM for no secure access */ + writel(0x0, ETZPC_TZMA1_SIZE); + + /* enable MCE clock */ + writel(BIT(1), RCC_MP_AHB6ENSETR); + + /* enable TZC clock */ + writel(BIT(11), RCC_MP_APB5ENSETR); + + /* Disable Filter 0 */ + writel(0, TZC_GATE_KEEPER); + + /* Region 0 set to no access by default */ + /* bit 0 / 16 => nsaid0 read/write Enable + * bit 1 / 17 => nsaid1 read/write Enable + * ... + * bit 15 / 31 => nsaid15 read/write Enable + */ + writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS(0)); + + /* bit 30 / 31 => Secure Global Enable : write/read */ + writel(BIT(0) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE(0)); + + writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS(1)); + writel(0xC0000000, TZC_REGION_BASE(1)); + writel(0xDDFFFFFF, TZC_REGION_TOP(1)); + writel(BIT(0) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE(1)); + + writel(0x00000000, TZC_REGION_ID_ACCESS(2)); + writel(0xDE000000, TZC_REGION_BASE(2)); + writel(0xDFFFFFFF, TZC_REGION_TOP(2)); + writel(BIT(0) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE(2)); + + writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS(3)); + writel(0x00000000, TZC_REGION_BASE(3)); + writel(0xBFFFFFFF, TZC_REGION_TOP(3)); + writel(BIT(0) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE(3)); + + /* Set Action */ + writel(BIT(0), TZC_ACTION); + + /* Enable Filter 0 */ + writel(BIT(0), TZC_GATE_KEEPER); + + /* RCC trust zone deactivated */ + writel(0x0, RCC_TZCR); + + /* TAMP: deactivate the internal tamper + * Bit 23 ITAMP8E: monotonic counter overflow + * Bit 20 ITAMP5E: RTC calendar overflow + * Bit 19 ITAMP4E: HSE monitoring + * Bit 18 ITAMP3E: LSE monitoring + * Bit 16 ITAMP1E: RTC power domain supply monitoring + */ + writel(0x0, TAMP_CR1); +} + +/* + * Debug init + */ +void dbgmcu_init(void) +{ + /* + * Freeze IWDG2 if Cortex-A7 is in debug mode + * done in TF-A for TRUSTED boot and + * DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE + */ + if (bsec_dbgswenable()) { + setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); + setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2); + } +} + +void spl_board_init(void) +{ + struct udevice *dev; + u8 *tlb; + int ret; + + dbgmcu_init(); + + /* force probe of BSEC driver to shadow the upper OTP */ + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(stm32mp_bsec), &dev); + if (ret) + log_warning("BSEC probe failed: %d\n", ret); + + /* Enable Dcache here, now that DRAM is available */ + if (IS_ENABLED(CONFIG_XPL_BUILD) && IS_ENABLED(CONFIG_STM32MP13X)) { + tlb = memalign(0x4000, PGTABLE_SIZE); + if (!tlb) + return; + + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = (unsigned long)tlb; + dcache_enable(); + } +} + +/* get bootmode from ROM code boot context: saved in TAMP register */ +static void update_bootmode(void) +{ + u32 boot_mode; + u32 bootrom_itf = readl(get_stm32mp_rom_api_table()); + u32 bootrom_device, bootrom_instance; + + /* enable TAMP clock = RTCAPBEN */ + writel(BIT(8), RCC_MP_APB5ENSETR); + + /* read bootrom context */ + bootrom_device = + (bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT; + bootrom_instance = + (bootrom_itf & BOOTROM_INSTANCE_MASK) >> BOOTROM_INSTANCE_SHIFT; + boot_mode = + ((bootrom_device << BOOT_TYPE_SHIFT) & BOOT_TYPE_MASK) | + ((bootrom_instance << BOOT_INSTANCE_SHIFT) & + BOOT_INSTANCE_MASK); + + /* save the boot mode in TAMP backup register */ + clrsetbits_le32(TAMP_BOOT_CONTEXT, + TAMP_BOOT_MODE_MASK, + boot_mode << TAMP_BOOT_MODE_SHIFT); +} + +/* weak function: STM32MP15x mach init for boot without TFA */ +void stm32mp_cpu_init(void) +{ + if (IS_ENABLED(CONFIG_XPL_BUILD)) { + security_init(); + update_bootmode(); + } +} + static u32 read_idc(void) { void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); diff --git a/arch/arm/mach-stm32mp/stm32mp2/Makefile b/arch/arm/mach-stm32mp/stm32mp2/Makefile index 5dbf75daa76..27fbf3ae728 100644 --- a/arch/arm/mach-stm32mp/stm32mp2/Makefile +++ b/arch/arm/mach-stm32mp/stm32mp2/Makefile @@ -7,4 +7,5 @@ obj-y += cpu.o obj-y += arm64-mmu.o obj-y += rifsc.o obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o +obj-$(CONFIG_STM32MP23X) += stm32mp23x.o obj-$(CONFIG_STM32MP25X) += stm32mp25x.o diff --git a/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c b/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c new file mode 100644 index 00000000000..022db60811a --- /dev/null +++ b/arch/arm/mach-stm32mp/stm32mp2/stm32mp23x.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2025, 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> + +/* 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 + * - 100: TFBGA424 => AK = 14x14, 424 balls pith 0.5mm + * - 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) +{ + int nb_eth; + + switch (get_cpu_type()) { + case CPU_STM32MP235Fxx: + fallthrough; + case CPU_STM32MP235Dxx: + fallthrough; + case CPU_STM32MP235Cxx: + fallthrough; + case CPU_STM32MP235Axx: + fallthrough; + case CPU_STM32MP233Fxx: + fallthrough; + case CPU_STM32MP233Dxx: + fallthrough; + case CPU_STM32MP233Cxx: + fallthrough; + case CPU_STM32MP233Axx: + nb_eth = 2; /* dual ETH */ + break; + case CPU_STM32MP231Fxx: + fallthrough; + case CPU_STM32MP231Dxx: + fallthrough; + case CPU_STM32MP231Cxx: + fallthrough; + case CPU_STM32MP231Axx: + 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_STM32MP23) { + switch (get_cpu_type()) { + case CPU_STM32MP235Fxx: + cpu_s = "235F"; + break; + case CPU_STM32MP235Dxx: + cpu_s = "235D"; + break; + case CPU_STM32MP235Cxx: + cpu_s = "235C"; + break; + case CPU_STM32MP235Axx: + cpu_s = "235A"; + break; + case CPU_STM32MP233Fxx: + cpu_s = "233F"; + break; + case CPU_STM32MP233Dxx: + cpu_s = "233D"; + break; + case CPU_STM32MP233Cxx: + cpu_s = "233C"; + break; + case CPU_STM32MP233Axx: + cpu_s = "233A"; + break; + case CPU_STM32MP231Fxx: + cpu_s = "231F"; + break; + case CPU_STM32MP231Dxx: + cpu_s = "231D"; + break; + case CPU_STM32MP231Cxx: + cpu_s = "231C"; + break; + case CPU_STM32MP231Axx: + cpu_s = "231A"; + break; + default: + cpu_s = "23??"; + break; + } + /* REVISION */ + switch (get_cpu_rev()) { + case OTP_REVID_1: + cpu_r = "A"; + 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; + } + /* PACKAGE */ + switch (get_cpu_package()) { + case STM32MP23_PKG_CUSTOM: + package = "XX"; + break; + case STM32MP23_PKG_AL_VFBGA361: + package = "AL"; + break; + case STM32MP23_PKG_AK_VFBGA424: + package = "AK"; + break; + case STM32MP23_PKG_AJ_TFBGA361: + package = "AJ"; + 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/timers.c b/arch/arm/mach-stm32mp/timers.c index a3207895f40..1940ba42f74 100644 --- a/arch/arm/mach-stm32mp/timers.c +++ b/arch/arm/mach-stm32mp/timers.c @@ -10,6 +10,7 @@ #include <asm/io.h> #include <asm/arch/timers.h> #include <dm/device_compat.h> +#include <linux/bitfield.h> static void stm32_timers_get_arr_size(struct udevice *dev) { @@ -29,6 +30,33 @@ static void stm32_timers_get_arr_size(struct udevice *dev) writel(arr, plat->base + TIM_ARR); } +static int stm32_timers_probe_hwcfgr(struct udevice *dev) +{ + struct stm32_timers_plat *plat = dev_get_plat(dev); + struct stm32_timers_priv *priv = dev_get_priv(dev); + u32 val; + + if (!plat->ipidr) { + /* fallback to legacy method for probing counter width */ + stm32_timers_get_arr_size(dev); + return 0; + } + + val = readl(plat->base + TIM_IPIDR); + /* Sanity check on IP identification register */ + if (val != plat->ipidr) { + dev_err(dev, "Unexpected identification: %u\n", val); + return -EINVAL; + } + + val = readl(plat->base + TIM_HWCFGR2); + /* Counter width in bits, max reload value is BIT(width) - 1 */ + priv->max_arr = BIT(FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)) - 1; + dev_dbg(dev, "TIM width: %ld\n", FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)); + + return 0; +} + static int stm32_timers_of_to_plat(struct udevice *dev) { struct stm32_timers_plat *plat = dev_get_plat(dev); @@ -38,6 +66,7 @@ static int stm32_timers_of_to_plat(struct udevice *dev) dev_err(dev, "can't get address\n"); return -ENOENT; } + plat->ipidr = (u32)dev_get_driver_data(dev); return 0; } @@ -60,13 +89,16 @@ static int stm32_timers_probe(struct udevice *dev) priv->rate = clk_get_rate(&clk); - stm32_timers_get_arr_size(dev); + ret = stm32_timers_probe_hwcfgr(dev); + if (ret) + clk_disable(&clk); return ret; } static const struct udevice_id stm32_timers_ids[] = { { .compatible = "st,stm32-timers" }, + { .compatible = "st,stm32mp25-timers", .data = STM32MP25_TIM_IPIDR }, {} }; |