1/*
2 * (C) Copyright 2014-2015 Freescale Semiconductor
3 *
4 * SPDX-License-Identifier:	GPL-2.0+
5 *
6 * Extracted from armv8/start.S
7 */
8
9#include <config.h>
10#include <linux/linkage.h>
11#include <asm/gic.h>
12#include <asm/macro.h>
13#include <asm/arch-fsl-layerscape/soc.h>
14#ifdef CONFIG_MP
15#include <asm/arch/mp.h>
16#endif
17#ifdef CONFIG_FSL_LSCH3
18#include <asm/arch-fsl-layerscape/immap_lsch3.h>
19#endif
20#include <asm/u-boot.h>
21
22/* Get GIC offset
23* For LS1043a rev1.0, GIC base address align with 4k.
24* For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
25* is set, GIC base address align with 4K, or else align
26* with 64k.
27* output:
28*	x0: the base address of GICD
29*	x1: the base address of GICC
30*/
31ENTRY(get_gic_offset)
32	ldr     x0, =GICD_BASE
33#ifdef CONFIG_GICV2
34	ldr     x1, =GICC_BASE
35#endif
36#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
37	ldr     x2, =DCFG_CCSR_SVR
38	ldr	w2, [x2]
39	rev	w2, w2
40	mov	w3, w2
41	ands	w3, w3, #SVR_WO_E << 8
42	mov	w4, #SVR_LS1043A << 8
43	cmp	w3, w4
44	b.ne	1f
45	ands	w2, w2, #0xff
46	cmp	w2, #REV1_0
47	b.eq	1f
48	ldr	x2, =SCFG_GIC400_ALIGN
49	ldr	w2, [x2]
50	rev	w2, w2
51	tbnz	w2, #GIC_ADDR_BIT, 1f
52	ldr     x0, =GICD_BASE_64K
53#ifdef CONFIG_GICV2
54	ldr     x1, =GICC_BASE_64K
55#endif
561:
57#endif
58	ret
59ENDPROC(get_gic_offset)
60
61ENTRY(smp_kick_all_cpus)
62	/* Kick secondary cpus up by SGI 0 interrupt */
63#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
64	mov	x29, lr			/* Save LR */
65	bl	get_gic_offset
66	bl	gic_kick_secondary_cpus
67	mov	lr, x29			/* Restore LR */
68#endif
69	ret
70ENDPROC(smp_kick_all_cpus)
71
72
73ENTRY(lowlevel_init)
74	mov	x29, lr			/* Save LR */
75
76	switch_el x1, 1f, 100f, 100f	/* skip if not in EL3 */
771:
78
79#ifdef CONFIG_FSL_LSCH3
80
81	/* Set Wuo bit for RN-I 20 */
82#ifdef CONFIG_ARCH_LS2080A
83	ldr	x0, =CCI_AUX_CONTROL_BASE(20)
84	ldr	x1, =0x00000010
85	bl	ccn504_set_aux
86
87	/*
88	 * Set forced-order mode in RNI-6, RNI-20
89	 * This is required for performance optimization on LS2088A
90	 * LS2080A family does not support setting forced-order mode,
91	 * so skip this operation for LS2080A family
92	 */
93	bl	get_svr
94	lsr	w0, w0, #16
95	ldr	w1, =SVR_DEV_LS2080A
96	cmp	w0, w1
97	b.eq	1f
98
99	ldr	x0, =CCI_AUX_CONTROL_BASE(6)
100	ldr	x1, =0x00000020
101	bl	ccn504_set_aux
102	ldr	x0, =CCI_AUX_CONTROL_BASE(20)
103	ldr	x1, =0x00000020
104	bl	ccn504_set_aux
1051:
106#endif
107
108	/* Add fully-coherent masters to DVM domain */
109	ldr	x0, =CCI_MN_BASE
110	ldr	x1, =CCI_MN_RNF_NODEID_LIST
111	ldr	x2, =CCI_MN_DVM_DOMAIN_CTL_SET
112	bl	ccn504_add_masters_to_dvm
113
114	/* Set all RN-I ports to QoS of 15 */
115	ldr	x0, =CCI_S0_QOS_CONTROL_BASE(0)
116	ldr	x1, =0x00FF000C
117	bl	ccn504_set_qos
118	ldr	x0, =CCI_S1_QOS_CONTROL_BASE(0)
119	ldr	x1, =0x00FF000C
120	bl	ccn504_set_qos
121	ldr	x0, =CCI_S2_QOS_CONTROL_BASE(0)
122	ldr	x1, =0x00FF000C
123	bl	ccn504_set_qos
124
125	ldr	x0, =CCI_S0_QOS_CONTROL_BASE(2)
126	ldr	x1, =0x00FF000C
127	bl	ccn504_set_qos
128	ldr	x0, =CCI_S1_QOS_CONTROL_BASE(2)
129	ldr	x1, =0x00FF000C
130	bl	ccn504_set_qos
131	ldr	x0, =CCI_S2_QOS_CONTROL_BASE(2)
132	ldr	x1, =0x00FF000C
133	bl	ccn504_set_qos
134
135	ldr	x0, =CCI_S0_QOS_CONTROL_BASE(6)
136	ldr	x1, =0x00FF000C
137	bl	ccn504_set_qos
138	ldr	x0, =CCI_S1_QOS_CONTROL_BASE(6)
139	ldr	x1, =0x00FF000C
140	bl	ccn504_set_qos
141	ldr	x0, =CCI_S2_QOS_CONTROL_BASE(6)
142	ldr	x1, =0x00FF000C
143	bl	ccn504_set_qos
144
145	ldr	x0, =CCI_S0_QOS_CONTROL_BASE(12)
146	ldr	x1, =0x00FF000C
147	bl	ccn504_set_qos
148	ldr	x0, =CCI_S1_QOS_CONTROL_BASE(12)
149	ldr	x1, =0x00FF000C
150	bl	ccn504_set_qos
151	ldr	x0, =CCI_S2_QOS_CONTROL_BASE(12)
152	ldr	x1, =0x00FF000C
153	bl	ccn504_set_qos
154
155	ldr	x0, =CCI_S0_QOS_CONTROL_BASE(16)
156	ldr	x1, =0x00FF000C
157	bl	ccn504_set_qos
158	ldr	x0, =CCI_S1_QOS_CONTROL_BASE(16)
159	ldr	x1, =0x00FF000C
160	bl	ccn504_set_qos
161	ldr	x0, =CCI_S2_QOS_CONTROL_BASE(16)
162	ldr	x1, =0x00FF000C
163	bl	ccn504_set_qos
164
165	ldr	x0, =CCI_S0_QOS_CONTROL_BASE(20)
166	ldr	x1, =0x00FF000C
167	bl	ccn504_set_qos
168	ldr	x0, =CCI_S1_QOS_CONTROL_BASE(20)
169	ldr	x1, =0x00FF000C
170	bl	ccn504_set_qos
171	ldr	x0, =CCI_S2_QOS_CONTROL_BASE(20)
172	ldr	x1, =0x00FF000C
173	bl	ccn504_set_qos
174#endif
175
176#ifdef SMMU_BASE
177	/* Set the SMMU page size in the sACR register */
178	ldr	x1, =SMMU_BASE
179	ldr	w0, [x1, #0x10]
180	orr	w0, w0, #1 << 16  /* set sACR.pagesize to indicate 64K page */
181	str	w0, [x1, #0x10]
182#endif
183
184	/* Initialize GIC Secure Bank Status */
185#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
186	branch_if_slave x0, 1f
187	bl	get_gic_offset
188	bl	gic_init_secure
1891:
190#ifdef CONFIG_GICV3
191	ldr	x0, =GICR_BASE
192	bl	gic_init_secure_percpu
193#elif defined(CONFIG_GICV2)
194	bl	get_gic_offset
195	bl	gic_init_secure_percpu
196#endif
197#endif
198
199100:
200	branch_if_master x0, x1, 2f
201
202#if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
203	ldr	x0, =secondary_boot_func
204	blr	x0
205#endif
206
2072:
208	switch_el x1, 1f, 100f, 100f	/* skip if not in EL3 */
2091:
210#ifdef CONFIG_FSL_TZPC_BP147
211	/* Set Non Secure access for all devices protected via TZPC */
212	ldr	x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
213	orr	w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
214	str	w0, [x1]
215
216	isb
217	dsb	sy
218#endif
219
220#ifdef CONFIG_FSL_TZASC_400
221	/*
222	 * LS2080 and its personalities does not support TZASC
223	 * So skip TZASC related operations
224	 */
225	bl	get_svr
226	lsr	w0, w0, #16
227	ldr	w1, =SVR_DEV_LS2080A
228	cmp	w0, w1
229	b.eq	1f
230
231	/* Set TZASC so that:
232	 * a. We use only Region0 whose global secure write/read is EN
233	 * b. We use only Region0 whose NSAID write/read is EN
234	 *
235	 * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
236	 * 	 placeholders.
237	 */
238#ifdef CONFIG_FSL_TZASC_1
239	ldr	x1, =TZASC_GATE_KEEPER(0)
240	ldr	w0, [x1]		/* Filter 0 Gate Keeper Register */
241	orr	w0, w0, #1 << 0		/* Set open_request for Filter 0 */
242	str	w0, [x1]
243
244	ldr	x1, =TZASC_REGION_ATTRIBUTES_0(0)
245	ldr	w0, [x1]		/* Region-0 Attributes Register */
246	orr	w0, w0, #1 << 31	/* Set Sec global write en, Bit[31] */
247	orr	w0, w0, #1 << 30	/* Set Sec global read en, Bit[30] */
248	str	w0, [x1]
249
250	ldr	x1, =TZASC_REGION_ID_ACCESS_0(0)
251	ldr	w0, [x1]		/* Region-0 Access Register */
252	mov	w0, #0xFFFFFFFF		/* Set nsaid_wr_en and nsaid_rd_en */
253	str	w0, [x1]
254#endif
255#ifdef CONFIG_FSL_TZASC_2
256	ldr	x1, =TZASC_GATE_KEEPER(1)
257	ldr	w0, [x1]		/* Filter 0 Gate Keeper Register */
258	orr	w0, w0, #1 << 0		/* Set open_request for Filter 0 */
259	str	w0, [x1]
260
261	ldr	x1, =TZASC_REGION_ATTRIBUTES_0(1)
262	ldr	w0, [x1]		/* Region-1 Attributes Register */
263	orr	w0, w0, #1 << 31	/* Set Sec global write en, Bit[31] */
264	orr	w0, w0, #1 << 30	/* Set Sec global read en, Bit[30] */
265	str	w0, [x1]
266
267	ldr	x1, =TZASC_REGION_ID_ACCESS_0(1)
268	ldr	w0, [x1]		/* Region-1 Attributes Register */
269	mov	w0, #0xFFFFFFFF		/* Set nsaid_wr_en and nsaid_rd_en */
270	str	w0, [x1]
271#endif
272	isb
273	dsb	sy
274#endif
275100:
2761:
277#ifdef CONFIG_ARCH_LS1046A
278	switch_el x1, 1f, 100f, 100f	/* skip if not in EL3 */
2791:
280	/* Initialize the L2 RAM latency */
281	mrs   x1, S3_1_c11_c0_2
282	mov   x0, #0x1C7
283	/* Clear L2 Tag RAM latency and L2 Data RAM latency */
284	bic   x1, x1, x0
285	/* Set L2 data ram latency bits [2:0] */
286	orr   x1, x1, #0x2
287	/* set L2 tag ram latency bits [8:6] */
288	orr   x1,  x1, #0x80
289	msr   S3_1_c11_c0_2, x1
290	isb
291100:
292#endif
293
294#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
295	bl	fsl_ocram_init
296#endif
297
298	mov	lr, x29			/* Restore LR */
299	ret
300ENDPROC(lowlevel_init)
301
302#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
303ENTRY(fsl_ocram_init)
304	mov	x28, lr			/* Save LR */
305	bl	fsl_clear_ocram
306	bl	fsl_ocram_clear_ecc_err
307	mov	lr, x28			/* Restore LR */
308	ret
309ENDPROC(fsl_ocram_init)
310
311ENTRY(fsl_clear_ocram)
312/* Clear OCRAM */
313	ldr	x0, =CONFIG_SYS_FSL_OCRAM_BASE
314	ldr	x1, =(CONFIG_SYS_FSL_OCRAM_BASE + CONFIG_SYS_FSL_OCRAM_SIZE)
315	mov	x2, #0
316clear_loop:
317	str	x2, [x0]
318	add	x0, x0, #8
319	cmp	x0, x1
320	b.lo	clear_loop
321	ret
322ENDPROC(fsl_clear_ocram)
323
324ENTRY(fsl_ocram_clear_ecc_err)
325	/* OCRAM1/2 ECC status bit */
326	mov	w1, #0x60
327	ldr	x0, =DCSR_DCFG_SBEESR2
328	str	w1, [x0]
329	ldr	x0, =DCSR_DCFG_MBEESR2
330	str	w1, [x0]
331	ret
332ENDPROC(fsl_ocram_init)
333#endif
334
335#ifdef CONFIG_FSL_LSCH3
336	.globl get_svr
337get_svr:
338	ldr	x1, =FSL_LSCH3_SVR
339	ldr	w0, [x1]
340	ret
341
342hnf_pstate_poll:
343	/* x0 has the desired status, return 0 for success, 1 for timeout
344	 * clobber x1, x2, x3, x4, x6, x7
345	 */
346	mov	x1, x0
347	mov	x7, #0			/* flag for timeout */
348	mrs	x3, cntpct_el0		/* read timer */
349	add	x3, x3, #1200		/* timeout after 100 microseconds */
350	mov	x0, #0x18
351	movk	x0, #0x420, lsl #16	/* HNF0_PSTATE_STATUS */
352	mov	w6, #8			/* HN-F node count */
3531:
354	ldr	x2, [x0]
355	cmp	x2, x1			/* check status */
356	b.eq	2f
357	mrs	x4, cntpct_el0
358	cmp	x4, x3
359	b.ls	1b
360	mov	x7, #1			/* timeout */
361	b	3f
3622:
363	add	x0, x0, #0x10000	/* move to next node */
364	subs	w6, w6, #1
365	cbnz	w6, 1b
3663:
367	mov	x0, x7
368	ret
369
370hnf_set_pstate:
371	/* x0 has the desired state, clobber x1, x2, x6 */
372	mov	x1, x0
373	/* power state to SFONLY */
374	mov	w6, #8			/* HN-F node count */
375	mov	x0, #0x10
376	movk	x0, #0x420, lsl #16	/* HNF0_PSTATE_REQ */
3771:	/* set pstate to sfonly */
378	ldr	x2, [x0]
379	and	x2, x2, #0xfffffffffffffffc	/* & HNFPSTAT_MASK */
380	orr	x2, x2, x1
381	str	x2, [x0]
382	add	x0, x0, #0x10000	/* move to next node */
383	subs	w6, w6, #1
384	cbnz	w6, 1b
385
386	ret
387
388ENTRY(__asm_flush_l3_dcache)
389	/*
390	 * Return status in x0
391	 *    success 0
392	 *    timeout 1 for setting SFONLY, 2 for FAM, 3 for both
393	 */
394	mov	x29, lr
395	mov	x8, #0
396
397	switch_el x0, 1f, 100f, 100f	/* skip if not in EL3 */
398
3991:
400	dsb	sy
401	mov	x0, #0x1		/* HNFPSTAT_SFONLY */
402	bl	hnf_set_pstate
403
404	mov	x0, #0x4		/* SFONLY status */
405	bl	hnf_pstate_poll
406	cbz	x0, 1f
407	mov	x8, #1			/* timeout */
4081:
409	dsb	sy
410	mov	x0, #0x3		/* HNFPSTAT_FAM */
411	bl	hnf_set_pstate
412
413	mov	x0, #0xc		/* FAM status */
414	bl	hnf_pstate_poll
415	cbz	x0, 1f
416	add	x8, x8, #0x2
417100:
4181:
419	mov	x0, x8
420	mov	lr, x29
421	ret
422ENDPROC(__asm_flush_l3_dcache)
423#endif
424
425#ifdef CONFIG_MP
426	/* Keep literals not used by the secondary boot code outside it */
427	.ltorg
428
429	/* Using 64 bit alignment since the spin table is accessed as data */
430	.align 4
431	.global secondary_boot_code
432	/* Secondary Boot Code starts here */
433secondary_boot_code:
434	.global __spin_table
435__spin_table:
436	.space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
437
438	.align 2
439ENTRY(secondary_boot_func)
440	/*
441	 * MPIDR_EL1 Fields:
442	 * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
443	 * MPIDR[7:2] = AFF0_RES
444	 * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
445	 * MPIDR[23:16] = AFF2_CLUSTERID
446	 * MPIDR[24] = MT
447	 * MPIDR[29:25] = RES0
448	 * MPIDR[30] = U
449	 * MPIDR[31] = ME
450	 * MPIDR[39:32] = AFF3
451	 *
452	 * Linear Processor ID (LPID) calculation from MPIDR_EL1:
453	 * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
454	 * until AFF2_CLUSTERID and AFF3 have non-zero values)
455	 *
456	 * LPID = MPIDR[15:8] | MPIDR[1:0]
457	 */
458	mrs	x0, mpidr_el1
459	ubfm	x1, x0, #8, #15
460	ubfm	x2, x0, #0, #1
461	orr	x10, x2, x1, lsl #2	/* x10 has LPID */
462	ubfm    x9, x0, #0, #15         /* x9 contains MPIDR[15:0] */
463	/*
464	 * offset of the spin table element for this core from start of spin
465	 * table (each elem is padded to 64 bytes)
466	 */
467	lsl	x1, x10, #6
468	ldr	x0, =__spin_table
469	/* physical address of this cpus spin table element */
470	add	x11, x1, x0
471
472	ldr	x0, =__real_cntfrq
473	ldr	x0, [x0]
474	msr	cntfrq_el0, x0	/* set with real frequency */
475	str	x9, [x11, #16]	/* LPID */
476	mov	x4, #1
477	str	x4, [x11, #8]	/* STATUS */
478	dsb	sy
479#if defined(CONFIG_GICV3)
480	gic_wait_for_interrupt_m x0
481#elif defined(CONFIG_GICV2)
482	bl	get_gic_offset
483	mov	x0, x1
484        gic_wait_for_interrupt_m x0, w1
485#endif
486
487slave_cpu:
488	wfe
489	ldr	x0, [x11]
490	cbz	x0, slave_cpu
491#ifndef CONFIG_ARMV8_SWITCH_TO_EL1
492	mrs     x1, sctlr_el2
493#else
494	mrs     x1, sctlr_el1
495#endif
496	tbz     x1, #25, cpu_is_le
497	rev     x0, x0                  /* BE to LE conversion */
498cpu_is_le:
499	ldr	x5, [x11, #24]
500	ldr	x6, =IH_ARCH_DEFAULT
501	cmp	x6, x5
502	b.eq	1f
503
504#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
505	adr	x4, secondary_switch_to_el1
506	ldr	x5, =ES_TO_AARCH64
507#else
508	ldr	x4, [x11]
509	ldr	x5, =ES_TO_AARCH32
510#endif
511	bl	secondary_switch_to_el2
512
5131:
514#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
515	adr	x4, secondary_switch_to_el1
516#else
517	ldr	x4, [x11]
518#endif
519	ldr	x5, =ES_TO_AARCH64
520	bl	secondary_switch_to_el2
521
522ENDPROC(secondary_boot_func)
523
524ENTRY(secondary_switch_to_el2)
525	switch_el x6, 1f, 0f, 0f
5260:	ret
5271:	armv8_switch_to_el2_m x4, x5, x6
528ENDPROC(secondary_switch_to_el2)
529
530ENTRY(secondary_switch_to_el1)
531	mrs	x0, mpidr_el1
532	ubfm	x1, x0, #8, #15
533	ubfm	x2, x0, #0, #1
534	orr	x10, x2, x1, lsl #2	/* x10 has LPID */
535
536	lsl	x1, x10, #6
537	ldr	x0, =__spin_table
538	/* physical address of this cpus spin table element */
539	add	x11, x1, x0
540
541	ldr	x4, [x11]
542
543	ldr	x5, [x11, #24]
544	ldr	x6, =IH_ARCH_DEFAULT
545	cmp	x6, x5
546	b.eq	2f
547
548	ldr	x5, =ES_TO_AARCH32
549	bl	switch_to_el1
550
5512:	ldr	x5, =ES_TO_AARCH64
552
553switch_to_el1:
554	switch_el x6, 0f, 1f, 0f
5550:	ret
5561:	armv8_switch_to_el1_m x4, x5, x6
557ENDPROC(secondary_switch_to_el1)
558
559	/* Ensure that the literals used by the secondary boot code are
560	 * assembled within it (this is required so that we can protect
561	 * this area with a single memreserve region
562	 */
563	.ltorg
564
565	/* 64 bit alignment for elements accessed as data */
566	.align 4
567	.global __real_cntfrq
568__real_cntfrq:
569	.quad COUNTER_FREQUENCY
570	.globl __secondary_boot_code_size
571	.type __secondary_boot_code_size, %object
572	/* Secondary Boot Code ends here */
573__secondary_boot_code_size:
574	.quad .-secondary_boot_code
575#endif
576