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#if defined (CONFIG_SYS_FSL_HAS_CCN504)
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 /* CONFIG_SYS_FSL_HAS_CCN504 */
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#endif
342
343#ifdef CONFIG_SYS_FSL_HAS_CCN504
344hnf_pstate_poll:
345	/* x0 has the desired status, return 0 for success, 1 for timeout
346	 * clobber x1, x2, x3, x4, x6, x7
347	 */
348	mov	x1, x0
349	mov	x7, #0			/* flag for timeout */
350	mrs	x3, cntpct_el0		/* read timer */
351	add	x3, x3, #1200		/* timeout after 100 microseconds */
352	mov	x0, #0x18
353	movk	x0, #0x420, lsl #16	/* HNF0_PSTATE_STATUS */
354	mov	w6, #8			/* HN-F node count */
3551:
356	ldr	x2, [x0]
357	cmp	x2, x1			/* check status */
358	b.eq	2f
359	mrs	x4, cntpct_el0
360	cmp	x4, x3
361	b.ls	1b
362	mov	x7, #1			/* timeout */
363	b	3f
3642:
365	add	x0, x0, #0x10000	/* move to next node */
366	subs	w6, w6, #1
367	cbnz	w6, 1b
3683:
369	mov	x0, x7
370	ret
371
372hnf_set_pstate:
373	/* x0 has the desired state, clobber x1, x2, x6 */
374	mov	x1, x0
375	/* power state to SFONLY */
376	mov	w6, #8			/* HN-F node count */
377	mov	x0, #0x10
378	movk	x0, #0x420, lsl #16	/* HNF0_PSTATE_REQ */
3791:	/* set pstate to sfonly */
380	ldr	x2, [x0]
381	and	x2, x2, #0xfffffffffffffffc	/* & HNFPSTAT_MASK */
382	orr	x2, x2, x1
383	str	x2, [x0]
384	add	x0, x0, #0x10000	/* move to next node */
385	subs	w6, w6, #1
386	cbnz	w6, 1b
387
388	ret
389
390ENTRY(__asm_flush_l3_dcache)
391	/*
392	 * Return status in x0
393	 *    success 0
394	 *    timeout 1 for setting SFONLY, 2 for FAM, 3 for both
395	 */
396	mov	x29, lr
397	mov	x8, #0
398
399	dsb	sy
400	mov	x0, #0x1		/* HNFPSTAT_SFONLY */
401	bl	hnf_set_pstate
402
403	mov	x0, #0x4		/* SFONLY status */
404	bl	hnf_pstate_poll
405	cbz	x0, 1f
406	mov	x8, #1			/* timeout */
4071:
408	dsb	sy
409	mov	x0, #0x3		/* HNFPSTAT_FAM */
410	bl	hnf_set_pstate
411
412	mov	x0, #0xc		/* FAM status */
413	bl	hnf_pstate_poll
414	cbz	x0, 1f
415	add	x8, x8, #0x2
4161:
417	mov	x0, x8
418	mov	lr, x29
419	ret
420ENDPROC(__asm_flush_l3_dcache)
421#endif /* CONFIG_SYS_FSL_HAS_CCN504 */
422
423#ifdef CONFIG_MP
424	/* Keep literals not used by the secondary boot code outside it */
425	.ltorg
426
427	/* Using 64 bit alignment since the spin table is accessed as data */
428	.align 4
429	.global secondary_boot_code
430	/* Secondary Boot Code starts here */
431secondary_boot_code:
432	.global __spin_table
433__spin_table:
434	.space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
435
436	.align 2
437ENTRY(secondary_boot_func)
438	/*
439	 * MPIDR_EL1 Fields:
440	 * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
441	 * MPIDR[7:2] = AFF0_RES
442	 * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
443	 * MPIDR[23:16] = AFF2_CLUSTERID
444	 * MPIDR[24] = MT
445	 * MPIDR[29:25] = RES0
446	 * MPIDR[30] = U
447	 * MPIDR[31] = ME
448	 * MPIDR[39:32] = AFF3
449	 *
450	 * Linear Processor ID (LPID) calculation from MPIDR_EL1:
451	 * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
452	 * until AFF2_CLUSTERID and AFF3 have non-zero values)
453	 *
454	 * LPID = MPIDR[15:8] | MPIDR[1:0]
455	 */
456	mrs	x0, mpidr_el1
457	ubfm	x1, x0, #8, #15
458	ubfm	x2, x0, #0, #1
459	orr	x10, x2, x1, lsl #2	/* x10 has LPID */
460	ubfm    x9, x0, #0, #15         /* x9 contains MPIDR[15:0] */
461	/*
462	 * offset of the spin table element for this core from start of spin
463	 * table (each elem is padded to 64 bytes)
464	 */
465	lsl	x1, x10, #6
466	ldr	x0, =__spin_table
467	/* physical address of this cpus spin table element */
468	add	x11, x1, x0
469
470	ldr	x0, =__real_cntfrq
471	ldr	x0, [x0]
472	msr	cntfrq_el0, x0	/* set with real frequency */
473	str	x9, [x11, #16]	/* LPID */
474	mov	x4, #1
475	str	x4, [x11, #8]	/* STATUS */
476	dsb	sy
477#if defined(CONFIG_GICV3)
478	gic_wait_for_interrupt_m x0
479#elif defined(CONFIG_GICV2)
480	bl	get_gic_offset
481	mov	x0, x1
482        gic_wait_for_interrupt_m x0, w1
483#endif
484
485slave_cpu:
486	wfe
487	ldr	x0, [x11]
488	cbz	x0, slave_cpu
489#ifndef CONFIG_ARMV8_SWITCH_TO_EL1
490	mrs     x1, sctlr_el2
491#else
492	mrs     x1, sctlr_el1
493#endif
494	tbz     x1, #25, cpu_is_le
495	rev     x0, x0                  /* BE to LE conversion */
496cpu_is_le:
497	ldr	x5, [x11, #24]
498	cbz	x5, 1f
499
500#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
501	adr	x4, secondary_switch_to_el1
502	ldr	x5, =ES_TO_AARCH64
503#else
504	ldr	x4, [x11]
505	ldr	x5, =ES_TO_AARCH32
506#endif
507	bl	secondary_switch_to_el2
508
5091:
510#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
511	adr	x4, secondary_switch_to_el1
512#else
513	ldr	x4, [x11]
514#endif
515	ldr	x5, =ES_TO_AARCH64
516	bl	secondary_switch_to_el2
517
518ENDPROC(secondary_boot_func)
519
520ENTRY(secondary_switch_to_el2)
521	switch_el x6, 1f, 0f, 0f
5220:	ret
5231:	armv8_switch_to_el2_m x4, x5, x6
524ENDPROC(secondary_switch_to_el2)
525
526ENTRY(secondary_switch_to_el1)
527	mrs	x0, mpidr_el1
528	ubfm	x1, x0, #8, #15
529	ubfm	x2, x0, #0, #1
530	orr	x10, x2, x1, lsl #2	/* x10 has LPID */
531
532	lsl	x1, x10, #6
533	ldr	x0, =__spin_table
534	/* physical address of this cpus spin table element */
535	add	x11, x1, x0
536
537	ldr	x4, [x11]
538
539	ldr	x5, [x11, #24]
540	cbz	x5, 2f
541
542	ldr	x5, =ES_TO_AARCH32
543	bl	switch_to_el1
544
5452:	ldr	x5, =ES_TO_AARCH64
546
547switch_to_el1:
548	switch_el x6, 0f, 1f, 0f
5490:	ret
5501:	armv8_switch_to_el1_m x4, x5, x6
551ENDPROC(secondary_switch_to_el1)
552
553	/* Ensure that the literals used by the secondary boot code are
554	 * assembled within it (this is required so that we can protect
555	 * this area with a single memreserve region
556	 */
557	.ltorg
558
559	/* 64 bit alignment for elements accessed as data */
560	.align 4
561	.global __real_cntfrq
562__real_cntfrq:
563	.quad COUNTER_FREQUENCY
564	.globl __secondary_boot_code_size
565	.type __secondary_boot_code_size, %object
566	/* Secondary Boot Code ends here */
567__secondary_boot_code_size:
568	.quad .-secondary_boot_code
569#endif
570