/*
 * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
 * Rohit Choraria <rohitkc@ti.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch/mem.h>
#include <linux/mtd/omap_gpmc.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/bch.h>
#include <linux/compiler.h>
#include <nand.h>
#include <linux/mtd/omap_elm.h>

#define BADBLOCK_MARKER_LENGTH	2
#define SECTOR_BYTES		512
#define ECCCLEAR		(0x1 << 8)
#define ECCRESULTREG1		(0x1 << 0)
/* 4 bit padding to make byte aligned, 56 = 52 + 4 */
#define BCH4_BIT_PAD		4

#ifdef CONFIG_BCH
static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
				0x97, 0x79, 0xe5, 0x24, 0xb5};
#endif
static uint8_t cs_next;
static __maybe_unused struct nand_ecclayout omap_ecclayout;

#if defined(CONFIG_NAND_OMAP_GPMC_WSCFG)
static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE] =
	{ CONFIG_NAND_OMAP_GPMC_WSCFG };
#else
/* wscfg is preset to zero since its a static variable */
static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE];
#endif

/*
 * Driver configurations
 */
struct omap_nand_info {
	struct bch_control *control;
	enum omap_ecc ecc_scheme;
	uint8_t cs;
	uint8_t ws;		/* wait status pin (0,1) */
};

/* We are wasting a bit of memory but al least we are safe */
static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];

/*
 * omap_nand_hwcontrol - Set the address pointers corretly for the
 *			following address/data/command operation
 */
static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
				uint32_t ctrl)
{
	register struct nand_chip *this = mtd->priv;
	struct omap_nand_info *info = this->priv;
	int cs = info->cs;

	/*
	 * Point the IO_ADDR to DATA and ADDRESS registers instead
	 * of chip address
	 */
	switch (ctrl) {
	case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
		this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
		break;
	case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
		this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
		break;
	case NAND_CTRL_CHANGE | NAND_NCE:
		this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
		break;
	}

	if (cmd != NAND_CMD_NONE)
		writeb(cmd, this->IO_ADDR_W);
}

/* Check wait pin as dev ready indicator */
static int omap_dev_ready(struct mtd_info *mtd)
{
	register struct nand_chip *this = mtd->priv;
	struct omap_nand_info *info = this->priv;
	return gpmc_cfg->status & (1 << (8 + info->ws));
}

/*
 * gen_true_ecc - This function will generate true ECC value, which
 * can be used when correcting data read from NAND flash memory core
 *
 * @ecc_buf:	buffer to store ecc code
 *
 * @return:	re-formatted ECC value
 */
static uint32_t gen_true_ecc(uint8_t *ecc_buf)
{
	return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
		((ecc_buf[2] & 0x0F) << 8);
}

/*
 * omap_correct_data - Compares the ecc read from nand spare area with ECC
 * registers values and corrects one bit error if it has occured
 * Further details can be had from OMAP TRM and the following selected links:
 * http://en.wikipedia.org/wiki/Hamming_code
 * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
 *
 * @mtd:		 MTD device structure
 * @dat:		 page data
 * @read_ecc:		 ecc read from nand flash
 * @calc_ecc:		 ecc read from ECC registers
 *
 * @return 0 if data is OK or corrected, else returns -1
 */
