1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * Low-level initialization for EP93xx 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> 5*4882a593Smuzhiyun * Copyright (C) 2013 6*4882a593Smuzhiyun * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru> 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de> 9*4882a593Smuzhiyun * Copyright (C) 2006 Cirrus Logic Inc. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * See file CREDITS for list of people who contributed to this 12*4882a593Smuzhiyun * project. 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun#include <config.h> 18*4882a593Smuzhiyun#include <asm/arch-ep93xx/ep93xx.h> 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun/* 21*4882a593Smuzhiyun/* Configure the SDRAM based on the supplied settings. 22*4882a593Smuzhiyun * 23*4882a593Smuzhiyun * Input: r0 - SDRAM DEVCFG register 24*4882a593Smuzhiyun * r2 - configuration for SDRAM chips 25*4882a593Smuzhiyun * Output: none 26*4882a593Smuzhiyun * Modifies: r3, r4 27*4882a593Smuzhiyun */ 28*4882a593Smuzhiyunep93xx_sdram_config: 29*4882a593Smuzhiyun /* Program the SDRAM device configuration register. */ 30*4882a593Smuzhiyun ldr r3, =SDRAM_BASE 31*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS0 32*4882a593Smuzhiyun str r0, [r3, #SDRAM_OFF_DEVCFG0] 33*4882a593Smuzhiyun#endif 34*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS1 35*4882a593Smuzhiyun str r0, [r3, #SDRAM_OFF_DEVCFG1] 36*4882a593Smuzhiyun#endif 37*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS2 38*4882a593Smuzhiyun str r0, [r3, #SDRAM_OFF_DEVCFG2] 39*4882a593Smuzhiyun#endif 40*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS3 41*4882a593Smuzhiyun str r0, [r3, #SDRAM_OFF_DEVCFG3] 42*4882a593Smuzhiyun#endif 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun /* Set the Initialize and MRS bits (issue continuous NOP commands 45*4882a593Smuzhiyun * (INIT & MRS set)) 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \ 48*4882a593Smuzhiyun EP93XX_SDRAMCTRL_GLOBALCFG_MRS | \ 49*4882a593Smuzhiyun EP93XX_SDRAMCTRL_GLOBALCFG_CKE) 50*4882a593Smuzhiyun str r4, [r3, #SDRAM_OFF_GLCONFIG] 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* Delay for 200us. */ 53*4882a593Smuzhiyun mov r4, #0x3000 54*4882a593Smuzhiyundelay1: 55*4882a593Smuzhiyun subs r4, r4, #1 56*4882a593Smuzhiyun bne delay1 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* Clear the MRS bit to issue a precharge all. */ 59*4882a593Smuzhiyun ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \ 60*4882a593Smuzhiyun EP93XX_SDRAMCTRL_GLOBALCFG_CKE) 61*4882a593Smuzhiyun str r4, [r3, #SDRAM_OFF_GLCONFIG] 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /* Temporarily set the refresh timer to 0x10. Make it really low so 64*4882a593Smuzhiyun * that refresh cycles are generated. 65*4882a593Smuzhiyun */ 66*4882a593Smuzhiyun ldr r4, =0x10 67*4882a593Smuzhiyun str r4, [r3, #SDRAM_OFF_REFRSHTIMR] 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun /* Delay for at least 80 SDRAM clock cycles. */ 70*4882a593Smuzhiyun mov r4, #80 71*4882a593Smuzhiyundelay2: 72*4882a593Smuzhiyun subs r4, r4, #1 73*4882a593Smuzhiyun bne delay2 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun /* Set the refresh timer to the fastest required for any device 76*4882a593Smuzhiyun * that might be used. Set 9.6 ms refresh time. 77*4882a593Smuzhiyun */ 78*4882a593Smuzhiyun ldr r4, =0x01e0 79*4882a593Smuzhiyun str r4, [r3, #SDRAM_OFF_REFRSHTIMR] 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /* Select mode register update mode. */ 82*4882a593Smuzhiyun ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_CKE | \ 83*4882a593Smuzhiyun EP93XX_SDRAMCTRL_GLOBALCFG_MRS) 84*4882a593Smuzhiyun str r4, [r3, #SDRAM_OFF_GLCONFIG] 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun /* Program the mode register on the SDRAM by performing fake read */ 87*4882a593Smuzhiyun ldr r4, [r2] 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /* Select normal operating mode. */ 90*4882a593Smuzhiyun ldr r4, =EP93XX_SDRAMCTRL_GLOBALCFG_CKE 91*4882a593Smuzhiyun str r4, [r3, #SDRAM_OFF_GLCONFIG] 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun /* Return to the caller. */ 94*4882a593Smuzhiyun mov pc, lr 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun/* 97*4882a593Smuzhiyun * Test to see if the SDRAM has been configured in a usable mode. 98*4882a593Smuzhiyun * 99*4882a593Smuzhiyun * Input: r0 - Test address of SDRAM 100*4882a593Smuzhiyun * Output: r0 - 0 -- Test OK, -1 -- Failed 101*4882a593Smuzhiyun * Modifies: r0-r5 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyunep93xx_sdram_test: 104*4882a593Smuzhiyun /* Load the test patterns to be written to SDRAM. */ 105*4882a593Smuzhiyun ldr r1, =0xf00dface 106*4882a593Smuzhiyun ldr r2, =0xdeadbeef 107*4882a593Smuzhiyun ldr r3, =0x08675309 108*4882a593Smuzhiyun ldr r4, =0xdeafc0ed 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun /* Store the test patterns to SDRAM. */ 111*4882a593Smuzhiyun stmia r0, {r1-r4} 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /* Load the test patterns from SDRAM one at a time and compare them 114*4882a593Smuzhiyun * to the actual pattern. 115*4882a593Smuzhiyun */ 116*4882a593Smuzhiyun ldr r5, [r0] 117*4882a593Smuzhiyun cmp r5, r1 118*4882a593Smuzhiyun ldreq r5, [r0, #0x0004] 119*4882a593Smuzhiyun cmpeq r5, r2 120*4882a593Smuzhiyun ldreq r5, [r0, #0x0008] 121*4882a593Smuzhiyun cmpeq r5, r3 122*4882a593Smuzhiyun ldreq r5, [r0, #0x000c] 123*4882a593Smuzhiyun cmpeq r5, r4 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun /* Return -1 if a mismatch was encountered, 0 otherwise. */ 126*4882a593Smuzhiyun mvnne r0, #0xffffffff 127*4882a593Smuzhiyun moveq r0, #0x00000000 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun /* Return to the caller. */ 130*4882a593Smuzhiyun mov pc, lr 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun/* 133*4882a593Smuzhiyun * Determine the size of the SDRAM. Use data=address for the scan. 134*4882a593Smuzhiyun * 135*4882a593Smuzhiyun * Input: r0 - Start SDRAM address 136*4882a593Smuzhiyun * Return: r0 - Single block size 137*4882a593Smuzhiyun * r1 - Valid block mask 138*4882a593Smuzhiyun * r2 - Total block count 139*4882a593Smuzhiyun * Modifies: r0-r5 140*4882a593Smuzhiyun */ 141*4882a593Smuzhiyunep93xx_sdram_size: 142*4882a593Smuzhiyun /* Store zero at offset zero. */ 143*4882a593Smuzhiyun str r0, [r0] 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun /* Start checking for an alias at 1MB into SDRAM. */ 146*4882a593Smuzhiyun ldr r1, =0x00100000 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* Store the offset at the current offset. */ 149*4882a593Smuzhiyuncheck_block_size: 150*4882a593Smuzhiyun str r1, [r0, r1] 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun /* Read back from zero. */ 153*4882a593Smuzhiyun ldr r2, [r0] 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun /* Stop searching of an alias was found. */ 156*4882a593Smuzhiyun cmp r1, r2 157*4882a593Smuzhiyun beq found_block_size 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun /* Advance to the next power of two boundary. */ 160*4882a593Smuzhiyun mov r1, r1, lsl #1 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun /* Loop back if the size has not reached 256MB. */ 163*4882a593Smuzhiyun cmp r1, #0x10000000 164*4882a593Smuzhiyun bne check_block_size 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun /* A full 256MB of memory was found, so return it now. */ 167*4882a593Smuzhiyun ldr r0, =0x10000000 168*4882a593Smuzhiyun ldr r1, =0x00000000 169*4882a593Smuzhiyun ldr r2, =0x00000001 170*4882a593Smuzhiyun mov pc, lr 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun /* An alias was found. See if the first block is 128MB in size. */ 173*4882a593Smuzhiyunfound_block_size: 174*4882a593Smuzhiyun cmp r1, #0x08000000 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun /* The first block is 128MB, so there is no further memory. Return it 177*4882a593Smuzhiyun * now. 178*4882a593Smuzhiyun */ 179*4882a593Smuzhiyun ldreq r0, =0x08000000 180*4882a593Smuzhiyun ldreq r1, =0x00000000 181*4882a593Smuzhiyun ldreq r2, =0x00000001 182*4882a593Smuzhiyun moveq pc, lr 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun /* Save the block size, set the block address bits to zero, and 185*4882a593Smuzhiyun * initialize the block count to one. 186*4882a593Smuzhiyun */ 187*4882a593Smuzhiyun mov r3, r1 188*4882a593Smuzhiyun ldr r4, =0x00000000 189*4882a593Smuzhiyun ldr r5, =0x00000001 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun /* Look for additional blocks of memory by searching for non-aliases. */ 192*4882a593Smuzhiyunfind_blocks: 193*4882a593Smuzhiyun /* Store zero back to address zero. It may be overwritten. */ 194*4882a593Smuzhiyun str r0, [r0] 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun /* Advance to the next power of two boundary. */ 197*4882a593Smuzhiyun mov r1, r1, lsl #1 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun /* Store the offset at the current offset. */ 200*4882a593Smuzhiyun str r1, [r0, r1] 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun /* Read back from zero. */ 203*4882a593Smuzhiyun ldr r2, [r0] 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /* See if a non-alias was found. */ 206*4882a593Smuzhiyun cmp r1, r2 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun /* If a non-alias was found, then or in the block address bit and 209*4882a593Smuzhiyun * multiply the block count by two (since there are two unique 210*4882a593Smuzhiyun * blocks, one with this bit zero and one with it one). 211*4882a593Smuzhiyun */ 212*4882a593Smuzhiyun orrne r4, r4, r1 213*4882a593Smuzhiyun movne r5, r5, lsl #1 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun /* Continue searching if there are more address bits to check. */ 216*4882a593Smuzhiyun cmp r1, #0x08000000 217*4882a593Smuzhiyun bne find_blocks 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun /* Return the block size, address mask, and count. */ 220*4882a593Smuzhiyun mov r0, r3 221*4882a593Smuzhiyun mov r1, r4 222*4882a593Smuzhiyun mov r2, r5 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun /* Return to the caller. */ 225*4882a593Smuzhiyun mov pc, lr 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun.globl lowlevel_init 229*4882a593Smuzhiyunlowlevel_init: 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun mov r6, lr 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun /* Make sure caches are off and invalidated. */ 234*4882a593Smuzhiyun ldr r0, =0x00000000 235*4882a593Smuzhiyun mcr p15, 0, r0, c1, c0, 0 236*4882a593Smuzhiyun nop 237*4882a593Smuzhiyun nop 238*4882a593Smuzhiyun nop 239*4882a593Smuzhiyun nop 240*4882a593Smuzhiyun nop 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun /* Turn off the green LED and turn on the red LED. If the red LED 243*4882a593Smuzhiyun * is left on for too long, the external reset circuit described 244*4882a593Smuzhiyun * by application note AN258 will cause the system to reset. 245*4882a593Smuzhiyun */ 246*4882a593Smuzhiyun ldr r1, =EP93XX_LED_DATA 247*4882a593Smuzhiyun ldr r0, [r1] 248*4882a593Smuzhiyun bic r0, r0, #EP93XX_LED_GREEN_ON 249*4882a593Smuzhiyun orr r0, r0, #EP93XX_LED_RED_ON 250*4882a593Smuzhiyun str r0, [r1] 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun /* Undo the silly static memory controller programming performed 253*4882a593Smuzhiyun * by the boot rom. 254*4882a593Smuzhiyun */ 255*4882a593Smuzhiyun ldr r0, =SMC_BASE 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun /* Set WST1 and WST2 to 31 HCLK cycles (slowest access) */ 258*4882a593Smuzhiyun ldr r1, =0x0000fbe0 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun /* Reset EP93XX_OFF_SMCBCR0 */ 261*4882a593Smuzhiyun ldr r2, [r0] 262*4882a593Smuzhiyun orr r2, r2, r1 263*4882a593Smuzhiyun str r2, [r0] 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun ldr r2, [r0, #EP93XX_OFF_SMCBCR1] 266*4882a593Smuzhiyun orr r2, r2, r1 267*4882a593Smuzhiyun str r2, [r0, #EP93XX_OFF_SMCBCR1] 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun ldr r2, [r0, #EP93XX_OFF_SMCBCR2] 270*4882a593Smuzhiyun orr r2, r2, r1 271*4882a593Smuzhiyun str r2, [r0, #EP93XX_OFF_SMCBCR2] 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun ldr r2, [r0, #EP93XX_OFF_SMCBCR3] 274*4882a593Smuzhiyun orr r2, r2, r1 275*4882a593Smuzhiyun str r2, [r0, #EP93XX_OFF_SMCBCR3] 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun ldr r2, [r0, #EP93XX_OFF_SMCBCR6] 278*4882a593Smuzhiyun orr r2, r2, r1 279*4882a593Smuzhiyun str r2, [r0, #EP93XX_OFF_SMCBCR6] 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun ldr r2, [r0, #EP93XX_OFF_SMCBCR7] 282*4882a593Smuzhiyun orr r2, r2, r1 283*4882a593Smuzhiyun str r2, [r0, #EP93XX_OFF_SMCBCR7] 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun /* Set the PLL1 and processor clock. */ 286*4882a593Smuzhiyun ldr r0, =SYSCON_BASE 287*4882a593Smuzhiyun#ifdef CONFIG_EDB9301 288*4882a593Smuzhiyun /* 332MHz, giving a 166MHz processor clock. */ 289*4882a593Smuzhiyun ldr r1, = 0x02b49907 290*4882a593Smuzhiyun#else 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_INDUSTRIAL 293*4882a593Smuzhiyun /* 384MHz, giving a 196MHz processor clock. */ 294*4882a593Smuzhiyun ldr r1, =0x02a4bb38 295*4882a593Smuzhiyun#else 296*4882a593Smuzhiyun /* 400MHz, giving a 200MHz processor clock. */ 297*4882a593Smuzhiyun ldr r1, =0x02a4e39e 298*4882a593Smuzhiyun#endif 299*4882a593Smuzhiyun#endif 300*4882a593Smuzhiyun str r1, [r0, #SYSCON_OFF_CLKSET1] 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun nop 303*4882a593Smuzhiyun nop 304*4882a593Smuzhiyun nop 305*4882a593Smuzhiyun nop 306*4882a593Smuzhiyun nop 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun /* Need to make sure that SDRAM is configured correctly before 309*4882a593Smuzhiyun * coping the code into it. 310*4882a593Smuzhiyun */ 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS0 313*4882a593Smuzhiyun mov r11, #SDRAM_DEVCFG0_BASE 314*4882a593Smuzhiyun#endif 315*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS1 316*4882a593Smuzhiyun mov r11, #SDRAM_DEVCFG1_BASE 317*4882a593Smuzhiyun#endif 318*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS2 319*4882a593Smuzhiyun mov r11, #SDRAM_DEVCFG2_BASE 320*4882a593Smuzhiyun#endif 321*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS3 322*4882a593Smuzhiyun ldr r0, =SYSCON_BASE 323*4882a593Smuzhiyun ldr r0, [r0, #SYSCON_OFF_SYSCFG] 324*4882a593Smuzhiyun ands r0, r0, #SYSCON_SYSCFG_LASDO 325*4882a593Smuzhiyun moveq r11, #SDRAM_DEVCFG3_ASD0_BASE 326*4882a593Smuzhiyun movne r11, #SDRAM_DEVCFG3_ASD1_BASE 327*4882a593Smuzhiyun#endif 328*4882a593Smuzhiyun /* See Table 13-5 in EP93xx datasheet for more info about DRAM 329*4882a593Smuzhiyun * register mapping */ 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun /* Try a 32-bit wide configuration of SDRAM. */ 332*4882a593Smuzhiyun ldr r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \ 333*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \ 334*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \ 335*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2) 336*4882a593Smuzhiyun 337*4882a593Smuzhiyun /* Set burst count: 4 and CAS: 2 338*4882a593Smuzhiyun * Burst mode [A11:A10]; CAS [A16:A14] 339*4882a593Smuzhiyun */ 340*4882a593Smuzhiyun orr r2, r11, #0x00008800 341*4882a593Smuzhiyun bl ep93xx_sdram_config 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun /* Test the SDRAM. */ 344*4882a593Smuzhiyun mov r0, r11 345*4882a593Smuzhiyun bl ep93xx_sdram_test 346*4882a593Smuzhiyun cmp r0, #0x00000000 347*4882a593Smuzhiyun beq ep93xx_sdram_done 348*4882a593Smuzhiyun 349*4882a593Smuzhiyun /* Try a 16-bit wide configuration of SDRAM. */ 350*4882a593Smuzhiyun ldr r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \ 351*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \ 352*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \ 353*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2 | \ 354*4882a593Smuzhiyun EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH) 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun /* Set burst count: 8, CAS: 2, sequential burst 357*4882a593Smuzhiyun * Accoring to Table 13-3 for 16bit operations mapping must be shifted. 358*4882a593Smuzhiyun * Burst mode [A10:A9]; CAS [A15:A13] 359*4882a593Smuzhiyun */ 360*4882a593Smuzhiyun orr r2, r11, #0x00004600 361*4882a593Smuzhiyun bl ep93xx_sdram_config 362*4882a593Smuzhiyun 363*4882a593Smuzhiyun /* Test the SDRAM. */ 364*4882a593Smuzhiyun mov r0, r11 365*4882a593Smuzhiyun bl ep93xx_sdram_test 366*4882a593Smuzhiyun cmp r0, #0x00000000 367*4882a593Smuzhiyun beq ep93xx_sdram_done 368*4882a593Smuzhiyun 369*4882a593Smuzhiyun /* Turn off the red LED. */ 370*4882a593Smuzhiyun ldr r0, =EP93XX_LED_DATA 371*4882a593Smuzhiyun ldr r1, [r0] 372*4882a593Smuzhiyun bic r1, r1, #EP93XX_LED_RED_ON 373*4882a593Smuzhiyun str r1, [r0] 374*4882a593Smuzhiyun 375*4882a593Smuzhiyun /* There is no SDRAM so flash the green LED. */ 376*4882a593Smuzhiyunflash_green: 377*4882a593Smuzhiyun orr r1, r1, #EP93XX_LED_GREEN_ON 378*4882a593Smuzhiyun str r1, [r0] 379*4882a593Smuzhiyun ldr r2, =0x00010000 380*4882a593Smuzhiyunflash_green_delay_1: 381*4882a593Smuzhiyun subs r2, r2, #1 382*4882a593Smuzhiyun bne flash_green_delay_1 383*4882a593Smuzhiyun bic r1, r1, #EP93XX_LED_GREEN_ON 384*4882a593Smuzhiyun str r1, [r0] 385*4882a593Smuzhiyun ldr r2, =0x00010000 386*4882a593Smuzhiyunflash_green_delay_2: 387*4882a593Smuzhiyun subs r2, r2, #1 388*4882a593Smuzhiyun bne flash_green_delay_2 389*4882a593Smuzhiyun orr r1, r1, #EP93XX_LED_GREEN_ON 390*4882a593Smuzhiyun str r1, [r0] 391*4882a593Smuzhiyun ldr r2, =0x00010000 392*4882a593Smuzhiyunflash_green_delay_3: 393*4882a593Smuzhiyun subs r2, r2, #1 394*4882a593Smuzhiyun bne flash_green_delay_3 395*4882a593Smuzhiyun bic r1, r1, #EP93XX_LED_GREEN_ON 396*4882a593Smuzhiyun str r1, [r0] 397*4882a593Smuzhiyun ldr r2, =0x00050000 398*4882a593Smuzhiyunflash_green_delay_4: 399*4882a593Smuzhiyun subs r2, r2, #1 400*4882a593Smuzhiyun bne flash_green_delay_4 401*4882a593Smuzhiyun b flash_green 402*4882a593Smuzhiyun 403*4882a593Smuzhiyun 404*4882a593Smuzhiyunep93xx_sdram_done: 405*4882a593Smuzhiyun ldr r1, =EP93XX_LED_DATA 406*4882a593Smuzhiyun ldr r0, [r1] 407*4882a593Smuzhiyun bic r0, r0, #EP93XX_LED_RED_ON 408*4882a593Smuzhiyun str r0, [r1] 409*4882a593Smuzhiyun 410*4882a593Smuzhiyun /* Determine the size of the SDRAM. */ 411*4882a593Smuzhiyun mov r0, r11 412*4882a593Smuzhiyun bl ep93xx_sdram_size 413*4882a593Smuzhiyun 414*4882a593Smuzhiyun /* Save the SDRAM characteristics. */ 415*4882a593Smuzhiyun mov r8, r0 416*4882a593Smuzhiyun mov r9, r1 417*4882a593Smuzhiyun mov r10, r2 418*4882a593Smuzhiyun 419*4882a593Smuzhiyun /* Compute total memory size into r1 */ 420*4882a593Smuzhiyun mul r1, r8, r10 421*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS0 422*4882a593Smuzhiyun ldr r2, [r0, #SDRAM_OFF_DEVCFG0] 423*4882a593Smuzhiyun#endif 424*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS1 425*4882a593Smuzhiyun ldr r2, [r0, #SDRAM_OFF_DEVCFG1] 426*4882a593Smuzhiyun#endif 427*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS2 428*4882a593Smuzhiyun ldr r2, [r0, #SDRAM_OFF_DEVCFG2] 429*4882a593Smuzhiyun#endif 430*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS3 431*4882a593Smuzhiyun ldr r2, [r0, #SDRAM_OFF_DEVCFG3] 432*4882a593Smuzhiyun#endif 433*4882a593Smuzhiyun 434*4882a593Smuzhiyun /* Consider small DRAM size as: 435*4882a593Smuzhiyun * < 32Mb for 32bit bus 436*4882a593Smuzhiyun * < 64Mb for 16bit bus 437*4882a593Smuzhiyun */ 438*4882a593Smuzhiyun tst r2, #EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH 439*4882a593Smuzhiyun moveq r1, r1, lsr #1 440*4882a593Smuzhiyun cmp r1, #0x02000000 441*4882a593Smuzhiyun 442*4882a593Smuzhiyun#if defined(CONFIG_EDB9301) 443*4882a593Smuzhiyun /* Set refresh counter to 20ms for small DRAM size, otherwise 9.6ms */ 444*4882a593Smuzhiyun movlt r1, #0x03f0 445*4882a593Smuzhiyun movge r1, #0x01e0 446*4882a593Smuzhiyun#else 447*4882a593Smuzhiyun /* Set refresh counter to 30.7ms for small DRAM size, otherwise 15ms */ 448*4882a593Smuzhiyun movlt r1, #0x0600 449*4882a593Smuzhiyun movge r1, #0x2f0 450*4882a593Smuzhiyun#endif 451*4882a593Smuzhiyun str r1, [r0, #SDRAM_OFF_REFRSHTIMR] 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun /* Save the memory configuration information. */ 454*4882a593Smuzhiyun orr r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE 455*4882a593Smuzhiyun stmia r0, {r8-r11} 456*4882a593Smuzhiyun 457*4882a593Smuzhiyun mov lr, r6 458*4882a593Smuzhiyun mov pc, lr 459