Merge by Hand
[linux-2.6] / arch / cris / arch-v32 / lib / nand_init.S
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>
30 #include <linux/config.h>
31
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
35 #define PAGE_SIZE 256
36 #else
37 #error 2
38 #define PAGE_SIZE 512
39 #endif
40 #define ERASE_BLOCK 16384
41
42 ;; GPIO pins connected to NAND flash
43 #define CE 4
44 #define CLE 5
45 #define ALE 6
46 #define BY 7
47
48 ;; Address space for NAND flash
49 #define NAND_RD_ADDR 0x90000000
50 #define NAND_WR_ADDR 0x94000000
51
52 #define READ_CMD 0x00
53
54 ;; Readability macros
55 #define CSP_MASK \
56         REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
57         REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
58 #define CSP_VAL \
59         REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
60         REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
61
62 ;;----------------------------------------------------------------------------
63 ;; Macros to set/clear GPIO bits
64
65 .macro SET x
66         or.b   (1<<\x),$r9
67         move.d $r9, [$r2]
68 .endm
69
70 .macro CLR x
71         and.b  ~(1<<\x),$r9
72         move.d $r9, [$r2]
73 .endm
74
75 ;;----------------------------------------------------------------------------
76
77 nand_boot:
78         ;; Check if nand boot was selected
79         move.d REG_ADDR(config, regi_config, r_bootsel), $r0
80         move.d [$r0], $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
84         nop
85
86 copy_nand_to_ram:
87         ;; copy_nand_to_ram
88         ;; Arguments
89         ;;   r10 - destination
90         ;;   r11 - source offset
91         ;;   r12 - size
92         ;;   r13 - Address to jump to after completion
93         ;; Note : r10-r12 are clobbered on return
94         ;; Registers used:
95         ;;   r0 - NAND_RD_ADDR
96         ;;   r1 - NAND_WR_ADDR
97         ;;   r2 - reg_gio_rw_pa_dout
98         ;;   r3 - reg_gio_r_pa_din
99         ;;   r4 - tmp
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
112
113 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
114         lsrq    1, $r11
115 #endif
116         ;; Set up GPIO
117         move.d [$r2], $r9
118         move.d [$r7], $r4
119         or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
120         move.d $r4, [$r7]
121
122         ;; Set up bif
123         move.d [$r8], $r4
124         and.d CSP_MASK, $r4
125         or.d CSP_VAL, $r4
126         move.d $r4, [$r8]
127
128 1:      ;; Copy one page
129         CLR CE
130         SET CLE
131         moveq   READ_CMD, $r4
132         move.b  $r4, [$r1]
133         moveq   20, $r4
134 2:      bne     2b
135         subq    1, $r4
136         CLR CLE
137         SET ALE
138         clear.w [$r1]           ; Column address = 0
139         move.d  $r11, $r4
140         lsrq    8, $r4
141         move.b  $r4, [$r1]      ; Row address
142         lsrq    8, $r4
143         move.b  $r4, [$r1]      ; Row adddress
144         moveq   20, $r4
145 2:      bne     2b
146         subq    1, $r4
147         CLR ALE
148 2:      move.d  [$r3], $r4
149         and.d   1 << BY, $r4
150         beq 2b
151         movu.w  PAGE_SIZE, $r5
152 2:      ; Copy one byte/word
153 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
154         move.w  [$r0], $r4
155 #else
156         move.b  [$r0], $r4
157 #endif
158         subq    1, $r5
159         bne     2b
160 #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
161         move.w  $r4, [$r10+]
162         subu.w  PAGE_SIZE*2, $r12
163 #else
164         move.b  $r4, [$r10+]
165         subu.w  PAGE_SIZE, $r12
166 #endif
167         bpl     1b
168         addu.w  PAGE_SIZE, $r11
169
170         ;; End of copy
171         jump    $r13
172         nop
173
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.
176         .org 256
177         .org ERASE_BLOCK
178
179 normal_boot: