]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/nand/mxc_nand_spl.c
Prepare v2013.07-rc2
[karo-tx-uboot.git] / drivers / mtd / nand / mxc_nand_spl.c
1 /*
2  * (C) Copyright 2009
3  * Magnus Lilja <lilja.magnus@gmail.com>
4  *
5  * (C) Copyright 2008
6  * Maxim Artamonov, <scn1874 at yandex.ru>
7  *
8  * (C) Copyright 2006-2008
9  * Stefan Roese, DENX Software Engineering, sr at denx.de.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 #include <common.h>
28 #include <nand.h>
29 #include <asm/arch/imx-regs.h>
30 #include <asm/io.h>
31 #include "mxc_nand.h"
32
33 #if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
34 static struct mxc_nand_regs *const nfc = (void *)NFC_BASE_ADDR;
35 #elif defined(MXC_NFC_V3_2)
36 static struct mxc_nand_regs *const nfc = (void *)NFC_BASE_ADDR_AXI;
37 static struct mxc_nand_ip_regs *const nfc_ip = (void *)NFC_BASE_ADDR;
38 #endif
39
40 static void nfc_wait_ready(void)
41 {
42         uint32_t tmp;
43
44 #if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
45         while (!(readnfc(&nfc->config2) & NFC_V1_V2_CONFIG2_INT))
46                 ;
47
48         /* Reset interrupt flag */
49         tmp = readnfc(&nfc->config2);
50         tmp &= ~NFC_V1_V2_CONFIG2_INT;
51         writenfc(tmp, &nfc->config2);
52 #elif defined(MXC_NFC_V3_2)
53         while (!(readnfc(&nfc_ip->ipc) & NFC_V3_IPC_INT))
54                 ;
55
56         /* Reset interrupt flag */
57         tmp = readnfc(&nfc_ip->ipc);
58         tmp &= ~NFC_V3_IPC_INT;
59         writenfc(tmp, &nfc_ip->ipc);
60 #endif
61 }
62
63 static void nfc_nand_init(void)
64 {
65 #if defined(MXC_NFC_V3_2)
66         int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
67         int tmp;
68
69         tmp = (readnfc(&nfc_ip->config2) & ~(NFC_V3_CONFIG2_SPAS_MASK |
70                         NFC_V3_CONFIG2_EDC_MASK | NFC_V3_CONFIG2_PS_MASK)) |
71                 NFC_V3_CONFIG2_SPAS(CONFIG_SYS_NAND_OOBSIZE / 2) |
72                 NFC_V3_CONFIG2_INT_MSK | NFC_V3_CONFIG2_ECC_EN |
73                 NFC_V3_CONFIG2_ONE_CYCLE;
74         if (CONFIG_SYS_NAND_PAGE_SIZE == 4096)
75                 tmp |= NFC_V3_CONFIG2_PS_4096;
76         else if (CONFIG_SYS_NAND_PAGE_SIZE == 2048)
77                 tmp |= NFC_V3_CONFIG2_PS_2048;
78         else if (CONFIG_SYS_NAND_PAGE_SIZE == 512)
79                 tmp |= NFC_V3_CONFIG2_PS_512;
80         /*
81          * if spare size is larger that 16 bytes per 512 byte hunk
82          * then use 8 symbol correction instead of 4
83          */
84         if (CONFIG_SYS_NAND_OOBSIZE / ecc_per_page > 16)
85                 tmp |= NFC_V3_CONFIG2_ECC_MODE_8;
86         else
87                 tmp &= ~NFC_V3_CONFIG2_ECC_MODE_8;
88         writenfc(tmp, &nfc_ip->config2);
89
90         tmp = NFC_V3_CONFIG3_NUM_OF_DEVS(0) |
91                         NFC_V3_CONFIG3_NO_SDMA |
92                         NFC_V3_CONFIG3_RBB_MODE |
93                         NFC_V3_CONFIG3_SBB(6) | /* Reset default */
94                         NFC_V3_CONFIG3_ADD_OP(0);
95 #ifndef CONFIG_SYS_NAND_BUSWIDTH_16
96         tmp |= NFC_V3_CONFIG3_FW8;
97 #endif
98         writenfc(tmp, &nfc_ip->config3);
99
100         writenfc(0, &nfc_ip->delay_line);
101 #elif defined(MXC_NFC_V2_1)
102         int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
103         int config1;
104
105         writenfc(CONFIG_SYS_NAND_OOBSIZE / 2, &nfc->spare_area_size);
106
107         /* unlocking RAM Buff */
108         writenfc(0x2, &nfc->config);
109
110         /* hardware ECC checking and correct */
111         config1 = readnfc(&nfc->config1) | NFC_V1_V2_CONFIG1_ECC_EN |
112                         NFC_V1_V2_CONFIG1_INT_MSK | NFC_V2_CONFIG1_ONE_CYCLE |
113                         NFC_V2_CONFIG1_FP_INT;
114         /*
115          * if spare size is larger that 16 bytes per 512 byte hunk
116          * then use 8 symbol correction instead of 4
117          */
118         if (CONFIG_SYS_NAND_OOBSIZE / ecc_per_page > 16)
119                 config1 &= ~NFC_V2_CONFIG1_ECC_MODE_4;
120         else
121                 config1 |= NFC_V2_CONFIG1_ECC_MODE_4;
122         writenfc(config1, &nfc->config1);
123 #elif defined(MXC_NFC_V1)
124         /* unlocking RAM Buff */
125         writenfc(0x2, &nfc->config);
126
127         /* hardware ECC checking and correct */
128         writenfc(NFC_V1_V2_CONFIG1_ECC_EN | NFC_V1_V2_CONFIG1_INT_MSK,
129                         &nfc->config1);
130 #endif
131 }
132
133 static void nfc_nand_command(unsigned short command)
134 {
135         writenfc(command, &nfc->flash_cmd);
136         writenfc(NFC_CMD, &nfc->operation);
137         nfc_wait_ready();
138 }
139
140 static void nfc_nand_address(unsigned short address)
141 {
142         writenfc(address, &nfc->flash_addr);
143         writenfc(NFC_ADDR, &nfc->operation);
144         nfc_wait_ready();
145 }
146
147 static void nfc_nand_page_address(unsigned int page_address)
148 {
149         unsigned int page_count;
150
151         nfc_nand_address(0x00);
152
153         /* code only for large page flash */
154         if (CONFIG_SYS_NAND_PAGE_SIZE > 512)
155                 nfc_nand_address(0x00);
156
157         page_count = CONFIG_SYS_NAND_SIZE / CONFIG_SYS_NAND_PAGE_SIZE;
158
159         if (page_address <= page_count) {
160                 page_count--; /* transform 0x01000000 to 0x00ffffff */
161                 do {
162                         nfc_nand_address(page_address & 0xff);
163                         page_address = page_address >> 8;
164                         page_count = page_count >> 8;
165                 } while (page_count);
166         }
167
168         nfc_nand_address(0x00);
169 }
170
171 static void nfc_nand_data_output(void)
172 {
173 #ifdef NAND_MXC_2K_MULTI_CYCLE
174         int i;
175 #endif
176
177 #if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
178         writenfc(0, &nfc->buf_addr);
179 #elif defined(MXC_NFC_V3_2)
180         int config1 = readnfc(&nfc->config1);
181         config1 &= ~NFC_V3_CONFIG1_RBA_MASK;
182         writenfc(config1, &nfc->config1);
183 #endif
184         writenfc(NFC_OUTPUT, &nfc->operation);
185         nfc_wait_ready();
186 #ifdef NAND_MXC_2K_MULTI_CYCLE
187         /*
188          * This NAND controller requires multiple input commands
189          * for pages larger than 512 bytes.
190          */
191         for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) {
192                 writenfc(i, &nfc->buf_addr);
193                 writenfc(NFC_OUTPUT, &nfc->operation);
194                 nfc_wait_ready();
195         }
196 #endif
197 }
198
199 static int nfc_nand_check_ecc(void)
200 {
201 #if defined(MXC_NFC_V1)
202         u16 ecc_status = readw(&nfc->ecc_status_result);
203         return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2;
204 #elif defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
205         u32 ecc_status = readl(&nfc->ecc_status_result);
206         int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
207         int err_limit = CONFIG_SYS_NAND_OOBSIZE / ecc_per_page > 16 ? 8 : 4;
208         int subpages = CONFIG_SYS_NAND_PAGE_SIZE / 512;
209
210         do {
211                 if ((ecc_status & 0xf) > err_limit)
212                         return 1;
213                 ecc_status >>= 4;
214         } while (--subpages);
215
216         return 0;
217 #endif
218 }
219
220 static void nfc_nand_read_page(unsigned int page_address)
221 {
222         /* read in first 0 buffer */
223 #if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
224         writenfc(0, &nfc->buf_addr);
225 #elif defined(MXC_NFC_V3_2)
226         int config1 = readnfc(&nfc->config1);
227         config1 &= ~NFC_V3_CONFIG1_RBA_MASK;
228         writenfc(config1, &nfc->config1);
229 #endif
230         nfc_nand_command(NAND_CMD_READ0);
231         nfc_nand_page_address(page_address);
232
233         if (CONFIG_SYS_NAND_PAGE_SIZE > 512)
234                 nfc_nand_command(NAND_CMD_READSTART);
235
236         nfc_nand_data_output(); /* fill the main buffer 0 */
237 }
238
239 static int nfc_read_page(unsigned int page_address, unsigned char *buf)
240 {
241         int i;
242         u32 *src;
243         u32 *dst;
244
245         nfc_nand_read_page(page_address);
246
247         if (nfc_nand_check_ecc())
248                 return -1;
249
250         src = (u32 *)&nfc->main_area[0][0];
251         dst = (u32 *)buf;
252
253         /* main copy loop from NAND-buffer to SDRAM memory */
254         for (i = 0; i < CONFIG_SYS_NAND_PAGE_SIZE / 4; i++) {
255                 writel(readl(src), dst);
256                 src++;
257                 dst++;
258         }
259
260         return 0;
261 }
262
263 static int is_badblock(int pagenumber)
264 {
265         int page = pagenumber;
266         u32 badblock;
267         u32 *src;
268
269         /* Check the first two pages for bad block markers */
270         for (page = pagenumber; page < pagenumber + 2; page++) {
271                 nfc_nand_read_page(page);
272
273                 src = (u32 *)&nfc->spare_area[0][0];
274
275                 /*
276                  * IMPORTANT NOTE: The nand flash controller uses a non-
277                  * standard layout for large page devices. This can
278                  * affect the position of the bad block marker.
279                  */
280                 /* Get the bad block marker */
281                 badblock = readl(&src[CONFIG_SYS_NAND_BAD_BLOCK_POS / 4]);
282                 badblock >>= 8 * (CONFIG_SYS_NAND_BAD_BLOCK_POS % 4);
283                 badblock &= 0xff;
284
285                 /* bad block marker verify */
286                 if (badblock != 0xff)
287                         return 1; /* potential bad block */
288         }
289
290         return 0;
291 }
292
293 int nand_spl_load_image(uint32_t from, unsigned int size, void *buf)
294 {
295         int i;
296         unsigned int page;
297         unsigned int maxpages = CONFIG_SYS_NAND_SIZE /
298                                 CONFIG_SYS_NAND_PAGE_SIZE;
299
300         nfc_nand_init();
301
302         /* Convert to page number */
303         page = from / CONFIG_SYS_NAND_PAGE_SIZE;
304         i = 0;
305
306         size = roundup(size, CONFIG_SYS_NAND_PAGE_SIZE);
307         while (i < size / CONFIG_SYS_NAND_PAGE_SIZE) {
308                 if (nfc_read_page(page, buf) < 0)
309                         return -1;
310
311                 page++;
312                 i++;
313                 buf = buf + CONFIG_SYS_NAND_PAGE_SIZE;
314
315                 /*
316                  * Check if we have crossed a block boundary, and if so
317                  * check for bad block.
318                  */
319                 if (!(page % CONFIG_SYS_NAND_PAGE_COUNT)) {
320                         /*
321                          * Yes, new block. See if this block is good. If not,
322                          * loop until we find a good block.
323                          */
324                         while (is_badblock(page)) {
325                                 page = page + CONFIG_SYS_NAND_PAGE_COUNT;
326                                 /* Check i we've reached the end of flash. */
327                                 if (page >= maxpages)
328                                         return -1;
329                         }
330                 }
331         }
332
333         return 0;
334 }
335
336 #ifndef CONFIG_SPL_FRAMEWORK
337 /*
338  * The main entry for NAND booting. It's necessary that SDRAM is already
339  * configured and available since this code loads the main U-Boot image
340  * from NAND into SDRAM and starts it from there.
341  */
342 void nand_boot(void)
343 {
344         __attribute__((noreturn)) void (*uboot)(void);
345
346         /*
347          * CONFIG_SYS_NAND_U_BOOT_OFFS and CONFIG_SYS_NAND_U_BOOT_SIZE must
348          * be aligned to full pages
349          */
350         if (!nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
351                         CONFIG_SYS_NAND_U_BOOT_SIZE,
352                         (uchar *)CONFIG_SYS_NAND_U_BOOT_DST)) {
353                 /* Copy from NAND successful, start U-boot */
354                 uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
355                 uboot();
356         } else {
357                 /* Unrecoverable error when copying from NAND */
358                 hang();
359         }
360 }
361 #endif
362
363 void nand_init(void) {}
364 void nand_deselect(void) {}