/* * Most of this taken from Redboot hal_platform_setup.h with cleanup * * NOTE: I haven't clean this up considerably, just enough to get it * running. See hal_platform_setup.h for the source. See * board/cradle/lowlevel_init.S for another PXA250 setup that is * much cleaner. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include DRAM_SIZE: .long CFG_DRAM_SIZE /* wait for coprocessor write complete */ .macro CPWAIT reg mrc p15,0,\reg,c2,c0,0 mov \reg,\reg sub pc,pc,#4 .endm .macro wait time ldr r2, =OSCR mov r3, #0 str r3, [r2] 0: ldr r3, [r2] cmp r3, \time bls 0b .endm /* * Memory setup */ .globl lowlevel_init lowlevel_init: /* Set up GPIO pins first ----------------------------------------- */ mov r10, lr /* Configure GPIO Pins 41 - 48 as UART1 / altern. Fkt. 2 */ ldr r0, =0x40E10438 @ GPIO41 FFRXD ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E1043C @ GPIO42 FFTXD ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E10440 @ GPIO43 FFCTS ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E10444 @ GPIO 44 FFDCD ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E10448 @ GPIO 45 FFDSR ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E1044C @ GPIO 46 FFRI ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E10450 @ GPIO 47 FFDTR ldr r1, =0x802 str r1, [r0] ldr r0, =0x40E10454 @ GPIO 48 ldr r1, =0x802 str r1, [r0] /* tebrandt - ASCR, clear the RDH bit */ ldr r0, =ASCR ldr r1, [r0] bic r1, r1, #0x80000000 str r1, [r0] /* ---------------------------------------------------------------- */ /* Enable memory interface */ /* */ /* The sequence below is based on the recommended init steps */ /* detailed in the Intel PXA250 Operating Systems Developers Guide, */ /* Chapter 10. */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* Step 1: Wait for at least 200 microsedonds to allow internal */ /* clocks to settle. Only necessary after hard reset... */ /* FIXME: can be optimized later */ /* ---------------------------------------------------------------- */ /* mk: replaced with wait macro */ /* 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 */ wait #300 mem_init: /* configure the MEMCLKCFG register */ ldr r1, =MEMCLKCFG ldr r2, =0x00010001 str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN /* set CSADRCFG[0] to data flash SRAM mode */ ldr r1, =CSADRCFG0 ldr r2, =0x00320809 str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN /* set CSADRCFG[1] to data flash SRAM mode */ ldr r1, =CSADRCFG1 ldr r2, =0x00320809 str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN /* set MSC 0 register for SRAM memory */ ldr r1, =MSC0 ldr r2, =0x11191119 str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN /* set CSADRCFG[2] to data flash SRAM mode */ ldr r1, =CSADRCFG2 ldr r2, =0x00320809 str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN /* set CSADRCFG[3] to VLIO mode */ ldr r1, =CSADRCFG3 ldr r2, =0x0032080B str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN /* set MSC 1 register for VLIO memory */ ldr r1, =MSC1 ldr r2, =0x123C1119 str r2, [r1] @ WRITE ldr r2, [r1] @ DELAY UNTIL WRITTEN #if 0 /* This does not work in Zylonite. -SC */ ldr r0, =0x15fffff0 ldr r1, =0xb10b str r1, [r0] str r1, [r0, #4] #endif /* Configure ACCR Register */ ldr r0, =ACCR @ ACCR ldr r1, =0x0180b108 str r1, [r0] ldr r1, [r0] /* Configure MDCNFG Register */ ldr r0, =MDCNFG @ MDCNFG ldr r1, =0x403 str r1, [r0] ldr r1, [r0] /* Perform Resistive Compensation by configuring RCOMP register */ ldr r1, =RCOMP @ RCOMP ldr r2, =0x000000ff str r2, [r1] ldr r2, [r1] /* Configure MDMRS Register for SDCS0 */ ldr r1, =MDMRS @ MDMRS ldr r2, =0x60000023 ldr r3, [r1] orr r2, r2, r3 str r2, [r1] ldr r2, [r1] /* Configure MDMRS Register for SDCS1 */ ldr r1, =MDMRS @ MDMRS ldr r2, =0xa0000023 ldr r3, [r1] orr r2, r2, r3 str r2, [r1] ldr r2, [r1] /* Configure MDREFR */ ldr r1, =MDREFR @ MDREFR ldr r2, =0x00000006 str r2, [r1] ldr r2, [r1] /* Configure EMPI */ ldr r1, =EMPI @ EMPI ldr r2, =0x80000000 str r2, [r1] ldr r2, [r1] /* Hardware DDR Read-Strobe Delay Calibration */ ldr r0, =DDR_HCAL @ DDR_HCAL ldr r1, =0x803ffc07 @ the offset is correct? -SC str r1, [r0] wait #5 ldr r1, [r0] /* Here we assume the hardware calibration alwasy be successful. -SC */ /* Set DMCEN bit in MDCNFG Register */ ldr r0, =MDCNFG @ MDCNFG ldr r1, [r0] orr r1, r1, #0x40000000 @ enable SDRAM for Normal Access str r1, [r0] #ifndef CFG_SKIP_DRAM_SCRUB /* scrub/init SDRAM if enabled/present */ /* ldr r11, =0xa0000000 /\* base address of SDRAM (CFG_DRAM_BASE) *\/ */ /* ldr r12, =0x04000000 /\* size of memory to scrub (CFG_DRAM_SIZE) *\/ */ /* mov r8,r12 /\* save DRAM size (mk: why???) *\/ */ ldr r8, =0xa0000000 /* base address of SDRAM (CFG_DRAM_BASE) */ ldr r9, =0x04000000 /* size of memory to scrub (CFG_DRAM_SIZE) */ mov r0, #0 /* scrub with 0x0000:0000 */ mov r1, #0 mov r2, #0 mov r3, #0 mov r4, #0 mov r5, #0 mov r6, #0 mov r7, #0 10: /* fastScrubLoop */ subs r9, r9, #32 /* 32 bytes/line */ stmia r8!, {r0-r7} beq 15f b 10b #endif /* CFG_SKIP_DRAM_SCRUB */ 15: /* Mask all interrupts */ mov r1, #0 mcr p6, 0, r1, c1, c0, 0 @ ICMR /* Disable software and data breakpoints */ mov r0, #0 mcr p15,0,r0,c14,c8,0 /* ibcr0 */ mcr p15,0,r0,c14,c9,0 /* ibcr1 */ mcr p15,0,r0,c14,c4,0 /* dbcon */ /* Enable all debug functionality */ mov r0,#0x80000000 mcr p14,0,r0,c10,c0,0 /* dcsr */ /* We are finished with Intel's memory controller initialisation */ /* ---------------------------------------------------------------- */ /* End lowlevel_init */ /* ---------------------------------------------------------------- */ endlowlevel_init: mov pc, lr /* @******************************************************************************** @ DDR calibration @ @ This function is used to calibrate DQS delay lines. @ Monahans supports three ways to do it. One is software @ calibration. Two is hardware calibration. Three is hybrid @ calibration. @ @ TBD @ -SC ddr_calibration: @ Case 1: Write the correct delay value once @ Configure DDR_SCAL Register ldr r0, =DDR_SCAL @ DDR_SCAL q ldr r1, =0xaf2f2f2f str r1, [r0] ldr r1, [r0] */ /* @ Case 2: Software Calibration @ Write test pattern to memory ldr r5, =0x0faf0faf @ Data Pattern ldr r4, =0xa0000000 @ DDR ram str r5, [r4] mov r1, =0x0 @ delay count mov r6, =0x0 mov r7, =0x0 ddr_loop1: add r1, r1, =0x1 cmp r1, =0xf ble end_loop mov r3, r1 mov r0, r1, lsl #30 orr r3, r3, r0 mov r0, r1, lsl #22 orr r3, r3, r0 mov r0, r1, lsl #14 orr r3, r3, r0 orr r3, r3, =0x80000000 ldr r2, =DDR_SCAL str r3, [r2] ldr r2, [r4] cmp r2, r5 bne ddr_loop1 mov r6, r1 ddr_loop2: add r1, r1, =0x1 cmp r1, =0xf ble end_loop mov r3, r1 mov r0, r1, lsl #30 orr r3, r3, r0 mov r0, r1, lsl #22 orr r3, r3, r0 mov r0, r1, lsl #14 orr r3, r3, r0 orr r3, r3, =0x80000000 ldr r2, =DDR_SCAL str r3, [r2] ldr r2, [r4] cmp r2, r5 be ddr_loop2 mov r7, r2 add r3, r6, r7 lsr r3, r3, =0x1 mov r0, r1, lsl #30 orr r3, r3, r0 mov r0, r1, lsl #22 orr r3, r3, r0 mov r0, r1, lsl #14 orr r3, r3, r0 orr r3, r3, =0x80000000 ldr r2, =DDR_SCAL end_loop: @ Case 3: Hardware Calibratoin ldr r0, =DDR_HCAL @ DDR_HCAL ldr r1, =0x803ffc07 @ the offset is correct? -SC str r1, [r0] wait #5 ldr r1, [r0] mov pc, lr */