linux/arch/cris/arch-v32/lib/nand_init.S
<<
>>
Prefs
   1##=============================================================================
   2##
   3##      nand_init.S
   4##
   5##      The bootrom copies data from the NAND flash to the internal RAM but
   6##      due to a bug/feature we can only trust the 256 first bytes. So this
   7##      code copies more data from NAND flash to internal RAM. Obvioulsy this
   8##      code must fit in the first 256 bytes so alter with care.
   9##
  10##      Some notes about the bug/feature for future reference:
  11##        The bootrom copies the first 127 KB from NAND flash to internal
  12##        memory. The problem is that it does a bytewise copy. NAND flashes
  13##        does autoincrement on the address so for a 16-bite device each
  14##        read/write increases the address by two. So the copy loop in the
  15##        bootrom will discard every second byte. This is solved by inserting
  16##        zeroes in every second byte in the first erase block.
  17##
  18##        The bootrom also incorrectly assumes that it can read the flash
  19##        linear with only one read command but the flash will actually
  20##        switch between normal area and spare area if you do that so we
  21##        can't trust more than the first 256 bytes.
  22##
  23##=============================================================================
  24
  25#include <arch/hwregs/asm/reg_map_asm.h>
  26#include <arch/hwregs/asm/gio_defs_asm.h>
  27#include <arch/hwregs/asm/pinmux_defs_asm.h>
  28#include <arch/hwregs/asm/bif_core_defs_asm.h>
  29#include <arch/hwregs/asm/config_defs_asm.h>
  30
  31;; There are 8-bit NAND flashes and 16-bit NAND flashes.
  32;; We need to treat them slightly different.
  33#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  34#define PAGE_SIZE 256
  35#else
  36#error 2
  37#define PAGE_SIZE 512
  38#endif
  39#define ERASE_BLOCK 16384
  40
  41;; GPIO pins connected to NAND flash
  42#define CE 4
  43#define CLE 5
  44#define ALE 6
  45#define BY 7
  46
  47;; Address space for NAND flash
  48#define NAND_RD_ADDR 0x90000000
  49#define NAND_WR_ADDR 0x94000000
  50
  51#define READ_CMD 0x00
  52
  53;; Readability macros
  54#define CSP_MASK \
  55        REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
  56        REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
  57#define CSP_VAL \
  58        REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
  59        REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
  60
  61;;----------------------------------------------------------------------------
  62;; Macros to set/clear GPIO bits
  63
  64.macro SET x
  65        or.b   (1<<\x),$r9
  66        move.d $r9, [$r2]
  67.endm
  68
  69.macro CLR x
  70        and.b  ~(1<<\x),$r9
  71        move.d $r9, [$r2]
  72.endm
  73
  74;;----------------------------------------------------------------------------
  75
  76nand_boot:
  77        ;; Check if nand boot was selected
  78        move.d REG_ADDR(config, regi_config, r_bootsel), $r0
  79        move.d [$r0], $r0
  80        and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
  81        cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
  82        bne normal_boot ; No NAND boot
  83        nop
  84
  85copy_nand_to_ram:
  86        ;; copy_nand_to_ram
  87        ;; Arguments
  88        ;;   r10 - destination
  89        ;;   r11 - source offset
  90        ;;   r12 - size
  91        ;;   r13 - Address to jump to after completion
  92        ;; Note : r10-r12 are clobbered on return
  93        ;; Registers used:
  94        ;;   r0 - NAND_RD_ADDR
  95        ;;   r1 - NAND_WR_ADDR
  96        ;;   r2 - reg_gio_rw_pa_dout
  97        ;;   r3 - reg_gio_r_pa_din
  98        ;;   r4 - tmp
  99        ;;   r5 - byte counter within a page
 100        ;;   r6 - reg_pinmux_rw_pa
 101        ;;   r7 - reg_gio_rw_pa_oe
 102        ;;   r8 - reg_bif_core_rw_grp3_cfg
 103        ;;   r9 - reg_gio_rw_pa_dout shadow
 104        move.d 0x90000000, $r0
 105        move.d 0x94000000, $r1
 106        move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
 107        move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
 108        move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
 109        move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
 110        move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
 111
 112#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
 113        lsrq    1, $r11
 114#endif
 115        ;; Set up GPIO
 116        move.d [$r2], $r9
 117        move.d [$r7], $r4
 118        or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
 119        move.d $r4, [$r7]
 120
 121        ;; Set up bif
 122        move.d [$r8], $r4
 123        and.d CSP_MASK, $r4
 124        or.d CSP_VAL, $r4
 125        move.d $r4, [$r8]
 126
 1271:      ;; Copy one page
 128        CLR CE
 129        SET CLE
 130        moveq   READ_CMD, $r4
 131        move.b  $r4, [$r1]
 132        moveq   20, $r4
 1332:      bne     2b
 134        subq    1, $r4
 135        CLR CLE
 136        SET ALE
 137        clear.w [$r1]           ; Column address = 0
 138        move.d  $r11, $r4
 139        lsrq    8, $r4
 140        move.b  $r4, [$r1]      ; Row address
 141        lsrq    8, $r4
 142        move.b  $r4, [$r1]      ; Row adddress
 143        moveq   20, $r4
 1442:      bne     2b
 145        subq    1, $r4
 146        CLR ALE
 1472:      move.d  [$r3], $r4
 148        and.d   1 << BY, $r4
 149        beq 2b
 150        movu.w  PAGE_SIZE, $r5
 1512:      ; Copy one byte/word
 152#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
 153        move.w  [$r0], $r4
 154#else
 155        move.b  [$r0], $r4
 156#endif
 157        subq    1, $r5
 158        bne     2b
 159#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
 160        move.w  $r4, [$r10+]
 161        subu.w  PAGE_SIZE*2, $r12
 162#else
 163        move.b  $r4, [$r10+]
 164        subu.w  PAGE_SIZE, $r12
 165#endif
 166        bpl     1b
 167        addu.w  PAGE_SIZE, $r11
 168
 169        ;; End of copy
 170        jump    $r13
 171        nop
 172
 173        ;; This will warn if the code above is too large. If you consider
 174        ;; to remove this you don't understand the bug/feature.
 175        .org 256
 176        .org ERASE_BLOCK
 177
 178normal_boot:
 179
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.