xref: /arm-trusted-firmware/plat/st/stm32mp1/stm32mp1_private.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <drivers/clk.h>
10*91f16700Schasinglulu #include <drivers/st/stm32_gpio.h>
11*91f16700Schasinglulu #include <drivers/st/stm32_iwdg.h>
12*91f16700Schasinglulu #include <lib/mmio.h>
13*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_v2.h>
14*91f16700Schasinglulu #include <libfdt.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu #include <plat/common/platform.h>
17*91f16700Schasinglulu #include <platform_def.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #if STM32MP13
20*91f16700Schasinglulu #define TAMP_BOOT_MODE_BACKUP_REG_ID	U(30)
21*91f16700Schasinglulu #endif
22*91f16700Schasinglulu #if STM32MP15
23*91f16700Schasinglulu #define TAMP_BOOT_MODE_BACKUP_REG_ID	U(20)
24*91f16700Schasinglulu #endif
25*91f16700Schasinglulu 
26*91f16700Schasinglulu /*
27*91f16700Schasinglulu  * Backup register to store fwu update information.
28*91f16700Schasinglulu  * It should be writeable only by secure world, but also readable by non secure
29*91f16700Schasinglulu  * (so it should be in Zone 2).
30*91f16700Schasinglulu  */
31*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_REG_ID	U(10)
32*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_IDX_MSK	GENMASK(3, 0)
33*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_IDX_OFF	U(0)
34*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_CNT_MSK	GENMASK(7, 4)
35*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_CNT_OFF	U(4)
36*91f16700Schasinglulu 
37*91f16700Schasinglulu #if defined(IMAGE_BL2)
38*91f16700Schasinglulu #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
39*91f16700Schasinglulu 					STM32MP_SYSRAM_SIZE, \
40*91f16700Schasinglulu 					MT_MEMORY | \
41*91f16700Schasinglulu 					MT_RW | \
42*91f16700Schasinglulu 					MT_SECURE | \
43*91f16700Schasinglulu 					MT_EXECUTE_NEVER)
44*91f16700Schasinglulu #elif defined(IMAGE_BL32)
45*91f16700Schasinglulu #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
46*91f16700Schasinglulu 					STM32MP_SEC_SYSRAM_SIZE, \
47*91f16700Schasinglulu 					MT_MEMORY | \
48*91f16700Schasinglulu 					MT_RW | \
49*91f16700Schasinglulu 					MT_SECURE | \
50*91f16700Schasinglulu 					MT_EXECUTE_NEVER)
51*91f16700Schasinglulu 
52*91f16700Schasinglulu /* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
53*91f16700Schasinglulu #define MAP_NS_SYSRAM	MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
54*91f16700Schasinglulu 					STM32MP_NS_SYSRAM_SIZE, \
55*91f16700Schasinglulu 					MT_DEVICE | \
56*91f16700Schasinglulu 					MT_RW | \
57*91f16700Schasinglulu 					MT_NS | \
58*91f16700Schasinglulu 					MT_EXECUTE_NEVER)
59*91f16700Schasinglulu #endif
60*91f16700Schasinglulu 
61*91f16700Schasinglulu #if STM32MP13
62*91f16700Schasinglulu #define MAP_SRAM_ALL	MAP_REGION_FLAT(SRAMS_BASE, \
63*91f16700Schasinglulu 					SRAMS_SIZE_2MB_ALIGNED, \
64*91f16700Schasinglulu 					MT_MEMORY | \
65*91f16700Schasinglulu 					MT_RW | \
66*91f16700Schasinglulu 					MT_SECURE | \
67*91f16700Schasinglulu 					MT_EXECUTE_NEVER)
68*91f16700Schasinglulu #endif
69*91f16700Schasinglulu 
70*91f16700Schasinglulu #define MAP_DEVICE1	MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
71*91f16700Schasinglulu 					STM32MP1_DEVICE1_SIZE, \
72*91f16700Schasinglulu 					MT_DEVICE | \
73*91f16700Schasinglulu 					MT_RW | \
74*91f16700Schasinglulu 					MT_SECURE | \
75*91f16700Schasinglulu 					MT_EXECUTE_NEVER)
76*91f16700Schasinglulu 
77*91f16700Schasinglulu #define MAP_DEVICE2	MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
78*91f16700Schasinglulu 					STM32MP1_DEVICE2_SIZE, \
79*91f16700Schasinglulu 					MT_DEVICE | \
80*91f16700Schasinglulu 					MT_RW | \
81*91f16700Schasinglulu 					MT_SECURE | \
82*91f16700Schasinglulu 					MT_EXECUTE_NEVER)
83*91f16700Schasinglulu 
84*91f16700Schasinglulu #if defined(IMAGE_BL2)
85*91f16700Schasinglulu static const mmap_region_t stm32mp1_mmap[] = {
86*91f16700Schasinglulu 	MAP_SEC_SYSRAM,
87*91f16700Schasinglulu #if STM32MP13
88*91f16700Schasinglulu 	MAP_SRAM_ALL,
89*91f16700Schasinglulu #endif
90*91f16700Schasinglulu 	MAP_DEVICE1,
91*91f16700Schasinglulu #if STM32MP_RAW_NAND
92*91f16700Schasinglulu 	MAP_DEVICE2,
93*91f16700Schasinglulu #endif
94*91f16700Schasinglulu 	{0}
95*91f16700Schasinglulu };
96*91f16700Schasinglulu #endif
97*91f16700Schasinglulu #if defined(IMAGE_BL32)
98*91f16700Schasinglulu static const mmap_region_t stm32mp1_mmap[] = {
99*91f16700Schasinglulu 	MAP_SEC_SYSRAM,
100*91f16700Schasinglulu 	MAP_NS_SYSRAM,
101*91f16700Schasinglulu 	MAP_DEVICE1,
102*91f16700Schasinglulu 	MAP_DEVICE2,
103*91f16700Schasinglulu 	{0}
104*91f16700Schasinglulu };
105*91f16700Schasinglulu #endif
106*91f16700Schasinglulu 
107*91f16700Schasinglulu void configure_mmu(void)
108*91f16700Schasinglulu {
109*91f16700Schasinglulu 	mmap_add(stm32mp1_mmap);
110*91f16700Schasinglulu 	init_xlat_tables();
111*91f16700Schasinglulu 
112*91f16700Schasinglulu 	enable_mmu_svc_mon(0);
113*91f16700Schasinglulu }
114*91f16700Schasinglulu 
115*91f16700Schasinglulu uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
116*91f16700Schasinglulu {
117*91f16700Schasinglulu #if STM32MP13
118*91f16700Schasinglulu 	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
119*91f16700Schasinglulu #endif
120*91f16700Schasinglulu #if STM32MP15
121*91f16700Schasinglulu 	if (bank == GPIO_BANK_Z) {
122*91f16700Schasinglulu 		return GPIOZ_BASE;
123*91f16700Schasinglulu 	}
124*91f16700Schasinglulu 
125*91f16700Schasinglulu 	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
126*91f16700Schasinglulu #endif
127*91f16700Schasinglulu 
128*91f16700Schasinglulu 	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
129*91f16700Schasinglulu }
130*91f16700Schasinglulu 
131*91f16700Schasinglulu uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
132*91f16700Schasinglulu {
133*91f16700Schasinglulu #if STM32MP13
134*91f16700Schasinglulu 	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
135*91f16700Schasinglulu #endif
136*91f16700Schasinglulu #if STM32MP15
137*91f16700Schasinglulu 	if (bank == GPIO_BANK_Z) {
138*91f16700Schasinglulu 		return 0;
139*91f16700Schasinglulu 	}
140*91f16700Schasinglulu 
141*91f16700Schasinglulu 	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
142*91f16700Schasinglulu #endif
143*91f16700Schasinglulu 
144*91f16700Schasinglulu 	return bank * GPIO_BANK_OFFSET;
145*91f16700Schasinglulu }
146*91f16700Schasinglulu 
147*91f16700Schasinglulu bool stm32_gpio_is_secure_at_reset(unsigned int bank)
148*91f16700Schasinglulu {
149*91f16700Schasinglulu #if STM32MP13
150*91f16700Schasinglulu 	return true;
151*91f16700Schasinglulu #endif
152*91f16700Schasinglulu #if STM32MP15
153*91f16700Schasinglulu 	if (bank == GPIO_BANK_Z) {
154*91f16700Schasinglulu 		return true;
155*91f16700Schasinglulu 	}
156*91f16700Schasinglulu 
157*91f16700Schasinglulu 	return false;
158*91f16700Schasinglulu #endif
159*91f16700Schasinglulu }
160*91f16700Schasinglulu 
161*91f16700Schasinglulu unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
162*91f16700Schasinglulu {
163*91f16700Schasinglulu #if STM32MP13
164*91f16700Schasinglulu 	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
165*91f16700Schasinglulu #endif
166*91f16700Schasinglulu #if STM32MP15
167*91f16700Schasinglulu 	if (bank == GPIO_BANK_Z) {
168*91f16700Schasinglulu 		return GPIOZ;
169*91f16700Schasinglulu 	}
170*91f16700Schasinglulu 
171*91f16700Schasinglulu 	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
172*91f16700Schasinglulu #endif
173*91f16700Schasinglulu 
174*91f16700Schasinglulu 	return GPIOA + (bank - GPIO_BANK_A);
175*91f16700Schasinglulu }
176*91f16700Schasinglulu 
177*91f16700Schasinglulu int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
178*91f16700Schasinglulu {
179*91f16700Schasinglulu 	const char *node_compatible = NULL;
180*91f16700Schasinglulu 
181*91f16700Schasinglulu 	switch (bank) {
182*91f16700Schasinglulu 	case GPIO_BANK_A:
183*91f16700Schasinglulu 	case GPIO_BANK_B:
184*91f16700Schasinglulu 	case GPIO_BANK_C:
185*91f16700Schasinglulu 	case GPIO_BANK_D:
186*91f16700Schasinglulu 	case GPIO_BANK_E:
187*91f16700Schasinglulu 	case GPIO_BANK_F:
188*91f16700Schasinglulu 	case GPIO_BANK_G:
189*91f16700Schasinglulu 	case GPIO_BANK_H:
190*91f16700Schasinglulu 	case GPIO_BANK_I:
191*91f16700Schasinglulu #if STM32MP13
192*91f16700Schasinglulu 		node_compatible = "st,stm32mp135-pinctrl";
193*91f16700Schasinglulu 		break;
194*91f16700Schasinglulu #endif
195*91f16700Schasinglulu #if STM32MP15
196*91f16700Schasinglulu 	case GPIO_BANK_J:
197*91f16700Schasinglulu 	case GPIO_BANK_K:
198*91f16700Schasinglulu 		node_compatible = "st,stm32mp157-pinctrl";
199*91f16700Schasinglulu 		break;
200*91f16700Schasinglulu 	case GPIO_BANK_Z:
201*91f16700Schasinglulu 		node_compatible = "st,stm32mp157-z-pinctrl";
202*91f16700Schasinglulu 		break;
203*91f16700Schasinglulu #endif
204*91f16700Schasinglulu 	default:
205*91f16700Schasinglulu 		panic();
206*91f16700Schasinglulu 	}
207*91f16700Schasinglulu 
208*91f16700Schasinglulu 	return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
209*91f16700Schasinglulu }
210*91f16700Schasinglulu 
211*91f16700Schasinglulu #if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
212*91f16700Schasinglulu /*
213*91f16700Schasinglulu  * UART Management
214*91f16700Schasinglulu  */
215*91f16700Schasinglulu static const uintptr_t stm32mp1_uart_addresses[8] = {
216*91f16700Schasinglulu 	USART1_BASE,
217*91f16700Schasinglulu 	USART2_BASE,
218*91f16700Schasinglulu 	USART3_BASE,
219*91f16700Schasinglulu 	UART4_BASE,
220*91f16700Schasinglulu 	UART5_BASE,
221*91f16700Schasinglulu 	USART6_BASE,
222*91f16700Schasinglulu 	UART7_BASE,
223*91f16700Schasinglulu 	UART8_BASE,
224*91f16700Schasinglulu };
225*91f16700Schasinglulu 
226*91f16700Schasinglulu uintptr_t get_uart_address(uint32_t instance_nb)
227*91f16700Schasinglulu {
228*91f16700Schasinglulu 	if ((instance_nb == 0U) ||
229*91f16700Schasinglulu 	    (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
230*91f16700Schasinglulu 		return 0U;
231*91f16700Schasinglulu 	}
232*91f16700Schasinglulu 
233*91f16700Schasinglulu 	return stm32mp1_uart_addresses[instance_nb - 1U];
234*91f16700Schasinglulu }
235*91f16700Schasinglulu #endif
236*91f16700Schasinglulu 
237*91f16700Schasinglulu #if STM32MP_USB_PROGRAMMER
238*91f16700Schasinglulu struct gpio_bank_pin_list {
239*91f16700Schasinglulu 	uint32_t bank;
240*91f16700Schasinglulu 	uint32_t pin;
241*91f16700Schasinglulu };
242*91f16700Schasinglulu 
243*91f16700Schasinglulu static const struct gpio_bank_pin_list gpio_list[] = {
244*91f16700Schasinglulu 	{	/* USART2_RX: GPIOA3 */
245*91f16700Schasinglulu 		.bank = 0U,
246*91f16700Schasinglulu 		.pin = 3U,
247*91f16700Schasinglulu 	},
248*91f16700Schasinglulu 	{	/* USART3_RX: GPIOB12 */
249*91f16700Schasinglulu 		.bank = 1U,
250*91f16700Schasinglulu 		.pin = 12U,
251*91f16700Schasinglulu 	},
252*91f16700Schasinglulu 	{	/* UART4_RX: GPIOB2 */
253*91f16700Schasinglulu 		.bank = 1U,
254*91f16700Schasinglulu 		.pin = 2U,
255*91f16700Schasinglulu 	},
256*91f16700Schasinglulu 	{	/* UART5_RX: GPIOB4 */
257*91f16700Schasinglulu 		.bank = 1U,
258*91f16700Schasinglulu 		.pin = 5U,
259*91f16700Schasinglulu 	},
260*91f16700Schasinglulu 	{	/* USART6_RX: GPIOC7 */
261*91f16700Schasinglulu 		.bank = 2U,
262*91f16700Schasinglulu 		.pin = 7U,
263*91f16700Schasinglulu 	},
264*91f16700Schasinglulu 	{	/* UART7_RX: GPIOF6 */
265*91f16700Schasinglulu 		.bank = 5U,
266*91f16700Schasinglulu 		.pin = 6U,
267*91f16700Schasinglulu 	},
268*91f16700Schasinglulu 	{	/* UART8_RX: GPIOE0 */
269*91f16700Schasinglulu 		.bank = 4U,
270*91f16700Schasinglulu 		.pin = 0U,
271*91f16700Schasinglulu 	},
272*91f16700Schasinglulu };
273*91f16700Schasinglulu 
274*91f16700Schasinglulu void stm32mp1_deconfigure_uart_pins(void)
275*91f16700Schasinglulu {
276*91f16700Schasinglulu 	size_t i;
277*91f16700Schasinglulu 
278*91f16700Schasinglulu 	for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
279*91f16700Schasinglulu 		set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
280*91f16700Schasinglulu 	}
281*91f16700Schasinglulu }
282*91f16700Schasinglulu #endif
283*91f16700Schasinglulu 
284*91f16700Schasinglulu uint32_t stm32mp_get_chip_version(void)
285*91f16700Schasinglulu {
286*91f16700Schasinglulu #if STM32MP13
287*91f16700Schasinglulu 	return stm32mp1_syscfg_get_chip_version();
288*91f16700Schasinglulu #endif
289*91f16700Schasinglulu #if STM32MP15
290*91f16700Schasinglulu 	uint32_t version = 0U;
291*91f16700Schasinglulu 
292*91f16700Schasinglulu 	if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
293*91f16700Schasinglulu 		INFO("Cannot get CPU version, debug disabled\n");
294*91f16700Schasinglulu 		return 0U;
295*91f16700Schasinglulu 	}
296*91f16700Schasinglulu 
297*91f16700Schasinglulu 	return version;
298*91f16700Schasinglulu #endif
299*91f16700Schasinglulu }
300*91f16700Schasinglulu 
301*91f16700Schasinglulu uint32_t stm32mp_get_chip_dev_id(void)
302*91f16700Schasinglulu {
303*91f16700Schasinglulu #if STM32MP13
304*91f16700Schasinglulu 	return stm32mp1_syscfg_get_chip_dev_id();
305*91f16700Schasinglulu #endif
306*91f16700Schasinglulu #if STM32MP15
307*91f16700Schasinglulu 	uint32_t dev_id;
308*91f16700Schasinglulu 
309*91f16700Schasinglulu 	if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
310*91f16700Schasinglulu 		INFO("Use default chip ID, debug disabled\n");
311*91f16700Schasinglulu 		dev_id = STM32MP1_CHIP_ID;
312*91f16700Schasinglulu 	}
313*91f16700Schasinglulu 
314*91f16700Schasinglulu 	return dev_id;
315*91f16700Schasinglulu #endif
316*91f16700Schasinglulu }
317*91f16700Schasinglulu 
318*91f16700Schasinglulu static uint32_t get_part_number(void)
319*91f16700Schasinglulu {
320*91f16700Schasinglulu 	static uint32_t part_number;
321*91f16700Schasinglulu 
322*91f16700Schasinglulu 	if (part_number != 0U) {
323*91f16700Schasinglulu 		return part_number;
324*91f16700Schasinglulu 	}
325*91f16700Schasinglulu 
326*91f16700Schasinglulu 	if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
327*91f16700Schasinglulu 		panic();
328*91f16700Schasinglulu 	}
329*91f16700Schasinglulu 
330*91f16700Schasinglulu 	part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
331*91f16700Schasinglulu 		PART_NUMBER_OTP_PART_SHIFT;
332*91f16700Schasinglulu 
333*91f16700Schasinglulu 	part_number |= stm32mp_get_chip_dev_id() << 16;
334*91f16700Schasinglulu 
335*91f16700Schasinglulu 	return part_number;
336*91f16700Schasinglulu }
337*91f16700Schasinglulu 
338*91f16700Schasinglulu #if STM32MP15
339*91f16700Schasinglulu static uint32_t get_cpu_package(void)
340*91f16700Schasinglulu {
341*91f16700Schasinglulu 	uint32_t package;
342*91f16700Schasinglulu 
343*91f16700Schasinglulu 	if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
344*91f16700Schasinglulu 		panic();
345*91f16700Schasinglulu 	}
346*91f16700Schasinglulu 
347*91f16700Schasinglulu 	package = (package & PACKAGE_OTP_PKG_MASK) >>
348*91f16700Schasinglulu 		PACKAGE_OTP_PKG_SHIFT;
349*91f16700Schasinglulu 
350*91f16700Schasinglulu 	return package;
351*91f16700Schasinglulu }
352*91f16700Schasinglulu #endif
353*91f16700Schasinglulu 
354*91f16700Schasinglulu void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
355*91f16700Schasinglulu {
356*91f16700Schasinglulu 	const char *cpu_s, *cpu_r, *pkg;
357*91f16700Schasinglulu 
358*91f16700Schasinglulu 	/* MPUs Part Numbers */
359*91f16700Schasinglulu 	switch (get_part_number()) {
360*91f16700Schasinglulu #if STM32MP13
361*91f16700Schasinglulu 	case STM32MP135F_PART_NB:
362*91f16700Schasinglulu 		cpu_s = "135F";
363*91f16700Schasinglulu 		break;
364*91f16700Schasinglulu 	case STM32MP135D_PART_NB:
365*91f16700Schasinglulu 		cpu_s = "135D";
366*91f16700Schasinglulu 		break;
367*91f16700Schasinglulu 	case STM32MP135C_PART_NB:
368*91f16700Schasinglulu 		cpu_s = "135C";
369*91f16700Schasinglulu 		break;
370*91f16700Schasinglulu 	case STM32MP135A_PART_NB:
371*91f16700Schasinglulu 		cpu_s = "135A";
372*91f16700Schasinglulu 		break;
373*91f16700Schasinglulu 	case STM32MP133F_PART_NB:
374*91f16700Schasinglulu 		cpu_s = "133F";
375*91f16700Schasinglulu 		break;
376*91f16700Schasinglulu 	case STM32MP133D_PART_NB:
377*91f16700Schasinglulu 		cpu_s = "133D";
378*91f16700Schasinglulu 		break;
379*91f16700Schasinglulu 	case STM32MP133C_PART_NB:
380*91f16700Schasinglulu 		cpu_s = "133C";
381*91f16700Schasinglulu 		break;
382*91f16700Schasinglulu 	case STM32MP133A_PART_NB:
383*91f16700Schasinglulu 		cpu_s = "133A";
384*91f16700Schasinglulu 		break;
385*91f16700Schasinglulu 	case STM32MP131F_PART_NB:
386*91f16700Schasinglulu 		cpu_s = "131F";
387*91f16700Schasinglulu 		break;
388*91f16700Schasinglulu 	case STM32MP131D_PART_NB:
389*91f16700Schasinglulu 		cpu_s = "131D";
390*91f16700Schasinglulu 		break;
391*91f16700Schasinglulu 	case STM32MP131C_PART_NB:
392*91f16700Schasinglulu 		cpu_s = "131C";
393*91f16700Schasinglulu 		break;
394*91f16700Schasinglulu 	case STM32MP131A_PART_NB:
395*91f16700Schasinglulu 		cpu_s = "131A";
396*91f16700Schasinglulu 		break;
397*91f16700Schasinglulu #endif
398*91f16700Schasinglulu #if STM32MP15
399*91f16700Schasinglulu 	case STM32MP157C_PART_NB:
400*91f16700Schasinglulu 		cpu_s = "157C";
401*91f16700Schasinglulu 		break;
402*91f16700Schasinglulu 	case STM32MP157A_PART_NB:
403*91f16700Schasinglulu 		cpu_s = "157A";
404*91f16700Schasinglulu 		break;
405*91f16700Schasinglulu 	case STM32MP153C_PART_NB:
406*91f16700Schasinglulu 		cpu_s = "153C";
407*91f16700Schasinglulu 		break;
408*91f16700Schasinglulu 	case STM32MP153A_PART_NB:
409*91f16700Schasinglulu 		cpu_s = "153A";
410*91f16700Schasinglulu 		break;
411*91f16700Schasinglulu 	case STM32MP151C_PART_NB:
412*91f16700Schasinglulu 		cpu_s = "151C";
413*91f16700Schasinglulu 		break;
414*91f16700Schasinglulu 	case STM32MP151A_PART_NB:
415*91f16700Schasinglulu 		cpu_s = "151A";
416*91f16700Schasinglulu 		break;
417*91f16700Schasinglulu 	case STM32MP157F_PART_NB:
418*91f16700Schasinglulu 		cpu_s = "157F";
419*91f16700Schasinglulu 		break;
420*91f16700Schasinglulu 	case STM32MP157D_PART_NB:
421*91f16700Schasinglulu 		cpu_s = "157D";
422*91f16700Schasinglulu 		break;
423*91f16700Schasinglulu 	case STM32MP153F_PART_NB:
424*91f16700Schasinglulu 		cpu_s = "153F";
425*91f16700Schasinglulu 		break;
426*91f16700Schasinglulu 	case STM32MP153D_PART_NB:
427*91f16700Schasinglulu 		cpu_s = "153D";
428*91f16700Schasinglulu 		break;
429*91f16700Schasinglulu 	case STM32MP151F_PART_NB:
430*91f16700Schasinglulu 		cpu_s = "151F";
431*91f16700Schasinglulu 		break;
432*91f16700Schasinglulu 	case STM32MP151D_PART_NB:
433*91f16700Schasinglulu 		cpu_s = "151D";
434*91f16700Schasinglulu 		break;
435*91f16700Schasinglulu #endif
436*91f16700Schasinglulu 	default:
437*91f16700Schasinglulu 		cpu_s = "????";
438*91f16700Schasinglulu 		break;
439*91f16700Schasinglulu 	}
440*91f16700Schasinglulu 
441*91f16700Schasinglulu 	/* Package */
442*91f16700Schasinglulu #if STM32MP13
443*91f16700Schasinglulu 	/* On STM32MP13, package is not present in OTP */
444*91f16700Schasinglulu 	pkg = "";
445*91f16700Schasinglulu #endif
446*91f16700Schasinglulu #if STM32MP15
447*91f16700Schasinglulu 	switch (get_cpu_package()) {
448*91f16700Schasinglulu 	case PKG_AA_LFBGA448:
449*91f16700Schasinglulu 		pkg = "AA";
450*91f16700Schasinglulu 		break;
451*91f16700Schasinglulu 	case PKG_AB_LFBGA354:
452*91f16700Schasinglulu 		pkg = "AB";
453*91f16700Schasinglulu 		break;
454*91f16700Schasinglulu 	case PKG_AC_TFBGA361:
455*91f16700Schasinglulu 		pkg = "AC";
456*91f16700Schasinglulu 		break;
457*91f16700Schasinglulu 	case PKG_AD_TFBGA257:
458*91f16700Schasinglulu 		pkg = "AD";
459*91f16700Schasinglulu 		break;
460*91f16700Schasinglulu 	default:
461*91f16700Schasinglulu 		pkg = "??";
462*91f16700Schasinglulu 		break;
463*91f16700Schasinglulu 	}
464*91f16700Schasinglulu #endif
465*91f16700Schasinglulu 
466*91f16700Schasinglulu 	/* REVISION */
467*91f16700Schasinglulu 	switch (stm32mp_get_chip_version()) {
468*91f16700Schasinglulu 	case STM32MP1_REV_B:
469*91f16700Schasinglulu 		cpu_r = "B";
470*91f16700Schasinglulu 		break;
471*91f16700Schasinglulu #if STM32MP13
472*91f16700Schasinglulu 	case STM32MP1_REV_Y:
473*91f16700Schasinglulu 		cpu_r = "Y";
474*91f16700Schasinglulu 		break;
475*91f16700Schasinglulu #endif
476*91f16700Schasinglulu 	case STM32MP1_REV_Z:
477*91f16700Schasinglulu 		cpu_r = "Z";
478*91f16700Schasinglulu 		break;
479*91f16700Schasinglulu 	default:
480*91f16700Schasinglulu 		cpu_r = "?";
481*91f16700Schasinglulu 		break;
482*91f16700Schasinglulu 	}
483*91f16700Schasinglulu 
484*91f16700Schasinglulu 	snprintf(name, STM32_SOC_NAME_SIZE,
485*91f16700Schasinglulu 		 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
486*91f16700Schasinglulu }
487*91f16700Schasinglulu 
488*91f16700Schasinglulu void stm32mp_print_cpuinfo(void)
489*91f16700Schasinglulu {
490*91f16700Schasinglulu 	char name[STM32_SOC_NAME_SIZE];
491*91f16700Schasinglulu 
492*91f16700Schasinglulu 	stm32mp_get_soc_name(name);
493*91f16700Schasinglulu 	NOTICE("CPU: %s\n", name);
494*91f16700Schasinglulu }
495*91f16700Schasinglulu 
496*91f16700Schasinglulu void stm32mp_print_boardinfo(void)
497*91f16700Schasinglulu {
498*91f16700Schasinglulu 	uint32_t board_id = 0U;
499*91f16700Schasinglulu 
500*91f16700Schasinglulu 	if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
501*91f16700Schasinglulu 		return;
502*91f16700Schasinglulu 	}
503*91f16700Schasinglulu 
504*91f16700Schasinglulu 	if (board_id != 0U) {
505*91f16700Schasinglulu 		stm32_display_board_info(board_id);
506*91f16700Schasinglulu 	}
507*91f16700Schasinglulu }
508*91f16700Schasinglulu 
509*91f16700Schasinglulu /* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
510*91f16700Schasinglulu bool stm32mp_is_single_core(void)
511*91f16700Schasinglulu {
512*91f16700Schasinglulu #if STM32MP13
513*91f16700Schasinglulu 	return true;
514*91f16700Schasinglulu #endif
515*91f16700Schasinglulu #if STM32MP15
516*91f16700Schasinglulu 	bool single_core = false;
517*91f16700Schasinglulu 
518*91f16700Schasinglulu 	switch (get_part_number()) {
519*91f16700Schasinglulu 	case STM32MP151A_PART_NB:
520*91f16700Schasinglulu 	case STM32MP151C_PART_NB:
521*91f16700Schasinglulu 	case STM32MP151D_PART_NB:
522*91f16700Schasinglulu 	case STM32MP151F_PART_NB:
523*91f16700Schasinglulu 		single_core = true;
524*91f16700Schasinglulu 		break;
525*91f16700Schasinglulu 	default:
526*91f16700Schasinglulu 		break;
527*91f16700Schasinglulu 	}
528*91f16700Schasinglulu 
529*91f16700Schasinglulu 	return single_core;
530*91f16700Schasinglulu #endif
531*91f16700Schasinglulu }
532*91f16700Schasinglulu 
533*91f16700Schasinglulu /* Return true when device is in closed state */
534*91f16700Schasinglulu bool stm32mp_is_closed_device(void)
535*91f16700Schasinglulu {
536*91f16700Schasinglulu 	uint32_t value;
537*91f16700Schasinglulu 
538*91f16700Schasinglulu 	if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
539*91f16700Schasinglulu 		return true;
540*91f16700Schasinglulu 	}
541*91f16700Schasinglulu 
542*91f16700Schasinglulu #if STM32MP13
543*91f16700Schasinglulu 	value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
544*91f16700Schasinglulu 
545*91f16700Schasinglulu 	switch (value) {
546*91f16700Schasinglulu 	case CFG0_OPEN_DEVICE:
547*91f16700Schasinglulu 		return false;
548*91f16700Schasinglulu 	case CFG0_CLOSED_DEVICE:
549*91f16700Schasinglulu 	case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
550*91f16700Schasinglulu 	case CFG0_CLOSED_DEVICE_NO_JTAG:
551*91f16700Schasinglulu 		return true;
552*91f16700Schasinglulu 	default:
553*91f16700Schasinglulu 		panic();
554*91f16700Schasinglulu 	}
555*91f16700Schasinglulu #endif
556*91f16700Schasinglulu #if STM32MP15
557*91f16700Schasinglulu 	return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
558*91f16700Schasinglulu #endif
559*91f16700Schasinglulu }
560*91f16700Schasinglulu 
561*91f16700Schasinglulu /* Return true when device supports secure boot */
562*91f16700Schasinglulu bool stm32mp_is_auth_supported(void)
563*91f16700Schasinglulu {
564*91f16700Schasinglulu 	bool supported = false;
565*91f16700Schasinglulu 
566*91f16700Schasinglulu 	switch (get_part_number()) {
567*91f16700Schasinglulu #if STM32MP13
568*91f16700Schasinglulu 	case STM32MP131C_PART_NB:
569*91f16700Schasinglulu 	case STM32MP131F_PART_NB:
570*91f16700Schasinglulu 	case STM32MP133C_PART_NB:
571*91f16700Schasinglulu 	case STM32MP133F_PART_NB:
572*91f16700Schasinglulu 	case STM32MP135C_PART_NB:
573*91f16700Schasinglulu 	case STM32MP135F_PART_NB:
574*91f16700Schasinglulu #endif
575*91f16700Schasinglulu #if STM32MP15
576*91f16700Schasinglulu 	case STM32MP151C_PART_NB:
577*91f16700Schasinglulu 	case STM32MP151F_PART_NB:
578*91f16700Schasinglulu 	case STM32MP153C_PART_NB:
579*91f16700Schasinglulu 	case STM32MP153F_PART_NB:
580*91f16700Schasinglulu 	case STM32MP157C_PART_NB:
581*91f16700Schasinglulu 	case STM32MP157F_PART_NB:
582*91f16700Schasinglulu #endif
583*91f16700Schasinglulu 		supported = true;
584*91f16700Schasinglulu 		break;
585*91f16700Schasinglulu 	default:
586*91f16700Schasinglulu 		break;
587*91f16700Schasinglulu 	}
588*91f16700Schasinglulu 
589*91f16700Schasinglulu 	return supported;
590*91f16700Schasinglulu }
591*91f16700Schasinglulu 
592*91f16700Schasinglulu uint32_t stm32_iwdg_get_instance(uintptr_t base)
593*91f16700Schasinglulu {
594*91f16700Schasinglulu 	switch (base) {
595*91f16700Schasinglulu 	case IWDG1_BASE:
596*91f16700Schasinglulu 		return IWDG1_INST;
597*91f16700Schasinglulu 	case IWDG2_BASE:
598*91f16700Schasinglulu 		return IWDG2_INST;
599*91f16700Schasinglulu 	default:
600*91f16700Schasinglulu 		panic();
601*91f16700Schasinglulu 	}
602*91f16700Schasinglulu }
603*91f16700Schasinglulu 
604*91f16700Schasinglulu uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
605*91f16700Schasinglulu {
606*91f16700Schasinglulu 	uint32_t iwdg_cfg = 0U;
607*91f16700Schasinglulu 	uint32_t otp_value;
608*91f16700Schasinglulu 
609*91f16700Schasinglulu 	if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
610*91f16700Schasinglulu 		panic();
611*91f16700Schasinglulu 	}
612*91f16700Schasinglulu 
613*91f16700Schasinglulu 	if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
614*91f16700Schasinglulu 		iwdg_cfg |= IWDG_HW_ENABLED;
615*91f16700Schasinglulu 	}
616*91f16700Schasinglulu 
617*91f16700Schasinglulu 	if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
618*91f16700Schasinglulu 		iwdg_cfg |= IWDG_DISABLE_ON_STOP;
619*91f16700Schasinglulu 	}
620*91f16700Schasinglulu 
621*91f16700Schasinglulu 	if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
622*91f16700Schasinglulu 		iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
623*91f16700Schasinglulu 	}
624*91f16700Schasinglulu 
625*91f16700Schasinglulu 	return iwdg_cfg;
626*91f16700Schasinglulu }
627*91f16700Schasinglulu 
628*91f16700Schasinglulu #if defined(IMAGE_BL2)
629*91f16700Schasinglulu uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
630*91f16700Schasinglulu {
631*91f16700Schasinglulu 	uint32_t otp_value;
632*91f16700Schasinglulu 	uint32_t otp;
633*91f16700Schasinglulu 	uint32_t result;
634*91f16700Schasinglulu 
635*91f16700Schasinglulu 	if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
636*91f16700Schasinglulu 		panic();
637*91f16700Schasinglulu 	}
638*91f16700Schasinglulu 
639*91f16700Schasinglulu 	if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
640*91f16700Schasinglulu 		panic();
641*91f16700Schasinglulu 	}
642*91f16700Schasinglulu 
643*91f16700Schasinglulu 	if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
644*91f16700Schasinglulu 		otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
645*91f16700Schasinglulu 	}
646*91f16700Schasinglulu 
647*91f16700Schasinglulu 	if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
648*91f16700Schasinglulu 		otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
649*91f16700Schasinglulu 	}
650*91f16700Schasinglulu 
651*91f16700Schasinglulu 	result = bsec_write_otp(otp_value, otp);
652*91f16700Schasinglulu 	if (result != BSEC_OK) {
653*91f16700Schasinglulu 		return result;
654*91f16700Schasinglulu 	}
655*91f16700Schasinglulu 
656*91f16700Schasinglulu 	/* Sticky lock OTP_IWDG (read and write) */
657*91f16700Schasinglulu 	if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
658*91f16700Schasinglulu 	    (bsec_set_sw_lock(otp) != BSEC_OK)) {
659*91f16700Schasinglulu 		return BSEC_LOCK_FAIL;
660*91f16700Schasinglulu 	}
661*91f16700Schasinglulu 
662*91f16700Schasinglulu 	return BSEC_OK;
663*91f16700Schasinglulu }
664*91f16700Schasinglulu #endif
665*91f16700Schasinglulu 
666*91f16700Schasinglulu uintptr_t stm32_get_bkpr_boot_mode_addr(void)
667*91f16700Schasinglulu {
668*91f16700Schasinglulu 	return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
669*91f16700Schasinglulu }
670*91f16700Schasinglulu 
671*91f16700Schasinglulu #if PSA_FWU_SUPPORT
672*91f16700Schasinglulu void stm32mp1_fwu_set_boot_idx(void)
673*91f16700Schasinglulu {
674*91f16700Schasinglulu 	clk_enable(RTCAPB);
675*91f16700Schasinglulu 	mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
676*91f16700Schasinglulu 			   TAMP_BOOT_FWU_INFO_IDX_MSK,
677*91f16700Schasinglulu 			   (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
678*91f16700Schasinglulu 			   TAMP_BOOT_FWU_INFO_IDX_MSK);
679*91f16700Schasinglulu 	clk_disable(RTCAPB);
680*91f16700Schasinglulu }
681*91f16700Schasinglulu 
682*91f16700Schasinglulu uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
683*91f16700Schasinglulu {
684*91f16700Schasinglulu 	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
685*91f16700Schasinglulu 	uint32_t try_cnt;
686*91f16700Schasinglulu 
687*91f16700Schasinglulu 	clk_enable(RTCAPB);
688*91f16700Schasinglulu 	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
689*91f16700Schasinglulu 		TAMP_BOOT_FWU_INFO_CNT_OFF;
690*91f16700Schasinglulu 
691*91f16700Schasinglulu 	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
692*91f16700Schasinglulu 
693*91f16700Schasinglulu 	if (try_cnt != 0U) {
694*91f16700Schasinglulu 		mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
695*91f16700Schasinglulu 				   (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
696*91f16700Schasinglulu 	}
697*91f16700Schasinglulu 	clk_disable(RTCAPB);
698*91f16700Schasinglulu 
699*91f16700Schasinglulu 	return try_cnt;
700*91f16700Schasinglulu }
701*91f16700Schasinglulu 
702*91f16700Schasinglulu void stm32_set_max_fwu_trial_boot_cnt(void)
703*91f16700Schasinglulu {
704*91f16700Schasinglulu 	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
705*91f16700Schasinglulu 
706*91f16700Schasinglulu 	clk_enable(RTCAPB);
707*91f16700Schasinglulu 	mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
708*91f16700Schasinglulu 			   (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
709*91f16700Schasinglulu 			   TAMP_BOOT_FWU_INFO_CNT_MSK);
710*91f16700Schasinglulu 	clk_disable(RTCAPB);
711*91f16700Schasinglulu }
712*91f16700Schasinglulu #endif /* PSA_FWU_SUPPORT */
713