|
@@ -1,178 +0,0 @@
|
|
|
-##=============================================================================
|
|
|
-##
|
|
|
-## nand_init.S
|
|
|
-##
|
|
|
-## The bootrom copies data from the NAND flash to the internal RAM but
|
|
|
-## due to a bug/feature we can only trust the 256 first bytes. So this
|
|
|
-## code copies more data from NAND flash to internal RAM. Obvioulsy this
|
|
|
-## code must fit in the first 256 bytes so alter with care.
|
|
|
-##
|
|
|
-## Some notes about the bug/feature for future reference:
|
|
|
-## The bootrom copies the first 127 KB from NAND flash to internal
|
|
|
-## memory. The problem is that it does a bytewise copy. NAND flashes
|
|
|
-## does autoincrement on the address so for a 16-bite device each
|
|
|
-## read/write increases the address by two. So the copy loop in the
|
|
|
-## bootrom will discard every second byte. This is solved by inserting
|
|
|
-## zeroes in every second byte in the first erase block.
|
|
|
-##
|
|
|
-## The bootrom also incorrectly assumes that it can read the flash
|
|
|
-## linear with only one read command but the flash will actually
|
|
|
-## switch between normal area and spare area if you do that so we
|
|
|
-## can't trust more than the first 256 bytes.
|
|
|
-##
|
|
|
-##=============================================================================
|
|
|
-
|
|
|
-#include <arch/hwregs/asm/reg_map_asm.h>
|
|
|
-#include <arch/hwregs/asm/gio_defs_asm.h>
|
|
|
-#include <arch/hwregs/asm/pinmux_defs_asm.h>
|
|
|
-#include <arch/hwregs/asm/bif_core_defs_asm.h>
|
|
|
-#include <arch/hwregs/asm/config_defs_asm.h>
|
|
|
-
|
|
|
-;; There are 8-bit NAND flashes and 16-bit NAND flashes.
|
|
|
-;; We need to treat them slightly different.
|
|
|
-#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
|
|
|
-#define PAGE_SIZE 256
|
|
|
-#else
|
|
|
-#error 2
|
|
|
-#define PAGE_SIZE 512
|
|
|
-#endif
|
|
|
-#define ERASE_BLOCK 16384
|
|
|
-
|
|
|
-;; GPIO pins connected to NAND flash
|
|
|
-#define CE 4
|
|
|
-#define CLE 5
|
|
|
-#define ALE 6
|
|
|
-#define BY 7
|
|
|
-
|
|
|
-;; Address space for NAND flash
|
|
|
-#define NAND_RD_ADDR 0x90000000
|
|
|
-#define NAND_WR_ADDR 0x94000000
|
|
|
-
|
|
|
-#define READ_CMD 0x00
|
|
|
-
|
|
|
-;; Readability macros
|
|
|
-#define CSP_MASK \
|
|
|
- REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
|
|
|
- REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
|
|
|
-#define CSP_VAL \
|
|
|
- REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
|
|
|
- REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
|
|
|
-
|
|
|
-;;----------------------------------------------------------------------------
|
|
|
-;; Macros to set/clear GPIO bits
|
|
|
-
|
|
|
-.macro SET x
|
|
|
- or.b (1<<\x),$r9
|
|
|
- move.d $r9, [$r2]
|
|
|
-.endm
|
|
|
-
|
|
|
-.macro CLR x
|
|
|
- and.b ~(1<<\x),$r9
|
|
|
- move.d $r9, [$r2]
|
|
|
-.endm
|
|
|
-
|
|
|
-;;----------------------------------------------------------------------------
|
|
|
-
|
|
|
-nand_boot:
|
|
|
- ;; Check if nand boot was selected
|
|
|
- move.d REG_ADDR(config, regi_config, r_bootsel), $r0
|
|
|
- move.d [$r0], $r0
|
|
|
- and.d REG_MASK(config, r_bootsel, boot_mode), $r0
|
|
|
- cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
|
|
|
- bne normal_boot ; No NAND boot
|
|
|
- nop
|
|
|
-
|
|
|
-copy_nand_to_ram:
|
|
|
- ;; copy_nand_to_ram
|
|
|
- ;; Arguments
|
|
|
- ;; r10 - destination
|
|
|
- ;; r11 - source offset
|
|
|
- ;; r12 - size
|
|
|
- ;; r13 - Address to jump to after completion
|
|
|
- ;; Note : r10-r12 are clobbered on return
|
|
|
- ;; Registers used:
|
|
|
- ;; r0 - NAND_RD_ADDR
|
|
|
- ;; r1 - NAND_WR_ADDR
|
|
|
- ;; r2 - reg_gio_rw_pa_dout
|
|
|
- ;; r3 - reg_gio_r_pa_din
|
|
|
- ;; r4 - tmp
|
|
|
- ;; r5 - byte counter within a page
|
|
|
- ;; r6 - reg_pinmux_rw_pa
|
|
|
- ;; r7 - reg_gio_rw_pa_oe
|
|
|
- ;; r8 - reg_bif_core_rw_grp3_cfg
|
|
|
- ;; r9 - reg_gio_rw_pa_dout shadow
|
|
|
- move.d 0x90000000, $r0
|
|
|
- move.d 0x94000000, $r1
|
|
|
- move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
|
|
|
- move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
|
|
|
- move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
|
|
|
- move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
|
|
|
- move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
|
|
|
-
|
|
|
-#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
|
|
|
- lsrq 1, $r11
|
|
|
-#endif
|
|
|
- ;; Set up GPIO
|
|
|
- move.d [$r2], $r9
|
|
|
- move.d [$r7], $r4
|
|
|
- or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
|
|
|
- move.d $r4, [$r7]
|
|
|
-
|
|
|
- ;; Set up bif
|
|
|
- move.d [$r8], $r4
|
|
|
- and.d CSP_MASK, $r4
|
|
|
- or.d CSP_VAL, $r4
|
|
|
- move.d $r4, [$r8]
|
|
|
-
|
|
|
-1: ;; Copy one page
|
|
|
- CLR CE
|
|
|
- SET CLE
|
|
|
- moveq READ_CMD, $r4
|
|
|
- move.b $r4, [$r1]
|
|
|
- moveq 20, $r4
|
|
|
-2: bne 2b
|
|
|
- subq 1, $r4
|
|
|
- CLR CLE
|
|
|
- SET ALE
|
|
|
- clear.w [$r1] ; Column address = 0
|
|
|
- move.d $r11, $r4
|
|
|
- lsrq 8, $r4
|
|
|
- move.b $r4, [$r1] ; Row address
|
|
|
- lsrq 8, $r4
|
|
|
- move.b $r4, [$r1] ; Row address
|
|
|
- moveq 20, $r4
|
|
|
-2: bne 2b
|
|
|
- subq 1, $r4
|
|
|
- CLR ALE
|
|
|
-2: move.d [$r3], $r4
|
|
|
- and.d 1 << BY, $r4
|
|
|
- beq 2b
|
|
|
- movu.w PAGE_SIZE, $r5
|
|
|
-2: ; Copy one byte/word
|
|
|
-#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
|
|
|
- move.w [$r0], $r4
|
|
|
-#else
|
|
|
- move.b [$r0], $r4
|
|
|
-#endif
|
|
|
- subq 1, $r5
|
|
|
- bne 2b
|
|
|
-#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
|
|
|
- move.w $r4, [$r10+]
|
|
|
- subu.w PAGE_SIZE*2, $r12
|
|
|
-#else
|
|
|
- move.b $r4, [$r10+]
|
|
|
- subu.w PAGE_SIZE, $r12
|
|
|
-#endif
|
|
|
- bpl 1b
|
|
|
- addu.w PAGE_SIZE, $r11
|
|
|
-
|
|
|
- ;; End of copy
|
|
|
- jump $r13
|
|
|
- nop
|
|
|
-
|
|
|
- ;; This will warn if the code above is too large. If you consider
|
|
|
- ;; to remove this you don't understand the bug/feature.
|
|
|
- .org 256
|
|
|
- .org ERASE_BLOCK
|
|
|
-
|
|
|
-normal_boot:
|