PXA: Fix reloc, Push lowlevel init into C code

Firstly, this fixes relocation issues. I had to use part of Dcache as RAM for a
while. I also moved around the lowlevel init code. It turned out so most of the
lowlevel init code ended in cpu.c (and eventually was rewritten into C).

This will also allow easier operation with FDT, multi-CPU-model support etc. in
later releases.

NOTE: This breaks most of the PXA boards (actually, the reloc stuff did already,
this only finishes the doom).

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S
index 9c5023b..684e44e 100644
--- a/arch/arm/cpu/pxa/start.S
+++ b/arch/arm/cpu/pxa/start.S
@@ -31,6 +31,14 @@
 #include <config.h>
 #include <version.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/macro.h>
+
+/* takes care the CP15 update has taken place */
+.macro CPWAIT reg
+mrc  p15,0,\reg,c2,c0,0
+mov  \reg,\reg
+sub  pc,pc,#4
+.endm
 
 .globl _start
 _start: b	reset
@@ -86,11 +94,9 @@
 _TEXT_BASE:
 	.word	CONFIG_SYS_TEXT_BASE
 
-#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
 .globl _armboot_start
 _armboot_start:
 	.word _start
-#endif
 
 /*
  * These are defined in the board-specific linker script.
@@ -115,7 +121,7 @@
 	.word 0x0badc0de
 #endif /* CONFIG_USE_IRQ */
 
-#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+#ifndef CONFIG_PRELOADER
 /* IRQ stack memory (calculated at run-time) + 8 bytes */
 .globl IRQ_STACK_START_IN
 IRQ_STACK_START_IN:
@@ -159,12 +165,84 @@
 	msr	cpsr,r0
 
 	/*
-	 * we do sys-critical inits only at reboot,
-	 * not when booting from ram!
+	 * Enable MMU to use DCache as DRAM
 	 */
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
-	bl	cpu_init_crit
-#endif
+	/* Domain access -- enable for all CPs */
+	ldr	r0, =0x0000ffff
+	mcr	p15, 0, r0, c3, c0, 0
+
+	/* Point TTBR to MMU table */
+	ldr	r0, =mmu_table
+	adr	r2, _start
+	orr	r0, r2
+	mcr	p15, 0, r0, c2, c0, 0
+
+/* !!! Hereby, check if the code is running from SRAM !!! */
+/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code
+ * is linked to 0x0 too, so this makes things easier. */
+	cmp	r2, #0x5c000000
+
+	ldreq	r1, [r0]
+	orreq	r1, r2
+	streq	r1, [r0]
+
+	/* Kick in MMU, ICache, DCache, BTB */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, #0x1b00
+	bic	r0, #0x0087
+	orr	r0, #0x1800
+	orr	r0, #0x0005
+	mcr	p15, 0, r0, c1, c0, 0
+	CPWAIT	r0
+
+	/* Unlock Icache, Dcache */
+	mcr	p15, 0, r0, c9, c1, 1
+	mcr	p15, 0, r0, c9, c2, 1
+
+	/* Flush Icache, Dcache, BTB */
+	mcr	p15, 0, r0, c7, c7, 0
+
+	/* Unlock I-TLB, D-TLB */
+	mcr	p15, 0, r0, c10, c4, 1
+	mcr	p15, 0, r0, c10, c8, 1
+
+	/* Flush TLB */
+	mcr	p15, 0, r0, c8, c7, 0
+	/* Allocate 4096 bytes of Dcache as RAM */
+
+	/* Drain pending loads and stores */
+	mcr	p15, 0, r0, c7, c10, 4
+
+	mov	r4, #0x00
+	mov	r5, #0x00
+	mov	r2, #0x01
+	mcr	p15, 0, r0, c9, c2, 0
+	CPWAIT	r0
+
+	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
+	mov	r0, #128
+	mov	r1, #0xa0000000
+alloc:
+	mcr	p15, 0, r1, c7, c2, 5
+	/* Drain pending loads and stores */
+	mcr	p15, 0, r0, c7, c10, 4
+	strd	r4, [r1], #8
+	strd	r4, [r1], #8
+	strd	r4, [r1], #8
+	strd	r4, [r1], #8
+	subs	r0, #0x01
+	bne	alloc
+	/* Drain pending loads and stores */
+	mcr	p15, 0, r0, c7, c10, 4
+	mov	r2, #0x00
+	mcr	p15, 0, r2, c9, c2, 0
+	CPWAIT	r0
+
+	/* Jump to 0x0 ( + offset) if running from SRAM */
+	adr	r0, zerojmp
+	bic	r0, #0x5c000000
+	mov	pc, r0
+zerojmp:
 
 /* Set stackpointer in internal RAM to call board_init_f */
 call_board_init_f:
@@ -201,11 +279,13 @@
 	beq	clear_bss
 
 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