static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
				uint8_t *read_ecc, uint8_t *calc_ecc)
{
	uint32_t orig_ecc, new_ecc, res, hm;
	uint16_t parity_bits, byte;
	uint8_t bit;

	/* Regenerate the orginal ECC */
	orig_ecc = gen_true_ecc(read_ecc);
	new_ecc = gen_true_ecc(calc_ecc);
	/* Get the XOR of real ecc */
	res = orig_ecc ^ new_ecc;
	if (res) {
		/* Get the hamming width */
		hm = hweight32(res);
		/* Single bit errors can be corrected! */
		if (hm == 12) {
			/* Correctable data! */
			parity_bits = res >> 16;
			bit = (parity_bits & 0x7);
			byte = (parity_bits >> 3) & 0x1FF;
			/* Flip the bit to correct */
			dat[byte] ^= (0x1 << bit);
		} else if (hm == 1) {
			printf("Error: Ecc is wrong\n");
			/* ECC itself is corrupted */
			return 2;
		} else {
			/*
			 * hm distance != parity pairs OR one, could mean 2 bit
			 * error OR potentially be on a blank page..
			 * orig_ecc: contains spare area data from nand flash.
			 * new_ecc: generated ecc while reading data area.
			 * Note: if the ecc = 0, all data bits from which it was
			 * generated are 0xFF.
			 * The 3 byte(24 bits) ecc is generated per 512byte
			 * chunk of a page. If orig_ecc(from spare area)
			 * is 0xFF && new_ecc(computed now from data area)=0x0,
			 * this means that data area is 0xFF and spare area is
			 * 0xFF. A sure sign of a erased page!
			 */
			if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
				return 0;
			printf("Error: Bad compare! failed\n");
			/* detected 2 bit error */
			return -1;
		}
	}
	return 0;
}

/*
 * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
 * @mtd:	MTD device structure
 * @mode:	Read/Write mode
 */
__maybe_unused
static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
{
	struct nand_chip	*nand	= mtd->priv;
	struct omap_nand_info	*info	= nand->priv;
	unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
	unsigned int ecc_algo = 0;
	unsigned int bch_type = 0;
	unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
	u32 ecc_size_config_val = 0;
	u32 ecc_config_val = 0;
	int cs = info->cs;

	/* configure GPMC for specific ecc-scheme */
	switch (info->ecc_scheme) {
	case OMAP_ECC_HAM1_CODE_SW:
		return;
	case OMAP_ECC_HAM1_CODE_HW:
		ecc_algo = 0x0;
		bch_type = 0x0;
		bch_wrapmode = 0x00;
		eccsize0 = 0xFF;
		eccsize1 = 0xFF;
		break;
	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
	case OMAP_ECC_BCH8_CODE_HW:
		ecc_algo = 0x1;
		bch_type = 0x1;
		if (mode == NAND_ECC_WRITE) {
			bch_wrapmode = 0x01;
			eccsize0 = 0;  /* extra bits in nibbles per sector */
			eccsize1 = 28; /* OOB bits in nibbles per sector */
		} else {
			bch_wrapmode = 0x01;
			eccsize0 = 26; /* ECC bits in nibbles per sector */
			eccsize1 = 2;  /* non-ECC bits in nibbles per sector */
		}
		break;
	case OMAP_ECC_BCH16_CODE_HW:
		ecc_algo = 0x1;
		bch_type = 0x2;
		if (mode == NAND_ECC_WRITE) {
			bch_wrapmode = 0x01;
			eccsize0 = 0;  /* extra bits in nibbles per sector */
			eccsize1 = 52; /* OOB bits in nibbles per sector */
		} else {
			bch_wrapmode = 0x01;
			eccsize0 = 52; /* ECC bits in nibbles per sector */
			eccsize1 = 0;  /* non-ECC bits in nibbles per sector */
		}
		break;
	default:
		return;
	}
	/* Clear ecc and enable bits */
	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
	/* Configure ecc size for BCH */
	ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
	writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);

	/* Configure device details for BCH engine */
	ecc_config_val = ((ecc_algo << 16)	| /* HAM1 | BCHx */
			(bch_type << 12)	| /* BCH4/BCH8/BCH16 */
			(bch_wrapmode << 8)	| /* wrap mode */
			(dev_width << 7)	| /* bus width */
			(0x0 << 4)		| /* number of sectors */
			(cs <<  1)		| /* ECC CS */
			(0x1));			  /* enable ECC */
	writel(ecc_config_val, &gpmc_cfg->ecc_config);
}

/*
 *  omap_calculate_ecc - Read ECC result
 *  @mtd:	MTD structure
 *  @dat:	unused
 *  @ecc_code:	ecc_code buffer
 *  Using noninverted ECC can be considered ugly since writing a blank
 *  page ie. padding will clear the ECC bytes. This is no problem as
 *  long nobody is trying to write data on the seemingly unused page.
 *  Reading an erased page will produce an ECC mismatch between
 *  generated and read ECC bytes that has to be dealt with separately.
 *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
 *  is used, the result of read will be 0x0 while the ECC offsets of the
 *  spare area will be 0xFF which will result in an ECC mismatch.
 */
