xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_helper.S (revision a9eda77c22d045dc7f09272b3cba76225177f9f5)
1/*
2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <platform_def.h>
8
9#include <arch.h>
10#include <asm_macros.S>
11#include <common/bl_common.h>
12#include <drivers/st/stm32_gpio.h>
13
14#define GPIO_TX_SHIFT		(DEBUG_UART_TX_GPIO_PORT << 1)
15#define GPIO_TX_ALT_SHIFT	((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
16
17	.globl	platform_mem_init
18	.globl	plat_report_exception
19	.globl	plat_get_my_entrypoint
20	.globl	plat_secondary_cold_boot_setup
21	.globl	plat_reset_handler
22	.globl	plat_is_my_cpu_primary
23	.globl	plat_my_core_pos
24	.globl	plat_crash_console_init
25	.globl	plat_crash_console_flush
26	.globl	plat_crash_console_putc
27	.globl	plat_panic_handler
28
29func platform_mem_init
30	/* Nothing to do, don't need to init SYSRAM */
31	bx	lr
32endfunc platform_mem_init
33
34func plat_report_exception
35#if DEBUG
36	mov	r8, lr
37
38	/* Test if an abort occurred */
39	cmp	r0, #MODE32_abt
40	bne	undef_inst_lbl
41	ldr	r4, =abort_str
42	bl	asm_print_str
43	mrs	r4, lr_abt
44	sub	r4, r4, #4
45	b	print_exception_info
46
47undef_inst_lbl:
48	/* Test for an undefined instruction */
49	cmp	r0, #MODE32_und
50	bne	other_exception_lbl
51	ldr	r4, =undefined_str
52	bl	asm_print_str
53	mrs	r4, lr_und
54	b	print_exception_info
55
56other_exception_lbl:
57	/* Other exceptions */
58	mov	r9, r0
59	ldr	r4, =exception_start_str
60	bl	asm_print_str
61	mov	r4, r9
62	bl	asm_print_hex
63	ldr	r4, =exception_end_str
64	bl	asm_print_str
65	mov	r4, r6
66
67print_exception_info:
68	bl	asm_print_hex
69
70	ldr	r4, =end_error_str
71	bl	asm_print_str
72
73	bx	r8
74#else
75	bx	lr
76#endif
77endfunc plat_report_exception
78
79func plat_reset_handler
80	bx	lr
81endfunc plat_reset_handler
82
83	/* ------------------------------------------------------------------
84	 * unsigned long plat_get_my_entrypoint (void);
85	 *
86	 * Main job of this routine is to distinguish between a cold and warm
87	 * boot.
88	 *
89	 * Currently supports only cold boot
90	 * ------------------------------------------------------------------
91	 */
92func plat_get_my_entrypoint
93	mov	r0, #0
94	bx	lr
95endfunc plat_get_my_entrypoint
96
97	/* ---------------------------------------------
98	 * void plat_secondary_cold_boot_setup (void);
99	 *
100	 * Cold-booting secondary CPUs is not supported.
101	 * ---------------------------------------------
102	 */
103func plat_secondary_cold_boot_setup
104	b	.
105endfunc plat_secondary_cold_boot_setup
106
107	/* -----------------------------------------------------
108	 * unsigned int plat_is_my_cpu_primary (void);
109	 *
110	 * Find out whether the current cpu is the primary cpu.
111	 * -----------------------------------------------------
112	 */
113func plat_is_my_cpu_primary
114	ldcopr	r0, MPIDR
115	ldr	r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
116	and	r0, r1
117	cmp	r0, #STM32MP_PRIMARY_CPU
118	moveq	r0, #1
119	movne	r0, #0
120	bx	lr
121endfunc plat_is_my_cpu_primary
122
123	/* -------------------------------------------
124	 *  int plat_stm32mp1_get_core_pos(int mpidr);
125	 *
126	 *  Return CorePos = (ClusterId * 4) + CoreId
127	 * -------------------------------------------
128	 */
129func plat_stm32mp1_get_core_pos
130	and	r1, r0, #MPIDR_CPU_MASK
131	and	r0, r0, #MPIDR_CLUSTER_MASK
132	add	r0, r1, r0, LSR #6
133	bx	lr
134endfunc plat_stm32mp1_get_core_pos
135
136	/* ------------------------------------
137	 *  unsigned int plat_my_core_pos(void)
138	 * ------------------------------------
139	 */
140func plat_my_core_pos
141	ldcopr	r0, MPIDR
142	b	plat_stm32mp1_get_core_pos
143endfunc plat_my_core_pos
144
145	/* ---------------------------------------------
146	 * int plat_crash_console_init(void)
147	 *
148	 * Initialize the crash console without a C Runtime stack.
149	 * ---------------------------------------------
150	 */
151func plat_crash_console_init
152	/* Enable GPIOs for UART TX */
153	ldr	r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
154	ldr	r2, [r1]
155	/* Configure GPIO */
156	orr	r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
157	str	r2, [r1]
158	ldr	r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
159	/* Set GPIO mode alternate */
160	ldr	r2, [r1, #GPIO_MODE_OFFSET]
161	bic	r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
162	orr	r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
163	str	r2, [r1, #GPIO_MODE_OFFSET]
164	/* Set GPIO speed low */
165	ldr	r2, [r1, #GPIO_SPEED_OFFSET]
166	bic	r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
167	str	r2, [r1, #GPIO_SPEED_OFFSET]
168	/* Set no-pull */
169	ldr	r2, [r1, #GPIO_PUPD_OFFSET]
170	bic	r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
171	str	r2, [r1, #GPIO_PUPD_OFFSET]
172	/* Set alternate */
173	ldr	r2, [r1, #GPIO_AFRH_OFFSET]
174	bic	r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
175	orr	r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)
176	str	r2, [r1, #GPIO_AFRH_OFFSET]
177	/* Enable UART clock, with its source */
178	ldr	r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
179	mov	r2, #DEBUG_UART_TX_CLKSRC
180	str	r2, [r1]
181	ldr	r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
182	ldr	r2, [r1]
183	orr	r2, r2, #DEBUG_UART_TX_EN
184	str	r2, [r1]
185
186	ldr	r0, =STM32MP_DEBUG_USART_BASE
187	ldr	r1, =STM32MP_DEBUG_USART_CLK_FRQ
188	ldr	r2, =STM32MP_UART_BAUDRATE
189	b	console_stm32_core_init
190endfunc plat_crash_console_init
191
192	/* ---------------------------------------------
193	 * int plat_crash_console_flush(void)
194	 *
195	 * Flush the crash console without a C Runtime stack.
196	 * ---------------------------------------------
197	 */
198func plat_crash_console_flush
199	ldr	r1, =STM32MP_DEBUG_USART_BASE
200	b	console_stm32_core_flush
201endfunc plat_crash_console_flush
202
203	/* ---------------------------------------------
204	 * int plat_crash_console_putc(int c)
205	 *
206	 * Print a character on the crash console without a C Runtime stack.
207	 * Clobber list : r1 - r3
208	 *
209	 * In case of bootloading through uart, we keep console crash as this.
210	 * Characters could be sent to the programmer, but will be ignored.
211	 * No specific code in that case.
212	 * ---------------------------------------------
213	 */
214func plat_crash_console_putc
215	ldr	r1, =STM32MP_DEBUG_USART_BASE
216	b	console_stm32_core_putc
217endfunc plat_crash_console_putc
218
219#if DEBUG
220.section .rodata.rev_err_str, "aS"
221abort_str:
222	.asciz "\nAbort at: 0x"
223undefined_str:
224	.asciz "\nUndefined instruction at: 0x"
225exception_start_str:
226	.asciz "\nException mode=0x"
227exception_end_str:
228	.asciz " at: 0x"
229end_error_str:
230	.asciz "\n\r"
231#endif
232