1 ##=============================================================================
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.
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.
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.
23 ##=============================================================================
25 #include <asm/arch/hwregs/asm/reg_map_asm.h>
26 #include <asm/arch/hwregs/asm/gio_defs_asm.h>
27 #include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
28 #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
29 #include <asm/arch/hwregs/asm/config_defs_asm.h>
30 #include <linux/config.h>
32 ;; There are 8-bit NAND flashes and 16-bit NAND flashes.
33 ;; We need to treat them slightly different.
34 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
40 #define ERASE_BLOCK 16384
42 ;; GPIO pins connected to NAND flash
48 ;; Address space for NAND flash
49 #define NAND_RD_ADDR 0x90000000
50 #define NAND_WR_ADDR 0x94000000
56 REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
57 REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
59 REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
60 REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
62 ;;----------------------------------------------------------------------------
63 ;; Macros to set/clear GPIO bits
75 ;;----------------------------------------------------------------------------
78 ;; Check if nand boot was selected
79 move.d REG_ADDR(config, regi_config, r_bootsel), $r0
81 and.d REG_MASK(config, r_bootsel, boot_mode), $r0
82 cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
83 bne normal_boot ; No NAND boot
90 ;; r11 - source offset
92 ;; r13 - Address to jump to after completion
93 ;; Note : r10-r12 are clobbered on return
97 ;; r2 - reg_gio_rw_pa_dout
98 ;; r3 - reg_gio_r_pa_din
100 ;; r5 - byte counter within a page
101 ;; r6 - reg_pinmux_rw_pa
102 ;; r7 - reg_gio_rw_pa_oe
103 ;; r8 - reg_bif_core_rw_grp3_cfg
104 ;; r9 - reg_gio_rw_pa_dout shadow
105 move.d 0x90000000, $r0
106 move.d 0x94000000, $r1
107 move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
108 move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
109 move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
110 move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
111 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
113 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
119 or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
138 clear.w [$r1] ; Column address = 0
141 move.b $r4, [$r1] ; Row address
143 move.b $r4, [$r1] ; Row adddress
151 movu.w PAGE_SIZE, $r5
152 2: ; Copy one byte/word
153 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
160 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
162 subu.w PAGE_SIZE*2, $r12
165 subu.w PAGE_SIZE, $r12
168 addu.w PAGE_SIZE, $r11
174 ;; This will warn if the code above is too large. If you consider
175 ;; to remove this you don't understand the bug/feature.