+	stmfd sp!, {r0-r12}
 copy_loop:
-	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
-	stmia	r6!, {r9-r10}		/* copy to   target address [r1]    */
+	ldmia	r0!, {r3-r5, r7-r11}	/* copy from source address [r0]    */
+	stmia	r6!, {r3-r5, r7-r11}	/* copy to   target address [r1]    */
 	cmp	r0, r2			/* until source end address [r2]    */
 	blo	copy_loop
+	ldmfd sp!, {r0-r12}
 
 #ifndef CONFIG_PRELOADER
 	/* fix got entries */
@@ -274,218 +354,28 @@
 
 /****************************************************************************/
 /*									    */
-/* the actual reset code						    */
+/* the actual reset code for OneNAND IPL				    */
 /*									    */
 /****************************************************************************/
 
+#ifndef	CONFIG_PXA27X
+#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM
+#endif
+
 reset:
-	mrs	r0,cpsr			/* set the CPU to SVC32 mode	    */
-	bic	r0,r0,#0x1f		/* (superviser mode, M=10011)	    */
+	/* Set CPU to SVC32 mode */
+	mrs	r0,cpsr
+	bic	r0,r0,#0x1f
 	orr	r0,r0,#0x13
 	msr	cpsr,r0
 
-	/*
-	 * we do sys-critical inits only at reboot,
-	 * not when booting from RAM!
-	 */
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
-	bl	cpu_init_crit		/* we do sys-critical inits	    */
-#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
+	/* Point stack at the end of SRAM and leave 32 words for abort-stack */
+	ldr	sp, =0x5c03ff80
 
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-relocate:				/* relocate U-Boot to RAM	    */
-	adr	r0, _start		/* r0 <- current position of code   */
-	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
-#ifndef	CONFIG_PRELOADER
-	cmp	r0, r1			/* don't reloc during debug	    */
-	beq	stack_setup
-#endif
+	/* Start OneNAND IPL */
+	ldr	pc, =start_oneboot
 