static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
				uint8_t *ecc_code)
{
	struct nand_chip *chip = mtd->priv;
	struct omap_nand_info *info = chip->priv;
	uint32_t *ptr, val = 0;
	int8_t i = 0, j;

	switch (info->ecc_scheme) {
	case OMAP_ECC_HAM1_CODE_HW:
		val = readl(&gpmc_cfg->ecc1_result);
		ecc_code[0] = val & 0xFF;
		ecc_code[1] = (val >> 16) & 0xFF;
		ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
		break;
#ifdef CONFIG_BCH
	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
#endif
	case OMAP_ECC_BCH8_CODE_HW:
		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
		val = readl(ptr);
		ecc_code[i++] = (val >>  0) & 0xFF;
		ptr--;
		for (j = 0; j < 3; j++) {
			val = readl(ptr);
			ecc_code[i++] = (val >> 24) & 0xFF;
			ecc_code[i++] = (val >> 16) & 0xFF;
			ecc_code[i++] = (val >>  8) & 0xFF;
			ecc_code[i++] = (val >>  0) & 0xFF;
			ptr--;
		}
		break;
	case OMAP_ECC_BCH16_CODE_HW:
		val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[2]);
		ecc_code[i++] = (val >>  8) & 0xFF;
		ecc_code[i++] = (val >>  0) & 0xFF;
		val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[1]);
		ecc_code[i++] = (val >> 24) & 0xFF;
		ecc_code[i++] = (val >> 16) & 0xFF;
		ecc_code[i++] = (val >>  8) & 0xFF;
		ecc_code[i++] = (val >>  0) & 0xFF;
		val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[0]);
		ecc_code[i++] = (val >> 24) & 0xFF;
		ecc_code[i++] = (val >> 16) & 0xFF;
		ecc_code[i++] = (val >>  8) & 0xFF;
		ecc_code[i++] = (val >>  0) & 0xFF;
		for (j = 3; j >= 0; j--) {
			val = readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[j]
									);
			ecc_code[i++] = (val >> 24) & 0xFF;
			ecc_code[i++] = (val >> 16) & 0xFF;
			ecc_code[i++] = (val >>  8) & 0xFF;
			ecc_code[i++] = (val >>  0) & 0xFF;
		}
		break;
	default:
		return -EINVAL;
	}
	/* ECC scheme specific syndrome customizations */
	switch (info->ecc_scheme) {
	case OMAP_ECC_HAM1_CODE_HW:
		break;
#ifdef CONFIG_BCH
	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:

		for (i = 0; i < chip->ecc.bytes; i++)
			*(ecc_code + i) = *(ecc_code + i) ^
						bch8_polynomial[i];
		break;
#endif
	case OMAP_ECC_BCH8_CODE_HW:
		ecc_code[chip->ecc.bytes - 1] = 0x00;
		break;
	case OMAP_ECC_BCH16_CODE_HW:
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH

#define PREFETCH_CONFIG1_CS_SHIFT	24
#define PREFETCH_FIFOTHRESHOLD_MAX	0x40
#define PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
#define PREFETCH_STATUS_COUNT(val)	(val & 0x00003fff)
#define PREFETCH_STATUS_FIFO_CNT(val)	((val >> 24) & 0x7F)
#define ENABLE_PREFETCH			(1 << 7)

/**
 * omap_prefetch_enable - configures and starts prefetch transfer
 * @fifo_th: fifo threshold to be used for read/ write
 * @count: number of bytes to be transferred
 * @is_write: prefetch read(0) or write post(1) mode
 * @cs: chip select to use
 */
static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs)
{
	uint32_t val;

	if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
		return -EINVAL;

	if (readl(&gpmc_cfg->prefetch_control))
		return -EBUSY;

	/* Set the amount of bytes to be prefetched */
	writel(count, &gpmc_cfg->prefetch_config2);

	val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) |
		PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH;
	writel(val, &gpmc_cfg->prefetch_config1);

	/*  Start the prefetch engine */
	writel(1, &gpmc_cfg->prefetch_control);

	return 0;
}

