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