summaryrefslogtreecommitdiff
path: root/cpu/arm1136/mx35/mxc_nand_load.S
blob: 2ff223def8357574ff06b68201cee5d1e8fe0163 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/*
 * (C) Copyright 2008 Freescale Semiconductor, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <config.h>
#include <asm/arch/mx35.h>

.macro nfc_cmd_input
	strh r3, [r12, #NAND_FLASH_CMD_REG_OFF]
	mov r3, #NAND_FLASH_CONFIG2_FCMD_EN;
	strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
	bl do_wait_op_done
.endm   // nfc_cmd_input

.macro do_addr_input
	and r3, r3, #0xFF
	strh r3, [r12, #NAND_FLASH_ADD_REG_OFF]
	mov r3, #NAND_FLASH_CONFIG2_FADD_EN
	strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
	bl do_wait_op_done
.endm   // do_addr_input

.section ".text.load", "x"
.globl mxc_nand_load
mxc_nand_load:
	ldr r2, U_BOOT_NAND_START
1:	ldmia r0!, {r3-r10}
	stmia r2!, {r3-r10}
	cmp r0, r1
	blo 1b

	ldr r1, CONST_0X0FFF
	ldr r2, U_BOOT_NAND_START
	and lr, lr, r1
	add lr, lr, r2
	and r12, r12, r1
	add r12, r12, r2
	add r2, r2, #0x8
	and r0, pc, r1
	add pc, r0, r2
	nop
	nop
	nop
	nop
	nop
	adr r0, SAVE_REGS
	str r12, [r0]
	str lr, [r0, #4]
Copy_Main:
	mov r0, #NFC_BASE_ADDR
	add r12, r0, #0x1E00
	ldrh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
	orr r3, r3, #1

	/* Setting NFC */
	ldr r7, =CCM_BASE_ADDR
	ldr r1, [r7, #CLKCTL_RCSR]
	/*BUS WIDTH setting*/
	tst r1, #0x20000000
	orrne r1, r1, #0x4000
	biceq r1, r1, #0x4000

	/*4K PAGE*/
	tst r1, #0x10000000
	orrne r1, r1, #0x200
	bne  1f
    	/*2K PAGE*/
	bic r1, r1, #0x200
	tst r1, #0x08000000
	orrne r1, r1, #0x100 /*2KB page size*/
	biceq r1, r1, #0x100 /*512B page size*/
	movne r2, #32 /*64 bytes*/
	moveq r2, #8  /*16 bytes*/
	b NAND_setup
1:
	tst r1, #0x08000000
	bicne r3, r3, #1   /*Enable 8bit ECC mode*/
	movne r2, #109 /*218 bytes*/
	moveq r2, #64  /*128 bytes*/
NAND_setup:
	str r1, [r7, #CLKCTL_RCSR]
	strh r2, [r12, #ECC_RSLT_SPARE_AREA_REG_OFF]
	strh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]

    	//unlock internal buffer
	mov r3, #0x2
	strh r3, [r12, #NFC_CONFIGURATION_REG_OFF]
    	//unlock nand device
	mov r3, #0
	strh r3, [r12, #UNLOCK_START_BLK_ADD_REG_OFF]
	sub r3, r3, #1
	strh r3, [r12, #UNLOCK_END_BLK_ADD_REG_OFF]
	mov r3, #4
	strh r3, [r12, #NF_WR_PROT_REG_OFF]

	/* r0: NFC base address. RAM buffer base address. [constantly]
	 * r1: starting flash address to be copied. [constantly]
	 * r2: page size. [Doesn't change]
	 * r3: used as argument.
	 * r11: starting SDRAM address for copying. [Updated constantly].
	 * r12: NFC register base address. [constantly].
	 * r13: end of SDRAM address for copying. [Doesn't change].
	 */

	mov r1, #0x1000
	ldr r3, [r7, #CLKCTL_RCSR]
	tst r3, #0x200
	movne r2, #0x1000
	bne 1f
	tst r3, #0x100
	mov r1, #0x800  /*Strange Why is not 4K offset*/
	movne r2, #0x800
	moveq r2, #0x200
1: /*Update the indicator of copy area */
	ldr r11, U_BOOT_NAND_START
	add r13, r11, #0x00088000; /*512K + 32K*/
	add r11, r11, r1

Nfc_Read_Page:
	mov r3, #0x0
	nfc_cmd_input

	cmp r2, #0x800
	bhi nfc_addr_ops_4kb
	beq nfc_addr_ops_2kb

	mov r3, r1
	do_addr_input       //1st addr cycle
	mov r3, r1, lsr #9
	do_addr_input       //2nd addr cycle
	mov r3, r1, lsr #17
	do_addr_input       //3rd addr cycle
	mov r3, r1, lsr #25
	do_addr_input       //4th addr cycle
	b end_of_nfc_addr_ops

nfc_addr_ops_2kb:
	mov r3, #0
	do_addr_input       //1st addr cycle
	mov r3, #0
	do_addr_input       //2nd addr cycle
	mov r3, r1, lsr #11
	do_addr_input       //3rd addr cycle
	mov r3, r1, lsr #19
	do_addr_input       //4th addr cycle
	mov r3, r1, lsr #27
	do_addr_input       //5th addr cycle

	mov r3, #0x30
	nfc_cmd_input
	b end_of_nfc_addr_ops

nfc_addr_ops_4kb:
	mov r3, #0
	do_addr_input       //1st addr cycle
	mov r3, #0
	do_addr_input       //2nd addr cycle
	mov r3, r1, lsr #12
	do_addr_input       //3rd addr cycle
	mov r3, r1, lsr #20
	do_addr_input       //4th addr cycle
	mov r3, r1, lsr #27
	do_addr_input       //5th addr cycle

	mov r3, #0x30
	nfc_cmd_input

end_of_nfc_addr_ops:
	mov r8, #0
	bl nfc_data_output
	bl do_wait_op_done
	// Check if x16/2kb page
	cmp r2, #0x800
	bhi nfc_addr_data_output_done_4k
	beq nfc_addr_data_output_done_2k
	beq nfc_addr_data_output_done_512

	// check for bad block
	//    mov r3, r1, lsl #(32-17)    // get rid of block number
	//    cmp r3, #(0x800 << (32-17)) // check if not page 0 or 1
	b nfc_addr_data_output_done

nfc_addr_data_output_done_4k:
//TODO
	b nfc_addr_data_output_done

nfc_addr_data_output_done_2k:
	// end of 4th
	// check for bad block
	//TODO    mov r3, r1, lsl #(32-17)    // get rid of block number
	//    cmp r3, #(0x800 << (32-17)) // check if not page 0 or 1
	b nfc_addr_data_output_done

nfc_addr_data_output_done_512:
    	// check for bad block
	// TODO   mov r3, r1, lsl #(32-5-9)    // get rid of block number
	// TODO   cmp r3, #(512 << (32-5-9))   // check if not page 0 or 1

nfc_addr_data_output_done:
Copy_Good_Blk:
    //copying page
	add r2, r2, #NFC_BASE_ADDR
1:	ldmia r0!, {r3-r10}
	stmia r11!, {r3-r10}
	cmp r0, r2
	blo 1b
	sub r2, r2, #NFC_BASE_ADDR

	cmp r11, r13
	bge NAND_Copy_Main_done
	// Check if x16/2kb page
	add r1, r1, r2
	mov r0, #NFC_BASE_ADDR
	b Nfc_Read_Page

NAND_Copy_Main_done:
	adr r0, SAVE_REGS
	ldr r12, [r0]
	ldr lr, [r0, #4]
	mov pc, lr

do_wait_op_done:
1:
	ldrh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
	ands r3, r3, #NAND_FLASH_CONFIG2_INT_DONE
	beq 1b
	bx lr     // do

nfc_data_output:
	ldrh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
	orr r3, r3, #(NAND_FLASH_CONFIG1_INT_MSK | NAND_FLASH_CONFIG1_ECC_EN)
	strh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]

	strh r8, [r12, #RAM_BUFFER_ADDRESS_REG_OFF]

	mov r3, #FDO_PAGE_SPARE_VAL
	strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
	bx lr

U_BOOT_NAND_START: .word TEXT_BASE
CONST_0X0FFF:	.word 0x0FFF
SAVE_REGS:	.word 0x0
		.word 0x0