/**
 * omap_prefetch_reset - disables and stops the prefetch engine
 */
static void omap_prefetch_reset(void)
{
	writel(0, &gpmc_cfg->prefetch_control);
	writel(0, &gpmc_cfg->prefetch_config1);
}

static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len)
{
	int ret;
	uint32_t cnt;
	struct omap_nand_info *info = chip->priv;

	ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
	if (ret < 0)
		return ret;

	do {
		int i;

		cnt = readl(&gpmc_cfg->prefetch_status);
		cnt = PREFETCH_STATUS_FIFO_CNT(cnt);

		for (i = 0; i < cnt / 4; i++) {
			*buf++ = readl(CONFIG_SYS_NAND_BASE);
			len -= 4;
		}
	} while (len);

	omap_prefetch_reset();

	return 0;
}

static inline void omap_nand_read(struct mtd_info *mtd, uint8_t *buf, int len)
{
	struct nand_chip *chip = mtd->priv;

	if (chip->options & NAND_BUSWIDTH_16)
		nand_read_buf16(mtd, buf, len);
	else
		nand_read_buf(mtd, buf, len);
}

static void omap_nand_read_prefetch(struct mtd_info *mtd, uint8_t *buf, int len)
{
	int ret;
	uint32_t head, tail;
	struct nand_chip *chip = mtd->priv;

	/*
	 * If the destination buffer is unaligned, start with reading
	 * the overlap byte-wise.
	 */
	head = ((uint32_t) buf) % 4;
	if (head) {
		omap_nand_read(mtd, buf, head);
		buf += head;
		len -= head;
	}

	/*
	 * Only transfer multiples of 4 bytes in a pre-fetched fashion.
	 * If there's a residue, care for it byte-wise afterwards.
	 */
	tail = len % 4;

	ret = __read_prefetch_aligned(chip, (uint32_t *)buf, len - tail);
	if (ret < 0) {
		/* fallback in case the prefetch engine is busy */
		omap_nand_read(mtd, buf, len);
	} else if (tail) {
		buf += len - tail;
		omap_nand_read(mtd, buf, tail);
	}
}
#endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */

#ifdef CONFIG_NAND_OMAP_ELM
/*
 * omap_reverse_list - re-orders list elements in reverse order [internal]
 * @list:	pointer to start of list
 * @length:	length of list
*/
static void omap_reverse_list(u8 *list, unsigned int length)
{
	unsigned int i, j;
	unsigned int half_length = length / 2;
	u8 tmp;
	for (i = 0, j = length - 1; i < half_length; i++, j--) {
		tmp = list[i];
		list[i] = list[j];
		list[j] = tmp;
	}
}

/*
 * omap_correct_data_bch - Compares the ecc read from nand spare area
 * with ECC registers values and corrects one bit error if it has occured
 *
 * @mtd:	MTD device structure
 * @dat:	page data
 * @read_ecc:	ecc read from nand flash (ignored)
 * @calc_ecc:	ecc read from ECC registers
 *
 * @return 0 if data is OK or corrected, else returns -1
 */
