[mcs814x] nuport-mac: various fixes
[openwrt.git] / package / uboot-xburst / files / nand_spl / nand_boot_jz4740.c
1 /*
2  * Copyright (C) 2007 Ingenic Semiconductor Inc.
3  * Author: Peter <jlwei@ingenic.cn>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA
19  */
20
21 #include <common.h>
22 #include <nand.h>
23
24 #include <asm/io.h>
25 #include <asm/jz4740.h>
26
27 #define KEY_U_OUT       (32 * 2 + 16)
28 #define KEY_U_IN        (32 * 3 + 19)
29
30 /*
31  * NAND flash definitions
32  */
33
34 #define NAND_DATAPORT   0xb8000000
35 #define NAND_ADDRPORT   0xb8010000
36 #define NAND_COMMPORT   0xb8008000
37
38 #define ECC_BLOCK       512
39 #define ECC_POS         6
40 #define PAR_SIZE        9
41
42 #define __nand_enable()         (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
43 #define __nand_disable()        (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1))
44 #define __nand_ecc_rs_encoding() \
45         (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING)
46 #define __nand_ecc_rs_decoding() \
47         (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING)
48 #define __nand_ecc_disable()    (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
49 #define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
50 #define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
51
52 static inline void __nand_dev_ready(void)
53 {
54         unsigned int timeout = 10000;
55         while ((REG_GPIO_PXPIN(2) & 0x40000000) && timeout--);
56         while (!(REG_GPIO_PXPIN(2) & 0x40000000));
57 }
58
59 #define __nand_cmd(n)           (REG8(NAND_COMMPORT) = (n))
60 #define __nand_addr(n)          (REG8(NAND_ADDRPORT) = (n))
61 #define __nand_data8()          REG8(NAND_DATAPORT)
62 #define __nand_data16()         REG16(NAND_DATAPORT)
63
64 #if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3)
65         #define NAND_BUS_WIDTH 8
66         #define NAND_ROW_CYCLE 3
67 #elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2)
68         #define NAND_BUS_WIDTH 8
69         #define NAND_ROW_CYCLE 2
70 #elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3)
71         #define NAND_BUS_WIDTH 16
72         #define NAND_ROW_CYCLE 3
73 #elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2)
74         #define NAND_BUS_WIDTH 16
75         #define NAND_ROW_CYCLE 2
76 #endif
77
78 /*
79  * NAND flash parameters
80  */
81 static int page_size = 2048;
82 static int oob_size = 64;
83 static int ecc_count = 4;
84 static int page_per_block = 64;
85 static int bad_block_pos = 0;
86 static int block_size = 131072;
87
88 static unsigned char oob_buf[128] = {0};
89
90 /*
91  * External routines
92  */
93 extern void flush_cache_all(void);
94 extern int serial_init(void);
95 extern void serial_puts(const char *s);
96 extern void sdram_init(void);
97 extern void pll_init(void);
98 extern void usb_boot();
99
100 /*
101  * NAND flash routines
102  */
103 #if NAND_BUS_WIDTH == 16
104 static inline void nand_read_buf16(void *buf, int count)
105 {
106         int i;
107         u16 *p = (u16 *)buf;
108
109         for (i = 0; i < count; i += 2)
110                 *p++ = __nand_data16();
111 }
112 #define nand_read_buf nand_read_buf16
113
114 #elif NAND_BUS_WIDTH == 8
115 static inline void nand_read_buf8(void *buf, int count)
116 {
117         int i;
118         u8 *p = (u8 *)buf;
119
120         for (i = 0; i < count; i++)
121                 *p++ = __nand_data8();
122 }
123 #define nand_read_buf nand_read_buf8
124
125 #endif
126
127 /* Correct 1~9-bit errors in 512-bytes data */
128 static void rs_correct(unsigned char *dat, int idx, int mask)
129 {
130         int i;
131
132         idx--;
133
134         i = idx + (idx >> 3);
135         if (i >= 512)
136                 return;
137
138         mask <<= (idx & 0x7);
139
140         dat[i] ^= mask & 0xff;
141         if (i < 511)
142                 dat[i+1] ^= (mask >> 8) & 0xff;
143 }
144
145 static int nand_read_oob(int page_addr, uchar *buf, int size)
146 {
147         int col_addr;
148         if (page_size != 512)
149                 col_addr = page_size;
150         else {
151                 col_addr = 0;
152                 __nand_dev_ready();
153         }
154
155         if (page_size != 512)
156                 /* Send READ0 command */
157                 __nand_cmd(NAND_CMD_READ0);
158         else
159                 /* Send READOOB command */
160                 __nand_cmd(NAND_CMD_READOOB);
161
162         /* Send column address */
163         __nand_addr(col_addr & 0xff);
164         if (page_size != 512)
165                 __nand_addr((col_addr >> 8) & 0xff);
166
167         /* Send page address */
168         __nand_addr(page_addr & 0xff);
169         __nand_addr((page_addr >> 8) & 0xff);
170         #ifdef NAND_ROW_CYCLE == 3
171                 __nand_addr((page_addr >> 16) & 0xff);
172         #endif
173
174         /* Send READSTART command for 2048 or 4096 ps NAND */
175         if (page_size != 512)
176                 __nand_cmd(NAND_CMD_READSTART);
177
178         /* Wait for device ready */
179         __nand_dev_ready();
180
181         /* Read oob data */
182         nand_read_buf(buf, size);
183         if (page_size == 512)
184                 __nand_dev_ready();
185         return 0;
186 }
187
188 static int nand_read_page(int page_addr, uchar *dst, uchar *oobbuf)
189 {
190         uchar *databuf = dst, *tmpbuf;
191         int i, j;
192
193         /*
194          * Read oob data
195          */
196         nand_read_oob(page_addr, oobbuf, oob_size);
197
198         /*
199          * Read page data
200          */
201
202         /* Send READ0 command */
203         __nand_cmd(NAND_CMD_READ0);
204
205         /* Send column address */
206         __nand_addr(0);
207         if (page_size != 512)
208                 __nand_addr(0);
209
210         /* Send page address */
211         __nand_addr(page_addr & 0xff);
212         __nand_addr((page_addr >> 8) & 0xff);
213         #if NAND_ROW_CYCLE == 3
214                 __nand_addr((page_addr >> 16) & 0xff);
215         #endif
216
217         /* Send READSTART command for 2048 or 4096 ps NAND */
218         if (page_size != 512)
219                 __nand_cmd(NAND_CMD_READSTART);
220
221         /* Wait for device ready */
222         __nand_dev_ready();
223
224         /* Read page data */
225         tmpbuf = databuf;
226
227         for (i = 0; i < ecc_count; i++) {
228                 volatile unsigned char *paraddr = (volatile unsigned char *)EMC_NFPAR0;
229                 unsigned int stat;
230
231                 /* Enable RS decoding */
232                 REG_EMC_NFINTS = 0x0;
233                 __nand_ecc_rs_decoding();
234
235                 /* Read data */
236                 nand_read_buf((void *)tmpbuf, ECC_BLOCK);
237
238                 /* Set PAR values */
239                 for (j = 0; j < PAR_SIZE; j++) {
240 #if defined(CONFIG_SYS_NAND_ECC_POS)
241                         *paraddr++ = oobbuf[CONFIG_SYS_NAND_ECC_POS + i*PAR_SIZE + j];
242 #else
243                         *paraddr++ = oobbuf[ECC_POS + i*PAR_SIZE + j];
244 #endif
245                 }
246
247                 /* Set PRDY */
248                 REG_EMC_NFECR |= EMC_NFECR_PRDY;
249
250                 /* Wait for completion */
251                 __nand_ecc_decode_sync();
252
253                 /* Disable decoding */
254                 __nand_ecc_disable();
255
256                 /* Check result of decoding */
257                 stat = REG_EMC_NFINTS;
258                 if (stat & EMC_NFINTS_ERR) {
259                         /* Error occurred */
260                         /* serial_puts("\n Error occurred\n"); */
261                         if (stat & EMC_NFINTS_UNCOR) {
262                                 /* Uncorrectable error occurred */
263                                 /* serial_puts("\nUncorrectable error occurred\n"); */
264                         }
265                         else {
266                                 unsigned int errcnt, index, mask;
267
268                                 errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
269                                 switch (errcnt) {
270                                 case 4:
271                                         index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
272                                         mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
273                                         rs_correct(tmpbuf, index, mask);
274                                         /* FALL-THROUGH */
275                                 case 3:
276                                         index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
277                                         mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
278                                         rs_correct(tmpbuf, index, mask);
279                                         /* FALL-THROUGH */
280                                 case 2:
281                                         index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
282                                         mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
283                                         rs_correct(tmpbuf, index, mask);
284                                         /* FALL-THROUGH */
285                                 case 1:
286                                         index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
287                                         mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
288                                         rs_correct(tmpbuf, index, mask);
289                                         break;
290                                 default:
291                                         break;
292                                 }
293                         }
294                 }
295
296                 tmpbuf += ECC_BLOCK;
297         }
298
299         return 0;
300 }
301
302 #ifndef CONFIG_SYS_NAND_BADBLOCK_PAGE
303 #define CONFIG_SYS_NAND_BADBLOCK_PAGE 0 /* NAND bad block was marked at this page in a block, starting from 0 */
304 #endif
305
306 static void nand_load(int offs, int uboot_size, uchar *dst)
307 {
308         int page;
309         int pagecopy_count;
310
311         __nand_enable();
312
313         page = offs / page_size;
314         pagecopy_count = 0;
315         while (pagecopy_count < (uboot_size / page_size)) {
316                 if (page % page_per_block == 0) {
317                         nand_read_oob(page + CONFIG_SYS_NAND_BADBLOCK_PAGE, oob_buf, oob_size);
318                         if (oob_buf[bad_block_pos] != 0xff) {
319                                 page += page_per_block;
320                                 /* Skip bad block */
321                                 continue;
322                         }
323                 }
324                 /* Load this page to dst, do the ECC */
325                 nand_read_page(page, dst, oob_buf);
326
327                 dst += page_size;
328                 page++;
329                 pagecopy_count++;
330         }
331
332         __nand_disable();
333 }
334
335 static void jz_nand_init(void) {
336
337         /* Optimize the timing of nand */
338         REG_EMC_SMCR1 = 0x094c4400;
339 }
340
341 static void gpio_init(void)
342 {
343         /*
344          * Initialize SDRAM pins
345          */
346 #if defined(CONFIG_JZ4720)
347         __gpio_as_sdram_16bit_4720();
348 #elif defined(CONFIG_JZ4725)
349         __gpio_as_sdram_16bit_4725();
350 #else
351         __gpio_as_sdram_32bit();
352 #endif
353
354         /*
355          * Initialize UART0 pins
356          */
357         __gpio_as_uart0();
358 }
359
360 static int is_usb_boot()
361 {
362         int keyU = 0;
363
364         __gpio_as_input(KEY_U_IN);
365         __gpio_enable_pull(KEY_U_IN);
366
367         __gpio_as_output(KEY_U_OUT);
368         __gpio_clear_pin(KEY_U_OUT);
369
370         keyU = __gpio_get_pin(KEY_U_IN);
371
372         if (keyU)
373                 serial_puts("[U] not pressed\n");
374         else
375                 serial_puts("[U] pressed\n");
376
377         return !keyU;
378 }
379
380 void nand_boot(void)
381 {
382         void (*uboot)(void);
383
384         /*
385          * Init hardware
386          */
387         jz_nand_init();
388         gpio_init();
389         serial_init();
390
391         serial_puts("\n\nNAND Secondary Program Loader\n\n");
392
393         pll_init();
394         sdram_init();
395
396 #if defined(CONFIG_NANONOTE)
397         if(is_usb_boot()) {
398                 serial_puts("enter USB BOOT mode\n");
399                 usb_boot();
400         }
401 #endif
402
403         page_size = CONFIG_SYS_NAND_PAGE_SIZE;
404         block_size = CONFIG_SYS_NAND_BLOCK_SIZE;
405         page_per_block = CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE;
406         bad_block_pos = (page_size == 512) ? 5 : 0;
407         oob_size = page_size / 32;
408         ecc_count = page_size / ECC_BLOCK;
409
410         /*
411          * Load U-Boot image from NAND into RAM
412          */
413         nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE,
414                   (uchar *)CONFIG_SYS_NAND_U_BOOT_DST);
415
416         uboot = (void (*)(void))CONFIG_SYS_NAND_U_BOOT_START;
417
418         serial_puts("Starting U-Boot ...\n");
419
420         /*
421          * Flush caches
422          */
423         flush_cache_all();
424
425         /*
426          * Jump to U-Boot image
427          */
428         (*uboot)();
429 }