www.pudn.com > mizi_vivi.rar > head.S


/*
 * boot-pxa250.S
	- initialise hardware
 *
 * Copyright (C) 2001 MIZI Research, Inc.
 *
 * Author: Yong-iL Joh 
 * Date  : $Date: 2002/09/03 07:42:28 $ 
 *
 * $Revision: 1.12 $
 *
   Mon May 23 2002 Yong-iL Joh 
   - initial based on bootldr-sa11x0.S
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 */

#include "config.h"
#include "linkage.h"
#include "machine.h"
#include "cap.h"

/*; *************************/
/*; Start of executable code*/
/*; *************************/
ENTRY(_start)	
ENTRY(ResetEntryPoint)		/* 0x00 */
	b	HiReset
UndefEntryPoint:		/* 0x04 */
	b	HandleUndef
SWIEntryPoint:			/* 0x08 */
	b	HandleSWI
PrefetchAbortEntryPoint:	/* 0x0c */
	b	HandlePrefetchAbort
DataAbortEntryPoint:		/* 0x10 */
	b	HandleDataAbort
NotUsedEntryPoint:      	/* 0x14 */
	nop
IRQEntryPoint:			/* 0x18 */
	b	HandleIRQ
FIQEntryPoint:			/* 0x1c */
	b	HandleFIQ
	
@ 0x20: magic number so we can verify that we only put 
	.long   0
@ 0x24:
	.long   0
@ 0x28: where this vivi was linked, so we can put it in memory in the right place
	.long   _start
@ 0x2C: this contains the platform, cpu and machine id
	.long   ARCHITECTURE_MAGIC
@ 0x30: vivi capabilities 
	.long   0

HandleUndef:	
	/* save all user registers */
	adr     r13, AbortStorage
	stm     r13, {r0-r12}
	mov     r12, r14

#if defined(DEBUG_L1)
	ldr	r0, STR_UNDEF
	BL	PrintWord
	mov     r0, r12
	BL	PrintHex
	mrc	p15, 0, r0, c6, c0, 0	/* fault address */
	BL	PrintHex
#endif
	nop
	mov     r14, r12
	/* restore registers */
	ldm     r13, {r0-r12}
	/* now loop */
1:	b 1b
	
HandleSWI:	
	/* save all user registers */
	adr     r13, AbortStorage
	stm     r13, {r0-r12}
	mov     r12, r14

#if defined(DEBUG_L1)
	ldr	r0,STR_SWI
	BL	PrintWord
	mov     r0, r12
	BL	PrintHex
	mrc	p15, 0, r0, c6, c0, 0	/* fault address */
	BL	PrintHex
#endif	
	nop
	mov     r14, r12
	/* restore registers */
	ldm     r13, {r0-r12}
	/* now loop */
1:      b 1b
	
HandlePrefetchAbort:	
	/* save all user registers */
	adr     r13, AbortStorage
	stm     r13, {r0-r12}
	mov     r12, r14

#if defined(DEBUG_L1)
	ldr	r0, STR_PREFETCH_ABORT
	BL	PrintWord
	mov     r0, r12
	BL	PrintHex
	mrc	p15, 0, r0, c6, c0, 0	/* fault address */
	BL	PrintHex
#endif
	nop	
	mov     r14, r12
	/* restore registers */
	ldm     r13, {r0-r12}
	/* now loop */
1:      b 1b
	
AbortStorage:
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	.word 0
	
HandleDataAbort:	
	/* save all user registers */
	adr     r13, AbortStorage
	stm     r13, {r0-r12}
	mov     r12, r14

#if defined(DEBUG_L1)
	ldr	r0, STR_DATA_ABORT
	BL	PrintWord
	mov     r0, r12
	BL	PrintHex
	mrc	p15, 0, r0, c6, c0, 0	/* fault address */
	BL	PrintHex