static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
				uint8_t *read_ecc, uint8_t *calc_ecc)
{
	struct nand_chip *chip = mtd->priv;
	struct omap_nand_info *info = chip->priv;
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	uint32_t error_count = 0, error_max;
	uint32_t error_loc[ELM_MAX_ERROR_COUNT];
	enum bch_level bch_type;
	uint32_t i, ecc_flag = 0;
	uint8_t count;
	uint32_t byte_pos, bit_pos;
	int err = 0;

	/* check calculated ecc */
	for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
		if (calc_ecc[i] != 0x00)
			ecc_flag = 1;
	}
	if (!ecc_flag)
		return 0;

	/* check for whether its a erased-page */
	ecc_flag = 0;
	for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
		if (read_ecc[i] != 0xff)
			ecc_flag = 1;
	}
	if (!ecc_flag)
		return 0;

	/*
	 * while reading ECC result we read it in big endian.
	 * Hence while loading to ELM we have rotate to get the right endian.
	 */
	switch (info->ecc_scheme) {
	case OMAP_ECC_BCH8_CODE_HW:
		bch_type = BCH_8_BIT;
		omap_reverse_list(calc_ecc, ecc->bytes - 1);
		break;
	case OMAP_ECC_BCH16_CODE_HW:
		bch_type = BCH_16_BIT;
		omap_reverse_list(calc_ecc, ecc->bytes);
		break;
	default:
		return -EINVAL;
	}
	/* use elm module to check for errors */
	elm_config(bch_type);
	err = elm_check_error(calc_ecc, bch_type, &error_count, error_loc);
	if (err)
		return err;

	/* correct bch error */
	for (count = 0; count < error_count; count++) {
		switch (info->ecc_scheme) {
		case OMAP_ECC_BCH8_CODE_HW:
			/* 14th byte in ECC is reserved to match ROM layout */
			error_max = SECTOR_BYTES + (ecc->bytes - 1);
			break;
		case OMAP_ECC_BCH16_CODE_HW:
			error_max = SECTOR_BYTES + ecc->bytes;
			break;
		default:
			return -EINVAL;
		}
		byte_pos = error_max - (error_loc[count] / 8) - 1;
		bit_pos  = error_loc[count] % 8;
		if (byte_pos < SECTOR_BYTES) {
			dat[byte_pos] ^= 1 << bit_pos;
			debug("nand: bit-flip corrected @data=%d\n", byte_pos);
		} else if (byte_pos < error_max) {
			read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
			debug("nand: bit-flip corrected @oob=%d\n", byte_pos -
								SECTOR_BYTES);
		} else {
			err = -EBADMSG;
			printf("nand: error: invalid bit-flip location\n");
		}
	}
	return (err) ? err : error_count;
}

/**
 * omap_read_page_bch - hardware ecc based page read function
 * @mtd:	mtd info structure
 * @chip:	nand chip info structure
 * @buf:	buffer to store read data
 * @oob_required: caller expects OOB data read to chip->oob_poi
 * @page:	page number to read
 *
 */
static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
				uint8_t *buf, int oob_required, int page)
{
	int i, eccsize = chip->ecc.size;
	int eccbytes = chip->ecc.bytes;
	int eccsteps = chip->ecc.steps;
	uint8_t *p = buf;
	uint8_t *ecc_calc = chip->buffers->ecccalc;
	uint8_t *ecc_code = chip->buffers->ecccode;
	uint32_t *eccpos = chip->ecc.layout->eccpos;
	uint8_t *oob = chip->oob_poi;
	uint32_t data_pos;
	uint32_t oob_pos;

	data_pos = 0;
	/* oob area start */
	oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
	oob += chip->ecc.layout->eccpos[0];

	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
				oob += eccbytes) {
		chip->ecc.hwctl(mtd, NAND_ECC_READ);
		/* read data */
		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, -1);
		chip->read_buf(mtd, p, eccsize);

		/* read respective ecc from oob area */
		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
		chip->read_buf(mtd, oob, eccbytes);
		/* read syndrome */
		chip->ecc.calculate(mtd, p, &ecc_calc[i]);

		data_pos += eccsize;
		oob_pos += eccbytes;
	}

	for (i = 0; i < chip->ecc.total; i++)
		ecc_code[i] = chip->oob_poi[eccpos[i]];

	eccsteps = chip->ecc.steps;
	p = buf;

	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
		int stat;

		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
		if (stat < 0)
			mtd->ecc_stats.failed++;
		else
			mtd->ecc_stats.corrected += stat;
	}
	return 0;
}
#endif /* CONFIG_NAND_OMAP_ELM */

/*
 * OMAP3 BCH8 support (with BCH library)
 */
#ifdef CONFIG_BCH
/**
 * omap_correct_data_bch_sw - Decode received data and correct errors
 * @mtd: MTD device structure
 * @data: page data
 * @read_ecc: ecc read from nand flash
 * @calc_ecc: ecc read from HW ECC registers
 */
