]>
Commit | Line | Data |
---|---|---|
51533b61 MS |
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 <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> | |
51533b61 MS |
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 | ||
76 | nand_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 | ||
85 | copy_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 | ||
127 | 1: ;; Copy one page | |
128 | CLR CE | |
129 | SET CLE | |
130 | moveq READ_CMD, $r4 | |
131 | move.b $r4, [$r1] | |
132 | moveq 20, $r4 | |
133 | 2: 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 | |
144 | 2: bne 2b | |
145 | subq 1, $r4 | |
146 | CLR ALE | |
147 | 2: move.d [$r3], $r4 | |
148 | and.d 1 << BY, $r4 | |
149 | beq 2b | |
150 | movu.w PAGE_SIZE, $r5 | |
151 | 2: ; 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 | ||
178 | normal_boot: |