1/*
2 * Copyright (c) 2023, 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_crash_console_init
18	.globl	plat_crash_console_flush
19	.globl	plat_crash_console_putc
20	.globl	plat_report_exception
21
22func platform_mem_init
23	/* Nothing to do, don't need to init SYSRAM */
24	ret
25endfunc platform_mem_init
26
27	/* ---------------------------------------------
28	 * void plat_secondary_cold_boot_setup (void);
29	 *
30	 * Set secondary core in WFI waiting for core reset.
31	 * ---------------------------------------------
32	 */
33func plat_secondary_cold_boot_setup
34	dsb	sy
35	wfi
36	/* This shouldn't be reached */
37	b	.
38endfunc plat_secondary_cold_boot_setup
39
40	/* ----------------------------------------------
41	 * unsigned int plat_is_my_cpu_primary(void);
42	 * This function checks if this is the primary CPU
43	 * ----------------------------------------------
44	 */
45func plat_is_my_cpu_primary
46	mrs	x0, mpidr_el1
47	and	x0, x0, #(MPIDR_CPU_MASK)
48	cmp	x0, #STM32MP_PRIMARY_CPU
49	cset	x0, eq
50	ret
51endfunc plat_is_my_cpu_primary
52
53	/* ---------------------------------------------
54	 * int plat_crash_console_init(void)
55	 *
56	 * Initialize the crash console without a C Runtime stack.
57	 * ---------------------------------------------
58	 */
59func plat_crash_console_init
60	/* Reset UART peripheral */
61	mov_imm	x1, (RCC_BASE + DEBUG_UART_RST_REG)
62	ldr	x2, =DEBUG_UART_RST_BIT
63	ldr	x0, [x1]
64	orr	x0, x0, x2
65	str	x0, [x1]
661:
67	ldr	x0, [x1]
68	ands	x2, x0, x2
69	beq	1b
70	bic	x2, x2, #DEBUG_UART_RST_BIT
71	str	x2, [x1]
722:
73	ldr	x0, [x1]
74	ands	x2, x0, x2
75	bne	2b
76	/* Enable GPIOs for UART TX */
77	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
78	ldr	w2, [x1]
79	/* Configure GPIO */
80	orr	w2, w2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
81	str	w2, [x1]
82	mov_imm	x1, DEBUG_UART_TX_GPIO_BANK_ADDRESS
83	/* Set GPIO mode alternate */
84	ldr	w2, [x1, #GPIO_MODE_OFFSET]
85	bic	w2, w2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
86	orr	w2, w2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
87	str	w2, [x1, #GPIO_MODE_OFFSET]
88	/* Set GPIO speed low */
89	ldr	w2, [x1, #GPIO_SPEED_OFFSET]
90	bic	w2, w2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
91	str	w2, [x1, #GPIO_SPEED_OFFSET]
92	/* Set no-pull */
93	ldr	w2, [x1, #GPIO_PUPD_OFFSET]
94	bic	w2, w2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
95	str	w2, [x1, #GPIO_PUPD_OFFSET]
96	/* Set alternate */
97#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
98	ldr	w2, [x1, #GPIO_AFRH_OFFSET]
99	bic	w2, w2, #(GPIO_ALTERNATE_MASK << \
100				((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
101	orr	w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
102				((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
103	str	w2, [x1, #GPIO_AFRH_OFFSET]
104#else
105	ldr	w2, [x1, #GPIO_AFRL_OFFSET]
106	bic	w2, w2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
107	orr	w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
108	str	w2, [x1, #GPIO_AFRL_OFFSET]
109#endif
110	/* Clear UART clock flexgen divisors, keep enable bit */
111	mov_imm	x1, (RCC_BASE + DEBUG_UART_PREDIV_CFGR)
112	mov	x2, #0
113	str	w2, [x1]
114	mov_imm	x1, (RCC_BASE + DEBUG_UART_FINDIV_CFGR)
115	mov	x2, #0x40
116	str	w2, [x1]
117	/* Enable UART clock, with its source */
118	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
119	mov_imm	w2, (DEBUG_UART_TX_CLKSRC | RCC_XBARxCFGR_XBARxEN)
120	str	w2, [x1]
121	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_EN_REG)
122	ldr	w2, [x1]
123	orr	w2, w2, #DEBUG_UART_TX_EN
124	str	w2, [x1]
125
126	mov_imm	x0, STM32MP_DEBUG_USART_BASE
127	mov_imm	x1, STM32MP_DEBUG_USART_CLK_FRQ
128	mov_imm	x2, STM32MP_UART_BAUDRATE
129	b	console_stm32_core_init
130endfunc plat_crash_console_init
131
132func plat_crash_console_flush
133	mov_imm	x0, STM32MP_DEBUG_USART_BASE
134	b	console_stm32_core_flush
135endfunc plat_crash_console_flush
136
137func plat_crash_console_putc
138	mov_imm	x1, STM32MP_DEBUG_USART_BASE
139	cmp	x0, #'\n'
140	b.ne	1f
141	mov	x15, x30
142	mov	x0, #'\r'
143	bl	console_stm32_core_putc
144	mov	x30, x15
145	mov	x0, #'\n'
1461:
147	b	console_stm32_core_putc
148endfunc plat_crash_console_putc
149
150#ifdef IMAGE_BL2
151	/* ---------------------------------------------
152	 * void plat_report_exception(unsigned int type)
153	 * Function to report an unhandled exception
154	 * with platform-specific means.
155	 * ---------------------------------------------
156	 */
157func plat_report_exception
158	mov	x8, x30
159
160	adr	x4, plat_err_str
161	bl	asm_print_str
162
163	adr	x4, esr_el3_str
164	bl	asm_print_str
165
166	mrs	x4, esr_el3
167	bl	asm_print_hex
168
169	adr	x4, elr_el3_str
170	bl	asm_print_str
171
172	mrs	x4, elr_el3
173	bl	asm_print_hex
174
175	adr	x4, far_el3_str
176	bl	asm_print_str
177
178	mrs	x4, far_el3
179	bl	asm_print_hex
180
181	mov	x30, x8
182	ret
183endfunc plat_report_exception
184
185.section .rodata.rev_err_str, "aS"
186plat_err_str:
187	.asciz "\nPlatform exception reporting:"
188esr_el3_str:
189	.asciz "\nESR_EL3: "
190elr_el3_str:
191	.asciz "\nELR_EL3: "
192far_el3_str:
193	.asciz "\nFAR_EL3: "
194#endif /* IMAGE_BL2 */
195