static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
				 u_char *read_ecc, u_char *calc_ecc)
{
	int i, count;
	/* cannot correct more than 8 errors */
	unsigned int errloc[8];
	struct nand_chip *chip = mtd->priv;
	struct omap_nand_info *info = chip->priv;

	count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
							NULL, errloc);
	if (count > 0) {
		/* correct errors */
		for (i = 0; i < count; i++) {
			/* correct data only, not ecc bytes */
			if (errloc[i] < 8*512)
				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
			debug("corrected bitflip %u\n", errloc[i]);
#ifdef DEBUG
			puts("read_ecc: ");
			/*
			 * BCH8 have 13 bytes of ECC; BCH4 needs adoption
			 * here!
			 */
			for (i = 0; i < 13; i++)
				printf("%02x ", read_ecc[i]);
			puts("\n");
			puts("calc_ecc: ");
			for (i = 0; i < 13; i++)
				printf("%02x ", calc_ecc[i]);
			puts("\n");
#endif
		}
	} else if (count < 0) {
		puts("ecc unrecoverable error\n");
	}
	return count;
}

/**
 * omap_free_bch - Release BCH ecc resources
 * @mtd: MTD device structure
 */
static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd->priv;
	struct omap_nand_info *info = chip->priv;

	if (info->control) {
		free_bch(info->control);
		info->control = NULL;
	}
}
#endif /* CONFIG_BCH */

/**
 * omap_select_ecc_scheme - configures driver for particular ecc-scheme
 * @nand: NAND chip device structure
 * @ecc_scheme: ecc scheme to configure
 * @pagesize: number of main-area bytes per page of NAND device
 * @oobsize: number of OOB/spare bytes per page of NAND device
 */
