xref: /rk3399_ARM-atf/plat/st/common/stm32mp_common.c (revision c8e1a2d9d27d4f7e3a919b7994e82f2a886f3e6a)
1c9d75b3cSYann Gautier /*
2*08252f9dSPatrick Delaunay  * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
3c9d75b3cSYann Gautier  *
4c9d75b3cSYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
5c9d75b3cSYann Gautier  */
6c9d75b3cSYann Gautier 
7c9d75b3cSYann Gautier #include <assert.h>
81e919529SYann Gautier #include <errno.h>
9c9d75b3cSYann Gautier 
10c9d75b3cSYann Gautier #include <arch_helpers.h>
11c9d75b3cSYann Gautier #include <common/debug.h>
1233667d29SYann Gautier #include <drivers/clk.h>
1353612f72SYann Gautier #include <drivers/delay_timer.h>
1453612f72SYann Gautier #include <drivers/st/stm32_console.h>
157ae58c6bSYann Gautier #include <drivers/st/stm32mp_clkfunc.h>
1653612f72SYann Gautier #include <drivers/st/stm32mp_reset.h>
17d8da13e5SYann Gautier #include <lib/mmio.h>
183d201787SYann Gautier #include <lib/smccc.h>
1984686ba3SYann Gautier #include <lib/xlat_tables/xlat_tables_v2.h>
20c9d75b3cSYann Gautier #include <plat/common/platform.h>
213d201787SYann Gautier #include <services/arm_arch_svc.h>
22c9d75b3cSYann Gautier 
2353612f72SYann Gautier #include <platform_def.h>
2453612f72SYann Gautier 
258ce89187SNicolas Le Bayon #define HEADER_VERSION_MAJOR_MASK	GENMASK(23, 16)
2653612f72SYann Gautier #define RESET_TIMEOUT_US_1MS		1000U
2753612f72SYann Gautier 
28992dba08SYann Gautier /* Internal layout of the 32bit OTP word board_id */
29992dba08SYann Gautier #define BOARD_ID_BOARD_NB_MASK		GENMASK_32(31, 16)
30992dba08SYann Gautier #define BOARD_ID_BOARD_NB_SHIFT		16
31992dba08SYann Gautier #define BOARD_ID_VARCPN_MASK		GENMASK_32(15, 12)
32992dba08SYann Gautier #define BOARD_ID_VARCPN_SHIFT		12
33992dba08SYann Gautier #define BOARD_ID_REVISION_MASK		GENMASK_32(11, 8)
34992dba08SYann Gautier #define BOARD_ID_REVISION_SHIFT		8
35992dba08SYann Gautier #define BOARD_ID_VARFG_MASK		GENMASK_32(7, 4)
36992dba08SYann Gautier #define BOARD_ID_VARFG_SHIFT		4
37992dba08SYann Gautier #define BOARD_ID_BOM_MASK		GENMASK_32(3, 0)
38992dba08SYann Gautier 
39992dba08SYann Gautier #define BOARD_ID2NB(_id)		(((_id) & BOARD_ID_BOARD_NB_MASK) >> \
40992dba08SYann Gautier 					 BOARD_ID_BOARD_NB_SHIFT)
41992dba08SYann Gautier #define BOARD_ID2VARCPN(_id)		(((_id) & BOARD_ID_VARCPN_MASK) >> \
42992dba08SYann Gautier 					 BOARD_ID_VARCPN_SHIFT)
43992dba08SYann Gautier #define BOARD_ID2REV(_id)		(((_id) & BOARD_ID_REVISION_MASK) >> \
44992dba08SYann Gautier 					 BOARD_ID_REVISION_SHIFT)
45992dba08SYann Gautier #define BOARD_ID2VARFG(_id)		(((_id) & BOARD_ID_VARFG_MASK) >> \
46992dba08SYann Gautier 					 BOARD_ID_VARFG_SHIFT)
47992dba08SYann Gautier #define BOARD_ID2BOM(_id)		((_id) & BOARD_ID_BOM_MASK)
48992dba08SYann Gautier 
49d8da13e5SYann Gautier #define BOOT_AUTH_MASK			GENMASK_32(23, 20)
50d8da13e5SYann Gautier #define BOOT_AUTH_SHIFT			20
51d8da13e5SYann Gautier #define BOOT_PART_MASK			GENMASK_32(19, 16)
52d8da13e5SYann Gautier #define BOOT_PART_SHIFT			16
53d8da13e5SYann Gautier #define BOOT_ITF_MASK			GENMASK_32(15, 12)
54d8da13e5SYann Gautier #define BOOT_ITF_SHIFT			12
55d8da13e5SYann Gautier #define BOOT_INST_MASK			GENMASK_32(11, 8)
56d8da13e5SYann Gautier #define BOOT_INST_SHIFT			8
57d8da13e5SYann Gautier 
58b91c7f5eSYann Gautier /* Layout for fwu update information. */
59b91c7f5eSYann Gautier #define FWU_INFO_IDX_MSK		GENMASK(3, 0)
60b91c7f5eSYann Gautier #define FWU_INFO_IDX_OFF		U(0)
61b91c7f5eSYann Gautier #define FWU_INFO_CNT_MSK		GENMASK(7, 4)
62b91c7f5eSYann Gautier #define FWU_INFO_CNT_OFF		U(4)
63b91c7f5eSYann Gautier 
6453612f72SYann Gautier static console_t console;
658ce89187SNicolas Le Bayon 
plat_get_ns_image_entrypoint(void)66c9d75b3cSYann Gautier uintptr_t plat_get_ns_image_entrypoint(void)
67c9d75b3cSYann Gautier {
68c9d75b3cSYann Gautier 	return BL33_BASE;
69c9d75b3cSYann Gautier }
70c9d75b3cSYann Gautier 
plat_get_syscnt_freq2(void)71c9d75b3cSYann Gautier unsigned int plat_get_syscnt_freq2(void)
72c9d75b3cSYann Gautier {
73c9d75b3cSYann Gautier 	return read_cntfrq_el0();
74c9d75b3cSYann Gautier }
75c9d75b3cSYann Gautier 
76c9d75b3cSYann Gautier static uintptr_t boot_ctx_address;
777e87ba25SYann Gautier static uint16_t boot_itf_selected;
78c9d75b3cSYann Gautier 
stm32mp_save_boot_ctx_address(uintptr_t address)793f9c9784SYann Gautier void stm32mp_save_boot_ctx_address(uintptr_t address)
80c9d75b3cSYann Gautier {
817e87ba25SYann Gautier 	boot_api_context_t *boot_context = (boot_api_context_t *)address;
827e87ba25SYann Gautier 
83c9d75b3cSYann Gautier 	boot_ctx_address = address;
847e87ba25SYann Gautier 	boot_itf_selected = boot_context->boot_interface_selected;
85c9d75b3cSYann Gautier }
86c9d75b3cSYann Gautier 
stm32mp_get_boot_ctx_address(void)873f9c9784SYann Gautier uintptr_t stm32mp_get_boot_ctx_address(void)
88c9d75b3cSYann Gautier {
89c9d75b3cSYann Gautier 	return boot_ctx_address;
90c9d75b3cSYann Gautier }
91c9d75b3cSYann Gautier 
stm32mp_get_boot_itf_selected(void)927e87ba25SYann Gautier uint16_t stm32mp_get_boot_itf_selected(void)
937e87ba25SYann Gautier {
947e87ba25SYann Gautier 	return boot_itf_selected;
957e87ba25SYann Gautier }
967e87ba25SYann Gautier 
stm32mp_ddrctrl_base(void)977ae58c6bSYann Gautier uintptr_t stm32mp_ddrctrl_base(void)
987ae58c6bSYann Gautier {
99ade9ce03SYann Gautier 	return DDRCTRL_BASE;
1007ae58c6bSYann Gautier }
1017ae58c6bSYann Gautier 
stm32mp_ddrphyc_base(void)1027ae58c6bSYann Gautier uintptr_t stm32mp_ddrphyc_base(void)
1037ae58c6bSYann Gautier {
104ade9ce03SYann Gautier 	return DDRPHYC_BASE;
1057ae58c6bSYann Gautier }
1067ae58c6bSYann Gautier 
stm32mp_pwr_base(void)1077ae58c6bSYann Gautier uintptr_t stm32mp_pwr_base(void)
1087ae58c6bSYann Gautier {
109ade9ce03SYann Gautier 	return PWR_BASE;
1107ae58c6bSYann Gautier }
1117ae58c6bSYann Gautier 
stm32mp_rcc_base(void)1127ae58c6bSYann Gautier uintptr_t stm32mp_rcc_base(void)
1137ae58c6bSYann Gautier {
114ade9ce03SYann Gautier 	return RCC_BASE;
1157ae58c6bSYann Gautier }
1167ae58c6bSYann Gautier 
stm32mp_lock_available(void)117e463d3f4SYann Gautier bool stm32mp_lock_available(void)
118e463d3f4SYann Gautier {
119e463d3f4SYann Gautier 	const uint32_t c_m_bits = SCTLR_M_BIT | SCTLR_C_BIT;
120e463d3f4SYann Gautier 
121e463d3f4SYann Gautier 	/* The spinlocks are used only when MMU and data cache are enabled */
122dad71816SYann Gautier #ifdef __aarch64__
123dad71816SYann Gautier 	return (read_sctlr_el3() & c_m_bits) == c_m_bits;
124dad71816SYann Gautier #else
125e463d3f4SYann Gautier 	return (read_sctlr() & c_m_bits) == c_m_bits;
126dad71816SYann Gautier #endif
127e463d3f4SYann Gautier }
128e463d3f4SYann Gautier 
stm32mp_map_ddr_non_cacheable(void)12984686ba3SYann Gautier int stm32mp_map_ddr_non_cacheable(void)
13084686ba3SYann Gautier {
13184686ba3SYann Gautier 	return  mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
13284686ba3SYann Gautier 					STM32MP_DDR_MAX_SIZE,
133c1ad41fbSYann Gautier 					MT_NON_CACHEABLE | MT_RW | MT_SECURE);
13484686ba3SYann Gautier }
13584686ba3SYann Gautier 
stm32mp_unmap_ddr(void)13684686ba3SYann Gautier int stm32mp_unmap_ddr(void)
13784686ba3SYann Gautier {
13884686ba3SYann Gautier 	return  mmap_remove_dynamic_region(STM32MP_DDR_BASE,
13984686ba3SYann Gautier 					   STM32MP_DDR_MAX_SIZE);
14084686ba3SYann Gautier }
1413d201787SYann Gautier 
stm32_get_otp_index(const char * otp_name,uint32_t * otp_idx,uint32_t * otp_len)142ae3ce8b2SLionel Debieve int stm32_get_otp_index(const char *otp_name, uint32_t *otp_idx,
143ae3ce8b2SLionel Debieve 			uint32_t *otp_len)
144ae3ce8b2SLionel Debieve {
145ae3ce8b2SLionel Debieve 	assert(otp_name != NULL);
146ae3ce8b2SLionel Debieve 	assert(otp_idx != NULL);
147ae3ce8b2SLionel Debieve 
148ae3ce8b2SLionel Debieve 	return dt_find_otp_name(otp_name, otp_idx, otp_len);
149ae3ce8b2SLionel Debieve }
150ae3ce8b2SLionel Debieve 
stm32_get_otp_value(const char * otp_name,uint32_t * otp_val)151ae3ce8b2SLionel Debieve int stm32_get_otp_value(const char *otp_name, uint32_t *otp_val)
152ae3ce8b2SLionel Debieve {
153ae3ce8b2SLionel Debieve 	uint32_t otp_idx;
154ae3ce8b2SLionel Debieve 
155ae3ce8b2SLionel Debieve 	assert(otp_name != NULL);
156ae3ce8b2SLionel Debieve 	assert(otp_val != NULL);
157ae3ce8b2SLionel Debieve 
158ae3ce8b2SLionel Debieve 	if (stm32_get_otp_index(otp_name, &otp_idx, NULL) != 0) {
159ae3ce8b2SLionel Debieve 		return -1;
160ae3ce8b2SLionel Debieve 	}
161ae3ce8b2SLionel Debieve 
162ae3ce8b2SLionel Debieve 	if (stm32_get_otp_value_from_idx(otp_idx, otp_val) != 0) {
163ae3ce8b2SLionel Debieve 		ERROR("BSEC: %s Read Error\n", otp_name);
164ae3ce8b2SLionel Debieve 		return -1;
165ae3ce8b2SLionel Debieve 	}
166ae3ce8b2SLionel Debieve 
167ae3ce8b2SLionel Debieve 	return 0;
168ae3ce8b2SLionel Debieve }
169ae3ce8b2SLionel Debieve 
stm32_get_otp_value_from_idx(const uint32_t otp_idx,uint32_t * otp_val)170ae3ce8b2SLionel Debieve int stm32_get_otp_value_from_idx(const uint32_t otp_idx, uint32_t *otp_val)
171ae3ce8b2SLionel Debieve {
172ae3ce8b2SLionel Debieve 	uint32_t ret = BSEC_NOT_SUPPORTED;
173ae3ce8b2SLionel Debieve 
174ae3ce8b2SLionel Debieve 	assert(otp_val != NULL);
175ae3ce8b2SLionel Debieve 
176ae3ce8b2SLionel Debieve #if defined(IMAGE_BL2)
1773007c728SYann Gautier 	ret = stm32_otp_shadow_read(otp_val, otp_idx);
178189db948SYann Gautier #elif defined(IMAGE_BL31) || defined(IMAGE_BL32)
1793007c728SYann Gautier 	ret = stm32_otp_read(otp_val, otp_idx);
180ae3ce8b2SLionel Debieve #else
181ae3ce8b2SLionel Debieve #error "Not supported"
182ae3ce8b2SLionel Debieve #endif
183ae3ce8b2SLionel Debieve 	if (ret != BSEC_OK) {
184ae3ce8b2SLionel Debieve 		ERROR("BSEC: idx=%u Read Error\n", otp_idx);
185ae3ce8b2SLionel Debieve 		return -1;
186ae3ce8b2SLionel Debieve 	}
187ae3ce8b2SLionel Debieve 
188ae3ce8b2SLionel Debieve 	return 0;
189ae3ce8b2SLionel Debieve }
190ae3ce8b2SLionel Debieve 
stm32_get_uid_otp(uint32_t uid[])191*08252f9dSPatrick Delaunay int stm32_get_uid_otp(uint32_t uid[])
192*08252f9dSPatrick Delaunay {
193*08252f9dSPatrick Delaunay 	uint8_t i;
194*08252f9dSPatrick Delaunay 	uint32_t otp;
195*08252f9dSPatrick Delaunay 	uint32_t len;
196*08252f9dSPatrick Delaunay 
197*08252f9dSPatrick Delaunay 	if (stm32_get_otp_index(UID_OTP, &otp, &len) != 0) {
198*08252f9dSPatrick Delaunay 		ERROR("BSEC: Get UID_OTP number Error\n");
199*08252f9dSPatrick Delaunay 		return -1;
200*08252f9dSPatrick Delaunay 	}
201*08252f9dSPatrick Delaunay 
202*08252f9dSPatrick Delaunay 	if ((len / __WORD_BIT) != UID_WORD_NB) {
203*08252f9dSPatrick Delaunay 		ERROR("BSEC: Get UID_OTP length Error\n");
204*08252f9dSPatrick Delaunay 		return -1;
205*08252f9dSPatrick Delaunay 	}
206*08252f9dSPatrick Delaunay 
207*08252f9dSPatrick Delaunay 	for (i = 0U; i < UID_WORD_NB; i++) {
208*08252f9dSPatrick Delaunay 		if (stm32_otp_shadow_read(&uid[i], i + otp) != BSEC_OK) {
209*08252f9dSPatrick Delaunay 			ERROR("BSEC: UID%u Error\n", i);
210*08252f9dSPatrick Delaunay 			return -1;
211*08252f9dSPatrick Delaunay 		}
212*08252f9dSPatrick Delaunay 	}
213*08252f9dSPatrick Delaunay 
214*08252f9dSPatrick Delaunay 	return 0;
215*08252f9dSPatrick Delaunay }
216*08252f9dSPatrick Delaunay 
217aafff043SYann Gautier #if defined(IMAGE_BL2)
reset_uart(uint32_t reset)21853612f72SYann Gautier static void reset_uart(uint32_t reset)
21953612f72SYann Gautier {
22053612f72SYann Gautier 	int ret;
22153612f72SYann Gautier 
22253612f72SYann Gautier 	ret = stm32mp_reset_assert(reset, RESET_TIMEOUT_US_1MS);
22353612f72SYann Gautier 	if (ret != 0) {
22453612f72SYann Gautier 		panic();
22553612f72SYann Gautier 	}
22653612f72SYann Gautier 
22753612f72SYann Gautier 	udelay(2);
22853612f72SYann Gautier 
22953612f72SYann Gautier 	ret = stm32mp_reset_deassert(reset, RESET_TIMEOUT_US_1MS);
23053612f72SYann Gautier 	if (ret != 0) {
23153612f72SYann Gautier 		panic();
23253612f72SYann Gautier 	}
23353612f72SYann Gautier 
23453612f72SYann Gautier 	mdelay(1);
23553612f72SYann Gautier }
236aafff043SYann Gautier #endif
23753612f72SYann Gautier 
set_console(uintptr_t base,uint32_t clk_rate)238c768b2b2SYann Gautier static void set_console(uintptr_t base, uint32_t clk_rate)
239c768b2b2SYann Gautier {
240c768b2b2SYann Gautier 	unsigned int console_flags;
241c768b2b2SYann Gautier 
242c768b2b2SYann Gautier 	if (console_stm32_register(base, clk_rate,
24399887cb9SYann Gautier 				   (uint32_t)STM32MP_UART_BAUDRATE, &console) == 0) {
244c768b2b2SYann Gautier 		panic();
245c768b2b2SYann Gautier 	}
246c768b2b2SYann Gautier 
247c768b2b2SYann Gautier 	console_flags = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH |
248c768b2b2SYann Gautier 			CONSOLE_FLAG_TRANSLATE_CRLF;
249c768b2b2SYann Gautier #if !defined(IMAGE_BL2) && defined(DEBUG)
250c768b2b2SYann Gautier 	console_flags |= CONSOLE_FLAG_RUNTIME;
251c768b2b2SYann Gautier #endif
252c768b2b2SYann Gautier 
253c768b2b2SYann Gautier 	console_set_scope(&console, console_flags);
254c768b2b2SYann Gautier }
255c768b2b2SYann Gautier 
stm32mp_uart_console_setup(void)25653612f72SYann Gautier int stm32mp_uart_console_setup(void)
25753612f72SYann Gautier {
25853612f72SYann Gautier 	struct dt_node_info dt_uart_info;
2599e52d45fSYann Gautier 	uint32_t clk_rate = 0U;
26053612f72SYann Gautier 	int result;
261acf28c26SYann Gautier 	uint32_t boot_itf __unused;
262acf28c26SYann Gautier 	uint32_t boot_instance __unused;
26353612f72SYann Gautier 
26453612f72SYann Gautier 	result = dt_get_stdout_uart_info(&dt_uart_info);
26553612f72SYann Gautier 
26653612f72SYann Gautier 	if ((result <= 0) ||
2679e52d45fSYann Gautier 	    (dt_uart_info.status == DT_DISABLED)) {
2689e52d45fSYann Gautier 		return -ENODEV;
2699e52d45fSYann Gautier 	}
2709e52d45fSYann Gautier 
2719e52d45fSYann Gautier #if defined(IMAGE_BL2)
2729e52d45fSYann Gautier 	if ((dt_uart_info.clock < 0) ||
27353612f72SYann Gautier 	    (dt_uart_info.reset < 0)) {
27453612f72SYann Gautier 		return -ENODEV;
27553612f72SYann Gautier 	}
2769e52d45fSYann Gautier #endif
27753612f72SYann Gautier 
278acf28c26SYann Gautier #if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
279acf28c26SYann Gautier 	stm32_get_boot_interface(&boot_itf, &boot_instance);
280acf28c26SYann Gautier 
281acf28c26SYann Gautier 	if ((boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) &&
282acf28c26SYann Gautier 	    (get_uart_address(boot_instance) == dt_uart_info.base)) {
283acf28c26SYann Gautier 		return -EACCES;
284acf28c26SYann Gautier 	}
285acf28c26SYann Gautier #endif
286acf28c26SYann Gautier 
287aafff043SYann Gautier #if defined(IMAGE_BL2)
28853612f72SYann Gautier 	if (dt_set_stdout_pinctrl() != 0) {
28953612f72SYann Gautier 		return -ENODEV;
29053612f72SYann Gautier 	}
29153612f72SYann Gautier 
29233667d29SYann Gautier 	clk_enable((unsigned long)dt_uart_info.clock);
29353612f72SYann Gautier 
29453612f72SYann Gautier 	reset_uart((uint32_t)dt_uart_info.reset);
29553612f72SYann Gautier 
29633667d29SYann Gautier 	clk_rate = clk_get_rate((unsigned long)dt_uart_info.clock);
2979e52d45fSYann Gautier #endif
29853612f72SYann Gautier 
299c768b2b2SYann Gautier 	set_console(dt_uart_info.base, clk_rate);
30053612f72SYann Gautier 
30153612f72SYann Gautier 	return 0;
30253612f72SYann Gautier }
30353612f72SYann Gautier 
30494cad75aSYann Gautier #if EARLY_CONSOLE
plat_setup_early_console(void)30594cad75aSYann Gautier void plat_setup_early_console(void)
306c768b2b2SYann Gautier {
3075223d880SYann Gautier #if defined(IMAGE_BL2) || STM32MP_RECONFIGURE_CONSOLE
308c768b2b2SYann Gautier 	plat_crash_console_init();
3095223d880SYann Gautier #endif
310c768b2b2SYann Gautier 	set_console(STM32MP_DEBUG_USART_BASE, STM32MP_DEBUG_USART_CLK_FRQ);
31100606df0SYann Gautier 	NOTICE("Early console setup\n");
312c768b2b2SYann Gautier }
31394cad75aSYann Gautier #endif /* EARLY_CONSOLE */
314c768b2b2SYann Gautier 
3153d201787SYann Gautier /*****************************************************************************
3163d201787SYann Gautier  * plat_is_smccc_feature_available() - This function checks whether SMCCC
3173d201787SYann Gautier  *                                     feature is availabile for platform.
3183d201787SYann Gautier  * @fid: SMCCC function id
3193d201787SYann Gautier  *
3203d201787SYann Gautier  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
3213d201787SYann Gautier  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
3223d201787SYann Gautier  *****************************************************************************/
plat_is_smccc_feature_available(u_register_t fid)3233d201787SYann Gautier int32_t plat_is_smccc_feature_available(u_register_t fid)
3243d201787SYann Gautier {
3253d201787SYann Gautier 	switch (fid) {
3263d201787SYann Gautier 	case SMCCC_ARCH_SOC_ID:
3273d201787SYann Gautier 		return SMC_ARCH_CALL_SUCCESS;
3283d201787SYann Gautier 	default:
3293d201787SYann Gautier 		return SMC_ARCH_CALL_NOT_SUPPORTED;
3303d201787SYann Gautier 	}
3313d201787SYann Gautier }
3323d201787SYann Gautier 
3333d201787SYann Gautier /* Get SOC version */
plat_get_soc_version(void)3343d201787SYann Gautier int32_t plat_get_soc_version(void)
3353d201787SYann Gautier {
3363d201787SYann Gautier 	uint32_t chip_id = stm32mp_get_chip_dev_id();
3373d201787SYann Gautier 	uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_ST_BKID, JEDEC_ST_MFID);
3383d201787SYann Gautier 
3393d201787SYann Gautier 	return (int32_t)(manfid | (chip_id & SOC_ID_IMPL_DEF_MASK));
3403d201787SYann Gautier }
3413d201787SYann Gautier 
3423d201787SYann Gautier /* Get SOC revision */
plat_get_soc_revision(void)3433d201787SYann Gautier int32_t plat_get_soc_revision(void)
3443d201787SYann Gautier {
3453d201787SYann Gautier 	return (int32_t)(stm32mp_get_chip_version() & SOC_ID_REV_MASK);
3463d201787SYann Gautier }
347d8da13e5SYann Gautier 
stm32_display_board_info(uint32_t board_id)348992dba08SYann Gautier void stm32_display_board_info(uint32_t board_id)
349992dba08SYann Gautier {
350992dba08SYann Gautier 	char rev[2];
351992dba08SYann Gautier 
352992dba08SYann Gautier 	rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
353992dba08SYann Gautier 	rev[1] = '\0';
354992dba08SYann Gautier 	NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
355992dba08SYann Gautier 	       BOARD_ID2NB(board_id),
356992dba08SYann Gautier 	       BOARD_ID2VARCPN(board_id),
357992dba08SYann Gautier 	       BOARD_ID2VARFG(board_id),
358992dba08SYann Gautier 	       rev,
359992dba08SYann Gautier 	       BOARD_ID2BOM(board_id));
360992dba08SYann Gautier }
361992dba08SYann Gautier 
stm32_save_boot_info(boot_api_context_t * boot_context)362d8da13e5SYann Gautier void stm32_save_boot_info(boot_api_context_t *boot_context)
363d8da13e5SYann Gautier {
364d8da13e5SYann Gautier 	uint32_t auth_status;
365d8da13e5SYann Gautier 
366d8da13e5SYann Gautier 	assert(boot_context->boot_interface_instance <= (BOOT_INST_MASK >> BOOT_INST_SHIFT));
367d8da13e5SYann Gautier 	assert(boot_context->boot_interface_selected <= (BOOT_ITF_MASK >> BOOT_ITF_SHIFT));
368d8da13e5SYann Gautier 	assert(boot_context->boot_partition_used_toboot <= (BOOT_PART_MASK >> BOOT_PART_SHIFT));
369d8da13e5SYann Gautier 
370d8da13e5SYann Gautier 	switch (boot_context->auth_status) {
371d8da13e5SYann Gautier 	case BOOT_API_CTX_AUTH_NO:
372d8da13e5SYann Gautier 		auth_status = 0x0U;
373d8da13e5SYann Gautier 		break;
374d8da13e5SYann Gautier 
375d8da13e5SYann Gautier 	case BOOT_API_CTX_AUTH_SUCCESS:
376d8da13e5SYann Gautier 		auth_status = 0x2U;
377d8da13e5SYann Gautier 		break;
378d8da13e5SYann Gautier 
379d8da13e5SYann Gautier 	case BOOT_API_CTX_AUTH_FAILED:
380d8da13e5SYann Gautier 	default:
381d8da13e5SYann Gautier 		auth_status = 0x1U;
382d8da13e5SYann Gautier 		break;
383d8da13e5SYann Gautier 	}
384d8da13e5SYann Gautier 
385d8da13e5SYann Gautier 	clk_enable(TAMP_BKP_REG_CLK);
386d8da13e5SYann Gautier 
387d8da13e5SYann Gautier 	mmio_clrsetbits_32(stm32_get_bkpr_boot_mode_addr(),
388d8da13e5SYann Gautier 			   BOOT_ITF_MASK | BOOT_INST_MASK | BOOT_PART_MASK | BOOT_AUTH_MASK,
389d8da13e5SYann Gautier 			   (boot_context->boot_interface_instance << BOOT_INST_SHIFT) |
390d8da13e5SYann Gautier 			   (boot_context->boot_interface_selected << BOOT_ITF_SHIFT) |
391d8da13e5SYann Gautier 			   (boot_context->boot_partition_used_toboot << BOOT_PART_SHIFT) |
392d8da13e5SYann Gautier 			   (auth_status << BOOT_AUTH_SHIFT));
393d8da13e5SYann Gautier 
394d8da13e5SYann Gautier 	clk_disable(TAMP_BKP_REG_CLK);
395d8da13e5SYann Gautier }
396d8da13e5SYann Gautier 
stm32_get_boot_interface(uint32_t * interface,uint32_t * instance)397d8da13e5SYann Gautier void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
398d8da13e5SYann Gautier {
399d8da13e5SYann Gautier 	static uint32_t itf;
400d8da13e5SYann Gautier 
401d8da13e5SYann Gautier 	if (itf == 0U) {
402d8da13e5SYann Gautier 		clk_enable(TAMP_BKP_REG_CLK);
403d8da13e5SYann Gautier 
404d8da13e5SYann Gautier 		itf = mmio_read_32(stm32_get_bkpr_boot_mode_addr()) &
405d8da13e5SYann Gautier 		      (BOOT_ITF_MASK | BOOT_INST_MASK);
406d8da13e5SYann Gautier 
407d8da13e5SYann Gautier 		clk_disable(TAMP_BKP_REG_CLK);
408d8da13e5SYann Gautier 	}
409d8da13e5SYann Gautier 
410d8da13e5SYann Gautier 	*interface = (itf & BOOT_ITF_MASK) >> BOOT_ITF_SHIFT;
411d8da13e5SYann Gautier 	*instance = (itf & BOOT_INST_MASK) >> BOOT_INST_SHIFT;
412d8da13e5SYann Gautier }
413b91c7f5eSYann Gautier 
414b91c7f5eSYann Gautier #if PSA_FWU_SUPPORT
stm32_fwu_set_boot_idx(void)415b91c7f5eSYann Gautier void stm32_fwu_set_boot_idx(void)
416b91c7f5eSYann Gautier {
417b91c7f5eSYann Gautier 	clk_enable(TAMP_BKP_REG_CLK);
418b91c7f5eSYann Gautier 	mmio_clrsetbits_32(stm32_get_bkpr_fwu_info_addr(),
419b91c7f5eSYann Gautier 			   FWU_INFO_IDX_MSK,
420b91c7f5eSYann Gautier 			   (plat_fwu_get_boot_idx() << FWU_INFO_IDX_OFF) &
421b91c7f5eSYann Gautier 			   FWU_INFO_IDX_MSK);
422b91c7f5eSYann Gautier 	clk_disable(TAMP_BKP_REG_CLK);
423b91c7f5eSYann Gautier }
424b91c7f5eSYann Gautier 
stm32_get_and_dec_fwu_trial_boot_cnt(void)425b91c7f5eSYann Gautier uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
426b91c7f5eSYann Gautier {
427b91c7f5eSYann Gautier 	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
428b91c7f5eSYann Gautier 	uint32_t try_cnt;
429b91c7f5eSYann Gautier 
430b91c7f5eSYann Gautier 	clk_enable(TAMP_BKP_REG_CLK);
431b91c7f5eSYann Gautier 	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & FWU_INFO_CNT_MSK) >> FWU_INFO_CNT_OFF;
432b91c7f5eSYann Gautier 
433b91c7f5eSYann Gautier 	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
434b91c7f5eSYann Gautier 
435b91c7f5eSYann Gautier 	if (try_cnt != 0U) {
436b91c7f5eSYann Gautier 		mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
437b91c7f5eSYann Gautier 				   (try_cnt - 1U) << FWU_INFO_CNT_OFF);
438b91c7f5eSYann Gautier 	}
439b91c7f5eSYann Gautier 	clk_disable(TAMP_BKP_REG_CLK);
440b91c7f5eSYann Gautier 
441b91c7f5eSYann Gautier 	return try_cnt;
442b91c7f5eSYann Gautier }
443b91c7f5eSYann Gautier 
stm32_set_max_fwu_trial_boot_cnt(void)444b91c7f5eSYann Gautier void stm32_set_max_fwu_trial_boot_cnt(void)
445b91c7f5eSYann Gautier {
446b91c7f5eSYann Gautier 	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
447b91c7f5eSYann Gautier 
448b91c7f5eSYann Gautier 	clk_enable(TAMP_BKP_REG_CLK);
449b91c7f5eSYann Gautier 	mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
450b91c7f5eSYann Gautier 			   (FWU_MAX_TRIAL_REBOOT << FWU_INFO_CNT_OFF) & FWU_INFO_CNT_MSK);
451b91c7f5eSYann Gautier 	clk_disable(TAMP_BKP_REG_CLK);
452b91c7f5eSYann Gautier }
453b91c7f5eSYann Gautier 
stm32_clear_fwu_trial_boot_cnt(void)454b91c7f5eSYann Gautier void stm32_clear_fwu_trial_boot_cnt(void)
455b91c7f5eSYann Gautier {
456b91c7f5eSYann Gautier 	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
457b91c7f5eSYann Gautier 
458b91c7f5eSYann Gautier 	clk_enable(TAMP_BKP_REG_CLK);
459b91c7f5eSYann Gautier 	mmio_clrbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK);
460b91c7f5eSYann Gautier 	clk_disable(TAMP_BKP_REG_CLK);
461b91c7f5eSYann Gautier }
462b91c7f5eSYann Gautier #endif /* PSA_FWU_SUPPORT */
463