1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
4  * Rohit Choraria <rohitkc@ti.com>
5  */
6 
7 #include <common.h>
8 #include <log.h>
9 #include <asm/io.h>
10 #include <linux/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/mtd/rawnand.h>
15 #include <linux/bch.h>
16 #include <linux/compiler.h>
17 #include <nand.h>
18 #include <linux/mtd/omap_elm.h>
19 
20 #define BADBLOCK_MARKER_LENGTH	2
21 #define SECTOR_BYTES		512
22 #define ECCCLEAR		(0x1 << 8)
23 #define ECCRESULTREG1		(0x1 << 0)
24 /* 4 bit padding to make byte aligned, 56 = 52 + 4 */
25 #define BCH4_BIT_PAD		4
26 
27 #ifdef CONFIG_BCH
28 static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
29 				0x97, 0x79, 0xe5, 0x24, 0xb5};
30 #endif
31 static uint8_t cs_next;
32 static __maybe_unused struct nand_ecclayout omap_ecclayout;
33 
34 #if defined(CONFIG_NAND_OMAP_GPMC_WSCFG)
35 static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE] =
36 	{ CONFIG_NAND_OMAP_GPMC_WSCFG };
37 #else
38 /* wscfg is preset to zero since its a static variable */
39 static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE];
40 #endif
41 
42 /*
43  * Driver configurations
44  */
45 struct omap_nand_info {
46 	struct bch_control *control;
47 	enum omap_ecc ecc_scheme;
48 	uint8_t cs;
49 	uint8_t ws;		/* wait status pin (0,1) */
50 };
51 
52 /* We are wasting a bit of memory but al least we are safe */
53 static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
54 
55 /*
56  * omap_nand_hwcontrol - Set the address pointers corretly for the
57  *			following address/data/command operation
58  */
omap_nand_hwcontrol(struct mtd_info * mtd,int32_t cmd,uint32_t ctrl)59 static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
60 				uint32_t ctrl)
61 {
62 	register struct nand_chip *this = mtd_to_nand(mtd);
63 	struct omap_nand_info *info = nand_get_controller_data(this);
64 	int cs = info->cs;
65 
66 	/*
67 	 * Point the IO_ADDR to DATA and ADDRESS registers instead
68 	 * of chip address
69 	 */
70 	switch (ctrl) {
71 	case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
72 		this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
73 		break;
74 	case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
75 		this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
76 		break;
77 	case NAND_CTRL_CHANGE | NAND_NCE:
78 		this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
79 		break;
80 	}
81 
82 	if (cmd != NAND_CMD_NONE)
83 		writeb(cmd, this->IO_ADDR_W);
84 }
85 
86 /* Check wait pin as dev ready indicator */
omap_dev_ready(struct mtd_info * mtd)87 static int omap_dev_ready(struct mtd_info *mtd)
88 {
89 	register struct nand_chip *this = mtd_to_nand(mtd);
90 	struct omap_nand_info *info = nand_get_controller_data(this);
91 	return gpmc_cfg->status & (1 << (8 + info->ws));
92 }
93 
94 /*
95  * gen_true_ecc - This function will generate true ECC value, which
96  * can be used when correcting data read from NAND flash memory core
97  *
98  * @ecc_buf:	buffer to store ecc code
99  *
100  * @return:	re-formatted ECC value
101  */
gen_true_ecc(uint8_t * ecc_buf)102 static uint32_t gen_true_ecc(uint8_t *ecc_buf)
103 {
104 	return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
105 		((ecc_buf[2] & 0x0F) << 8);
106 }
107 
108 /*
109  * omap_correct_data - Compares the ecc read from nand spare area with ECC
110  * registers values and corrects one bit error if it has occurred
111  * Further details can be had from OMAP TRM and the following selected links:
112  * http://en.wikipedia.org/wiki/Hamming_code
113  * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
114  *
115  * @mtd:		 MTD device structure
116  * @dat:		 page data
117  * @read_ecc:		 ecc read from nand flash
118  * @calc_ecc:		 ecc read from ECC registers
119  *
120  * @return 0 if data is OK or corrected, else returns -1
121  */
omap_correct_data(struct mtd_info * mtd,uint8_t * dat,uint8_t * read_ecc,uint8_t * calc_ecc)122 static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
123 				uint8_t *read_ecc, uint8_t *calc_ecc)
124 {
125 	uint32_t orig_ecc, new_ecc, res, hm;
126 	uint16_t parity_bits, byte;
127 	uint8_t bit;
128 
129 	/* Regenerate the orginal ECC */
130 	orig_ecc = gen_true_ecc(read_ecc);
131 	new_ecc = gen_true_ecc(calc_ecc);
132 	/* Get the XOR of real ecc */
133 	res = orig_ecc ^ new_ecc;
134 	if (res) {
135 		/* Get the hamming width */
136 		hm = hweight32(res);
137 		/* Single bit errors can be corrected! */
138 		if (hm == 12) {
139 			/* Correctable data! */
140 			parity_bits = res >> 16;
141 			bit = (parity_bits & 0x7);
142 			byte = (parity_bits >> 3) & 0x1FF;
143 			/* Flip the bit to correct */
144 			dat[byte] ^= (0x1 << bit);
145 		} else if (hm == 1) {
146 			printf("Error: Ecc is wrong\n");
147 			/* ECC itself is corrupted */
148 			return 2;
149 		} else {
150 			/*
151 			 * hm distance != parity pairs OR one, could mean 2 bit
152 			 * error OR potentially be on a blank page..
153 			 * orig_ecc: contains spare area data from nand flash.
154 			 * new_ecc: generated ecc while reading data area.
155 			 * Note: if the ecc = 0, all data bits from which it was
156 			 * generated are 0xFF.
157 			 * The 3 byte(24 bits) ecc is generated per 512byte
158 			 * chunk of a page. If orig_ecc(from spare area)
159 			 * is 0xFF && new_ecc(computed now from data area)=0x0,
160 			 * this means that data area is 0xFF and spare area is
161 			 * 0xFF. A sure sign of a erased page!
162 			 */
163 			if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
164 				return 0;
165 			printf("Error: Bad compare! failed\n");
166 			/* detected 2 bit error */
167 			return -EBADMSG;
168 		}
169 	}
170 	return 0;
171 }
172 
173 /*
174  * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
175  * @mtd:	MTD device structure
176  * @mode:	Read/Write mode
177  */
178 __maybe_unused
omap_enable_hwecc(struct mtd_info * mtd,int32_t mode)179 static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
180 {
181 	struct nand_chip	*nand	= mtd_to_nand(mtd);
182 	struct omap_nand_info	*info	= nand_get_controller_data(nand);
183 	unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
184 	unsigned int ecc_algo = 0;
185 	unsigned int bch_type = 0;
186 	unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
187 	u32 ecc_size_config_val = 0;
188 	u32 ecc_config_val = 0;
189 	int cs = info->cs;
190 
191 	/* configure GPMC for specific ecc-scheme */
192 	switch (info->ecc_scheme) {
193 	case OMAP_ECC_HAM1_CODE_SW:
194 		return;
195 	case OMAP_ECC_HAM1_CODE_HW:
196 		ecc_algo = 0x0;
197 		bch_type = 0x0;
198 		bch_wrapmode = 0x00;
199 		eccsize0 = 0xFF;
200 		eccsize1 = 0xFF;
201 		break;
202 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
203 	case OMAP_ECC_BCH8_CODE_HW:
204 		ecc_algo = 0x1;
205 		bch_type = 0x1;
206 		if (mode == NAND_ECC_WRITE) {
207 			bch_wrapmode = 0x01;
208 			eccsize0 = 0;  /* extra bits in nibbles per sector */
209 			eccsize1 = 28; /* OOB bits in nibbles per sector */
210 		} else {
211 			bch_wrapmode = 0x01;
212 			eccsize0 = 26; /* ECC bits in nibbles per sector */
213 			eccsize1 = 2;  /* non-ECC bits in nibbles per sector */
214 		}
215 		break;
216 	case OMAP_ECC_BCH16_CODE_HW:
217 		ecc_algo = 0x1;
218 		bch_type = 0x2;
219 		if (mode == NAND_ECC_WRITE) {
220 			bch_wrapmode = 0x01;
221 			eccsize0 = 0;  /* extra bits in nibbles per sector */
222 			eccsize1 = 52; /* OOB bits in nibbles per sector */
223 		} else {
224 			bch_wrapmode = 0x01;
225 			eccsize0 = 52; /* ECC bits in nibbles per sector */
226 			eccsize1 = 0;  /* non-ECC bits in nibbles per sector */
227 		}
228 		break;
229 	default:
230 		return;
231 	}
232 	/* Clear ecc and enable bits */
233 	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
234 	/* Configure ecc size for BCH */
235 	ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
236 	writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);
237 
238 	/* Configure device details for BCH engine */
239 	ecc_config_val = ((ecc_algo << 16)	| /* HAM1 | BCHx */
240 			(bch_type << 12)	| /* BCH4/BCH8/BCH16 */
241 			(bch_wrapmode << 8)	| /* wrap mode */
242 			(dev_width << 7)	| /* bus width */
243 			(0x0 << 4)		| /* number of sectors */
244 			(cs <<  1)		| /* ECC CS */
245 			(0x1));			  /* enable ECC */
246 	writel(ecc_config_val, &gpmc_cfg->ecc_config);
247 }
248 
249 /*
250  *  omap_calculate_ecc - Read ECC result
251  *  @mtd:	MTD structure
252  *  @dat:	unused
253  *  @ecc_code:	ecc_code buffer
254  *  Using noninverted ECC can be considered ugly since writing a blank
255  *  page ie. padding will clear the ECC bytes. This is no problem as
256  *  long nobody is trying to write data on the seemingly unused page.
257  *  Reading an erased page will produce an ECC mismatch between
258  *  generated and read ECC bytes that has to be dealt with separately.
259  *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
260  *  is used, the result of read will be 0x0 while the ECC offsets of the
261  *  spare area will be 0xFF which will result in an ECC mismatch.
262  */
omap_calculate_ecc(struct mtd_info * mtd,const uint8_t * dat,uint8_t * ecc_code)263 static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
264 				uint8_t *ecc_code)
265 {
266 	struct nand_chip *chip = mtd_to_nand(mtd);
267 	struct omap_nand_info *info = nand_get_controller_data(chip);
268 	const uint32_t *ptr;
269 	uint32_t val = 0;
270 	int8_t i = 0, j;
271 
272 	switch (info->ecc_scheme) {
273 	case OMAP_ECC_HAM1_CODE_HW:
274 		val = readl(&gpmc_cfg->ecc1_result);
275 		ecc_code[0] = val & 0xFF;
276 		ecc_code[1] = (val >> 16) & 0xFF;
277 		ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
278 		break;
279 #ifdef CONFIG_BCH
280 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
281 #endif
282 	case OMAP_ECC_BCH8_CODE_HW:
283 		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
284 		val = readl(ptr);
285 		ecc_code[i++] = (val >>  0) & 0xFF;
286 		ptr--;
287 		for (j = 0; j < 3; j++) {
288 			val = readl(ptr);
289 			ecc_code[i++] = (val >> 24) & 0xFF;
290 			ecc_code[i++] = (val >> 16) & 0xFF;
291 			ecc_code[i++] = (val >>  8) & 0xFF;
292 			ecc_code[i++] = (val >>  0) & 0xFF;
293 			ptr--;
294 		}
295 		break;
296 	case OMAP_ECC_BCH16_CODE_HW:
297 		val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[2]);
298 		ecc_code[i++] = (val >>  8) & 0xFF;
299 		ecc_code[i++] = (val >>  0) & 0xFF;
300 		val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[1]);
301 		ecc_code[i++] = (val >> 24) & 0xFF;
302 		ecc_code[i++] = (val >> 16) & 0xFF;
303 		ecc_code[i++] = (val >>  8) & 0xFF;
304 		ecc_code[i++] = (val >>  0) & 0xFF;
305 		val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[0]);
306 		ecc_code[i++] = (val >> 24) & 0xFF;
307 		ecc_code[i++] = (val >> 16) & 0xFF;
308 		ecc_code[i++] = (val >>  8) & 0xFF;
309 		ecc_code[i++] = (val >>  0) & 0xFF;
310 		for (j = 3; j >= 0; j--) {
311 			val = readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[j]
312 									);
313 			ecc_code[i++] = (val >> 24) & 0xFF;
314 			ecc_code[i++] = (val >> 16) & 0xFF;
315 			ecc_code[i++] = (val >>  8) & 0xFF;
316 			ecc_code[i++] = (val >>  0) & 0xFF;
317 		}
318 		break;
319 	default:
320 		return -EINVAL;
321 	}
322 	/* ECC scheme specific syndrome customizations */
323 	switch (info->ecc_scheme) {
324 	case OMAP_ECC_HAM1_CODE_HW:
325 		break;
326 #ifdef CONFIG_BCH
327 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
328 
329 		for (i = 0; i < chip->ecc.bytes; i++)
330 			*(ecc_code + i) = *(ecc_code + i) ^
331 						bch8_polynomial[i];
332 		break;
333 #endif
334 	case OMAP_ECC_BCH8_CODE_HW:
335 		ecc_code[chip->ecc.bytes - 1] = 0x00;
336 		break;
337 	case OMAP_ECC_BCH16_CODE_HW:
338 		break;
339 	default:
340 		return -EINVAL;
341 	}
342 	return 0;
343 }
344 
345 #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
346 
347 #define PREFETCH_CONFIG1_CS_SHIFT	24
348 #define PREFETCH_FIFOTHRESHOLD_MAX	0x40
349 #define PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
350 #define PREFETCH_STATUS_COUNT(val)	(val & 0x00003fff)
351 #define PREFETCH_STATUS_FIFO_CNT(val)	((val >> 24) & 0x7F)
352 #define ENABLE_PREFETCH			(1 << 7)
353 
354 /**
355  * omap_prefetch_enable - configures and starts prefetch transfer
356  * @fifo_th: fifo threshold to be used for read/ write
357  * @count: number of bytes to be transferred
358  * @is_write: prefetch read(0) or write post(1) mode
359  * @cs: chip select to use
360  */
omap_prefetch_enable(int fifo_th,unsigned int count,int is_write,int cs)361 static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs)
362 {
363 	uint32_t val;
364 
365 	if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
366 		return -EINVAL;
367 
368 	if (readl(&gpmc_cfg->prefetch_control))
369 		return -EBUSY;
370 
371 	/* Set the amount of bytes to be prefetched */
372 	writel(count, &gpmc_cfg->prefetch_config2);
373 
374 	val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) |
375 		PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH;
376 	writel(val, &gpmc_cfg->prefetch_config1);
377 
378 	/*  Start the prefetch engine */
379 	writel(1, &gpmc_cfg->prefetch_control);
380 
381 	return 0;
382 }
383 
384 /**
385  * omap_prefetch_reset - disables and stops the prefetch engine
386  */
omap_prefetch_reset(void)387 static void omap_prefetch_reset(void)
388 {
389 	writel(0, &gpmc_cfg->prefetch_control);
390 	writel(0, &gpmc_cfg->prefetch_config1);
391 }
392 
__read_prefetch_aligned(struct nand_chip * chip,uint32_t * buf,int len)393 static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len)
394 {
395 	int ret;
396 	uint32_t cnt;
397 	struct omap_nand_info *info = nand_get_controller_data(chip);
398 
399 	ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
400 	if (ret < 0)
401 		return ret;
402 
403 	do {
404 		int i;
405 
406 		cnt = readl(&gpmc_cfg->prefetch_status);
407 		cnt = PREFETCH_STATUS_FIFO_CNT(cnt);
408 
409 		for (i = 0; i < cnt / 4; i++) {
410 			*buf++ = readl(CONFIG_SYS_NAND_BASE);
411 			len -= 4;
412 		}
413 	} while (len);
414 
415 	omap_prefetch_reset();
416 
417 	return 0;
418 }
419 
omap_nand_read(struct mtd_info * mtd,uint8_t * buf,int len)420 static inline void omap_nand_read(struct mtd_info *mtd, uint8_t *buf, int len)
421 {
422 	struct nand_chip *chip = mtd_to_nand(mtd);
423 
424 	if (chip->options & NAND_BUSWIDTH_16)
425 		nand_read_buf16(mtd, buf, len);
426 	else
427 		nand_read_buf(mtd, buf, len);
428 }
429 
omap_nand_read_prefetch(struct mtd_info * mtd,uint8_t * buf,int len)430 static void omap_nand_read_prefetch(struct mtd_info *mtd, uint8_t *buf, int len)
431 {
432 	int ret;
433 	uint32_t head, tail;
434 	struct nand_chip *chip = mtd_to_nand(mtd);
435 
436 	/*
437 	 * If the destination buffer is unaligned, start with reading
438 	 * the overlap byte-wise.
439 	 */
440 	head = ((uint32_t) buf) % 4;
441 	if (head) {
442 		omap_nand_read(mtd, buf, head);
443 		buf += head;
444 		len -= head;
445 	}
446 
447 	/*
448 	 * Only transfer multiples of 4 bytes in a pre-fetched fashion.
449 	 * If there's a residue, care for it byte-wise afterwards.
450 	 */
451 	tail = len % 4;
452 
453 	ret = __read_prefetch_aligned(chip, (uint32_t *)buf, len - tail);
454 	if (ret < 0) {
455 		/* fallback in case the prefetch engine is busy */
456 		omap_nand_read(mtd, buf, len);
457 	} else if (tail) {
458 		buf += len - tail;
459 		omap_nand_read(mtd, buf, tail);
460 	}
461 }
462 #endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */
463 
464 #ifdef CONFIG_NAND_OMAP_ELM
465 /*
466  * omap_reverse_list - re-orders list elements in reverse order [internal]
467  * @list:	pointer to start of list
468  * @length:	length of list
469 */
omap_reverse_list(u8 * list,unsigned int length)470 static void omap_reverse_list(u8 *list, unsigned int length)
471 {
472 	unsigned int i, j;
473 	unsigned int half_length = length / 2;
474 	u8 tmp;
475 	for (i = 0, j = length - 1; i < half_length; i++, j--) {
476 		tmp = list[i];
477 		list[i] = list[j];
478 		list[j] = tmp;
479 	}
480 }
481 
482 /*
483  * omap_correct_data_bch - Compares the ecc read from nand spare area
484  * with ECC registers values and corrects one bit error if it has occurred
485  *
486  * @mtd:	MTD device structure
487  * @dat:	page data
488  * @read_ecc:	ecc read from nand flash (ignored)
489  * @calc_ecc:	ecc read from ECC registers
490  *
491  * @return 0 if data is OK or corrected, else returns -1
492  */
omap_correct_data_bch(struct mtd_info * mtd,uint8_t * dat,uint8_t * read_ecc,uint8_t * calc_ecc)493 static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
494 				uint8_t *read_ecc, uint8_t *calc_ecc)
495 {
496 	struct nand_chip *chip = mtd_to_nand(mtd);
497 	struct omap_nand_info *info = nand_get_controller_data(chip);
498 	struct nand_ecc_ctrl *ecc = &chip->ecc;
499 	uint32_t error_count = 0, error_max;
500 	uint32_t error_loc[ELM_MAX_ERROR_COUNT];
501 	enum bch_level bch_type;
502 	uint32_t i, ecc_flag = 0;
503 	uint8_t count;
504 	uint32_t byte_pos, bit_pos;
505 	int err = 0;
506 
507 	/* check calculated ecc */
508 	for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
509 		if (calc_ecc[i] != 0x00)
510 			ecc_flag = 1;
511 	}
512 	if (!ecc_flag)
513 		return 0;
514 
515 	/* check for whether its a erased-page */
516 	ecc_flag = 0;
517 	for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
518 		if (read_ecc[i] != 0xff)
519 			ecc_flag = 1;
520 	}
521 	if (!ecc_flag)
522 		return 0;
523 
524 	/*
525 	 * while reading ECC result we read it in big endian.
526 	 * Hence while loading to ELM we have rotate to get the right endian.
527 	 */
528 	switch (info->ecc_scheme) {
529 	case OMAP_ECC_BCH8_CODE_HW:
530 		bch_type = BCH_8_BIT;
531 		omap_reverse_list(calc_ecc, ecc->bytes - 1);
532 		break;
533 	case OMAP_ECC_BCH16_CODE_HW:
534 		bch_type = BCH_16_BIT;
535 		omap_reverse_list(calc_ecc, ecc->bytes);
536 		break;
537 	default:
538 		return -EINVAL;
539 	}
540 	/* use elm module to check for errors */
541 	elm_config(bch_type);
542 	err = elm_check_error(calc_ecc, bch_type, &error_count, error_loc);
543 	if (err)
544 		return err;
545 
546 	/* correct bch error */
547 	for (count = 0; count < error_count; count++) {
548 		switch (info->ecc_scheme) {
549 		case OMAP_ECC_BCH8_CODE_HW:
550 			/* 14th byte in ECC is reserved to match ROM layout */
551 			error_max = SECTOR_BYTES + (ecc->bytes - 1);
552 			break;
553 		case OMAP_ECC_BCH16_CODE_HW:
554 			error_max = SECTOR_BYTES + ecc->bytes;
555 			break;
556 		default:
557 			return -EINVAL;
558 		}
559 		byte_pos = error_max - (error_loc[count] / 8) - 1;
560 		bit_pos  = error_loc[count] % 8;
561 		if (byte_pos < SECTOR_BYTES) {
562 			dat[byte_pos] ^= 1 << bit_pos;
563 			debug("nand: bit-flip corrected @data=%d\n", byte_pos);
564 		} else if (byte_pos < error_max) {
565 			read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
566 			debug("nand: bit-flip corrected @oob=%d\n", byte_pos -
567 								SECTOR_BYTES);
568 		} else {
569 			err = -EBADMSG;
570 			printf("nand: error: invalid bit-flip location\n");
571 		}
572 	}
573 	return (err) ? err : error_count;
574 }
575 
576 /**
577  * omap_read_page_bch - hardware ecc based page read function
578  * @mtd:	mtd info structure
579  * @chip:	nand chip info structure
580  * @buf:	buffer to store read data
581  * @oob_required: caller expects OOB data read to chip->oob_poi
582  * @page:	page number to read
583  *
584  */
omap_read_page_bch(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)585 static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
586 				uint8_t *buf, int oob_required, int page)
587 {
588 	int i, eccsize = chip->ecc.size;
589 	int eccbytes = chip->ecc.bytes;
590 	int eccsteps = chip->ecc.steps;
591 	uint8_t *p = buf;
592 	uint8_t *ecc_calc = chip->buffers->ecccalc;
593 	uint8_t *ecc_code = chip->buffers->ecccode;
594 	uint32_t *eccpos = chip->ecc.layout->eccpos;
595 	uint8_t *oob = chip->oob_poi;
596 	uint32_t data_pos;
597 	uint32_t oob_pos;
598 
599 	data_pos = 0;
600 	/* oob area start */
601 	oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
602 	oob += chip->ecc.layout->eccpos[0];
603 
604 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
605 				oob += eccbytes) {
606 		chip->ecc.hwctl(mtd, NAND_ECC_READ);
607 		/* read data */
608 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, -1);
609 		chip->read_buf(mtd, p, eccsize);
610 
611 		/* read respective ecc from oob area */
612 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
613 		chip->read_buf(mtd, oob, eccbytes);
614 		/* read syndrome */
615 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
616 
617 		data_pos += eccsize;
618 		oob_pos += eccbytes;
619 	}
620 
621 	for (i = 0; i < chip->ecc.total; i++)
622 		ecc_code[i] = chip->oob_poi[eccpos[i]];
623 
624 	eccsteps = chip->ecc.steps;
625 	p = buf;
626 
627 	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
628 		int stat;
629 
630 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
631 		if (stat < 0)
632 			mtd->ecc_stats.failed++;
633 		else
634 			mtd->ecc_stats.corrected += stat;
635 	}
636 	return 0;
637 }
638 #endif /* CONFIG_NAND_OMAP_ELM */
639 
640 /*
641  * OMAP3 BCH8 support (with BCH library)
642  */
643 #ifdef CONFIG_BCH
644 /**
645  * omap_correct_data_bch_sw - Decode received data and correct errors
646  * @mtd: MTD device structure
647  * @data: page data
648  * @read_ecc: ecc read from nand flash
649  * @calc_ecc: ecc read from HW ECC registers
650  */
omap_correct_data_bch_sw(struct mtd_info * mtd,u_char * data,u_char * read_ecc,u_char * calc_ecc)651 static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
652 				 u_char *read_ecc, u_char *calc_ecc)
653 {
654 	int i, count;
655 	/* cannot correct more than 8 errors */
656 	unsigned int errloc[8];
657 	struct nand_chip *chip = mtd_to_nand(mtd);
658 	struct omap_nand_info *info = nand_get_controller_data(chip);
659 
660 	count = decode_bch(info->control, NULL, SECTOR_BYTES,
661 				read_ecc, calc_ecc, NULL, errloc);
662 	if (count > 0) {
663 		/* correct errors */
664 		for (i = 0; i < count; i++) {
665 			/* correct data only, not ecc bytes */
666 			if (errloc[i] < SECTOR_BYTES << 3)
667 				data[errloc[i] >> 3] ^= 1 << (errloc[i] & 7);
668 			debug("corrected bitflip %u\n", errloc[i]);
669 #ifdef DEBUG
670 			puts("read_ecc: ");
671 			/*
672 			 * BCH8 have 13 bytes of ECC; BCH4 needs adoption
673 			 * here!
674 			 */
675 			for (i = 0; i < 13; i++)
676 				printf("%02x ", read_ecc[i]);
677 			puts("\n");
678 			puts("calc_ecc: ");
679 			for (i = 0; i < 13; i++)
680 				printf("%02x ", calc_ecc[i]);
681 			puts("\n");
682 #endif
683 		}
684 	} else if (count < 0) {
685 		puts("ecc unrecoverable error\n");
686 	}
687 	return count;
688 }
689 
690 /**
691  * omap_free_bch - Release BCH ecc resources
692  * @mtd: MTD device structure
693  */
omap_free_bch(struct mtd_info * mtd)694 static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
695 {
696 	struct nand_chip *chip = mtd_to_nand(mtd);
697 	struct omap_nand_info *info = nand_get_controller_data(chip);
698 
699 	if (info->control) {
700 		free_bch(info->control);
701 		info->control = NULL;
702 	}
703 }
704 #endif /* CONFIG_BCH */
705 
706 /**
707  * omap_select_ecc_scheme - configures driver for particular ecc-scheme
708  * @nand: NAND chip device structure
709  * @ecc_scheme: ecc scheme to configure
710  * @pagesize: number of main-area bytes per page of NAND device
711  * @oobsize: number of OOB/spare bytes per page of NAND device
712  */
omap_select_ecc_scheme(struct nand_chip * nand,enum omap_ecc ecc_scheme,unsigned int pagesize,unsigned int oobsize)713 static int omap_select_ecc_scheme(struct nand_chip *nand,
714 	enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
715 	struct omap_nand_info	*info		= nand_get_controller_data(nand);
716 	struct nand_ecclayout	*ecclayout	= &omap_ecclayout;
717 	int eccsteps = pagesize / SECTOR_BYTES;
718 	int i;
719 
720 	switch (ecc_scheme) {
721 	case OMAP_ECC_HAM1_CODE_SW:
722 		debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
723 		/* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
724 		 * initialized in nand_scan_tail(), so just set ecc.mode */
725 		info->control		= NULL;
726 		nand->ecc.mode		= NAND_ECC_SOFT;
727 		nand->ecc.layout	= NULL;
728 		nand->ecc.size		= 0;
729 		break;
730 
731 	case OMAP_ECC_HAM1_CODE_HW:
732 		debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
733 		/* check ecc-scheme requirements before updating ecc info */
734 		if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
735 			printf("nand: error: insufficient OOB: require=%d\n", (
736 				(3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
737 			return -EINVAL;
738 		}
739 		info->control		= NULL;
740 		/* populate ecc specific fields */
741 		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
742 		nand->ecc.mode		= NAND_ECC_HW;
743 		nand->ecc.strength	= 1;
744 		nand->ecc.size		= SECTOR_BYTES;
745 		nand->ecc.bytes		= 3;
746 		nand->ecc.hwctl		= omap_enable_hwecc;
747 		nand->ecc.correct	= omap_correct_data;
748 		nand->ecc.calculate	= omap_calculate_ecc;
749 		/* define ecc-layout */
750 		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
751 		for (i = 0; i < ecclayout->eccbytes; i++) {
752 			if (nand->options & NAND_BUSWIDTH_16)
753 				ecclayout->eccpos[i] = i + 2;
754 			else
755 				ecclayout->eccpos[i] = i + 1;
756 		}
757 		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
758 		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
759 						BADBLOCK_MARKER_LENGTH;
760 		break;
761 
762 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
763 #ifdef CONFIG_BCH
764 		debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
765 		/* check ecc-scheme requirements before updating ecc info */
766 		if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
767 			printf("nand: error: insufficient OOB: require=%d\n", (
768 				(13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
769 			return -EINVAL;
770 		}
771 		/* check if BCH S/W library can be used for error detection */
772 		info->control = init_bch(13, 8, 0x201b);
773 		if (!info->control) {
774 			printf("nand: error: could not init_bch()\n");
775 			return -ENODEV;
776 		}
777 		/* populate ecc specific fields */
778 		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
779 		nand->ecc.mode		= NAND_ECC_HW;
780 		nand->ecc.strength	= 8;
781 		nand->ecc.size		= SECTOR_BYTES;
782 		nand->ecc.bytes		= 13;
783 		nand->ecc.hwctl		= omap_enable_hwecc;
784 		nand->ecc.correct	= omap_correct_data_bch_sw;
785 		nand->ecc.calculate	= omap_calculate_ecc;
786 		/* define ecc-layout */
787 		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
788 		ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
789 		for (i = 1; i < ecclayout->eccbytes; i++) {
790 			if (i % nand->ecc.bytes)
791 				ecclayout->eccpos[i] =
792 						ecclayout->eccpos[i - 1] + 1;
793 			else
794 				ecclayout->eccpos[i] =
795 						ecclayout->eccpos[i - 1] + 2;
796 		}
797 		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
798 		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
799 						BADBLOCK_MARKER_LENGTH;
800 		break;
801 #else
802 		printf("nand: error: CONFIG_BCH required for ECC\n");
803 		return -EINVAL;
804 #endif
805 
806 	case OMAP_ECC_BCH8_CODE_HW:
807 #ifdef CONFIG_NAND_OMAP_ELM
808 		debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
809 		/* check ecc-scheme requirements before updating ecc info */
810 		if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
811 			printf("nand: error: insufficient OOB: require=%d\n", (
812 				(14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
813 			return -EINVAL;
814 		}
815 		/* intialize ELM for ECC error detection */
816 		elm_init();
817 		info->control		= NULL;
818 		/* populate ecc specific fields */
819 		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
820 		nand->ecc.mode		= NAND_ECC_HW;
821 		nand->ecc.strength	= 8;
822 		nand->ecc.size		= SECTOR_BYTES;
823 		nand->ecc.bytes		= 14;
824 		nand->ecc.hwctl		= omap_enable_hwecc;
825 		nand->ecc.correct	= omap_correct_data_bch;
826 		nand->ecc.calculate	= omap_calculate_ecc;
827 		nand->ecc.read_page	= omap_read_page_bch;
828 		/* define ecc-layout */
829 		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
830 		for (i = 0; i < ecclayout->eccbytes; i++)
831 			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
832 		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
833 		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
834 						BADBLOCK_MARKER_LENGTH;
835 		break;
836 #else
837 		printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
838 		return -EINVAL;
839 #endif
840 
841 	case OMAP_ECC_BCH16_CODE_HW:
842 #ifdef CONFIG_NAND_OMAP_ELM
843 		debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");
844 		/* check ecc-scheme requirements before updating ecc info */
845 		if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
846 			printf("nand: error: insufficient OOB: require=%d\n", (
847 				(26 * eccsteps) + BADBLOCK_MARKER_LENGTH));
848 			return -EINVAL;
849 		}
850 		/* intialize ELM for ECC error detection */
851 		elm_init();
852 		/* populate ecc specific fields */
853 		nand->ecc.mode		= NAND_ECC_HW;
854 		nand->ecc.size		= SECTOR_BYTES;
855 		nand->ecc.bytes		= 26;
856 		nand->ecc.strength	= 16;
857 		nand->ecc.hwctl		= omap_enable_hwecc;
858 		nand->ecc.correct	= omap_correct_data_bch;
859 		nand->ecc.calculate	= omap_calculate_ecc;
860 		nand->ecc.read_page	= omap_read_page_bch;
861 		/* define ecc-layout */
862 		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
863 		for (i = 0; i < ecclayout->eccbytes; i++)
864 			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
865 		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
866 		ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
867 						BADBLOCK_MARKER_LENGTH;
868 		break;
869 #else
870 		printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
871 		return -EINVAL;
872 #endif
873 	default:
874 		debug("nand: error: ecc scheme not enabled or supported\n");
875 		return -EINVAL;
876 	}
877 
878 	/* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
879 	if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
880 		nand->ecc.layout = ecclayout;
881 
882 	info->ecc_scheme = ecc_scheme;
883 	return 0;
884 }
885 
886 #ifndef CONFIG_SPL_BUILD
887 /*
888  * omap_nand_switch_ecc - switch the ECC operation between different engines
889  * (h/w and s/w) and different algorithms (hamming and BCHx)
890  *
891  * @hardware		- true if one of the HW engines should be used
892  * @eccstrength		- the number of bits that could be corrected
893  *			  (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
894  */
omap_nand_switch_ecc(uint32_t hardware,uint32_t eccstrength)895 int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
896 {
897 	struct nand_chip *nand;
898 	struct mtd_info *mtd = get_nand_dev_by_index(nand_curr_device);
899 	int err = 0;
900 
901 	if (!mtd) {
902 		printf("nand: error: no NAND devices found\n");
903 		return -ENODEV;
904 	}
905 
906 	nand = mtd_to_nand(mtd);
907 	nand->options |= NAND_OWN_BUFFERS;
908 	nand->options &= ~NAND_SUBPAGE_READ;
909 	/* Setup the ecc configurations again */
910 	if (hardware) {
911 		if (eccstrength == 1) {
912 			err = omap_select_ecc_scheme(nand,
913 					OMAP_ECC_HAM1_CODE_HW,
914 					mtd->writesize, mtd->oobsize);
915 		} else if (eccstrength == 8) {
916 			err = omap_select_ecc_scheme(nand,
917 					OMAP_ECC_BCH8_CODE_HW,
918 					mtd->writesize, mtd->oobsize);
919 		} else if (eccstrength == 16) {
920 			err = omap_select_ecc_scheme(nand,
921 					OMAP_ECC_BCH16_CODE_HW,
922 					mtd->writesize, mtd->oobsize);
923 		} else {
924 			printf("nand: error: unsupported ECC scheme\n");
925 			return -EINVAL;
926 		}
927 	} else {
928 		if (eccstrength == 1) {
929 			err = omap_select_ecc_scheme(nand,
930 					OMAP_ECC_HAM1_CODE_SW,
931 					mtd->writesize, mtd->oobsize);
932 		} else if (eccstrength == 8) {
933 			err = omap_select_ecc_scheme(nand,
934 					OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
935 					mtd->writesize, mtd->oobsize);
936 		} else {
937 			printf("nand: error: unsupported ECC scheme\n");
938 			return -EINVAL;
939 		}
940 	}
941 
942 	/* Update NAND handling after ECC mode switch */
943 	if (!err)
944 		err = nand_scan_tail(mtd);
945 	return err;
946 }
947 #endif /* CONFIG_SPL_BUILD */
948 
949 /*
950  * Board-specific NAND initialization. The following members of the
951  * argument are board-specific:
952  * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
953  * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
954  * - cmd_ctrl: hardwarespecific function for accesing control-lines
955  * - waitfunc: hardwarespecific function for accesing device ready/busy line
956  * - ecc.hwctl: function to enable (reset) hardware ecc generator
957  * - ecc.mode: mode of ecc, see defines
958  * - chip_delay: chip dependent delay for transfering data from array to
959  *   read regs (tR)
960  * - options: various chip options. They can partly be set to inform
961  *   nand_scan about special functionality. See the defines for further
962  *   explanation
963  */
board_nand_init(struct nand_chip * nand)964 int board_nand_init(struct nand_chip *nand)
965 {
966 	int32_t gpmc_config = 0;
967 	int cs = cs_next++;
968 	int err = 0;
969 	/*
970 	 * xloader/Uboot's gpmc configuration would have configured GPMC for
971 	 * nand type of memory. The following logic scans and latches on to the
972 	 * first CS with NAND type memory.
973 	 * TBD: need to make this logic generic to handle multiple CS NAND
974 	 * devices.
975 	 */
976 	while (cs < GPMC_MAX_CS) {
977 		/* Check if NAND type is set */
978 		if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
979 			/* Found it!! */
980 			break;
981 		}
982 		cs++;
983 	}
984 	if (cs >= GPMC_MAX_CS) {
985 		printf("nand: error: Unable to find NAND settings in "
986 			"GPMC Configuration - quitting\n");
987 		return -ENODEV;
988 	}
989 
990 	gpmc_config = readl(&gpmc_cfg->config);
991 	/* Disable Write protect */
992 	gpmc_config |= 0x10;
993 	writel(gpmc_config, &gpmc_cfg->config);
994 
995 	nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
996 	nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
997 	omap_nand_info[cs].control = NULL;
998 	omap_nand_info[cs].cs = cs;
999 	omap_nand_info[cs].ws = wscfg[cs];
1000 	nand_set_controller_data(nand, &omap_nand_info[cs]);
1001 	nand->cmd_ctrl	= omap_nand_hwcontrol;
1002 	nand->options	|= NAND_NO_PADDING | NAND_CACHEPRG;
1003 	nand->chip_delay = 100;
1004 	nand->ecc.layout = &omap_ecclayout;
1005 
1006 	/* configure driver and controller based on NAND device bus-width */
1007 	gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
1008 #if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
1009 	nand->options |= NAND_BUSWIDTH_16;
1010 	writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
1011 #else
1012 	nand->options &= ~NAND_BUSWIDTH_16;
1013 	writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
1014 #endif
1015 	/* select ECC scheme */
1016 #if defined(CONFIG_NAND_OMAP_ECCSCHEME)
1017 	err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
1018 			CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
1019 #else
1020 	/* pagesize and oobsize are not required to configure sw ecc-scheme */
1021 	err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
1022 			0, 0);
1023 #endif
1024 	if (err)
1025 		return err;
1026 
1027 #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
1028 	nand->read_buf = omap_nand_read_prefetch;
1029 #else
1030 	if (nand->options & NAND_BUSWIDTH_16)
1031 		nand->read_buf = nand_read_buf16;
1032 	else
1033 		nand->read_buf = nand_read_buf;
1034 #endif
1035 
1036 	nand->dev_ready = omap_dev_ready;
1037 
1038 	return 0;
1039 }
1040