Root/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/jz4740.h>
25#include "nanonote_gpm940b0.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#define NAND_DATAPORT 0xb8000000
34#define NAND_ADDRPORT 0xb8010000
35#define NAND_COMMPORT 0xb8008000
36
37#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
38#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1))
39#define __nand_ecc_rs_encoding() \
40    (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING)
41#define __nand_ecc_rs_decoding() \
42    (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING)
43#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
44#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
45#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
46#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n))
47#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n))
48#define __nand_data8() REG8(NAND_DATAPORT)
49#define __nand_data16() REG16(NAND_DATAPORT)
50
51#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3)
52    #define NAND_BUS_WIDTH 8
53    #define NAND_ROW_CYCLE 3
54#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2)
55    #define NAND_BUS_WIDTH 8
56    #define NAND_ROW_CYCLE 2
57#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3)
58    #define NAND_BUS_WIDTH 16
59    #define NAND_ROW_CYCLE 3
60#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2)
61    #define NAND_BUS_WIDTH 16
62    #define NAND_ROW_CYCLE 2
63#endif
64
65static inline void __nand_dev_ready(void)
66{
67    unsigned int timeout = 10000;
68    while ((REG_GPIO_PXPIN(2) & 0x40000000) && timeout--);
69    while (!(REG_GPIO_PXPIN(2) & 0x40000000));
70}
71
72/*
73 * NAND flash parameters
74 */
75static int page_size = 2048;
76static int oob_size = 64;
77static int ecc_count = 4;
78static int page_per_block = 64;
79static int bad_block_pos = 0;
80static int block_size = 131072;
81static unsigned char oob_buf[128] = {0};
82
83/*
84 * External routines
85 */
86extern void flush_cache_all(void);
87extern int serial_init(void);
88extern void serial_puts(const char *s);
89extern void sdram_init(void);
90extern void pll_init(void);
91extern void usb_boot();
92
93/*
94 * NAND flash routines
95 */
96#if NAND_BUS_WIDTH == 16
97static inline void nand_read_buf16(void *buf, int count)
98{
99    int i;
100    u16 *p = (u16 *)buf;
101
102    for (i = 0; i < count; i += 2)
103        *p++ = __nand_data16();
104}
105#define nand_read_buf nand_read_buf16
106
107#elif NAND_BUS_WIDTH == 8
108static inline void nand_read_buf8(void *buf, int count)
109{
110    int i;
111    u8 *p = (u8 *)buf;
112
113    for (i = 0; i < count; i++)
114        *p++ = __nand_data8();
115}
116#define nand_read_buf nand_read_buf8
117
118#endif
119
120/* Correct 1~9-bit errors in 512-bytes data */
121static void rs_correct(unsigned char *dat, int idx, int mask)
122{
123    int i;
124
125    idx--;
126
127    i = idx + (idx >> 3);
128    if (i >= 512)
129        return;
130
131    mask <<= (idx & 0x7);
132
133    dat[i] ^= mask & 0xff;
134    if (i < 511)
135        dat[i+1] ^= (mask >> 8) & 0xff;
136}
137
138static int nand_read_oob(int page_addr, uchar *buf, int size)
139{
140    int col_addr;
141    if (page_size != 512)
142        col_addr = page_size;
143    else {
144        col_addr = 0;
145        __nand_dev_ready();
146    }
147
148    if (page_size != 512)
149        /* Send READ0 command */
150        __nand_cmd(NAND_CMD_READ0);
151    else
152        /* Send READOOB command */
153        __nand_cmd(NAND_CMD_READOOB);
154
155    /* Send column address */
156    __nand_addr(col_addr & 0xff);
157    if (page_size != 512)
158        __nand_addr((col_addr >> 8) & 0xff);
159
160    /* Send page address */
161    __nand_addr(page_addr & 0xff);
162    __nand_addr((page_addr >> 8) & 0xff);
163    #if defined NAND_ROW_CYCLE && NAND_ROW_CYCLE == 3
164        __nand_addr((page_addr >> 16) & 0xff);
165    #endif
166
167    /* Send READSTART command for 2048 or 4096 ps NAND */
168    if (page_size != 512)
169        __nand_cmd(NAND_CMD_READSTART);
170
171    /* Wait for device ready */
172    __nand_dev_ready();
173
174    /* Read oob data */
175    nand_read_buf(buf, size);
176    if (page_size == 512)
177        __nand_dev_ready();
178    return 0;
179}
180
181static int nand_read_page(int page_addr, uchar *dst, uchar *oobbuf)
182{
183    uchar *databuf = dst, *tmpbuf;
184    int i, j;
185
186    /*
187     * Read oob data
188     */
189    nand_read_oob(page_addr, oobbuf, oob_size);
190
191    /*
192     * Read page data
193     */
194    /* Send READ0 command */
195    __nand_cmd(NAND_CMD_READ0);
196
197    /* Send column address */
198    __nand_addr(0);
199    if (page_size != 512)
200        __nand_addr(0);
201
202    /* Send page address */
203    __nand_addr(page_addr & 0xff);
204    __nand_addr((page_addr >> 8) & 0xff);
205    #if defined NAND_ROW_CYCLE && NAND_ROW_CYCLE == 3
206        __nand_addr((page_addr >> 16) & 0xff);
207    #endif
208
209    /* Send READSTART command for 2048 or 4096 ps NAND */
210    if (page_size != 512)
211        __nand_cmd(NAND_CMD_READSTART);
212
213    /* Wait for device ready */
214    __nand_dev_ready();
215
216    /* Read page data */
217    tmpbuf = databuf;
218
219    for (i = 0; i < ecc_count; i++) {
220        volatile unsigned char *paraddr = (volatile unsigned char *)EMC_NFPAR0;
221        unsigned int stat;
222
223        /* Enable RS decoding */
224        REG_EMC_NFINTS = 0x0;
225        __nand_ecc_rs_decoding();
226
227        /* Read data */
228        nand_read_buf((void *)tmpbuf, CONFIG_SYS_NAND_ECCSIZE);
229
230        /* Set PAR values */
231        for (j = 0; j < CONFIG_SYS_NAND_ECCBYTES; j++)
232            *paraddr++ = oobbuf[CONFIG_SYS_NAND_ECC_POS + i*CONFIG_SYS_NAND_ECCBYTES + j];
233
234        /* Set PRDY */
235        REG_EMC_NFECR |= EMC_NFECR_PRDY;
236
237        /* Wait for completion */
238        __nand_ecc_decode_sync();
239
240        /* Disable decoding */
241        __nand_ecc_disable();
242
243        /* Check result of decoding */
244        stat = REG_EMC_NFINTS;
245        if (stat & EMC_NFINTS_ERR) {
246            /* Error occurred */
247            /* serial_puts("Error occurred\n"); */
248            if (stat & EMC_NFINTS_UNCOR) {
249                /* Uncorrectable error occurred */
250                /* serial_puts("Uncorrectable error occurred\n"); */
251            } else {
252                unsigned int errcnt, index, mask;
253
254                errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
255                switch (errcnt) {
256                case 4:
257                    index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
258                    mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
259                    rs_correct(tmpbuf, index, mask);
260                    /* FALL-THROUGH */
261                case 3:
262                    index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
263                    mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
264                    rs_correct(tmpbuf, index, mask);
265                    /* FALL-THROUGH */
266                case 2:
267                    index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
268                    mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
269                    rs_correct(tmpbuf, index, mask);
270                    /* FALL-THROUGH */
271                case 1:
272                    index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
273                    mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
274                    rs_correct(tmpbuf, index, mask);
275                    break;
276                default:
277                    break;
278                }
279            }
280        }
281        tmpbuf += CONFIG_SYS_NAND_ECCSIZE;
282    }
283
284    return 0;
285}
286
287#ifndef CONFIG_SYS_NAND_BADBLOCK_PAGE
288#define CONFIG_SYS_NAND_BADBLOCK_PAGE 0 /* NAND bad block was marked at this page in a block, starting from 0 */
289#endif
290
291static void nand_load(int offs, int uboot_size, uchar *dst)
292{
293    int page;
294    int pagecopy_count;
295
296    __nand_enable();
297
298    page = offs / page_size;
299    pagecopy_count = 0;
300    while (pagecopy_count < (uboot_size / page_size)) {
301        if (page % page_per_block == 0) {
302            nand_read_oob(page + CONFIG_SYS_NAND_BADBLOCK_PAGE, oob_buf, oob_size);
303            if (oob_buf[bad_block_pos] != 0xff) {
304                page += page_per_block;
305                /* Skip bad block */
306                continue;
307            }
308        }
309        /* Load this page to dst, do the ECC */
310        nand_read_page(page, dst, oob_buf);
311
312        dst += page_size;
313        page++;
314        pagecopy_count++;
315    }
316
317    __nand_disable();
318}
319
320static void jz_nand_init(void) {
321     /* Optimize the timing of nand */
322    REG_EMC_SMCR1 = 0x094c4400;
323}
324
325static void gpio_init(void)
326{
327    /*
328     * Initialize SDRAM pins
329     */
330    __gpio_as_sdram_16bit_4720();
331
332    /*
333     * Initialize UART0 pins
334     */
335    __gpio_as_uart0();
336    __gpio_jtag_to_uart0();
337}
338
339static int is_usb_boot()
340{
341    __gpio_as_input(KEY_U_IN);
342    __gpio_enable_pull(KEY_U_IN);
343    __gpio_as_output(KEY_U_OUT);
344    __gpio_clear_pin(KEY_U_OUT);
345
346    if (__gpio_get_pin(KEY_U_IN) == 0)
347        return 1;
348
349    return 0;
350}
351
352void nand_boot(void)
353{
354    void (*uboot)(void);
355
356    /*
357     * Init hardware
358     */
359    gpio_init();
360    pll_init();
361
362    __lcd_display_pin_init();
363    __lcd_display_on() ;
364
365    serial_init();
366    sdram_init();
367    jz_nand_init();
368
369    serial_puts("\nNAND Boot\n");
370
371#if defined(CONFIG_NANONOTE)
372    if(is_usb_boot()) {
373        serial_puts("[U] pressed, goto USBBOOT mode\n");
374        usb_boot();
375    }
376#endif
377    page_size = CONFIG_SYS_NAND_PAGE_SIZE;
378    block_size = CONFIG_SYS_NAND_BLOCK_SIZE;
379    page_per_block = CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE;
380    bad_block_pos = (page_size == 512) ? 5 : 0;
381    oob_size = page_size / 32;
382    ecc_count = page_size / CONFIG_SYS_NAND_ECCSIZE;
383
384    /*
385     * Load U-Boot image from NAND into RAM
386     */
387    nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE,
388          (uchar *)CONFIG_SYS_NAND_U_BOOT_DST);
389
390    uboot = (void (*)(void))CONFIG_SYS_NAND_U_BOOT_START;
391
392    serial_puts("Starting U-Boot ...\n");
393
394    /* Flush caches */
395    flush_cache_all();
396
397    /* Jump to U-Boot image */
398    (*uboot)();
399}
400

Archive Download this file



interactive