static int omap_select_ecc_scheme(struct nand_chip *nand,
	enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
	struct omap_nand_info	*info		= nand->priv;
	struct nand_ecclayout	*ecclayout	= &omap_ecclayout;
	int eccsteps = pagesize / SECTOR_BYTES;
	int i;

	switch (ecc_scheme) {
	case OMAP_ECC_HAM1_CODE_SW:
		debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
		/* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
		 * initialized in nand_scan_tail(), so just set ecc.mode */
		info->control		= NULL;
		nand->ecc.mode		= NAND_ECC_SOFT;
		nand->ecc.layout	= NULL;
		nand->ecc.size		= 0;
		break;

	case OMAP_ECC_HAM1_CODE_HW:
		debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
		/* check ecc-scheme requirements before updating ecc info */
		if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
			printf("nand: error: insufficient OOB: require=%d\n", (
				(3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
			return -EINVAL;
		}
		info->control		= NULL;
		/* populate ecc specific fields */
		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
		nand->ecc.mode		= NAND_ECC_HW;
		nand->ecc.strength	= 1;
		nand->ecc.size		= SECTOR_BYTES;
		nand->ecc.bytes		= 3;
		nand->ecc.hwctl		= omap_enable_hwecc;
		nand->ecc.correct	= omap_correct_data;
		nand->ecc.calculate	= omap_calculate_ecc;
		/* define ecc-layout */
		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
		for (i = 0; i < ecclayout->eccbytes; i++) {
			if (nand->options & NAND_BUSWIDTH_16)
				ecclayout->eccpos[i] = i + 2;
			else
				ecclayout->eccpos[i] = i + 1;
		}
		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
						BADBLOCK_MARKER_LENGTH;
		break;

	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
#ifdef CONFIG_BCH
		debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
		/* check ecc-scheme requirements before updating ecc info */
		if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
			printf("nand: error: insufficient OOB: require=%d\n", (
				(13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
			return -EINVAL;
		}
		/* check if BCH S/W library can be used for error detection */
		info->control = init_bch(13, 8, 0x201b);
		if (!info->control) {
			printf("nand: error: could not init_bch()\n");
			return -ENODEV;
		}
		/* populate ecc specific fields */
		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
		nand->ecc.mode		= NAND_ECC_HW;
		nand->ecc.strength	= 8;
		nand->ecc.size		= SECTOR_BYTES;
		nand->ecc.bytes		= 13;
		nand->ecc.hwctl		= omap_enable_hwecc;
		nand->ecc.correct	= omap_correct_data_bch_sw;
		nand->ecc.calculate	= omap_calculate_ecc;
		/* define ecc-layout */
		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
		ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
		for (i = 1; i < ecclayout->eccbytes; i++) {
			if (i % nand->ecc.bytes)
				ecclayout->eccpos[i] =
						ecclayout->eccpos[i - 1] + 1;
			else
				ecclayout->eccpos[i] =
						ecclayout->eccpos[i - 1] + 2;
		}
		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
						BADBLOCK_MARKER_LENGTH;
		break;
#else
		printf("nand: error: CONFIG_BCH required for ECC\n");
		return -EINVAL;
#endif

	case OMAP_ECC_BCH8_CODE_HW:
#ifdef CONFIG_NAND_OMAP_ELM
		debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
		/* check ecc-scheme requirements before updating ecc info */
		if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
			printf("nand: error: insufficient OOB: require=%d\n", (
				(14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
			return -EINVAL;
		}
		/* intialize ELM for ECC error detection */
		elm_init();
		info->control		= NULL;
		/* populate ecc specific fields */
		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
		nand->ecc.mode		= NAND_ECC_HW;
		nand->ecc.strength	= 8;
		nand->ecc.size		= SECTOR_BYTES;
		nand->ecc.bytes		= 14;
		nand->ecc.hwctl		= omap_enable_hwecc;
		nand->ecc.correct	= omap_correct_data_bch;
		nand->ecc.calculate	= omap_calculate_ecc;
		nand->ecc.read_page	= omap_read_page_bch;
		/* define ecc-layout */
		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
		for (i = 0; i < ecclayout->eccbytes; i++)
			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
						BADBLOCK_MARKER_LENGTH;
		break;
#else
		printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
		return -EINVAL;
#endif

	case OMAP_ECC_BCH16_CODE_HW:
#ifdef CONFIG_NAND_OMAP_ELM
		debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");
		/* check ecc-scheme requirements before updating ecc info */
		if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
			printf("nand: error: insufficient OOB: require=%d\n", (
				(26 * eccsteps) + BADBLOCK_MARKER_LENGTH));
			return -EINVAL;
		}
		/* intialize ELM for ECC error detection */
		elm_init();
		/* populate ecc specific fields */
		nand->ecc.mode		= NAND_ECC_HW;
		nand->ecc.size		= SECTOR_BYTES;
		nand->ecc.bytes		= 26;
		nand->ecc.strength	= 16;
		nand->ecc.hwctl		= omap_enable_hwecc;
		nand->ecc.correct	= omap_correct_data_bch;
		nand->ecc.calculate	= omap_calculate_ecc;
		nand->ecc.read_page	= omap_read_page_bch;
		/* define ecc-layout */
		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps;
		for (i = 0; i < ecclayout->eccbytes; i++)
			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
		ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
						BADBLOCK_MARKER_LENGTH;
		break;
#else
		printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
		return -EINVAL;
#endif
	default:
		debug("nand: error: ecc scheme not enabled or supported\n");
		return -EINVAL;
	}

	/* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
	if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
		nand->ecc.layout = ecclayout;

	info->ecc_scheme = ecc_scheme;
	return 0;
}

#ifndef CONFIG_SPL_BUILD
/*
 * omap_nand_switch_ecc - switch the ECC operation between different engines
 * (h/w and s/w) and different algorithms (hamming and BCHx)
 *
 * @hardware		- true if one of the HW engines should be used
 * @eccstrength		- the number of bits that could be corrected
 *			  (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
 */
int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
{
	struct nand_chip *nand;
	struct mtd_info *mtd;
	int err = 0;

	if (nand_curr_device < 0 ||
	    nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
	    !nand_info[nand_curr_device].name) {
		printf("nand: error: no NAND devices found\n");
		return -ENODEV;
	}

	mtd = &nand_info[nand_curr_device];
	nand = mtd->priv;
	nand->options |= NAND_OWN_BUFFERS;
	nand->options &= ~NAND_SUBPAGE_READ;
	/* Setup the ecc configurations again */
	if (hardware) {
		if (eccstrength == 1) {
			err = omap_select_ecc_scheme(nand,
					OMAP_ECC_HAM1_CODE_HW,
					mtd->writesize, mtd->oobsize);
		} else if (eccstrength == 8) {
			err = omap_select_ecc_scheme(nand,
					OMAP_ECC_BCH8_CODE_HW,
					mtd->writesize, mtd->oobsize);
		} else {
			printf("nand: error: unsupported ECC scheme\n");
			return -EINVAL;
		}
	} else {
		if (eccstrength == 1) {
			err = omap_select_ecc_scheme(nand,
					OMAP_ECC_HAM1_CODE_SW,
					mtd->writesize, mtd->oobsize);
		} else if (eccstrength == 8) {
			err = omap_select_ecc_scheme(nand,
					OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
					mtd->writesize, mtd->oobsize);
		} else {
			printf("nand: error: unsupported ECC scheme\n");
			return -EINVAL;
		}
	}

	/* Update NAND handling after ECC mode switch */
	if (!err)
		err = nand_scan_tail(mtd);
	return err;
}
#endif /* CONFIG_SPL_BUILD */

/*
 * Board-specific NAND initialization. The following members of the
 * argument are board-specific:
 * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
 * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
 * - cmd_ctrl: hardwarespecific function for accesing control-lines
 * - waitfunc: hardwarespecific function for accesing device ready/busy line
 * - ecc.hwctl: function to enable (reset) hardware ecc generator
 * - ecc.mode: mode of ecc, see defines
 * - chip_delay: chip dependent delay for transfering data from array to
 *   read regs (tR)
 * - options: various chip options. They can partly be set to inform
 *   nand_scan about special functionality. See the defines for further
 *   explanation
 */
int board_nand_init(struct nand_chip *nand)
{
	int32_t gpmc_config = 0;
	int cs = cs_next++;
	int err = 0;
	/*
	 * xloader/Uboot's gpmc configuration would have configured GPMC for
	 * nand type of memory. The following logic scans and latches on to the
	 * first CS with NAND type memory.
	 * TBD: need to make this logic generic to handle multiple CS NAND
	 * devices.
	 */
	while (cs < GPMC_MAX_CS) {
		/* Check if NAND type is set */
		if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
			/* Found it!! */
			break;
		}
		cs++;
	}
	if (cs >= GPMC_MAX_CS) {
		printf("nand: error: Unable to find NAND settings in "
			"GPMC Configuration - quitting\n");
		return -ENODEV;
	}

	gpmc_config = readl(&gpmc_cfg->config);
	/* Disable Write protect */
	gpmc_config |= 0x10;
	writel(gpmc_config, &gpmc_cfg->config);

	nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
	nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
	omap_nand_info[cs].control = NULL;
	omap_nand_info[cs].cs = cs;
	omap_nand_info[cs].ws = wscfg[cs];
	nand->priv	= &omap_nand_info[cs];
	nand->cmd_ctrl	= omap_nand_hwcontrol;
	nand->options	|= NAND_NO_PADDING | NAND_CACHEPRG;
	nand->chip_delay = 100;
	nand->ecc.layout = &omap_ecclayout;

	/* configure driver and controller based on NAND device bus-width */
	gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
#if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
	nand->options |= NAND_BUSWIDTH_16;
	writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
#else
	nand->options &= ~NAND_BUSWIDTH_16;
	writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
#endif
	/* select ECC scheme */
#if defined(CONFIG_NAND_OMAP_ECCSCHEME)
	err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
			CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
#else
	/* pagesize and oobsize are not required to configure sw ecc-scheme */
	err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
			0, 0);
#endif
	if (err)
		return err;

#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
	nand->read_buf = omap_nand_read_prefetch;
#else
	if (nand->options & NAND_BUSWIDTH_16)
		nand->read_buf = nand_read_buf16;
	else
		nand->read_buf = nand_read_buf;
#endif

	nand->dev_ready = omap_dev_ready;

	return 0;
}