#endif
	nop	
	mov     r14, r12
	/* restore registers */
	ldm     r13, {r0-r12}
	/* now loop */
1:      b 1b

HandleIRQ:	
	/* save all user registers */
	adr     r13, AbortStorage
	stm     r13, {r0-r12}
	mov     r12, r14

#if defined(DEBUG_L1)
	ldr	r0, STR_IRQ
	BL	PrintWord
	mov     r0, r12
	BL	PrintHex
#endif
	nop	
	mov     r14, r12
	/* restore registers */
	ldm     r13, {r0-r12}
	/* now loop */
1:      b 1b
	
HandleFIQ:	
	/* save all user registers */
	adr     r13, AbortStorage
	stm     r13, {r0-r12}
	mov     r12, r14

#if defined(DEBUG_L1)
	ldr	r0, STR_FIQ
	BL	PrintWord
	mov     r0, r12
	BL	PrintHex
#endif
	nop	
	mov     r14, r12
	/* restore registers */
	ldm     r13, {r0-r12}
	/* now loop */
1:      b 1b
	
HiReset:
#ifdef CONFIG_GPIO_LED
	bl	offLED
#endif	/* CONFIG_GPIO_LED */

#define COTULLA_CP15_B1_VAL	0x69052903
/*  Workaround for early termination of SDRAM autorefresh on exit from 
    processor's sleep state in B1 stepping of XPA250/210. (sighting 27004) 
    Need first forced refresh within 8 usec.

    - Code snippet received from validation team, slightly modified

  Notes: - MMU assumed to be inactive at this time, so use physical addresses
         -  Eboot didn't boot on A1 stepping without the leading exclusion,
            so the core code must be restricted to B1 only.
*/

	mrc	p15, 0, r9, c0, c0, 0		@ Grab CPU ID
	ldr	r3, =COTULLA_CP15_B1_VAL	@ Load the B1 CPU ID value
	cmp	r9, r3
	bne	EARLY_REFRESH_DONE

	@ Eboot loads BIN image into RAM,
	@ turns off the MMU and then jumps here.
	@ If we're already executing from RAM, don't mess with it

	mov	r0, #0x4000000		@ Just at the end of boot device addressing space
	cmp	r0, pc			@ Are we executing from boot flash space?
	bpl	EARLY_REFRESH_DONE	@ if outside that space, skip this.

	/*
	   Need to set MDREFR:DRI field to 0 for this to work.  Side effect is
	    picking the MEMCLK:SDCLK ratio.  The specified value (0x038FF000)
	    sets that ratio as 2:1.
	   This corresponds to the defaults after reset, including sleep reset.
	0x038ff000  == MDREFR_K2FREE | MDREFR_K1FREE | MDREFR_K0FREE |
			MDREFR_K2DB2 | MDREFR_K2RUN |
			MDREFR_K1DB2 | MDREFR_K1RUN | MDREFR_E1PIN |
			MDREFR_K0DB2 | MDREFR_K0RUN | MDREFR_E0PIN
	*/
	mov	r0, #PXA250_MEMC_BASE	@ Memory controller base physical addr.
	mov	r1, #0x03800000
	orr	r1, r1, #0x000FF000
	str	r1, [r0, #MDREFR_OFFSET]

	mov	r0, #DRAM_BASE
	ldr	r1, [r0]	@ CAUSES the 1st row refresh to all partitions
	mov	r2, #0x2000	@ 8k loo
1:
	ldr	r1, [r0]	@ CAUSES a row refresh to all partitions
	
	subs	r2, r2, #0x1
	bpl	1b		@ while >= 0
EARLY_REFRESH_DONE:

	bl	PreINIT

	@ r10 now has RCSR in lower half and PSSR in upper.

GPIO_Reset:
	tst	r10, #RCSR_GPR
	beq	WatchDog_Reset
	bl	InitGPIO
	bl	InitMEMC
	bl	InitINTC
	bl	InitPWR
	bl	EnableCLKS
	b	call_main

WatchDog_Reset:			@ kernel¿¡¼­ rebootÇϸé WatchDog_ResetÀ¸·Î
	tst	r10, #RCSR_WDR
	beq	Sleep_Mode
	bl	InitGPIO
	bl	InitMEMC
	bl	InitINTC
	bl	InitPWR
	bl	EnableCLKS
	bl	InitUART
	b	call_main

Sleep_Mode:
	tst	r10, #RCSR_SMR
	beq	HW_Reset
	bl	InitGPIO
	bl	InitMEMC
	b	call_main	@ ³ªÁß¿¡ ¹Ù²Ü °Í

HW_Reset:
	@ disable MMU
	mrc	p15, 0, r0, c1, c0, 0
	bic	r0, r0, #CP15_1_MMU
	mcr	p15, 0, r0, c1, c0, 0

	bl	InitGPIO
	bl	InitMEMC
	bl	InitINTC
	mov	r4, #0
	bl	InitCLK
	bl	InitOST
	bl	InitRTC
	bl	InitPWR
	bl	EnableCLKS

	/*; Initialize the UARTs */
	bl	InitUART

#ifdef CONFIG_DEBUG
	mov	r0, #'\r'
	bl	PrintChar
	mov	r0, #'\n'
	bl	PrintChar
	
	mov	r0, pc
	bl	PrintHex

	/* check to see if we're operating out of DRAM */
	bic	r4, pc, #0x000000FF
	bic	r4, r4, #0x0000FF00
	bic	r4, r4, #0x00FF0000

	cmp     r4, #DRAM_BASE
	moveq	r0, #'D'	/* RunningInDRAM */
	movne	r0, #'F'	/* RunningInFlash */
	bl	PrintChar
	
	/* otherwise, assume we're running in Flash and do a complete reset */
	mov	r0, #'\r'
	bl	PrintChar
	mov	r0,#'\n'
	bl	PrintChar
	mov	r0,#'M'
	bl	PrintChar
#endif

#if 0	/* Áö±ÝÀº ¹«½Ã. --v */
	bl	InitMem
#else
	mov	r0, #SZ_64M		
#endif
#ifdef CONFIG_DEBUG
	/* r0 contains DRAM size */
	str	r0, [r1]
	bl	PrintHex
	
	/*; debug print*/
	mov	r0, #'\r'
	bl	PrintChar
	mov	r0, #'\n'
	bl	PrintChar
	mov	r0, #'*'
	bl	PrintChar
	
	ldr     r0, STR_MTST
	bl	PrintWord
	
	/*; debug print*/
	ldr	r0, STR_ENDM
	bl	PrintWord

	/*; Get ready to call C functions*/
	ldr	r0, STR_STACK
	bl	PrintWord
	ldr	r0, DW_STACK_START
	bl	PrintHex
#endif

call_main:	
	/* setup stack */
	ldr	sp, DW_STACK_START
	mov	fp, #0		/* no previous frame, so fp=0*/
	mov	r2, #0		/* set argv to NUL*/
	
	bl	main		/* call main*/
	
	mov	pc, #FLASH_BASE	/* otherwise, reboot */

	/*
	;; ********************************************************************
	;; InitUART - Initialize Serial Communications
	;; ********************************************************************
	*/
#define MZ96K_BAUD_MSB		0x00
#define MZ96K_BAUD_LSB		0x60
#define MZ192K_BAUD_MSB		0x00
#define MZ192K_BAUD_LSB		0x30
#define MZ384K_BAUD_MSB		0x00
#define MZ384K_BAUD_LSB		0x18
#define MZ576K_BAUD_MSB		0x00
#define MZ576K_BAUD_LSB		0x10
#define MZ1152K_BAUD_MSB	0x00
#define MZ1152K_BAUD_LSB	0x08
InitUART:
	/* from eboot for winCE */
	ldr	r1, =UART_BASE

	/* disable the UART */
	mov	r2, #0x0
	str	r2, [r1, #UART_LCR]
	str	r2, [r1, #UART_IER]

	/* Setup divisor */
	mov	r2, #SIO_LCR_DLAB
	str	r2, [r1, #UART_LCR]
	mov	r0, #MZ1152K_BAUD_LSB
	str	r0, [r1, #UART_DLL]
	mov	r0, #MZ1152K_BAUD_MSB
	str	r0, [r1, #UART_DLH]
	mov	r2, #0x0
	str	r2, [r1, #UART_LCR]

	/* 8-1-N */
	mov	r2, #(SIO_LCR_WLS0 | SIO_LCR_WLS1)
	str	r2, [r1, #UART_LCR]

	/* clear FIFOs */
#if 0
	mov	r2, #(SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2)
#else
	mov	r2, #(SIO_FCR_FCR1 | SIO_FCR_FCR2)
#endif
	str	r2, [r1, #UART_FCR]

	/* clear IER */
	mov	r2, #0x0
	str	r2, [r1, #UART_IER]

	/* clear MCR */
	mov	r2, #0x0
	str	r2, [r1, #UART_MCR]

EnableUART:	
	ldr	r2, [r1, #UART_IER]
	orr	r2, r2, #SIO_IER_UUE
	str	r2, [r1, #UART_IER]

	/* empty buffer */
1:
	ldr	r2, [r1, #UART_LSR]
	tst	r2, #SIO_LSR_DR
	ldrne	r2, [r1, #UART_RBR]
	bne	1b

	/* transmit a character or two */
1:
	ldr	r2, [r1, #UART_LSR]
	tst	r2, #SIO_LSR_THRE
	beq	1b
	mov	r2, #'U'
	str	r2, [r1, #UART_THR]

1:
	ldr	r2, [r1, #UART_LSR]
	tst	r2, #SIO_LSR_THRE
	beq	1b
	mov	r2, #'1'
	str	r2, [r1, #UART_THR]

	mov	pc, lr		/* All done, return*/

#define W_ACCESS_TO_CP	0x2001
PreINIT:
	/* Set processor into Supervisior mode (SVC) and disable IRQ & FIQ */
	mov	r0, #(SVC_MODE|F_BIT|I_BIT)
	msr	cpsr_c, r0		@ reset CPSR

	ldr	r0, =W_ACCESS_TO_CP
	mcr	p15, 0, r0, c15, c1, 0	@ grant access to cp except cp0, cp13
	mrc	p15, 0, r0, c2, c0, 0	@ read translation table base
	nop
	sub	pc, pc, #4

	mov	r0, #0x78
	mcr	p15, 0, r0, c1, c0, 0	@ ctrl register
	mrc	p15, 0, r0, c2, c0, 0
	nop
	sub	pc, pc, #4

	mov	r0, #0
	mcr	p15, 0, r0, c8, c7, 0	@ invalidate I & D TLBs
	mcr	p15, 0, r0, c7, c7, 0	@ invalidate I,D caches & BTB
	mcr	p15, 0, r0, c7, c10, 4	@ Drain Write (& Fill) Buffer
	nop
	nop
	nop

	mov	r0, #0xffffffff		@ grant permission for all 16 domains
	mcr	p15, 0, r0, c3, c0, 0  

	/*
	  Init Reset Cause bits in RCSR.  
	*/
	ldr	r0,  =RCSR
	ldr	r10, [r0]
	mov	r2,  #RCSR_ALL		@ Mask RCSR (read lower byte only)
	and	r10, r10, r2
	/* clear the reset cause bits (they're sticky) */
	str	r2,  [r0]

	ldr	r0, =PSSR
	ldr	r12, [r0]
	mov	r2, #PSSR_MASK
	and	r12, r12, r2
	mov	r12, r12, lsl #16
	orr	r10, r10, r12
	mov	pc, lr

InitGPIO:
	/* must set the GPIOs up before any chip selects will work */
	ldr	r0, =PXA250_GPIO_BASE
	ldr	r1, =GPSR0_VAL
	str	r1, [r0, #GPSR0_OFFSET]
	ldr	r1, =GPSR1_VAL
	str	r1, [r0, #GPSR1_OFFSET]
	ldr	r1, =GPSR2_VAL
	str	r1, [r0, #GPSR2_OFFSET]

	ldr	r1, =GPCR0_VAL
	str	r1, [r0, #GPCR0_OFFSET]
	ldr	r1, =GPCR1_VAL
	str	r1, [r0, #GPCR1_OFFSET]
	ldr	r1, =GPCR2_VAL
	str	r1, [r0, #GPCR2_OFFSET]
	
	ldr	r1, =GPDR0_VAL
	str	r1, [r0, #GPDR0_OFFSET]
	ldr	r1, =GPDR1_VAL
	str	r1, [r0, #GPDR1_OFFSET]
	ldr	r1, =GPDR2_VAL
	str	r1, [r0, #GPDR2_OFFSET]
	
	ldr	r1, =GAFR0L_VAL
	str	r1, [r0, #GAFR0_L_OFFSET]
	ldr	r1, =GAFR0U_VAL
	str	r1, [r0, #GAFR0_U_OFFSET]
	ldr	r1, =GAFR1L_VAL
	str	r1, [r0, #GAFR1_L_OFFSET]
	ldr	r1, =GAFR1U_VAL
	str	r1, [r0, #GAFR1_U_OFFSET]
	ldr	r1, =GAFR2L_VAL
	str	r1, [r0, #GAFR2_L_OFFSET]
	ldr	r1, =GAFR2U_VAL
	str	r1, [r0, #GAFR2_U_OFFSET]

	/*
	  Next, set-to-clear the RDH bit in the PSSR
	  to allow GPIO's configged as inputs to function
	*/
	ldr	r0, =PSSR
	ldr	r1, =PSSR_VAL
	str	r1, [r0, #0]
	
	mov	pc, lr

InitMEMC:
	/*********************************************************************
	  Initlialize Memory Controller
	    The sequence below is based on the recommended init steps detailed
		 in the EAS, chapter 5.
	*/

	/* pause for 200 uSecs- allow internal clocks to settle
	   *Note: only need this if hard reset... doing it anyway for now
	*/

	@---- Wait 200 usec
	ldr	r3, =OSCR	@ reset the OS Timer Count to zero
	mov	r2, #0
	str	r2, [r3] 
	ldr	r4, =0x300	/* really 0x2E1 is about 200usec,
				   so 0x300 should be plenty */
1:	
	ldr	r2, [r3] 
	cmp	r4, r2
	bgt	1b

/*************************** START ROD CODE **********************************/
	@ get memory controller base address
	ldr	r1, =PXA250_MEMC_BASE

/****************************************************************************
    Step 1
*/

	@ write msc0, read back to ensure data latches
	@
	ldr	r2,   =MSC0_VAL
	str	r2,   [r1, #MSC0_OFFSET]
	ldr	r2,   [r1, #MSC0_OFFSET]

	ldr	r2,  =MSC1_VAL
	str	r2,  [r1, #MSC1_OFFSET]
	ldr	r2,  [r1, #MSC1_OFFSET]

	@ write msc2
	ldr	r2,  =MSC2_VAL
	str	r2,  [r1, #MSC2_OFFSET]
	ldr	r2,  [r1, #MSC2_OFFSET]

	@ write mecr
	ldr	r2,  =MECR_VAL
	str	r2,  [r1, #MECR_OFFSET]

	@ write mcmem0
	ldr	r2,  =MCMEM0_VAL
	str	r2,  [r1, #MCMEM0_OFFSET]

	@ write mcmem1
	ldr	r2,  =MCMEM1_VAL
	str	r2,  [r1, #MCMEM1_OFFSET]

	@ write mcatt0
	ldr	r2,  =MCATT0_VAL
	str	r2,  [r1, #MCATT0_OFFSET]

	@ write mcatt1
	ldr	r2,  =MCATT1_VAL
	str	r2,  [r1, #MCATT1_OFFSET]

	@ write mcio0
	ldr	r2,  =MCIO0_VAL
	str	r2,  [r1, #MCIO0_OFFSET]

	@ write mcio1
	ldr	r2,  =MCIO1_VAL
	str	r2,  [r1, #MCIO1_OFFSET]

	@-------------------------------------------------------
	@ 3rd bullet, Step 1
	@

	@ get the mdrefr settings
	ldr	r3,  =MDREFR_VAL

	@ extract DRI field (we need a valid DRI field)
	@
	ldr	r2,  =0xFFF

	@ valid DRI field in r3
	@
	and	r3,  r3,  r2

	@ get the reset state of MDREFR
	@
	ldr	r4,  [r1, #MDREFR_OFFSET]

	@ clear the DRI field
	@
	bic	r4,  r4,  r2

	@ insert the valid DRI field loaded above
	@
	orr	r4,  r4,  r3

	@ write back mdrefr
	@
	str	r4,  [r1, #MDREFR_OFFSET]

	/* Note: preserve the mdrefr value in r4 */


/****************************************************************************
    Step 3
*/

	@ Assumes previous mdrefr value in r4, if not then read current mdrefr

	@ clear the free-running clock bits
	@  (clear K0Free, K1Free, K2Free
	@
	bic	r4,  r4,  #(MDREFR_K2FREE | MDREFR_K1FREE | MDREFR_K0FREE)
	 
	@ set K1RUN if bank 0 installed
	orr	r4,  r4,  #MDREFR_K1RUN

	/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	  Lubbock: Allow the user to select the {T/R/M} with predetermined
	    SDCLK.  Based on Table 3-1 in PXA250 and PXA210 Dev Man.

	   * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1]
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
	@
	@  run SDCLK=MemClk/2
	@
	orr	r4, r4, #MDREFR_K1DB2

	@ write back mdrefr
	@
	str	r4,  [r1, #MDREFR_OFFSET]
	ldr	r4,  [r1, #MDREFR_OFFSET]

	@ deassert SLFRSH
	@
	bic	r4,  r4,  #MDREFR_SLFRSH
	
	@ write back mdrefr
	@
	str	r4,  [r1, #MDREFR_OFFSET]

	@ assert E1PIN
	@
	orr	r4,  r4,  #MDREFR_E1PIN
	
	@ write back mdrefr
	@
	str	r4,  [r1, #MDREFR_OFFSET]
	ldr	r4,  [r1, #MDREFR_OFFSET]
	nop
	nop


/****************************************************************************
    Step 4
*/

	@ fetch platform value of mdcnfg
	@
	ldr	r2,  =MDCNFG_VAL

	@ disable all sdram banks
	@
	bic	r2,  r2,  #(MDCNFG_DE0 | MDCNFG_DE1)
	bic	r2,  r2,  #(MDCNFG_DE2 | MDCNFG_DE3)

	@ program banks 0/1 for bus width
	bic	r2,  r2,  #MDCNFG_DWID0		@ 0=32-bit

	@ write initial value of mdcnfg, w/o enabling sdram banks
	@
	str	r2,  [r1, #MDCNFG_OFFSET]


/****************************************************************************
    Step 5
*/
	
	@ pause for 200 uSecs
	@
	ldr	r3, =OSCR	@ reset the OS Timer Count to zero
	mov	r2, #0
	str	r2, [r3] 
	ldr	r4, =0x300	/* really 0x2E1 is about 200usec,
				   so 0x300 should be plenty */
1:
	ldr	r2, [r3]
	cmp	r4, r2
	bgt	1b


/****************************************************************************
    Step 6
*/

	mov	r0, #0x78		@ turn everything off
	mcr	p15, 0, r0, c1, c0, 0	@ (caches off, MMU off, etc.)


/****************************************************************************
    Step 7
*/
	@  Access memory *not yet enabled* for CBR refresh cycles (8)
	@  - CBR is generated for all banks

	ldr	r2, =DRAM_BASE
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]


/****************************************************************************
    Step 8: NOP (enable dcache if you wanna... we dont)
*/

	
/****************************************************************************
    Step 9
*/


	@ get memory controller base address
	@
	ldr	r1,  =PXA250_MEMC_BASE

	@ fetch current mdcnfg value
	@
	ldr	r3,  [r1, #MDCNFG_OFFSET]

	@ enable sdram bank 0 if installed (must do for any populated bank)
	@
	orr	r3,  r3,  #MDCNFG_DE0

	@ write back mdcnfg, enabling the sdram bank(s)
	@
	str	r3,  [r1, #MDCNFG_OFFSET]


/****************************************************************************
    Step 10
*/
	
	@ write mdmrs
	@
	ldr	r2,  =MDMRS_VAL
	str	r2,  [r1, #MDMRS_OFFSET]


/****************************************************************************
    Step 11: Final Step

	do not enable APD. MEMC issuing excessive refreshes when set.
	* A1 Errata #5: Do not enable APD here, since I will be doing
	 a frequency change later. Doing so will hang the MEMC state machine.
*/
	mov	pc, lr

InitINTC:
	@ Disable (mask) all interrupts at the interrupt controller
	@ clear the interrupt level register (use IRQ, not FIQ)
	mov	r1, #0
	ldr	r2,  =ICLR
	str	r1,  [r2]
	
	@ mask all interrupts at the controller
	ldr	r2,  =ICMR
	str	r1,  [r2]

	mov	pc, lr

InitPWR:
	/********************************************************************
	  Initialize the power mgr registers.
	*/

	@ get base address of power mgr / reset control regs
	@
	ldr	r2,  =PXA250_PWR_BASE

	@
	@ set the immediate sleep mode on batt/vdd fault
	@  
/* Move to immediately after reset, because cleared by resets! */
	mov	r1, #0			@ force Imprecise Data Abort on Fault
	str	r1, [r2, #PMCR_OFFSET]

	@ initialize the pcfr
	@
	mov	r1, #PCFR_OPDE		@ enable 3.68Mhz power-down during sleep
	orr	r1, r1, #PCFR_FP	@ enable PCMCIA pin float during sleep
	orr	r1, r1, #PCFR_FS	@ enable static memory pin float during sleep
	bic	r1, r1, #PCFR_DS	@ disable deep-sleep mode
	str	r1, [r2, #PCFR_OFFSET]

	@ initialize the pwer
	@
	mov	r1, #PWER_WE0		@ enable gpio0 wakeup
	orr	r1, r1, #PWER_WE1	@ enable gpio1 wakeup
	orr	r1, r1, #PWER_WERTC	@ enable rtc alarm wakeup 
	str	r1, [r2, #PWER_OFFSET]

	mov	pc, lr

EnableCLKS:
	@ Re-Enable On-Chip Peripheral Clocking
	@  *Note:  Currently enabling: ALL 17 clocks.
	
	ldr	r1, =CKEN
	ldr	r2, =CKEN_VAL
	str	r2, [r1]

	mov	pc, lr

	/*
	;; ********************************************************************
	;; InitCLK - Frequency Change Sequence
	;; ********************************************************************
	*/
InitCLK:
	ldr	r1, =PXA250_CCLK_BASE

	@ Turn Off ALL on-chip peripheral clocks for re-configuration
	@ *Note: See label 'ENABLECLKS' for the re-enabling
	@
	mov	r2, #0x0
	str	r2, [r1, #CKEN_OFFSET]

	@ Set Core Clock
	ldr	r2, =CCCR_VAL
	str	r2, [r1, #CCCR_OFFSET]

	@ Enter Frequency Change Sequence
	mov	r1, #0x2
	mcr	p14, 0, r1, c6, c0, 0		@ write CCLKCFG

	@  after a frequency change, the memory controller must be restarted
	@
	ldr	r1, =PXA250_MEMC_BASE

	@ get the current state of MDREFR
	@
	ldr	r2, [r1, #MDREFR_OFFSET]

	@ clear E0PIN, E1PIN
	@
	bic	r3, r2, #(MDREFR_E0PIN | MDREFR_E1PIN)

	@ write MDREFR with E0PIN, E1PIN cleared (disable sdclk[0,1])
	@
	str	r3, [r1, #MDREFR_OFFSET]

	@ then write MDREFR with E0PIN, E1PIN set (enable sdclk[0,1])
	@
	str	r2, [r1, #MDREFR_OFFSET]

	@ get the current state of MDCNFG
	@
	ldr	r3, [r1, #MDCNFG_OFFSET]

	@ disable all SDRAM banks
	@
	bic	r3, r3, #(MDCNFG_DE0 | MDCNFG_DE1)
	bic	r3, r3, #(MDCNFG_DE2 | MDCNFG_DE3)

	@ write back MDCNFG   
	@
	str	r3, [r1, #MDCNFG_OFFSET]
	
	@  Access memory *not yet enabled* for CBR refresh cycles (8)
	@  - CBR is generated for all banks
	ldr	r2, =DRAM_BASE
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]
	str	r2, [r2]

	@ fetch current mdcnfg value
	@
	ldr	r3, [r1, #MDCNFG_OFFSET]

	@ enable sdram bank 0 if installed
	@
	orr	r3, r3, #MDCNFG_DE0

	@ write back mdcnfg, enabling the sdram bank(s)
	@
	str	r3, [r1, #MDCNFG_OFFSET]

	@ write mdmrs
	@
	mov	r2, #0x0
	str	r2, [r1, #MDMRS_OFFSET]

	mov	pc, lr

InitOST:
	@ Initialize the OST count register to zero.
	@
	ldr	r3, =OSCR
	mov	r2, #0
	str	r2, [r3]

	mov	pc, lr

InitRTC:
	@ Initialize the RTC count register to zero.
	@ Currently not adjusting the trim reg (RTTR).
	ldr     r1,  =RCNR
	mov     r2,  #0
	str     r2,  [r1]

	mov	pc, lr

/*
;; ********************************************************************
;; Data Area
;; ********************************************************************
*/
#ifdef CONFIG_DEBUG
	.align	2
STR_STACK:
	.ascii	"STKP"
#endif

	.align	2
DW_STACK_START:
	.word	STACK_BASE+STACK_SIZE-4

#ifdef CONFIG_DEBUG
	.align	2
STR_MTST:
        .ascii	"MTST"
	.align	2
STR_ENDM:
        .ascii	"ENDM"
#endif

#if defined(DEBUG_L1)
	.align 2
STR_UNDEF:
        .ascii	"UNDF"

	.align	2
STR_SWI:
        .ascii  "SWI "

	.align	2
STR_PREFETCH_ABORT:
        .ascii	"PABT"

	.align	2
STR_DATA_ABORT:
        .ascii	"DABT"

	.align	2
STR_IRQ:
        .ascii	"IRQ "

	.align	2
STR_FIQ:
        .ascii	"FIQ "
#endif

/*
 | $Id: head.S,v 1.12 2002/09/03 07:42:28 tolkien Exp $
 |
 | Local Variables:
 | mode: asm
 | mode: font-lock
 | version-control: t
 | delete-old-versions: t
 | End:
 |
 | -*- End-Of-File -*-
 */