2 * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
3 * Rohit Choraria <rohitkc@ti.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/errno.h>
11 #include <asm/arch/mem.h>
12 #include <linux/mtd/omap_gpmc.h>
13 #include <linux/mtd/nand_ecc.h>
14 #include <linux/bch.h>
15 #include <linux/compiler.h>
17 #include <linux/mtd/omap_elm.h>
19 #define BADBLOCK_MARKER_LENGTH 2
20 #define SECTOR_BYTES 512
21 #define ECCCLEAR (0x1 << 8)
22 #define ECCRESULTREG1 (0x1 << 0)
23 /* 4 bit padding to make byte aligned, 56 = 52 + 4 */
24 #define BCH4_BIT_PAD 4
27 static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
28 0x97, 0x79, 0xe5, 0x24, 0xb5};
30 static uint8_t cs_next;
31 static __maybe_unused struct nand_ecclayout omap_ecclayout;
34 * Driver configurations
36 struct omap_nand_info {
37 struct bch_control *control;
38 enum omap_ecc ecc_scheme;
42 /* We are wasting a bit of memory but al least we are safe */
43 static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
46 * omap_nand_hwcontrol - Set the address pointers corretly for the
47 * following address/data/command operation
49 static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
52 register struct nand_chip *this = mtd->priv;
53 struct omap_nand_info *info = this->priv;
57 * Point the IO_ADDR to DATA and ADDRESS registers instead
61 case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
62 this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
64 case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
65 this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
67 case NAND_CTRL_CHANGE | NAND_NCE:
68 this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
72 if (cmd != NAND_CMD_NONE)
73 writeb(cmd, this->IO_ADDR_W);
76 /* Check wait pin as dev ready indicator */
77 static int omap_dev_ready(struct mtd_info *mtd)
79 return gpmc_cfg->status & (1 << 8);
83 * gen_true_ecc - This function will generate true ECC value, which
84 * can be used when correcting data read from NAND flash memory core
86 * @ecc_buf: buffer to store ecc code
88 * @return: re-formatted ECC value
90 static uint32_t gen_true_ecc(uint8_t *ecc_buf)
92 return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
93 ((ecc_buf[2] & 0x0F) << 8);
97 * omap_correct_data - Compares the ecc read from nand spare area with ECC
98 * registers values and corrects one bit error if it has occured
99 * Further details can be had from OMAP TRM and the following selected links:
100 * http://en.wikipedia.org/wiki/Hamming_code
101 * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
103 * @mtd: MTD device structure
105 * @read_ecc: ecc read from nand flash
106 * @calc_ecc: ecc read from ECC registers
108 * @return 0 if data is OK or corrected, else returns -1
110 static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
111 uint8_t *read_ecc, uint8_t *calc_ecc)
113 uint32_t orig_ecc, new_ecc, res, hm;
114 uint16_t parity_bits, byte;
117 /* Regenerate the orginal ECC */
118 orig_ecc = gen_true_ecc(read_ecc);
119 new_ecc = gen_true_ecc(calc_ecc);
120 /* Get the XOR of real ecc */
121 res = orig_ecc ^ new_ecc;
123 /* Get the hamming width */
125 /* Single bit errors can be corrected! */
127 /* Correctable data! */
128 parity_bits = res >> 16;
129 bit = (parity_bits & 0x7);
130 byte = (parity_bits >> 3) & 0x1FF;
131 /* Flip the bit to correct */
132 dat[byte] ^= (0x1 << bit);
133 } else if (hm == 1) {
134 printf("Error: Ecc is wrong\n");
135 /* ECC itself is corrupted */
139 * hm distance != parity pairs OR one, could mean 2 bit
140 * error OR potentially be on a blank page..
141 * orig_ecc: contains spare area data from nand flash.
142 * new_ecc: generated ecc while reading data area.
143 * Note: if the ecc = 0, all data bits from which it was
144 * generated are 0xFF.
145 * The 3 byte(24 bits) ecc is generated per 512byte
146 * chunk of a page. If orig_ecc(from spare area)
147 * is 0xFF && new_ecc(computed now from data area)=0x0,
148 * this means that data area is 0xFF and spare area is
149 * 0xFF. A sure sign of a erased page!
151 if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
153 printf("Error: Bad compare! failed\n");
154 /* detected 2 bit error */
162 * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
163 * @mtd: MTD device structure
164 * @mode: Read/Write mode
167 static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
169 struct nand_chip *nand = mtd->priv;
170 struct omap_nand_info *info = nand->priv;
171 unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
172 unsigned int ecc_algo = 0;
173 unsigned int bch_type = 0;
174 unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
175 u32 ecc_size_config_val = 0;
176 u32 ecc_config_val = 0;
179 /* configure GPMC for specific ecc-scheme */
180 switch (info->ecc_scheme) {
181 case OMAP_ECC_HAM1_CODE_SW:
183 case OMAP_ECC_HAM1_CODE_HW:
190 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
191 case OMAP_ECC_BCH8_CODE_HW:
194 if (mode == NAND_ECC_WRITE) {
196 eccsize0 = 0; /* extra bits in nibbles per sector */
197 eccsize1 = 28; /* OOB bits in nibbles per sector */
200 eccsize0 = 26; /* ECC bits in nibbles per sector */
201 eccsize1 = 2; /* non-ECC bits in nibbles per sector */
204 case OMAP_ECC_BCH16_CODE_HW:
207 if (mode == NAND_ECC_WRITE) {
209 eccsize0 = 0; /* extra bits in nibbles per sector */
210 eccsize1 = 52; /* OOB bits in nibbles per sector */
213 eccsize0 = 52; /* ECC bits in nibbles per sector */
214 eccsize1 = 0; /* non-ECC bits in nibbles per sector */
220 /* Clear ecc and enable bits */
221 writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
222 /* Configure ecc size for BCH */
223 ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
224 writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);
226 /* Configure device details for BCH engine */
227 ecc_config_val = ((ecc_algo << 16) | /* HAM1 | BCHx */
228 (bch_type << 12) | /* BCH4/BCH8/BCH16 */
229 (bch_wrapmode << 8) | /* wrap mode */
230 (dev_width << 7) | /* bus width */
231 (0x0 << 4) | /* number of sectors */
232 (cs << 1) | /* ECC CS */
233 (0x1)); /* enable ECC */
234 writel(ecc_config_val, &gpmc_cfg->ecc_config);
238 * omap_calculate_ecc - Read ECC result
239 * @mtd: MTD structure
241 * @ecc_code: ecc_code buffer
242 * Using noninverted ECC can be considered ugly since writing a blank
243 * page ie. padding will clear the ECC bytes. This is no problem as
244 * long nobody is trying to write data on the seemingly unused page.
245 * Reading an erased page will produce an ECC mismatch between
246 * generated and read ECC bytes that has to be dealt with separately.
247 * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
248 * is used, the result of read will be 0x0 while the ECC offsets of the
249 * spare area will be 0xFF which will result in an ECC mismatch.
251 static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
254 struct nand_chip *chip = mtd->priv;
255 struct omap_nand_info *info = chip->priv;
256 uint32_t *ptr, val = 0;
259 switch (info->ecc_scheme) {
260 case OMAP_ECC_HAM1_CODE_HW:
261 val = readl(&gpmc_cfg->ecc1_result);
262 ecc_code[0] = val & 0xFF;
263 ecc_code[1] = (val >> 16) & 0xFF;
264 ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
267 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
269 case OMAP_ECC_BCH8_CODE_HW:
270 ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
272 ecc_code[i++] = (val >> 0) & 0xFF;
274 for (j = 0; j < 3; j++) {
276 ecc_code[i++] = (val >> 24) & 0xFF;
277 ecc_code[i++] = (val >> 16) & 0xFF;
278 ecc_code[i++] = (val >> 8) & 0xFF;
279 ecc_code[i++] = (val >> 0) & 0xFF;
283 case OMAP_ECC_BCH16_CODE_HW:
284 val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[2]);
285 ecc_code[i++] = (val >> 8) & 0xFF;
286 ecc_code[i++] = (val >> 0) & 0xFF;
287 val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[1]);
288 ecc_code[i++] = (val >> 24) & 0xFF;
289 ecc_code[i++] = (val >> 16) & 0xFF;
290 ecc_code[i++] = (val >> 8) & 0xFF;
291 ecc_code[i++] = (val >> 0) & 0xFF;
292 val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[0]);
293 ecc_code[i++] = (val >> 24) & 0xFF;
294 ecc_code[i++] = (val >> 16) & 0xFF;
295 ecc_code[i++] = (val >> 8) & 0xFF;
296 ecc_code[i++] = (val >> 0) & 0xFF;
297 for (j = 3; j >= 0; j--) {
298 val = readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[j]
300 ecc_code[i++] = (val >> 24) & 0xFF;
301 ecc_code[i++] = (val >> 16) & 0xFF;
302 ecc_code[i++] = (val >> 8) & 0xFF;
303 ecc_code[i++] = (val >> 0) & 0xFF;
309 /* ECC scheme specific syndrome customizations */
310 switch (info->ecc_scheme) {
311 case OMAP_ECC_HAM1_CODE_HW:
314 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
316 for (i = 0; i < chip->ecc.bytes; i++)
317 *(ecc_code + i) = *(ecc_code + i) ^
321 case OMAP_ECC_BCH8_CODE_HW:
322 ecc_code[chip->ecc.bytes - 1] = 0x00;
324 case OMAP_ECC_BCH16_CODE_HW:
332 #ifdef CONFIG_NAND_OMAP_ELM
334 * omap_reverse_list - re-orders list elements in reverse order [internal]
335 * @list: pointer to start of list
336 * @length: length of list
338 static void omap_reverse_list(u8 *list, unsigned int length)
341 unsigned int half_length = length / 2;
343 for (i = 0, j = length - 1; i < half_length; i++, j--) {
351 * omap_correct_data_bch - Compares the ecc read from nand spare area
352 * with ECC registers values and corrects one bit error if it has occured
354 * @mtd: MTD device structure
356 * @read_ecc: ecc read from nand flash (ignored)
357 * @calc_ecc: ecc read from ECC registers
359 * @return 0 if data is OK or corrected, else returns -1
361 static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
362 uint8_t *read_ecc, uint8_t *calc_ecc)
364 struct nand_chip *chip = mtd->priv;
365 struct omap_nand_info *info = chip->priv;
366 struct nand_ecc_ctrl *ecc = &chip->ecc;
367 uint32_t error_count = 0, error_max;
368 uint32_t error_loc[ELM_MAX_ERROR_COUNT];
369 enum bch_level bch_type;
370 uint32_t i, ecc_flag = 0;
372 uint32_t byte_pos, bit_pos;
375 /* check calculated ecc */
376 for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
377 if (calc_ecc[i] != 0x00)
383 /* check for whether its a erased-page */
385 for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
386 if (read_ecc[i] != 0xff)
393 * while reading ECC result we read it in big endian.
394 * Hence while loading to ELM we have rotate to get the right endian.
396 switch (info->ecc_scheme) {
397 case OMAP_ECC_BCH8_CODE_HW:
398 bch_type = BCH_8_BIT;
399 omap_reverse_list(calc_ecc, ecc->bytes - 1);
401 case OMAP_ECC_BCH16_CODE_HW:
402 bch_type = BCH_16_BIT;
403 omap_reverse_list(calc_ecc, ecc->bytes);
408 /* use elm module to check for errors */
409 elm_config(bch_type);
410 err = elm_check_error(calc_ecc, bch_type, &error_count, error_loc);
414 /* correct bch error */
415 for (count = 0; count < error_count; count++) {
416 switch (info->ecc_scheme) {
417 case OMAP_ECC_BCH8_CODE_HW:
418 /* 14th byte in ECC is reserved to match ROM layout */
419 error_max = SECTOR_BYTES + (ecc->bytes - 1);
421 case OMAP_ECC_BCH16_CODE_HW:
422 error_max = SECTOR_BYTES + ecc->bytes;
427 byte_pos = error_max - (error_loc[count] / 8) - 1;
428 bit_pos = error_loc[count] % 8;
429 if (byte_pos < SECTOR_BYTES) {
430 dat[byte_pos] ^= 1 << bit_pos;
431 printf("nand: bit-flip corrected @data=%d\n", byte_pos);
432 } else if (byte_pos < error_max) {
433 read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
434 printf("nand: bit-flip corrected @oob=%d\n", byte_pos -
438 printf("nand: error: invalid bit-flip location\n");
441 return (err) ? err : error_count;
444 #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
446 #define PREFETCH_CONFIG1_CS_SHIFT 24
447 #define PREFETCH_FIFOTHRESHOLD_MAX 0x40
448 #define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8)
449 #define PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
450 #define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
451 #define ENABLE_PREFETCH (1 << 7)
454 * omap_prefetch_enable - configures and starts prefetch transfer
455 * @fifo_th: fifo threshold to be used for read/ write
456 * @count: number of bytes to be transferred
457 * @is_write: prefetch read(0) or write post(1) mode
458 * @cs: chip select to use
460 static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs)
464 if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
467 if (readl(&gpmc_cfg->prefetch_control))
470 /* Set the amount of bytes to be prefetched */
471 writel(count, &gpmc_cfg->prefetch_config2);
473 val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) |
474 PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH;
475 writel(val, &gpmc_cfg->prefetch_config1);
477 /* Start the prefetch engine */
478 writel(1, &gpmc_cfg->prefetch_control);
484 * omap_prefetch_reset - disables and stops the prefetch engine
486 static void omap_prefetch_reset(void)
488 writel(0, &gpmc_cfg->prefetch_control);
489 writel(0, &gpmc_cfg->prefetch_config1);
492 static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len)
496 struct omap_nand_info *info = chip->priv;
498 ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
505 cnt = readl(&gpmc_cfg->prefetch_status);
506 cnt = PREFETCH_STATUS_FIFO_CNT(cnt);
508 for (i = 0; i < cnt / 4; i++) {
509 *buf++ = readl(CONFIG_SYS_NAND_BASE);
514 omap_prefetch_reset();
519 static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len)
523 struct nand_chip *chip = mtd->priv;
526 * If the destination buffer is unaligned, start with reading
527 * the overlap byte-wise.
529 head = ((uint32_t) buf) % 4;
531 nand_read_buf(mtd, buf, head);
537 * Only transfer multiples of 4 bytes in a pre-fetched fashion.
538 * If there's a residue, care for it byte-wise afterwards.
542 ret = __read_prefetch_aligned(chip, (uint32_t *) buf, len - tail);
544 /* fallback in case the prefetch engine is busy */
545 nand_read_buf(mtd, buf, len);
548 nand_read_buf(mtd, buf, tail);
551 #endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */
554 * omap_read_page_bch - hardware ecc based page read function
555 * @mtd: mtd info structure
556 * @chip: nand chip info structure
557 * @buf: buffer to store read data
558 * @oob_required: caller expects OOB data read to chip->oob_poi
559 * @page: page number to read
562 static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
563 uint8_t *buf, int oob_required, int page)
565 int i, eccsize = chip->ecc.size;
566 int eccbytes = chip->ecc.bytes;
567 int eccsteps = chip->ecc.steps;
569 uint8_t *ecc_calc = chip->buffers->ecccalc;
570 uint8_t *ecc_code = chip->buffers->ecccode;
571 uint32_t *eccpos = chip->ecc.layout->eccpos;
572 uint8_t *oob = chip->oob_poi;
578 oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
579 oob += chip->ecc.layout->eccpos[0];
581 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
583 chip->ecc.hwctl(mtd, NAND_ECC_READ);
585 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, -1);
586 chip->read_buf(mtd, p, eccsize);
588 /* read respective ecc from oob area */
589 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
590 chip->read_buf(mtd, oob, eccbytes);
592 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
598 for (i = 0; i < chip->ecc.total; i++)
599 ecc_code[i] = chip->oob_poi[eccpos[i]];
601 eccsteps = chip->ecc.steps;
604 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
607 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
609 mtd->ecc_stats.failed++;
611 mtd->ecc_stats.corrected += stat;
615 #endif /* CONFIG_NAND_OMAP_ELM */
618 * OMAP3 BCH8 support (with BCH library)
622 * omap_correct_data_bch_sw - Decode received data and correct errors
623 * @mtd: MTD device structure
625 * @read_ecc: ecc read from nand flash
626 * @calc_ecc: ecc read from HW ECC registers
628 static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
629 u_char *read_ecc, u_char *calc_ecc)
632 /* cannot correct more than 8 errors */
633 unsigned int errloc[8];
634 struct nand_chip *chip = mtd->priv;
635 struct omap_nand_info *info = chip->priv;
637 count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
641 for (i = 0; i < count; i++) {
642 /* correct data only, not ecc bytes */
643 if (errloc[i] < 8*512)
644 data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
645 printf("corrected bitflip %u\n", errloc[i]);
649 * BCH8 have 13 bytes of ECC; BCH4 needs adoption
652 for (i = 0; i < 13; i++)
653 printf("%02x ", read_ecc[i]);
656 for (i = 0; i < 13; i++)
657 printf("%02x ", calc_ecc[i]);
661 } else if (count < 0) {
662 puts("ecc unrecoverable error\n");
668 * omap_free_bch - Release BCH ecc resources
669 * @mtd: MTD device structure
671 static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
673 struct nand_chip *chip = mtd->priv;
674 struct omap_nand_info *info = chip->priv;
677 free_bch(info->control);
678 info->control = NULL;
681 #endif /* CONFIG_BCH */
684 * omap_select_ecc_scheme - configures driver for particular ecc-scheme
685 * @nand: NAND chip device structure
686 * @ecc_scheme: ecc scheme to configure
687 * @pagesize: number of main-area bytes per page of NAND device
688 * @oobsize: number of OOB/spare bytes per page of NAND device
690 static int omap_select_ecc_scheme(struct nand_chip *nand,
691 enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
692 struct omap_nand_info *info = nand->priv;
693 struct nand_ecclayout *ecclayout = &omap_ecclayout;
694 int eccsteps = pagesize / SECTOR_BYTES;
697 switch (ecc_scheme) {
698 case OMAP_ECC_HAM1_CODE_SW:
699 debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
700 /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
701 * initialized in nand_scan_tail(), so just set ecc.mode */
702 info->control = NULL;
703 nand->ecc.mode = NAND_ECC_SOFT;
704 nand->ecc.layout = NULL;
708 case OMAP_ECC_HAM1_CODE_HW:
709 debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
710 /* check ecc-scheme requirements before updating ecc info */
711 if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
712 printf("nand: error: insufficient OOB: require=%d\n", (
713 (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
716 info->control = NULL;
717 /* populate ecc specific fields */
718 memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
719 nand->ecc.mode = NAND_ECC_HW;
720 nand->ecc.strength = 1;
721 nand->ecc.size = SECTOR_BYTES;
723 nand->ecc.hwctl = omap_enable_hwecc;
724 nand->ecc.correct = omap_correct_data;
725 nand->ecc.calculate = omap_calculate_ecc;
726 /* define ecc-layout */
727 ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
728 for (i = 0; i < ecclayout->eccbytes; i++) {
729 if (nand->options & NAND_BUSWIDTH_16)
730 ecclayout->eccpos[i] = i + 2;
732 ecclayout->eccpos[i] = i + 1;
734 ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
735 ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
736 BADBLOCK_MARKER_LENGTH;
739 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
741 debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
742 /* check ecc-scheme requirements before updating ecc info */
743 if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
744 printf("nand: error: insufficient OOB: require=%d\n", (
745 (13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
748 /* check if BCH S/W library can be used for error detection */
749 info->control = init_bch(13, 8, 0x201b);
750 if (!info->control) {
751 printf("nand: error: could not init_bch()\n");
754 /* populate ecc specific fields */
755 memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
756 nand->ecc.mode = NAND_ECC_HW;
757 nand->ecc.strength = 8;
758 nand->ecc.size = SECTOR_BYTES;
759 nand->ecc.bytes = 13;
760 nand->ecc.hwctl = omap_enable_hwecc;
761 nand->ecc.correct = omap_correct_data_bch_sw;
762 nand->ecc.calculate = omap_calculate_ecc;
763 /* define ecc-layout */
764 ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
765 ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH;
766 for (i = 1; i < ecclayout->eccbytes; i++) {
767 if (i % nand->ecc.bytes)
768 ecclayout->eccpos[i] =
769 ecclayout->eccpos[i - 1] + 1;
771 ecclayout->eccpos[i] =
772 ecclayout->eccpos[i - 1] + 2;
774 ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
775 ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
776 BADBLOCK_MARKER_LENGTH;
779 printf("nand: error: CONFIG_BCH required for ECC\n");
783 case OMAP_ECC_BCH8_CODE_HW:
784 #ifdef CONFIG_NAND_OMAP_ELM
785 debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
786 /* check ecc-scheme requirements before updating ecc info */
787 if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
788 printf("nand: error: insufficient OOB: require=%d\n", (
789 (14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
792 /* intialize ELM for ECC error detection */
794 info->control = NULL;
795 /* populate ecc specific fields */
796 memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
797 nand->ecc.mode = NAND_ECC_HW;
798 nand->ecc.strength = 8;
799 nand->ecc.size = SECTOR_BYTES;
800 nand->ecc.bytes = 14;
801 nand->ecc.hwctl = omap_enable_hwecc;
802 nand->ecc.correct = omap_correct_data_bch;
803 nand->ecc.calculate = omap_calculate_ecc;
804 nand->ecc.read_page = omap_read_page_bch;
805 /* define ecc-layout */
806 ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
807 for (i = 0; i < ecclayout->eccbytes; i++)
808 ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
809 ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
810 ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
811 BADBLOCK_MARKER_LENGTH;
814 printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
818 case OMAP_ECC_BCH16_CODE_HW:
819 #ifdef CONFIG_NAND_OMAP_ELM
820 debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");
821 /* check ecc-scheme requirements before updating ecc info */
822 if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
823 printf("nand: error: insufficient OOB: require=%d\n", (
824 (26 * eccsteps) + BADBLOCK_MARKER_LENGTH));
827 /* intialize ELM for ECC error detection */
829 /* populate ecc specific fields */
830 nand->ecc.mode = NAND_ECC_HW;
831 nand->ecc.size = SECTOR_BYTES;
832 nand->ecc.bytes = 26;
833 nand->ecc.strength = 16;
834 nand->ecc.hwctl = omap_enable_hwecc;
835 nand->ecc.correct = omap_correct_data_bch;
836 nand->ecc.calculate = omap_calculate_ecc;
837 nand->ecc.read_page = omap_read_page_bch;
838 /* define ecc-layout */
839 ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
840 for (i = 0; i < ecclayout->eccbytes; i++)
841 ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
842 ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
843 ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
844 BADBLOCK_MARKER_LENGTH;
847 printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
851 debug("nand: error: ecc scheme not enabled or supported\n");
855 /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
856 if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
857 nand->ecc.layout = ecclayout;
859 info->ecc_scheme = ecc_scheme;
863 #ifndef CONFIG_SPL_BUILD
865 * omap_nand_switch_ecc - switch the ECC operation between different engines
866 * (h/w and s/w) and different algorithms (hamming and BCHx)
868 * @hardware - true if one of the HW engines should be used
869 * @eccstrength - the number of bits that could be corrected
870 * (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
872 int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
874 struct nand_chip *nand;
875 struct mtd_info *mtd;
878 if (nand_curr_device < 0 ||
879 nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
880 !nand_info[nand_curr_device].name) {
881 printf("nand: error: no NAND devices found\n");
885 mtd = &nand_info[nand_curr_device];
887 nand->options |= NAND_OWN_BUFFERS;
888 nand->options &= ~NAND_SUBPAGE_READ;
889 /* Setup the ecc configurations again */
891 if (eccstrength == 1) {
892 err = omap_select_ecc_scheme(nand,
893 OMAP_ECC_HAM1_CODE_HW,
894 mtd->writesize, mtd->oobsize);
895 } else if (eccstrength == 8) {
896 err = omap_select_ecc_scheme(nand,
897 OMAP_ECC_BCH8_CODE_HW,
898 mtd->writesize, mtd->oobsize);
900 printf("nand: error: unsupported ECC scheme\n");
904 err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
905 mtd->writesize, mtd->oobsize);
908 /* Update NAND handling after ECC mode switch */
910 err = nand_scan_tail(mtd);
913 #endif /* CONFIG_SPL_BUILD */
916 * Board-specific NAND initialization. The following members of the
917 * argument are board-specific:
918 * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
919 * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
920 * - cmd_ctrl: hardwarespecific function for accesing control-lines
921 * - waitfunc: hardwarespecific function for accesing device ready/busy line
922 * - ecc.hwctl: function to enable (reset) hardware ecc generator
923 * - ecc.mode: mode of ecc, see defines
924 * - chip_delay: chip dependent delay for transfering data from array to
926 * - options: various chip options. They can partly be set to inform
927 * nand_scan about special functionality. See the defines for further
930 int board_nand_init(struct nand_chip *nand)
932 int32_t gpmc_config = 0;
936 * xloader/Uboot's gpmc configuration would have configured GPMC for
937 * nand type of memory. The following logic scans and latches on to the
938 * first CS with NAND type memory.
939 * TBD: need to make this logic generic to handle multiple CS NAND
942 while (cs < GPMC_MAX_CS) {
943 /* Check if NAND type is set */
944 if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
950 if (cs >= GPMC_MAX_CS) {
951 printf("nand: error: Unable to find NAND settings in "
952 "GPMC Configuration - quitting\n");
956 gpmc_config = readl(&gpmc_cfg->config);
957 /* Disable Write protect */
959 writel(gpmc_config, &gpmc_cfg->config);
961 nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
962 nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
963 omap_nand_info[cs].control = NULL;
964 omap_nand_info[cs].cs = cs;
965 nand->priv = &omap_nand_info[cs];
966 nand->cmd_ctrl = omap_nand_hwcontrol;
967 nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
968 nand->chip_delay = 100;
969 nand->ecc.layout = &omap_ecclayout;
971 /* configure driver and controller based on NAND device bus-width */
972 gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
973 #if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
974 nand->options |= NAND_BUSWIDTH_16;
975 writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
977 nand->options &= ~NAND_BUSWIDTH_16;
978 writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
980 /* select ECC scheme */
981 #if defined(CONFIG_NAND_OMAP_ECCSCHEME)
982 err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
983 CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
985 /* pagesize and oobsize are not required to configure sw ecc-scheme */
986 err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
992 #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
993 /* TODO: Implement for 16-bit bus width */
994 if (nand->options & NAND_BUSWIDTH_16)
995 nand->read_buf = nand_read_buf16;
997 nand->read_buf = omap_nand_read_prefetch8;
1000 nand->dev_ready = omap_dev_ready;