1/*
2 * Copyright (c) 2020, ARM Limited. All rights reserved.
3 * Copyright (C) 2018 Marvell International Ltd.
4 *
5 * SPDX-License-Identifier:     BSD-3-Clause
6 * https://spdx.org/licenses
7 */
8
9#include <asm_macros.S>
10#include <cortex_a72.h>
11#ifndef PLAT_a3700
12#include <drivers/marvell/ccu.h>
13#include <drivers/marvell/cache_llc.h>
14#endif
15#include <marvell_def.h>
16#include <platform_def.h>
17
18	.weak	plat_marvell_calc_core_pos
19	.weak	plat_my_core_pos
20	.globl	plat_crash_console_init
21	.globl	plat_crash_console_putc
22	.globl	plat_crash_console_flush
23	.globl	platform_mem_init
24	.globl	disable_mmu_dcache
25	.globl	invalidate_tlb_all
26	.globl	platform_unmap_sram
27	.globl	disable_sram
28	.globl	disable_icache
29	.globl	invalidate_icache_all
30	.globl	marvell_exit_bootrom
31	.globl	ca72_l2_enable_unique_clean
32
33	/* -----------------------------------------------------
34	 *  unsigned int plat_my_core_pos(void)
35	 *  This function uses the plat_marvell_calc_core_pos()
36	 *  definition to get the index of the calling CPU.
37	 * -----------------------------------------------------
38	 */
39func plat_my_core_pos
40	mrs	x0, mpidr_el1
41	b	plat_marvell_calc_core_pos
42endfunc plat_my_core_pos
43
44	/* -----------------------------------------------------
45	 *  unsigned int plat_marvell_calc_core_pos(uint64_t mpidr)
46	 *  Helper function to calculate the core position.
47	 *  With this function: CorePos = (ClusterId * 2) +
48	 *  				  CoreId
49	 * -----------------------------------------------------
50	 */
51func plat_marvell_calc_core_pos
52	and	x1, x0, #MPIDR_CPU_MASK
53	and	x0, x0, #MPIDR_CLUSTER_MASK
54	add	x0, x1, x0, LSR #7
55	ret
56endfunc plat_marvell_calc_core_pos
57
58	/* ---------------------------------------------
59	 * int plat_crash_console_init(void)
60	 * Function to initialize the crash console
61	 * without a C Runtime to print crash report.
62	 * Clobber list : x0, x1, x2
63	 * ---------------------------------------------
64	 */
65func plat_crash_console_init
66	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
67	mov_imm	x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ
68	mov_imm	x2, MARVELL_CONSOLE_BAUDRATE
69#ifdef PLAT_a3700
70	b	console_a3700_core_init
71#else
72	b	console_16550_core_init
73#endif
74endfunc plat_crash_console_init
75
76	/* ---------------------------------------------
77	 * int plat_crash_console_putc(int c)
78	 * Function to print a character on the crash
79	 * console without a C Runtime.
80	 * Clobber list : x1, x2
81	 * ---------------------------------------------
82	 */
83func plat_crash_console_putc
84	mov_imm	x1, PLAT_MARVELL_CRASH_UART_BASE
85#ifdef PLAT_a3700
86
87	b	console_a3700_core_putc
88#else
89	b	console_16550_core_putc
90#endif
91endfunc plat_crash_console_putc
92
93	/* ---------------------------------------------
94	 * void plat_crash_console_flush()
95	 * Function to force a write of all buffered
96	 * data that hasn't been output.
97	 * Out : void.
98	 * Clobber list : r0
99	 * ---------------------------------------------
100	 */
101func plat_crash_console_flush
102	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
103#ifdef PLAT_a3700
104	b	console_a3700_core_flush
105#else
106	b	console_16550_core_flush
107#endif
108endfunc plat_crash_console_flush
109
110	/* ---------------------------------------------------------------------
111	 * We don't need to carry out any memory initialization on ARM
112	 * platforms. The Secure RAM is accessible straight away.
113	 * ---------------------------------------------------------------------
114	 */
115func platform_mem_init
116	ret
117endfunc platform_mem_init
118
119	/* -----------------------------------------------------
120	 * Disable icache, dcache, and MMU
121	 * -----------------------------------------------------
122	 */
123func disable_mmu_dcache
124	mrs	x0, sctlr_el3
125	bic	x0, x0, 0x1		/* M bit - MMU */
126	bic	x0, x0, 0x4		/* C bit - Dcache L1 & L2 */
127	msr	sctlr_el3, x0
128	isb
129	b	mmu_off
130mmu_off:
131	ret
132endfunc disable_mmu_dcache
133
134	/* -----------------------------------------------------
135	 * Disable all TLB entries
136	 * -----------------------------------------------------
137	 */
138func invalidate_tlb_all
139	tlbi	alle3
140	dsb	sy
141	isb
142	ret
143endfunc invalidate_tlb_all
144
145	/* -----------------------------------------------------
146	 * Disable the i cache
147	 * -----------------------------------------------------
148	 */
149func disable_icache
150	mrs 	x0, sctlr_el3
151	bic	x0, x0, 0x1000	/* I bit - Icache L1 & L2 */
152	msr	sctlr_el3, x0
153	isb
154	ret
155endfunc disable_icache
156
157	/* -----------------------------------------------------
158	 * Disable all of the i caches
159	 * -----------------------------------------------------
160	 */
161func invalidate_icache_all
162	ic	ialluis
163	isb	sy
164	ret
165endfunc invalidate_icache_all
166
167	/* -----------------------------------------------------
168	 * Clear the SRAM enabling bit to unmap SRAM
169	 * -----------------------------------------------------
170	 */
171func platform_unmap_sram
172	ldr	x0, =CCU_SRAM_WIN_CR
173	str	wzr, [x0]
174	ret
175endfunc platform_unmap_sram
176
177	/* -----------------------------------------------------
178	 * Disable the SRAM
179	 * -----------------------------------------------------
180	 */
181func disable_sram
182	/* Disable the line lockings. They must be disabled expictly
183	 * or the OS will have problems using the cache */
184	ldr	x1, =MASTER_LLC_TC0_LOCK
185	str	wzr, [x1]
186
187	/* Invalidate all ways */
188	ldr	w1, =LLC_WAY_MASK
189	ldr	x0, =MASTER_LLC_INV_WAY
190	str	w1, [x0]
191
192	/* Finally disable LLC */
193	ldr	x0, =MASTER_LLC_CTRL
194	str	wzr, [x0]
195
196	ret
197endfunc disable_sram
198
199	/* -----------------------------------------------------
200	 * Operation when exit bootROM:
201	 * Disable the MMU
202	 * Disable and invalidate the dcache
203	 * Unmap and disable the SRAM
204	 * Disable and invalidate the icache
205	 * -----------------------------------------------------
206	 */
207func marvell_exit_bootrom
208	/* Save the system restore address */
209	mov	x28, x0
210
211	/* Close the caches and MMU */
212	bl	disable_mmu_dcache
213
214	/*
215	 * There is nothing important in the caches now,
216	 * so invalidate them instead of cleaning.
217	 */
218	adr	x0, __RW_START__
219	adr	x1, __RW_END__
220	sub	x1, x1, x0
221	bl	inv_dcache_range
222	bl	invalidate_tlb_all
223
224	/*
225	 * Clean the memory mapping of SRAM
226	 * the DDR mapping will remain to enable boot image to execute
227	 */
228	bl	platform_unmap_sram
229
230	/* Disable the SRAM */
231	bl	disable_sram
232
233	/* Disable and invalidate icache */
234	bl	disable_icache
235	bl	invalidate_icache_all
236
237	mov	x0, x28
238	br	x0
239endfunc marvell_exit_bootrom
240
241	/*
242	 * Enable L2 UniqueClean evictions with data
243	 */
244func ca72_l2_enable_unique_clean
245
246	mrs	x0, CORTEX_A72_L2ACTLR_EL1
247	orr	x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN
248	msr	CORTEX_A72_L2ACTLR_EL1, x0
249
250	ret
251endfunc ca72_l2_enable_unique_clean
252