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#ifdef PLAT_a3700
67	mov	x1, x30
68	bl	get_ref_clk
69	mov	x30, x1
70	mov_imm	x1, 1000000
71	mul	x1, x0, x1
72#else
73	mov_imm	x1, PLAT_MARVELL_UART_CLK_IN_HZ
74#endif
75	mov_imm	x0, PLAT_MARVELL_UART_BASE
76	mov_imm	x2, MARVELL_CONSOLE_BAUDRATE
77#ifdef PLAT_a3700
78	b	console_a3700_core_init
79#else
80	b	console_16550_core_init
81#endif
82endfunc plat_crash_console_init
83
84	/* ---------------------------------------------
85	 * int plat_crash_console_putc(int c)
86	 * Function to print a character on the crash
87	 * console without a C Runtime.
88	 * Clobber list : x1, x2
89	 * ---------------------------------------------
90	 */
91func plat_crash_console_putc
92	mov_imm	x1, PLAT_MARVELL_UART_BASE
93#ifdef PLAT_a3700
94
95	b	console_a3700_core_putc
96#else
97	b	console_16550_core_putc
98#endif
99endfunc plat_crash_console_putc
100
101	/* ---------------------------------------------
102	 * void plat_crash_console_flush()
103	 * Function to force a write of all buffered
104	 * data that hasn't been output.
105	 * Out : void.
106	 * Clobber list : r0
107	 * ---------------------------------------------
108	 */
109func plat_crash_console_flush
110	mov_imm	x0, PLAT_MARVELL_UART_BASE
111#ifdef PLAT_a3700
112	b	console_a3700_core_flush
113#else
114	b	console_16550_core_flush
115#endif
116endfunc plat_crash_console_flush
117
118	/* ---------------------------------------------------------------------
119	 * We don't need to carry out any memory initialization on ARM
120	 * platforms. The Secure RAM is accessible straight away.
121	 * ---------------------------------------------------------------------
122	 */
123func platform_mem_init
124	ret
125endfunc platform_mem_init
126
127	/* -----------------------------------------------------
128	 * Disable icache, dcache, and MMU
129	 * -----------------------------------------------------
130	 */
131func disable_mmu_dcache
132	mrs	x0, sctlr_el3
133	bic	x0, x0, 0x1		/* M bit - MMU */
134	bic	x0, x0, 0x4		/* C bit - Dcache L1 & L2 */
135	msr	sctlr_el3, x0
136	isb
137	b	mmu_off
138mmu_off:
139	ret
140endfunc disable_mmu_dcache
141
142	/* -----------------------------------------------------
143	 * Disable all TLB entries
144	 * -----------------------------------------------------
145	 */
146func invalidate_tlb_all
147	tlbi	alle3
148	dsb	sy
149	isb
150	ret
151endfunc invalidate_tlb_all
152
153	/* -----------------------------------------------------
154	 * Disable the i cache
155	 * -----------------------------------------------------
156	 */
157func disable_icache
158	mrs 	x0, sctlr_el3
159	bic	x0, x0, 0x1000	/* I bit - Icache L1 & L2 */
160	msr	sctlr_el3, x0
161	isb
162	ret
163endfunc disable_icache
164
165	/* -----------------------------------------------------
166	 * Disable all of the i caches
167	 * -----------------------------------------------------
168	 */
169func invalidate_icache_all
170	ic	ialluis
171	isb	sy
172	ret
173endfunc invalidate_icache_all
174
175	/* -----------------------------------------------------
176	 * Clear the SRAM enabling bit to unmap SRAM
177	 * -----------------------------------------------------
178	 */
179func platform_unmap_sram
180	ldr	x0, =CCU_SRAM_WIN_CR
181	str	wzr, [x0]
182	ret
183endfunc platform_unmap_sram
184
185	/* -----------------------------------------------------
186	 * Disable the SRAM
187	 * -----------------------------------------------------
188	 */
189func disable_sram
190	/* Disable the line lockings. They must be disabled expictly
191	 * or the OS will have problems using the cache */
192	ldr	x1, =MASTER_LLC_TC0_LOCK
193	str	wzr, [x1]
194
195	/* Invalidate all ways */
196	ldr	w1, =LLC_WAY_MASK
197	ldr	x0, =MASTER_LLC_INV_WAY
198	str	w1, [x0]
199
200	/* Finally disable LLC */
201	ldr	x0, =MASTER_LLC_CTRL
202	str	wzr, [x0]
203
204	ret
205endfunc disable_sram
206
207	/* -----------------------------------------------------
208	 * Operation when exit bootROM:
209	 * Disable the MMU
210	 * Disable and invalidate the dcache
211	 * Unmap and disable the SRAM
212	 * Disable and invalidate the icache
213	 * -----------------------------------------------------
214	 */
215func marvell_exit_bootrom
216	/* Save the system restore address */
217	mov	x28, x0
218
219	/* Close the caches and MMU */
220	bl	disable_mmu_dcache
221
222	/*
223	 * There is nothing important in the caches now,
224	 * so invalidate them instead of cleaning.
225	 */
226	adr	x0, __RW_START__
227	adr	x1, __RW_END__
228	sub	x1, x1, x0
229	bl	inv_dcache_range
230	bl	invalidate_tlb_all
231
232	/*
233	 * Clean the memory mapping of SRAM
234	 * the DDR mapping will remain to enable boot image to execute
235	 */
236	bl	platform_unmap_sram
237
238	/* Disable the SRAM */
239	bl	disable_sram
240
241	/* Disable and invalidate icache */
242	bl	disable_icache
243	bl	invalidate_icache_all
244
245	mov	x0, x28
246	br	x0
247endfunc marvell_exit_bootrom
248
249	/*
250	 * Enable L2 UniqueClean evictions with data
251	 */
252func ca72_l2_enable_unique_clean
253
254	mrs	x0, CORTEX_A72_L2ACTLR_EL1
255	orr	x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN
256	msr	CORTEX_A72_L2ACTLR_EL1, x0
257
258	ret
259endfunc ca72_l2_enable_unique_clean
260