]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/nand/am33xx_nand.c
Merge remote branch 'remotes/origin/karo-tx53' into karo-tx51
[karo-tx-uboot.git] / drivers / mtd / nand / am33xx_nand.c
1 /*
2  * (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
3  * based on ti81xx_nand.c
4  * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
5  * Mansoor Ahamed <mansoor.ahamed@ti.com>
6  *
7  * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27 #include <common.h>
28 #include <asm/io.h>
29 #include <asm/errno.h>
30 #include <asm/arch/cpu.h>
31 #include <asm/arch/mem.h>
32 #include <asm/arch/nand.h>
33 #include <linux/mtd/nand_ecc.h>
34 #include <nand.h>
35
36 struct nand_bch_priv {
37         uint8_t type;
38         uint8_t nibbles;
39 };
40
41 /* bch types */
42 #define ECC_BCH4        0
43 #define ECC_BCH8        1
44 #define ECC_BCH16       2
45
46 /* BCH nibbles for diff bch levels */
47 #define ECC_BCH4_NIBBLES        13
48 #define ECC_BCH8_NIBBLES        26
49 #define ECC_BCH16_NIBBLES       52
50
51 static uint8_t cs;
52 #ifndef CONFIG_SPL_BUILD
53 static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT_KERNEL;
54 static struct nand_ecclayout hw_bch4_nand_oob = GPMC_NAND_HW_BCH4_ECC_LAYOUT;
55 static struct nand_ecclayout hw_bch16_nand_oob = GPMC_NAND_HW_BCH16_ECC_LAYOUT;
56 #endif
57 static struct nand_ecclayout hw_bch8_nand_oob = GPMC_NAND_HW_BCH8_ECC_LAYOUT;
58
59 static struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
60
61 static struct nand_bch_priv bch_priv = {
62         .type = ECC_BCH8,
63         .nibbles = ECC_BCH8_NIBBLES
64 };
65
66 /*
67  * am33xx_read_bch8_result - Read BCH result for BCH8 level
68  *
69  * @mtd:        MTD device structure
70  * @big_endian: When set read register 3 first
71  * @ecc_code:   Read syndrome from BCH result registers
72  */
73 static void am33xx_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
74                                 uint8_t *ecc_code)
75 {
76         uint32_t *ptr;
77         int8_t i = 0, j;
78
79         if (big_endian) {
80                 ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
81                 ecc_code[i++] = readl(ptr) & 0xFF;
82                 ptr--;
83                 for (j = 0; j < 3; j++) {
84                         ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
85                         ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
86                         ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
87                         ecc_code[i++] = readl(ptr) & 0xFF;
88                         ptr--;
89                 }
90         }
91         else {
92                 ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[0];
93                 for (j = 0; j < 3; j++) {
94                         ecc_code[i++] = readl(ptr) & 0xFF;
95                         ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
96                         ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
97                         ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
98                         ptr++;
99                 }
100                 ecc_code[i++] = readl(ptr) & 0xFF;
101         }
102 }
103
104 /*
105  * am33xx_ecc_disable - Disable H/W ECC calculation
106  *
107  * @mtd:        MTD device structure
108  *
109  */
110 static void am33xx_ecc_disable(struct mtd_info *mtd) {
111
112         writel((readl(&gpmc_cfg->ecc_config) & ~0x1),
113                 &gpmc_cfg->ecc_config);
114 }
115
116 #if 0
117 /*
118  * am33xx_ecc_enable_bch - Enable BCH H/W ECC calculation
119  *
120  * @mtd:        MTD device structure
121  *
122  */
123 static void am33xx_ecc_enable_bch(struct mtd_info *mtd) {
124         uint32_t val;
125
126         val = readl(&gpmc_cfg->ecc_control);
127         val |= 0x00000100u;
128         writel(val, &gpmc_cfg->ecc_control); /* clear ECC outputs */
129
130         val = readl(&gpmc_cfg->ecc_control);
131         val &= ~0xF;
132         val |= 0x1;
133         writel(val, &gpmc_cfg->ecc_control);  /* reset ecc pointer to result 1 */
134
135         val = readl(&gpmc_cfg->ecc_config);
136         val |= 0x1;
137         writel(val, &gpmc_cfg->ecc_config); /* enable ecc */
138 }
139 #endif
140
141 /*
142  * am33xx_nand_hwcontrol - Set the address pointers correctly for the
143  *                      following address/data/command operation
144  */
145 static void am33xx_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
146                                 uint32_t ctrl)
147 {
148         register struct nand_chip *this = mtd->priv;
149
150         /*
151          * Point the IO_ADDR to DATA and ADDRESS registers instead
152          * of chip address
153          */
154         switch (ctrl) {
155         case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
156                 this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
157                 break;
158         case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
159                 this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
160                 break;
161         case NAND_CTRL_CHANGE | NAND_NCE:
162                 this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
163         }
164
165         if (cmd != NAND_CMD_NONE)
166                 writeb(cmd, this->IO_ADDR_W);
167 }
168
169 /*
170  * am33xx_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
171  *                              GPMC controller
172  * @mtd:       MTD device structure
173  * @mode:       Read/Write mode
174  */
175 static void am33xx_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
176 {
177         uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
178         uint32_t unused_length = 0;
179         struct nand_bch_priv *bch = chip->priv;
180
181         switch(bch->nibbles) {
182                 case ECC_BCH4_NIBBLES:
183                         unused_length = 3;
184                         break;
185                 case ECC_BCH8_NIBBLES:
186                         unused_length = 2;
187                         break;
188                 case ECC_BCH16_NIBBLES:
189                         unused_length = 0;
190         }
191
192         /* Clear the ecc result registers, select ecc reg as 1 */
193         writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
194
195         switch (mode) {
196                 case NAND_ECC_WRITE:
197                         /* eccsize1 config */
198                         val = ((unused_length + bch->nibbles) << 22);
199                         break;
200
201                 case NAND_ECC_READ:
202                 default:
203                         /* by default eccsize0 selected for ecc1resultsize */
204                         /* eccsize0 config */
205                         val  = (bch->nibbles << 12);
206                         /* eccsize1 config */
207                         val |= (unused_length << 22);
208         }
209         /* ecc size configuration */
210         writel(val, &gpmc_cfg->ecc_size_config);
211         /* by default 512bytes sector page is selected */
212         /* set bch mode */
213         val  = (1 << 16);
214         /* bch4 / bch8 / bch16 */
215         val |= (bch->type << 12);
216         /* set wrap mode to 1 */
217         val |= (1 << 8);
218         val |= (dev_width << 7);
219         val |= (cs << 1);
220         /* enable ecc */
221         /* val |= (1); */ /* should not enable ECC just init i.e. config */
222         writel(val, &gpmc_cfg->ecc_config);
223 }
224
225
226 #ifndef CONFIG_SPL_BUILD
227 /*
228  * am33xx_hwecc_init - Initialize the Hardware ECC for NAND flash in
229  *                   GPMC controller
230  * @mtd:        MTD device structure
231  *
232  */
233 static void am33xx_hwecc_init(struct nand_chip *chip)
234 {
235         /*
236          * Init ECC Control Register
237          * Clear all ECC | Enable Reg1
238          */
239         writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
240         writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL, &gpmc_cfg->ecc_size_config);
241 }
242
243 /*
244  * gen_true_ecc - This function will generate true ECC value, which
245  * can be used when correcting data read from NAND flash memory core
246  *
247  * @ecc_buf:    buffer to store ecc code
248  *
249  * @return:     re-formatted ECC value
250  */
251 static uint32_t gen_true_ecc(uint8_t *ecc_buf)
252 {
253         return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
254                 ((ecc_buf[2] & 0x0F) << 8);
255 }
256 #endif
257
258 /*
259  * am33xx_rotate_ecc_bch - Rotate the syndrome bytes
260  *
261  * @mtd:        MTD device structure
262  * @calc_ecc:   ECC read from ECC registers
263  * @syndrome:   Rotated syndrome will be retuned in this array
264  *
265  */
266 static void am33xx_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
267                 uint8_t *syndrome)
268 {
269         struct nand_chip *chip = mtd->priv;
270         struct nand_bch_priv *bch = chip->priv;
271         uint8_t n_bytes = 0;
272         int8_t i,j;
273
274         switch(bch->type) {
275                 case ECC_BCH4:
276                         n_bytes = 8;
277                         break;
278
279                 case ECC_BCH16:
280                         n_bytes = 28;
281                         break;
282
283                 case ECC_BCH8:
284                 default:
285                         n_bytes = 13;
286         }
287
288         for (i = 0, j = (n_bytes-1); i < n_bytes; i++, j--)
289                 syndrome[i] =  calc_ecc[j];
290 }
291
292
293 /*
294  * am33xx_fix_errors_bch - Correct bch error in the data
295  *
296  * @mtd:        MTD device structure
297  * @data:       Data read from flash
298  * @error_count:Number of errors in data
299  * @error_loc:  Locations of errors in the data
300  *
301  */
302 static void am33xx_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
303                 uint32_t error_count, uint32_t *error_loc)
304 {
305         struct nand_chip *chip = mtd->priv;
306         struct nand_bch_priv *bch = chip->priv;
307         uint8_t count = 0;
308         uint32_t error_byte_pos;
309         uint32_t error_bit_mask;
310         uint32_t last_bit = (bch->nibbles * 4) - 1;
311
312         /* Flip all bits as specified by the error location array. */
313         /* FOR( each found error location flip the bit ) */
314         for (count = 0; count < error_count; count++) {
315                 if (error_loc[count] > last_bit) {
316                         /* Remove the ECC spare bits from correction. */
317                         error_loc[count] -= (last_bit + 1);
318                         /* Offset bit in data region */
319                         error_byte_pos = ((512 * 8) - (error_loc[count]) - 1) / 8;
320                         /* Error Bit mask */
321                         error_bit_mask = 0x1 << (error_loc[count] % 8);
322                         /* Toggle the error bit to make the correction. */
323                         data[error_byte_pos] ^= error_bit_mask;
324                 }
325         }
326 }
327
328 /*
329  * am33xx_correct_data_bch - Compares the ecc read from nand spare area
330  * with ECC registers values and corrects one bit error if it has occured
331  *
332  * @mtd:        MTD device structure
333  * @dat:        page data
334  * @read_ecc:   ecc read from nand flash (ignored)
335  * @calc_ecc:   ecc read from ECC registers
336  *
337  * @return 0 if data is OK or corrected, else returns -1
338  */
339 static int am33xx_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
340                                 uint8_t *read_ecc, uint8_t *calc_ecc)
341 {
342         struct nand_chip *chip = mtd->priv;
343         struct nand_bch_priv *bch = chip->priv;
344         uint8_t syndrome[28];
345         uint32_t error_count = 0;
346         uint32_t error_loc[8];
347         uint32_t i, ecc_flag;
348
349         ecc_flag = 0;
350         for (i = 0; i < (chip->ecc.bytes - 1); i++)
351                 if (read_ecc[i] != 0xff)
352                         ecc_flag = 1;
353
354         if (!ecc_flag)
355                 return 0;
356
357         elm_reset();
358         elm_config(bch->type);
359
360         /* while reading ECC result we read it in big endian.
361          * Hence while loading to ELM we have rotate to get the right endian.
362          */
363         am33xx_rotate_ecc_bch(mtd, calc_ecc, syndrome);
364
365 #ifdef DEBUG
366         {
367                 uint8_t i = 0;
368
369                 printf("ecc: ");
370                 for (i = 0; i < 13; i++)
371                         printf(" 0x%02x", syndrome[i]);
372                 printf("\n");
373         }
374 #endif
375
376
377         /* use elm module to check for errors */
378         if (elm_check_error(syndrome, bch->nibbles, &error_count, error_loc) != 0) {
379 #ifndef CONFIG_SPL_BUILD
380                 /* This currently sees all pages as being completely full of
381                  * uncorrectable errors.  The suspicion is that this is due
382                  * to limitations in the elm support we have in U-Boot today
383                  */
384                 printf("ECC: uncorrectable.\n");
385 #endif
386                 return -1;
387         }
388
389         /* correct bch error */
390         if (error_count > 0) {
391                 am33xx_fix_errors_bch(mtd, dat, error_count, error_loc);
392         }
393
394         return 0;
395 }
396
397 #ifndef CONFIG_SPL_BUILD
398 /*
399  * am33xx_correct_data - Compares the ecc read from nand spare area with ECC
400  * registers values and corrects one bit error if it has occured
401  * Further details can be had from Am33xx TRM and the following selected links:
402  * http://en.wikipedia.org/wiki/Hamming_code
403  * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
404  *
405  * @mtd:                 MTD device structure
406  * @dat:                 page data
407  * @read_ecc:            ecc read from nand flash
408  * @calc_ecc:            ecc read from ECC registers
409  *
410  * @return 0 if data is OK or corrected, else returns -1
411  */
412 static int am33xx_correct_data(struct mtd_info *mtd, uint8_t *dat,
413                                 uint8_t *read_ecc, uint8_t *calc_ecc)
414 {
415         uint32_t orig_ecc, new_ecc, res, hm;
416         uint16_t parity_bits, byte;
417         uint8_t bit;
418
419         /* Regenerate the orginal ECC */
420         orig_ecc = gen_true_ecc(read_ecc);
421         new_ecc = gen_true_ecc(calc_ecc);
422         /* Get the XOR of real ecc */
423         res = orig_ecc ^ new_ecc;
424         if (res) {
425                 /* Get the hamming width */
426                 hm = hweight32(res);
427                 /* Single bit errors can be corrected! */
428                 if (hm == 12) {
429                         /* Correctable data! */
430                         parity_bits = res >> 16;
431                         bit = (parity_bits & 0x7);
432                         byte = (parity_bits >> 3) & 0x1FF;
433                         /* Flip the bit to correct */
434                         dat[byte] ^= (0x1 << bit);
435                 } else if (hm == 1) {
436                         printf("am33xx_nand: Error: Corrupted ECC\n");
437                         /* ECC itself is corrupted */
438                         return 2;
439                 } else {
440                         /*
441                          * hm distance != parity pairs OR one, could mean 2 bit
442                          * error OR potentially be on a blank page..
443                          * orig_ecc: contains spare area data from nand flash.
444                          * new_ecc: generated ecc while reading data area.
445                          * Note: if the ecc = 0, all data bits from which it was
446                          * generated are 0xFF.
447                          * The 3 byte(24 bits) ecc is generated per 512byte
448                          * chunk of a page. If orig_ecc(from spare area)
449                          * is 0xFF && new_ecc(computed now from data area)=0x0,
450                          * this means that data area is 0xFF and spare area is
451                          * 0xFF. A sure sign of an erased page!
452                          */
453                         if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
454                                 return 0;
455                         printf("am33xx_nand: Error: Multibit error detected; hm=%d\n",
456                                 hm);
457                         /* detected 2 bit error */
458                         return -1;
459                 }
460         }
461         return 0;
462 }
463 #endif
464
465 /*
466  *  am33xx_calculate_ecc_bch - Read BCH ECC result
467  *
468  *  @mtd:       MTD structure
469  *  @dat:       unused
470  *  @ecc_code:  ecc_code buffer
471  */
472 static int am33xx_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
473                                 uint8_t *ecc_code)
474 {
475         struct nand_chip *chip = mtd->priv;
476         struct nand_bch_priv *bch = chip->priv;
477         uint8_t big_endian = 1;
478         int8_t ret = 0;
479
480         if (bch->type == ECC_BCH8)
481                 am33xx_read_bch8_result(mtd, big_endian, ecc_code);
482         else /* BCH4 and BCH16 currently not supported */
483                 ret = -1;
484
485 #ifdef DEBUG
486         {
487                 int8_t i = 0;
488
489                 printf("ECC: ");
490                 for (i = 0; i < 13; i++)
491                         printf(" 0x%02x", ecc_code[i]);
492                 printf("\n");
493         }
494 #endif
495
496         /*
497          * Stop reading anymore ECC vals and clear old results
498          * enable will be called if more reads are required
499          */
500         am33xx_ecc_disable(mtd);
501
502         return ret;
503 }
504
505 #ifndef CONFIG_SPL_BUILD
506 /*
507  *  am33xx_calculate_ecc - Generate non-inverted ECC bytes.
508  *
509  *  Using noninverted ECC can be considered ugly since writing a blank
510  *  page ie. padding will clear the ECC bytes. This is no problem as
511  *  long nobody is trying to write data on the seemingly unused page.
512  *  Reading an erased page will produce an ECC mismatch between
513  *  generated and read ECC bytes that has to be dealt with separately.
514  *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
515  *  is used, the result of read will be 0x0 while the ECC offsets of the
516  *  spare area will be 0xFF which will result in an ECC mismatch.
517  *  @mtd:       MTD structure
518  *  @dat:       unused
519  *  @ecc_code:  ecc_code buffer
520  */
521 static int am33xx_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
522                                 uint8_t *ecc_code)
523 {
524         u_int32_t val;
525
526         /* Start Reading from HW ECC1_Result = 0x200 */
527         val = readl(&gpmc_cfg->ecc1_result);
528
529         ecc_code[0] = val & 0xFF;
530         ecc_code[1] = (val >> 16) & 0xFF;
531         ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
532
533         /*
534          * Stop reading anymore ECC vals and clear old results
535          * enable will be called if more reads are required
536          */
537         writel(0x000, &gpmc_cfg->ecc_config);
538
539         return 0;
540 }
541
542 /**
543  * am33xx_write_page_bch - [REPLACABLE] hardware ecc based page write function
544  * @mtd:        mtd info structure
545  * @chip:       nand chip info structure
546  * @buf:        data buffer
547  */
548 static void am33xx_write_page_bch(struct mtd_info *mtd,
549         struct nand_chip *chip, const uint8_t *buf)
550 {
551         int i, eccsize = chip->ecc.size;
552         int eccbytes = chip->ecc.bytes;
553         int eccsteps = chip->ecc.steps;
554         uint8_t *ecc_calc = chip->buffers->ecccalc;
555         const uint8_t *p = buf;
556         uint32_t *eccpos = chip->ecc.layout->eccpos;
557
558         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
559                 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
560                 chip->write_buf(mtd, p, eccsize);
561                 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
562         }
563
564         for (i = 0; i < chip->ecc.total; i++)
565                 chip->oob_poi[eccpos[i]] = ecc_calc[i];
566
567         chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
568 }
569
570
571 /**
572  * am33xx_read_page_bch - hardware ecc based page read function
573  * @mtd:        mtd info structure
574  * @chip:       nand chip info structure
575  * @buf:        buffer to store read data
576  * @page:       page number to read
577  *
578  */
579 static int am33xx_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
580                                 uint8_t *buf, int page)
581 {
582         int i, eccsize = chip->ecc.size;
583         int eccbytes = chip->ecc.bytes;
584         int eccsteps = chip->ecc.steps;
585         uint8_t *p = buf;
586         uint8_t *ecc_calc = chip->buffers->ecccalc;
587         uint8_t *ecc_code = chip->buffers->ecccode;
588         uint32_t *eccpos = chip->ecc.layout->eccpos;
589         uint8_t *oob = chip->oob_poi;
590         uint32_t data_pos;
591         uint32_t oob_pos;
592
593         data_pos = 0;
594         /* oob area start */
595         oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
596         //oob_pos = (eccsize * eccsteps) + 2;
597
598         for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
599                                 oob += eccbytes) {
600                 chip->ecc.hwctl(mtd, NAND_ECC_READ);
601                 /* read data */
602                 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
603                 chip->read_buf(mtd, p, eccsize);
604 #ifdef DEBUG
605                 {
606                         uint32_t j;
607
608                         printf("DATA: ");
609                         for (j = 0; j < 13; j++)
610                                 printf(" 0x%02x", p[j]);
611                         printf("\n");
612                 }
613 #endif
614
615                 /* read respective ecc from oob area */
616                 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
617                 chip->read_buf(mtd, oob, eccbytes);
618 #ifdef DEBUG
619                 {
620                         uint32_t j;
621
622                         printf("OOB:  ");
623                         for (j = 0; j < 13; j++)
624                                 printf(" 0x%02x", oob[j]);
625                         printf("\n");
626                 }
627 #endif
628                 /* read syndrome */
629                 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
630
631                 data_pos += eccsize;
632                 oob_pos += eccbytes;
633         }
634
635         for (i = 0; i < chip->ecc.total; i++)
636                 ecc_code[i] = chip->oob_poi[eccpos[i]];
637
638         eccsteps = chip->ecc.steps;
639         p = buf;
640
641         for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
642                 int stat;
643
644                 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
645                 if (stat < 0) {
646                         printf("am33xx_nand: uncorrectable ECC error in page %5d\n",
647                                 page);
648                         mtd->ecc_stats.failed++;
649                 } else {
650                         mtd->ecc_stats.corrected += stat;
651                 }
652         }
653         return 0;
654 }
655 #endif
656
657 /*
658  * am33xx_enable_ecc_bch- This function enables the bch h/w ecc functionality
659  * @mtd:        MTD device structure
660  * @mode:       Read/Write mode
661  *
662  */
663 static void am33xx_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
664 {
665         struct nand_chip *chip = mtd->priv;
666
667         am33xx_hwecc_init_bch(chip, mode);
668         /* enable ecc */
669         writel(readl(&gpmc_cfg->ecc_config) | 0x1, &gpmc_cfg->ecc_config);
670 }
671
672 #ifndef CONFIG_SPL_BUILD
673 /*
674  * am33xx_enable_ecc - This function enables the hardware ecc functionality
675  * @mtd:        MTD device structure
676  * @mode:       Read/Write mode
677  */
678 static void am33xx_enable_ecc(struct mtd_info *mtd, int32_t mode)
679 {
680         struct nand_chip *chip = mtd->priv;
681         uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
682
683         switch (mode) {
684         case NAND_ECC_READ:
685         case NAND_ECC_WRITE:
686                 /* Clear the ecc result registers, select ecc reg as 1 */
687                 writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
688
689                 /*
690                  * Size 0 = 0xFF, Size1 is 0xFF - both are 512 bytes
691                  * tell all regs to generate size0 sized regs
692                  * we just have a single ECC engine for all CS
693                  */
694                 writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL,
695                         &gpmc_cfg->ecc_size_config);
696                 val = (dev_width << 7) | (cs << 1) | (0x1);
697                 writel(val, &gpmc_cfg->ecc_config);
698                 break;
699         default:
700                 printf("Error: Unrecognized Mode[%d]!\n", mode);
701         }
702 }
703
704 /*
705  * __am33xx_nand_switch_ecc - switch the ECC operation ib/w h/w ecc
706  * (i.e. hamming / bch) and s/w ecc.
707  * The default is to come up on s/w ecc
708  *
709  * @nand:       NAND chip datastructure
710  * @hardware:  NAND_ECC_HW -switch to h/w ecc
711  *                              NAND_ECC_SOFT -switch to s/w ecc
712  *
713  * @mode:       0 - hamming code
714  *              1 - bch4
715  *              2 - bch8
716  *              3 - bch16
717  */
718 void __am33xx_nand_switch_ecc(struct nand_chip *nand,
719                 nand_ecc_modes_t hardware, int32_t mode)
720 {
721         struct nand_bch_priv *bch;
722
723         debug("switching ECC mode to %d %d\n", hardware, mode);
724
725         bch = nand->priv;
726         nand->options |= NAND_OWN_BUFFERS;
727
728         /* Reset ecc interface */
729         nand->ecc.read_page = NULL;
730         nand->ecc.write_page = NULL;
731         nand->ecc.read_oob = NULL;
732         nand->ecc.write_oob = NULL;
733         nand->ecc.hwctl = NULL;
734         nand->ecc.correct = NULL;
735         nand->ecc.calculate = NULL;
736
737         nand->ecc.mode = hardware;
738         /* Setup the ecc configurations again */
739         if (hardware == NAND_ECC_HW) {
740                 if (mode) {
741                         /* -1 for converting mode to bch type */
742                         bch->type = mode - 1;
743                         debug("HW ECC BCH");
744                         switch (bch->type) {
745                                 case ECC_BCH4:
746                                         nand->ecc.layout = &hw_bch4_nand_oob;
747                                         bch->nibbles = ECC_BCH4_NIBBLES;
748                                         nand->ecc.bytes = 8;
749                                         debug("4 not supported\n");
750                                         return;
751
752                                 case ECC_BCH16:
753                                         nand->ecc.bytes = 26;
754                                         nand->ecc.layout = &hw_bch16_nand_oob;
755                                         bch->nibbles = ECC_BCH16_NIBBLES;
756                                         debug("16 not supported\n");
757                                         return;
758
759                                 case ECC_BCH8:
760                                 default:
761                                         nand->ecc.bytes = 14;
762                                         nand->ecc.layout = &hw_bch8_nand_oob;
763                                         bch->nibbles = ECC_BCH8_NIBBLES;
764                                         debug("8 Selected\n");
765                         }
766                         nand->ecc.mode = NAND_ECC_HW_SYNDROME;
767                         nand->ecc.steps = 4;
768                         nand->ecc.size = 512;
769                         nand->ecc.total = nand->ecc.steps * nand->ecc.bytes;
770                         nand->ecc.write_page = am33xx_write_page_bch;
771                         nand->ecc.read_page = am33xx_read_page_bch;
772                         nand->ecc.hwctl = am33xx_enable_ecc_bch;
773                         nand->ecc.correct = am33xx_correct_data_bch;
774                         nand->ecc.calculate = am33xx_calculate_ecc_bch;
775                         am33xx_hwecc_init_bch(nand, NAND_ECC_READ);
776                 } else {
777                         nand->ecc.layout = &hw_nand_oob;
778                         nand->ecc.size = 512;
779                         nand->ecc.bytes = 3;
780                         nand->ecc.hwctl = am33xx_enable_ecc;
781                         nand->ecc.correct = am33xx_correct_data;
782                         nand->ecc.calculate = am33xx_calculate_ecc;
783                         am33xx_hwecc_init(nand);
784                         debug("HW ECC Hamming Code selected\n");
785                 }
786         } else if (hardware == NAND_ECC_SOFT) {
787                 /* Use mtd default settings */
788                 nand->ecc.layout = NULL;
789                 debug("SW ECC selected\n");
790         } else {
791                 debug("ECC Disabled\n");
792         }
793 }
794
795 /*
796  * am33xx_nand_switch_ecc - switch the ECC operation ib/w h/w ecc
797  * (i.e. hamming / bch) and s/w ecc.
798  * The default is to come up on s/w ecc
799  *
800  * @hardware -  NAND_ECC_HW -switch to h/w ecc
801  *                              NAND_ECC_SOFT -switch to s/w ecc
802  *
803  * @mode -      0 - hamming code
804  *              1 - bch4
805  *              2 - bch8
806  *              3 - bch16
807  */
808 void am33xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode)
809 {
810         struct nand_chip *nand;
811         struct mtd_info *mtd;
812
813         if (nand_curr_device < 0 ||
814             nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE) {
815                 printf("Error: Can't switch ecc, no devices available\n");
816                 return;
817         }
818
819         mtd = &nand_info[nand_curr_device];
820         nand = mtd->priv;
821
822         __am33xx_nand_switch_ecc(nand, hardware, mode);
823
824         /* Update NAND handling after ECC mode switch */
825         nand_scan_tail(mtd);
826
827         nand->options &= ~NAND_OWN_BUFFERS;
828         return;
829 }
830
831 static int am33xx_scan_bbt(struct mtd_info *mtd)
832 {
833         int ret;
834
835         am33xx_nand_switch_ecc(NAND_ECC_HW, 0);
836         ret = nand_default_bbt(mtd);
837         am33xx_nand_switch_ecc(NAND_ECC_HW, 2);
838         return ret;
839 }
840 #else /* CONFIG_SPL_BUILD */
841 /* Check wait pin as dev ready indicator */
842 static int am33xx_spl_dev_ready(struct mtd_info *mtd)
843 {
844         return gpmc_cfg->status & (1 << 8);
845 }
846
847 static int am33xx_scan_bbt(struct mtd_info *mtd)
848 {
849         return 0;
850 }
851 #endif
852
853 /*
854  * Board-specific NAND initialization. The following members of the
855  * argument are board-specific:
856  * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
857  * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
858  * - cmd_ctrl: hardwarespecific function for accesing control-lines
859  * - waitfunc: hardwarespecific function for accesing device ready/busy line
860  * - ecc.hwctl: function to enable (reset) hardware ecc generator
861  * - ecc.mode: mode of ecc, see defines
862  * - chip_delay: chip dependent delay for transfering data from array to
863  *   read regs (tR)
864  * - options: various chip options. They can partly be set to inform
865  *   nand_scan about special functionality. See the defines for further
866  *   explanation
867  */
868 int board_nand_init(struct nand_chip *nand)
869 {
870         /* int32_t gpmc_config = 0; */
871         cs = 0;
872
873         /*
874          * xloader/Uboot's gpmc configuration would have configured GPMC for
875          * nand type of memory. The following logic scans and latches on to the
876          * first CS with NAND type memory.
877          * TBD: need to make this logic generic to handle multiple CS NAND
878          * devices.
879          */
880         while (cs < GPMC_MAX_CS) {
881                 /* Check if NAND type is set */
882                 if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
883                         /* Found it!! */
884                         debug("Searching for NAND device @ GPMC CS:%d\n", cs);
885                         break;
886                 }
887                 cs++;
888         }
889         if (cs >= GPMC_MAX_CS) {
890                 printf("NAND: Unable to find NAND settings in "
891                         "GPMC Configuration - quitting\n");
892                 return -ENODEV;
893         }
894
895         nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
896         nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
897
898         nand->cmd_ctrl = am33xx_nand_hwcontrol;
899         nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR;
900         nand->scan_bbt = am33xx_scan_bbt;
901
902         /* If we are 16 bit dev, our gpmc config tells us that */
903         if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000) {
904                 nand->options |= NAND_BUSWIDTH_16;
905         }
906
907         nand->chip_delay = 100;
908
909         /* required in case of BCH */
910         elm_init();
911
912         /* BCH info that will be correct for SPL or overridden otherwise. */
913         nand->priv = &bch_priv;
914
915 #ifndef CONFIG_SPL_BUILD
916         /* For undocumented reasons we need to currently keep our environment
917          * in 1-bit ECC so we configure ourself thusly. */
918         nand_curr_device = 0;
919         am33xx_nand_switch_ecc(NAND_ECC_HW, 2);
920 #else
921         /* The NAND chip present requires that we have written data in with
922          * at least 4-bit ECC so we configure outself for that in SPL.
923          */
924         nand->ecc.mode = NAND_ECC_HW_SYNDROME;
925         nand->ecc.layout = &hw_bch8_nand_oob;
926         nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
927         nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
928         nand->ecc.steps = CONFIG_SYS_NAND_ECCSTEPS;
929         nand->ecc.total = CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS;
930         nand->ecc.hwctl = am33xx_enable_ecc_bch;
931         nand->ecc.correct = am33xx_correct_data_bch;
932         nand->ecc.calculate = am33xx_calculate_ecc_bch;
933
934 #if 1
935         if (nand->options & NAND_BUSWIDTH_16)
936                 nand->read_buf = nand_read_buf16;
937         else
938                 nand->read_buf = nand_read_buf;
939 #else
940         nand_scan_ident(&nand_info[nand_curr_device], 1, NULL);
941 #endif
942         nand->dev_ready = am33xx_spl_dev_ready;
943
944         am33xx_hwecc_init_bch(nand, NAND_ECC_READ);
945 #endif
946
947         return 0;
948 }