Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/cris/arch-v32/lib/nand_init.S
15125 views
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
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 address
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:
179
180