-	ldr	r2, _armboot_start
-	ldr	r3, _bss_start
-	sub	r2, r3, r2		/* r2 <- size of armboot	    */
-	add	r2, r0, r2		/* r2 <- source end address	    */
-
-copy_loop:
-	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
-	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
-	cmp	r0, r2			/* until source end address [r2]    */
-	blo	copy_loop
-#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
-
-	/* Set up the stack						    */
-stack_setup:
-	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
-#ifdef CONFIG_PRELOADER
-	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
-#else
-	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area		    */
-	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo		    */
-#ifdef CONFIG_USE_IRQ
-	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
-#endif /* CONFIG_USE_IRQ */
-	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
-	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
-#endif
-
-clear_bss:
-	ldr	r0, _bss_start		/* find start of bss segment	    */
-	ldr	r1, _bss_end		/* stop here			    */
-	mov	r2, #0x00000000		/* clear			    */
-
-#ifndef CONFIG_PRELOADER
-clbss_l:str	r2, [r0]		/* clear loop...		    */
-	add	r0, r0, #4
-	cmp	r0, r1
-	blo	clbss_l
-#endif
-
-	ldr	pc, _start_armboot
-
-#ifdef CONFIG_ONENAND_IPL
-_start_armboot: .word start_oneboot
-#else
-_start_armboot: .word start_armboot
-#endif
-#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
-
-/****************************************************************************/
-/*									    */
-/* CPU_init_critical registers						    */
-/*									    */
-/* - setup important registers						    */
-/* - setup memory timing						    */
-/*									    */
-/****************************************************************************/
-/* mk@tbd: Fix this! */
-#undef RCSR
-#undef ICMR
-#undef OSMR3
-#undef OSCR
-#undef OWER
-#undef OIER
-#undef CCCR
-
-/* Interrupt-Controller base address					    */
-IC_BASE:	   .word	   0x40d00000
-#define ICMR	0x04
-
-/* Reset-Controller */
-RST_BASE:	.word	0x40f00030
-#define RCSR	0x00
-
-/* Operating System Timer */
-OSTIMER_BASE:	.word	0x40a00000
-#define OSMR3	0x0C
-#define OSCR	0x10
-#define OWER	0x18
-#define OIER	0x1C
-
-/* Clock Manager Registers						    */
-#ifdef CONFIG_CPU_MONAHANS
-# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
-#  error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!"
-# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */
-# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO
-#  define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
-# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */
-#else /* !CONFIG_CPU_MONAHANS */
-#ifdef CONFIG_SYS_CPUSPEED
-CC_BASE:	.word	0x41300000
-#define CCCR	0x00
-cpuspeed:	.word	CONFIG_SYS_CPUSPEED
-#else /* !CONFIG_SYS_CPUSPEED */
-#error "You have to define CONFIG_SYS_CPUSPEED!!"
-#endif /* CONFIG_SYS_CPUSPEED */
-#endif /* CONFIG_CPU_MONAHANS */
-
-	/* takes care the CP15 update has taken place */
-	.macro CPWAIT reg
-	mrc  p15,0,\reg,c2,c0,0
-	mov  \reg,\reg
-	sub  pc,pc,#4
-	.endm
-
-cpu_init_crit:
-
-	/* mask all IRQs						    */
-#ifndef CONFIG_CPU_MONAHANS
-	ldr	r0, IC_BASE
-	mov	r1, #0x00
-	str	r1, [r0, #ICMR]
-#else /* CONFIG_CPU_MONAHANS */
-	/* Step 1 - Enable CP6 permission */
-	mrc	p15, 0, r1, c15, c1, 0	@ read CPAR
-	orr	r1, r1, #0x40
-		mcr	p15, 0, r1, c15, c1, 0
-	CPWAIT	r1
-
-	/* Step 2 - Mask ICMR & ICMR2 */
-	mov	r1, #0
-	mcr	p6, 0, r1, c1, c0, 0	@ ICMR
-	mcr	p6, 0, r1, c7, c0, 0	@ ICMR2
-
-	/* turn off all clocks but the ones we will definitly require */
-	ldr	r1, =CKENA
-	ldr	r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
-	str	r2, [r1]
-	ldr	r1, =CKENB
-	ldr	r2, =(CKENB_6_IRQ)
-	str	r2, [r1]
-#endif /* !CONFIG_CPU_MONAHANS */
-
-	/* set clock speed */
-#ifdef CONFIG_CPU_MONAHANS
-	ldr	r0, =ACCR
-	ldr	r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
-	str	r1, [r0]
-#else /* !CONFIG_CPU_MONAHANS */
-#ifdef CONFIG_SYS_CPUSPEED
-	ldr	r0, CC_BASE
-	ldr	r1, cpuspeed
-	str	r1, [r0, #CCCR]
-	mov	r0, #2
-	mcr	p14, 0, r0, c6, c0, 0
-
-setspeed_done:
-
-#endif /* CONFIG_SYS_CPUSPEED */
-#endif /* CONFIG_CPU_MONAHANS */
-
-	/*
-	 * before relocating, we have to setup RAM timing
-	 * because memory timing is board-dependend, you will
-	 * find a lowlevel_init.S in your board directory.
-	 */
-	mov	ip,	lr
-	bl	lowlevel_init
-	mov	lr,	ip
-
-	/* Memory interfaces are working. Disable MMU and enable I-cache.   */
-	/* mk: hmm, this is not in the monahans docs, leave it now but
-	 *     check here if it doesn't work :-) */
-
-	ldr	r0, =0x2001		/* enable access to all coproc.	    */
-	mcr	p15, 0, r0, c15, c1, 0
-	CPWAIT r0
-
-	mcr	p15, 0, r0, c7, c10, 4	/* drain the write & fill buffers   */
-	CPWAIT r0
-
-	mcr	p15, 0, r0, c7, c7, 0	/* flush Icache, Dcache and BTB	    */
-	CPWAIT r0
-
-	mcr	p15, 0, r0, c8, c7, 0	/* flush instuction and data TLBs   */
-	CPWAIT r0
-
-	/* Enable the Icache						    */
-/*
-	mrc	p15, 0, r0, c1, c0, 0
-	orr	r0, r0, #0x1800
-	mcr	p15, 0, r0, c1, c0, 0
-	CPWAIT
-*/
-	mov	pc, lr
+#endif /* #if !defined(CONFIG_ONENAND_IPL) */
 
 #ifndef CONFIG_PRELOADER
 /****************************************************************************/
@@ -676,6 +566,12 @@
 /* perform a watchdog timeout for a soft reset.				    */
 /*									    */
 /****************************************************************************/
+/* Operating System Timer */
+OSTIMER_BASE:	.word	0x40a00000
+#define OSMR3	0x0C
+#define OSCR	0x10
+#define OWER	0x18
+#define OIER	0x1C
 
 	.align	5
 .globl reset_cpu
@@ -703,3 +599,25 @@
 reset_endless:
 
 	b	reset_endless
+
+#ifndef CONFIG_PRELOADER
+.section .mmudata, "a"
+	.align	14
+	.globl	mmu_table
+mmu_table:
+	/* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */
+	.set	__base, 0
+	.rept	0xa00
+	.word	(__base << 20) | 0xc12
+	.set	__base, __base + 1
+	.endr
+
+	/* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */
+	.word	(0xa00 << 20) | 0x1c1e
+
+	.set	__base, 0xa01
+	.rept	0x1000 - 0xa01
+	.word	(__base << 20) | 0xc12
+	.set	__base, __base + 1
+	.endr
+#endif