1/*
2 * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <asm_macros.S>
8#include <drivers/st/stm32_gpio.h>
9
10#include <platform_def.h>
11
12#define GPIO_TX_SHIFT		(DEBUG_UART_TX_GPIO_PORT << 1)
13
14	.globl	platform_mem_init
15	.globl	plat_secondary_cold_boot_setup
16	.globl	plat_is_my_cpu_primary
17	.globl	plat_my_core_pos
18	.globl	plat_crash_console_init
19	.globl	plat_crash_console_flush
20	.globl	plat_crash_console_putc
21	.globl	plat_report_exception
22
23func platform_mem_init
24	/* Nothing to do, don't need to init SYSRAM */
25	ret
26endfunc platform_mem_init
27
28	/* ---------------------------------------------
29	 * void plat_secondary_cold_boot_setup (void);
30	 *
31	 * Set secondary core in WFI waiting for core reset.
32	 * ---------------------------------------------
33	 */
34func plat_secondary_cold_boot_setup
35	dsb	sy
361:
37	wfi
38	/*
39	 * This shouldn't be reached, but when a debugger halts the
40	 * secondary core it causes exit from wfi.
41	 * Put back the core in wfi.
42	 */
43	b	1b
44endfunc plat_secondary_cold_boot_setup
45
46	/* ----------------------------------------------
47	 * unsigned int plat_is_my_cpu_primary(void);
48	 * This function checks if this is the primary CPU
49	 * ----------------------------------------------
50	 */
51func plat_is_my_cpu_primary
52	mrs	x0, mpidr_el1
53	and	x0, x0, #(MPIDR_CPU_MASK)
54	cmp	x0, #STM32MP_PRIMARY_CPU
55	cset	x0, eq
56	ret
57endfunc plat_is_my_cpu_primary
58
59	/* -----------------------------------------------------------
60	 *  unsigned int plat_stm32mp_get_core_pos(u_register_t mpidr)
61	 *  Helper function to calculate the core position.
62	 *  With this function: CorePos = (ClusterId * 4) +
63	 *  				  CoreId
64	 * -----------------------------------------------------------
65	 */
66func plat_stm32mp_get_core_pos
67	and	x1, x0, #MPIDR_CPU_MASK
68	and	x0, x0, #MPIDR_CLUSTER_MASK
69	add	x0, x1, x0, LSR #6
70	ret
71endfunc plat_stm32mp_get_core_pos
72
73	/* -----------------------------------------------------
74	 *  unsigned int plat_my_core_pos(void)
75	 *  This function uses the plat_stm32mp_get_core_pos()
76	 *  definition to get the index of the calling CPU.
77	 * -----------------------------------------------------
78	 */
79func plat_my_core_pos
80	mrs	x0, mpidr_el1
81	b	plat_stm32mp_get_core_pos
82endfunc plat_my_core_pos
83
84	/* ---------------------------------------------
85	 * int plat_crash_console_init(void)
86	 *
87	 * Initialize the crash console without a C Runtime stack.
88	 * ---------------------------------------------
89	 */
90func plat_crash_console_init
91	/* Reset UART peripheral */
92	mov_imm	x1, (RCC_BASE + DEBUG_UART_RST_REG)
93	ldr	x2, =DEBUG_UART_RST_BIT
94	ldr	x0, [x1]
95	orr	x0, x0, x2
96	str	x0, [x1]
971:
98	ldr	x0, [x1]
99	tst	x0, #DEBUG_UART_RST_BIT
100	beq	1b
101	bic	x0, x0, #DEBUG_UART_RST_BIT
102	str	x0, [x1]
1032:
104	ldr	x0, [x1]
105	tst	x0, #DEBUG_UART_RST_BIT
106	bne	2b
107	/* Enable GPIOs for UART TX */
108	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
109	ldr	w2, [x1]
110	/* Configure GPIO */
111	orr	w2, w2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
112	str	w2, [x1]
113	mov_imm	x1, DEBUG_UART_TX_GPIO_BANK_ADDRESS
114	/* Set GPIO mode alternate */
115	ldr	w2, [x1, #GPIO_MODE_OFFSET]
116	bic	w2, w2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
117	orr	w2, w2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
118	str	w2, [x1, #GPIO_MODE_OFFSET]
119	/* Set GPIO speed low */
120	ldr	w2, [x1, #GPIO_SPEED_OFFSET]
121	bic	w2, w2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
122	str	w2, [x1, #GPIO_SPEED_OFFSET]
123	/* Set no-pull */
124	ldr	w2, [x1, #GPIO_PUPD_OFFSET]
125	bic	w2, w2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
126	str	w2, [x1, #GPIO_PUPD_OFFSET]
127	/* Set alternate */
128#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
129	ldr	w2, [x1, #GPIO_AFRH_OFFSET]
130	bic	w2, w2, #(GPIO_ALTERNATE_MASK << \
131				((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
132	orr	w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
133				((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
134	str	w2, [x1, #GPIO_AFRH_OFFSET]
135#else
136	ldr	w2, [x1, #GPIO_AFRL_OFFSET]
137	bic	w2, w2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
138	orr	w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
139	str	w2, [x1, #GPIO_AFRL_OFFSET]
140#endif
141	/* Clear UART clock flexgen divisors, keep enable bit */
142	mov_imm	x1, (RCC_BASE + DEBUG_UART_PREDIV_CFGR)
143	mov	x2, #0
144	str	w2, [x1]
145	mov_imm	x1, (RCC_BASE + DEBUG_UART_FINDIV_CFGR)
146	mov	x2, #0x40
147	str	w2, [x1]
148	/* Enable UART clock, with its source */
149	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
150	mov_imm	w2, (DEBUG_UART_TX_CLKSRC | RCC_XBARxCFGR_XBARxEN)
151	str	w2, [x1]
152	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_EN_REG)
153	ldr	w2, [x1]
154	orr	w2, w2, #DEBUG_UART_TX_EN
155	str	w2, [x1]
156
157	mov_imm	x0, STM32MP_DEBUG_USART_BASE
158	mov_imm	x1, STM32MP_DEBUG_USART_CLK_FRQ
159	mov_imm	x2, STM32MP_UART_BAUDRATE
160	b	console_stm32_core_init
161endfunc plat_crash_console_init
162
163func plat_crash_console_flush
164	mov_imm	x0, STM32MP_DEBUG_USART_BASE
165	b	console_stm32_core_flush
166endfunc plat_crash_console_flush
167
168func plat_crash_console_putc
169	mov_imm	x1, STM32MP_DEBUG_USART_BASE
170	cmp	x0, #'\n'
171	b.ne	1f
172	mov	x15, x30
173	mov	x0, #'\r'
174	bl	console_stm32_core_putc
175	mov	x30, x15
176	mov	x0, #'\n'
1771:
178	b	console_stm32_core_putc
179endfunc plat_crash_console_putc
180
181#ifdef IMAGE_BL2
182	/* ---------------------------------------------
183	 * void plat_report_exception(unsigned int type)
184	 * Function to report an unhandled exception
185	 * with platform-specific means.
186	 * ---------------------------------------------
187	 */
188func plat_report_exception
189	mov	x8, x30
190
191	adr	x4, plat_err_str
192	bl	asm_print_str
193
194	adr	x4, esr_el3_str
195	bl	asm_print_str
196
197	mrs	x4, esr_el3
198	bl	asm_print_hex
199
200	adr	x4, elr_el3_str
201	bl	asm_print_str
202
203	mrs	x4, elr_el3
204	bl	asm_print_hex
205
206	adr	x4, far_el3_str
207	bl	asm_print_str
208
209	mrs	x4, far_el3
210	bl	asm_print_hex
211
212	mov	x30, x8
213	ret
214endfunc plat_report_exception
215
216.section .rodata.rev_err_str, "aS"
217plat_err_str:
218	.asciz "\nPlatform exception reporting:"
219esr_el3_str:
220	.asciz "\nESR_EL3: "
221elr_el3_str:
222	.asciz "\nELR_EL3: "
223far_el3_str:
224	.asciz "\nFAR_EL3: "
225#endif /* IMAGE_BL2 */
226