• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
3 *
4 * Copyright (c) 2004	Texas Instruments <r-woodruff2@ti.com>
5 *
6 * Copyright (c) 2001	Marius Gröger <mag@sysgo.de>
7 * Copyright (c) 2002	Alex Züpke <azu@sysgo.de>
8 * Copyright (c) 2002	Gary Jennejohn <garyj@denx.de>
9 * Copyright (c) 2003	Richard Woodruff <r-woodruff2@ti.com>
10 * Copyright (c) 2003	Kshitij <kshitij@ti.com>
11 * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
12 *
13 * SPDX-License-Identifier:	GPL-2.0+
14 */
15
16#include <asm-offsets.h>
17#include <config.h>
18#include <asm/system.h>
19#include <linux/linkage.h>
20#include <asm/armv7.h>
21
22/*************************************************************************
23 *
24 * Startup Code (reset vector)
25 *
26 * Do important init only if we don't start from memory!
27 * Setup memory and board specific bits prior to relocation.
28 * Relocate armboot to ram. Setup stack.
29 *
30 *************************************************************************/
31.globl	_start
32_start:
33	b	reset
34	b	.
35	b	.
36	b	.
37	b	.
38	b	.
39	b	.
40	b	.
41	.balignl 64,0xdeadbeef
42
43	.globl	reset
44	.globl	save_boot_params_ret
45#ifdef CONFIG_ARMV7_LPAE
46	.global	switch_to_hypervisor_ret
47#endif
48
49 __blank_zone_start:
50	.fill 1024*8,1,0
51__blank_zone_end:
52
53	.globl _blank_zone_start
54_blank_zone_start:
55	.word __blank_zone_start
56
57
58	.globl _blank_zone_end
59_blank_zone_end:
60	.word __blank_zone_end
61
62	.balignl 16,0xdeadbeef
63	.globl	_TEXT_BASE
64_TEXT_BASE:
65	.word TEXT_BASE
66
67
68_clr_remap_fmc_entry:
69	.word   FMC_TEXT_ADRS + do_clr_remap - CONFIG_SYS_TEXT_BASE_ORI
70
71_start_armboot:
72	.word start_armboot
73
74reset:
75	/* Allow the board to save important registers */
76	b	save_boot_params
77save_boot_params_ret:
78#ifdef CONFIG_ARMV7_LPAE
79/*
80 * check for Hypervisor support
81 */
82	mrc	p15, 0, r0, c0, c1, 1		@ read ID_PFR1
83	and	r0, r0, #CPUID_ARM_VIRT_MASK	@ mask virtualization bits
84	cmp	r0, #(1 << CPUID_ARM_VIRT_SHIFT)
85	beq	switch_to_hypervisor
86switch_to_hypervisor_ret:
87#endif
88	/*
89	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
90	 * except if in HYP mode already
91	 */
92	mrs	r0, cpsr
93	and	r1, r0, #0x1f		@ mask mode bits
94	teq	r1, #0x1a		@ test for HYP mode
95	bicne	r0, r0, #0x1f		@ clear all mode bits
96	orrne	r0, r0, #0x13		@ set SVC mode
97	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
98	msr	cpsr,r0
99
100	mov r0, #0x55
101	mcr p15, 0,r0, c3,c0,0		@ set DACR accesses are checked
102
103/*
104 * Setup vector:
105 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
106 * Continue to use ROM code vector only in OMAP4 spl)
107 */
108#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
109	/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
110	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTLR Register
111	bic	r0, #CR_V		@ V = 0
112	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTLR Register
113
114	/* Set vector address in CP15 VBAR register */
115	adrl	r0, _start
116	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
117#endif
118
119	/* the mask ROM code should have PLL and others stable */
120#ifndef CONFIG_SKIP_LOWLEVEL_INIT
121	bl	cpu_init_cp15
122#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
123	bl	cpu_init_crit
124#endif
125#endif
126
127#ifndef CONFIG_HISI_DISABLE_DOWNLOAD
128	/*
129	 *  read system register REG_SC_GEN2
130         *  check if ziju flag
131	 */
132	ldr	r0, =SYS_CTRL_REG_BASE
133	ldr	r1, [r0, #REG_SC_GEN2]
134	ldr	r2, =0x7a696a75          /* magic for "ziju" */
135	cmp	r1, r2
136	bne	normal_start_flow
137	mov	r1, sp                   /* save sp */
138	str	r1, [r0, #REG_SC_GEN2]  /* clear ziju flag */
139
140    /* init PLL/DDRC/pin mux/... */
141	ldr	r0, _blank_zone_start
142	ldr	r1, _TEXT_BASE
143	sub	r0, r0, r1
144	ldr	r1, =RAM_START_ADRS
145	ldr	sp, =STACK_TRAINING
146	add	r0, r0, r1
147	mov	r1, #0x0                 /* flags: 0->normal 1->pm */
148	bl	init_registers           /* init PLL/DDRC/... */
149	/* after ziju, we need ddr traning */
150	ldr	r0, =REG_BASE_SCTL
151
152	bl	start_ddr_training       /* DDR training */
153	ldr	r0, =SYS_CTRL_REG_BASE
154	ldr	r1, [r0, #REG_SC_GEN2]
155	mov	sp, r1		         /* restore sp */
156	ldr	r1, [r0, #REG_SC_GEN3]
157	mov	pc, r1                  /* return to bootrom */
158	nop
159	nop
160	nop
161	nop
162	nop
163	nop
164	nop
165	nop
166	b	.                        /* bug here */
167
168normal_start_flow:
169#endif
170	/* init serial and printf a string. */
171	ldr     sp, =STACK_TRAINING
172	bl      uart_early_init
173	bl      msg_main_cpu_startup
174
175	/*
176	 * enable syscnt
177	 */
178	ldr	r0, =SYSCNT_REG_BASE
179	ldr 	r3, =SYSCNT_FREQ
180	str	r3, [r0, #SYSCNT_FREQ_REG]
181	mov	r3, #0x1
182	str	r3, [r0, #SYSCNT_ENABLE_REG]
183
184	@if running not boot from nand/spi/emmc,
185	@we skipping boot_type checking.
186	mov    r0, pc, lsr#24
187	cmp    r0, #0x0
188	bne    do_clr_remap
189
190check_boot_type:
191	ldr     r0, =SYS_CTRL_REG_BASE
192	ldr     r0, [r0, #REG_SYSSTAT]
193	mov     r6, r0, lsr #3
194	and     r6, #0x1
195	cmp     r6, #0x1
196	ldrlo   pc, _clr_remap_fmc_entry
197
198do_clr_remap:
199        /* do clear remap */
200	ldr     r4, =SYS_CTRL_REG_BASE
201	ldr	r0, [r4, #REG_SC_CTRL]
202
203	@Set clear remap bit.
204	orr	r0, #(1<<8)
205	str	r0, [r4, #REG_SC_CTRL]
206
207	@enable I-Cache now
208	mrc p15, 0, r0, c1, c0, 0
209	orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
210	mcr p15, 0, r0, c1, c0, 0
211
212	@Check wether I am running in dynamic mem bank:<0x40000000
213	mov r0, pc, lsr#28
214	cmp r0, #4
215	blo	ddr_init
216
217no_ddr_init:
218	adrl	r0, _start
219	b       copy_to_ddr
220
221ddr_init:
222	ldr     r0, _blank_zone_start
223	ldr     r1, _TEXT_BASE
224	sub     r0, r0, r1
225	adrl	r1, _start
226	add     r0, r0, r1
227	mov     r1, #0          /* flags: 0->normal 1->pm */
228	bl      init_registers
229
230	ldr	sp, =STACK_TRAINING
231	ldr	r0, =REG_BASE_SCTL
232	bl	start_ddr_training       /* DDR training */
233
234check_boot_mode:
235	ldr	r0, =SYS_CTRL_REG_BASE
236	ldr     r0, [r0, #REG_SYSSTAT]
237	mov     r6, r0, lsr #BOOT_SEL_SHIFT
238	and	r6, #0x3
239	cmp     r6, #BOOT_FROM_EMMC
240	bne     copy_flash_to_ddr
241
242emmc_boot:
243	ldr     r0, _TEXT_BASE
244	ldr	r1, =__image_copy_start
245	ldr	r2, =__bss_start
246	sub	r1, r2, r1
247	bl	emmc_boot_read
248	b       relocate
249
250copy_flash_to_ddr:
251	/* relocate SPI nor/nand Boot to DDR  */
252	ldr	r0, =FMC_TEXT_ADRS
253
254copy_to_ddr:
255	/* now, r0 stores __reset offset from where we get started */
256	ldr     r1, =__image_copy_start
257
258	/* compare source and target address, *
259	 *if equal no copy to target address */
260	cmp     r0, r1
261	beq	start_armboot
262
263	ldr     r2, =__image_copy_start/*_start*/
264	ldr     r3, =__bss_start
265	sub     r2, r3, r2      /* r2 <- size of armboot */
266	/* memcpy(r1, r0, r2) */
267	bl      memcpy
268
269relocate:
270	ldr r0, =_start_armboot
271	ldr pc, [r0]
272
273bug:
274	nop
275	nop
276	nop
277	nop
278	nop
279	nop
280	nop
281	nop
282	b       .                       /* bug here */
283@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
284@
285@       void memcpy(r1, r0, r2);
286@
287
288.align  2
289memcpy:
290	add     r2, r0, r2
291	memcpy_loop:
292	ldmia   r0!, {r3 - r10}
293	stmia   r1!, {r3 - r10}
294	cmp     r0, r2
295	ble     memcpy_loop
296	mov     pc, lr
297
298@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
299
300.align  2
301msg_main_cpu_startup:
302	mov     r5, lr
303	add     r0, pc, #4
304	bl      uart_early_puts
305	mov     pc, r5
306	L10:
307#ifndef CONFIG_SUPPORT_CA_RELEASE
308	.ascii "\r\n\r\nSystem startup\r\n\0"
309#else
310	.ascii "\r\n\r\n\r\n\0"
311#endif
312
313/*------------------------------------------------------------------------------*/
314
315ENTRY(c_runtime_cpu_setup)
316/*
317 * If I-cache is enabled invalidate it
318 */
319#ifndef CONFIG_SYS_ICACHE_OFF
320	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
321	mcr     p15, 0, r0, c7, c10, 4	@ DSB
322	mcr     p15, 0, r0, c7, c5, 4	@ ISB
323#endif
324
325	bx	lr
326
327ENDPROC(c_runtime_cpu_setup)
328
329/*************************************************************************
330 *
331 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
332 *	__attribute__((weak));
333 *
334 * Stack pointer is not yet initialized at this moment
335 * Don't save anything to stack even if compiled with -O0
336 *
337 *************************************************************************/
338ENTRY(save_boot_params)
339	b	save_boot_params_ret		@ back to my caller
340ENDPROC(save_boot_params)
341	.weak	save_boot_params
342
343#ifdef CONFIG_ARMV7_LPAE
344ENTRY(switch_to_hypervisor)
345	b	switch_to_hypervisor_ret
346ENDPROC(switch_to_hypervisor)
347	.weak	switch_to_hypervisor
348#endif
349
350/*************************************************************************
351 *
352 * cpu_init_cp15
353 *
354 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
355 * CONFIG_SYS_ICACHE_OFF is defined.
356 *
357 *************************************************************************/
358ENTRY(cpu_init_cp15)
359	/*
360	 * Invalidate L1 I/D
361	 */
362	mov	r0, #0			@ set up for MCR
363	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
364	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
365	mcr	p15, 0, r0, c7, c5, 6	@ invalidate BP array
366	mcr     p15, 0, r0, c7, c10, 4	@ DSB
367	mcr     p15, 0, r0, c7, c5, 4	@ ISB
368
369	/*
370	 * disable MMU stuff and caches
371	 */
372	mrc	p15, 0, r0, c1, c0, 0
373	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
374	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
375	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
376	orr	r0, r0, #0x00000800	@ set bit 11 (Z---) BTB
377#ifdef CONFIG_SYS_ICACHE_OFF
378	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
379#else
380	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
381#endif
382	mcr	p15, 0, r0, c1, c0, 0
383
384#ifdef CONFIG_ARM_ERRATA_716044
385	mrc	p15, 0, r0, c1, c0, 0	@ read system control register
386	orr	r0, r0, #1 << 11	@ set bit #11
387	mcr	p15, 0, r0, c1, c0, 0	@ write system control register
388#endif
389
390#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
391	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
392	orr	r0, r0, #1 << 4		@ set bit #4
393	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
394#endif
395
396#ifdef CONFIG_ARM_ERRATA_743622
397	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
398	orr	r0, r0, #1 << 6		@ set bit #6
399	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
400#endif
401
402#ifdef CONFIG_ARM_ERRATA_751472
403	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
404	orr	r0, r0, #1 << 11	@ set bit #11
405	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
406#endif
407#ifdef CONFIG_ARM_ERRATA_761320
408	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
409	orr	r0, r0, #1 << 21	@ set bit #21
410	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
411#endif
412
413	mov	r5, lr			@ Store my Caller
414	mrc	p15, 0, r1, c0, c0, 0	@ r1 has Read Main ID Register (MIDR)
415	mov	r3, r1, lsr #20		@ get variant field
416	and	r3, r3, #0xf		@ r3 has CPU variant
417	and	r4, r1, #0xf		@ r4 has CPU revision
418	mov	r2, r3, lsl #4		@ shift variant field for combined value
419	orr	r2, r4, r2		@ r2 has combined CPU variant + revision
420
421#ifdef CONFIG_ARM_ERRATA_798870
422	cmp	r2, #0x30		@ Applies to lower than R3p0
423	bge	skip_errata_798870      @ skip if not affected rev
424	cmp	r2, #0x20		@ Applies to including and above R2p0
425	blt	skip_errata_798870      @ skip if not affected rev
426
427	mrc	p15, 1, r0, c15, c0, 0  @ read l2 aux ctrl reg
428	orr	r0, r0, #1 << 7         @ Enable hazard-detect timeout
429	push	{r1-r5}			@ Save the cpu info registers
430	bl	v7_arch_cp15_set_l2aux_ctrl
431	isb				@ Recommended ISB after l2actlr update
432	pop	{r1-r5}			@ Restore the cpu info - fall through
433skip_errata_798870:
434#endif
435
436#ifdef CONFIG_ARM_ERRATA_801819
437	cmp	r2, #0x24		@ Applies to lt including R2p4
438	bgt	skip_errata_801819      @ skip if not affected rev
439	cmp	r2, #0x20		@ Applies to including and above R2p0
440	blt	skip_errata_801819      @ skip if not affected rev
441	mrc	p15, 0, r0, c0, c0, 6	@ pick up REVIDR reg
442	and	r0, r0, #1 << 3		@ check REVIDR[3]
443	cmp	r0, #1 << 3
444	beq	skip_errata_801819	@ skip erratum if REVIDR[3] is set
445
446	mrc	p15, 0, r0, c1, c0, 1	@ read auxilary control register
447	orr	r0, r0, #3 << 27	@ Disables streaming. All write-allocate
448					@ lines allocate in the L1 or L2 cache.
449	orr	r0, r0, #3 << 25	@ Disables streaming. All write-allocate
450					@ lines allocate in the L1 cache.
451	push	{r1-r5}			@ Save the cpu info registers
452	bl	v7_arch_cp15_set_acr
453	pop	{r1-r5}			@ Restore the cpu info - fall through
454skip_errata_801819:
455#endif
456
457#ifdef CONFIG_ARM_ERRATA_454179
458	cmp	r2, #0x21		@ Only on < r2p1
459	bge	skip_errata_454179
460
461	mrc	p15, 0, r0, c1, c0, 1	@ Read ACR
462	orr	r0, r0, #(0x3 << 6)	@ Set DBSM(BIT7) and IBE(BIT6) bits
463	push	{r1-r5}			@ Save the cpu info registers
464	bl	v7_arch_cp15_set_acr
465	pop	{r1-r5}			@ Restore the cpu info - fall through
466
467skip_errata_454179:
468#endif
469
470#ifdef CONFIG_ARM_ERRATA_430973
471	cmp	r2, #0x21		@ Only on < r2p1
472	bge	skip_errata_430973
473
474	mrc	p15, 0, r0, c1, c0, 1	@ Read ACR
475	orr	r0, r0, #(0x1 << 6)	@ Set IBE bit
476	push	{r1-r5}			@ Save the cpu info registers
477	bl	v7_arch_cp15_set_acr
478	pop	{r1-r5}			@ Restore the cpu info - fall through
479
480skip_errata_430973:
481#endif
482
483#ifdef CONFIG_ARM_ERRATA_621766
484	cmp	r2, #0x21		@ Only on < r2p1
485	bge	skip_errata_621766
486
487	mrc	p15, 0, r0, c1, c0, 1	@ Read ACR
488	orr	r0, r0, #(0x1 << 5)	@ Set L1NEON bit
489	push	{r1-r5}			@ Save the cpu info registers
490	bl	v7_arch_cp15_set_acr
491	pop	{r1-r5}			@ Restore the cpu info - fall through
492
493skip_errata_621766:
494#endif
495
496	mov	pc, r5			@ back to my caller
497ENDPROC(cpu_init_cp15)
498
499#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \
500	!defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY)
501/*************************************************************************
502 *
503 * CPU_init_critical registers
504 *
505 * setup important registers
506 * setup memory timing
507 *
508 *************************************************************************/
509ENTRY(cpu_init_crit)
510	/*
511	 * Jump to board specific initialization...
512	 * The Mask ROM will have already initialized
513	 * basic memory. Go here to bump up clock rate and handle
514	 * wake up conditions.
515	 */
516	b	lowlevel_init		@ go setup pll,mux,memory
517ENDPROC(cpu_init_crit)
518#endif
519
520