mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com>
To: <robh+dt@kernel.org>, <pawel.moll@arm.com>,
	<mark.rutland@arm.com>, <ijc+devicetree@hellion.org.uk>,
	<galak@codeaurora.org>, <rob@landley.net>,
	<michal.simek@xilinx.com>, <grant.likely@linaro.org>,
	<gregkh@linuxfoundation.org>, <jason@lakedaemon.net>,
	<ezequiel.garcia@free-electrons.com>, <arnd@arndb.de>,
	<dwmw2@infradead.org>, <computersforpeace@gmail.com>,
	<artem.bityutskiy@linux.intel.com>, <jussi.kivilinna@iki.fi>,
	<acourbot@nvidia.com>, <ivan.khoronzhuk@ti.com>,
	<joern@logfs.org>
Cc: <devicetree@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <linux-mtd@lists.infradead.org>,
	<kpc528@gmail.com>, <kalluripunnaiahchoudary@gmail.com>,
	<punnaia@xilinx.com>
Subject: [PATCH v7 2/3] nand: pl353: Add software ecc support
Date: Mon, 8 Jun 2015 23:38:37 +0530	[thread overview]
Message-ID: <1433786918-21500-3-git-send-email-punnaia@xilinx.com> (raw)
In-Reply-To: <1433786918-21500-1-git-send-email-punnaia@xilinx.com>

Added software ecc support.

Signed-off-by: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
---
Changes in v7:
- None
Changes in v6:
- None
Changes in v5:
- None
Changes in v4:
- Updated the driver to sync with pl353_smc driver APIs
---
 drivers/mtd/nand/pl353_nand.c |  164 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 164 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/nand/pl353_nand.c b/drivers/mtd/nand/pl353_nand.c
index ff6cf3e..7e39939 100644
--- a/drivers/mtd/nand/pl353_nand.c
+++ b/drivers/mtd/nand/pl353_nand.c
@@ -331,6 +331,71 @@ static int pl353_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
+ * pl353_nand_read_page_raw - [Intern] read raw page data without ecc
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ * @page:		Page number to read
+ *
+ * Return:	Always return zero
+ */
+static int pl353_nand_read_page_raw(struct mtd_info *mtd,
+				struct nand_chip *chip,
+				uint8_t *buf, int oob_required, int page)
+{
+	unsigned long data_phase_addr;
+	uint8_t *p;
+
+	chip->read_buf(mtd, buf, mtd->writesize);
+
+	p = chip->oob_poi;
+	chip->read_buf(mtd, p,
+			(mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH));
+	p += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH);
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_R;
+	data_phase_addr |= PL353_NAND_CLEAR_CS;
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+
+	chip->read_buf(mtd, p, PL353_NAND_LAST_TRANSFER_LENGTH);
+	return 0;
+}
+
+/**
+ * pl353_nand_write_page_raw - [Intern] raw page write function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ *
+ * Return:	Always return zero
+ */
+static int pl353_nand_write_page_raw(struct mtd_info *mtd,
+				    struct nand_chip *chip,
+				    const uint8_t *buf, int oob_required)
+{
+	unsigned long data_phase_addr;
+	uint8_t *p;
+
+	chip->write_buf(mtd, buf, mtd->writesize);
+
+	p = chip->oob_poi;
+	chip->write_buf(mtd, p,
+			(mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH));
+	p += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH);
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_W;
+	data_phase_addr |= PL353_NAND_CLEAR_CS;
+	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+	chip->IO_ADDR_W = (void __iomem * __force)data_phase_addr;
+
+	chip->write_buf(mtd, p, PL353_NAND_LAST_TRANSFER_LENGTH);
+
+	return 0;
+}
+
+/**
  * nand_write_page_hwecc - Hardware ECC based page write function
  * @mtd:		Pointer to the mtd info structure
  * @chip:		Pointer to the NAND chip info structure
@@ -396,6 +461,39 @@ static int pl353_nand_write_page_hwecc(struct mtd_info *mtd,
 }
 
 /**
+ * pl353_nand_write_page_swecc - [REPLACEABLE] software ecc based page write
+ * function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ *
+ * Return:	Always return zero
+ */
+static int pl353_nand_write_page_swecc(struct mtd_info *mtd,
+				    struct nand_chip *chip, const uint8_t *buf,
+				    int oob_required)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	const uint8_t *p = buf;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	/* Software ecc calculation */
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+	chip->ecc.write_page_raw(mtd, chip, buf, 1);
+
+	return 0;
+}
+
+/**
  * pl353_nand_read_page_hwecc - Hardware ECC based page read function
  * @mtd:		Pointer to the mtd info structure
  * @chip:		Pointer to the NAND chip info structure
@@ -477,6 +575,52 @@ static int pl353_nand_read_page_hwecc(struct mtd_info *mtd,
 }
 
 /**
+ * pl353_nand_read_page_swecc - [REPLACEABLE] software ecc based page read
+ * function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the buffer to store read data
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ * @page:		Page number to read
+ *
+ * Return:	Always return zero
+ */
+static int pl353_nand_read_page_swecc(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;
+
+	chip->ecc.read_page_raw(mtd, chip, buf, page, 1);
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+	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;
+}
+
+/**
  * pl353_nand_select_chip - Select the flash device
  * @mtd:	Pointer to the mtd info structure
  * @chip:	Pointer to the NAND chip info structure
@@ -708,6 +852,8 @@ static int pl353_nand_ecc_init(struct mtd_info *mtd)
 	nand_chip->ecc.read_oob = pl353_nand_read_oob;
 	nand_chip->ecc.write_oob = pl353_nand_write_oob;
 	nand_chip->ecc.strength = 1;
+	nand_chip->ecc.read_page_raw = pl353_nand_read_page_raw;
+	nand_chip->ecc.write_page_raw = pl353_nand_write_page_raw;
 
 	switch (xnand->ecc_mode) {
 	case NAND_ECC_HW:
@@ -734,6 +880,24 @@ static int pl353_nand_ecc_init(struct mtd_info *mtd)
 			nand_chip->ecc.layout = &nand_oob_64;
 
 		break;
+	case NAND_ECC_SOFT:
+		/*
+		 * The software ECC routines won't work with the
+		 * SMC controller
+		 */
+		nand_chip->ecc.mode = NAND_ECC_HW;
+		nand_chip->ecc.calculate = nand_calculate_ecc;
+		nand_chip->ecc.correct = nand_correct_data;
+		nand_chip->ecc.read_page = pl353_nand_read_page_swecc;
+		nand_chip->ecc.write_page = pl353_nand_write_page_swecc;
+		nand_chip->ecc.size = 256;
+		nand_chip->ecc.bytes = 3;
+		/* Bypass the controller ECC block */
+		pl353_smc_set_ecc_pg_size(mtd->dev.parent, mtd->writesize);
+		pl353_smc_set_ecc_mode(mtd->dev.parent,
+					PL353_SMC_ECCMODE_BYPASS);
+
+		break;
 	default:
 		return -ENOTSUPP;
 	}
-- 
1.7.4


  parent reply	other threads:[~2015-06-08 18:09 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-08 18:08 [PATCH v7 0/3] Add arm pl353 smc nand driver for xilinx zynq soc Punnaiah Choudary Kalluri
2015-06-08 18:08 ` [PATCH v7 1/3] nand: pl353: Add basic driver for arm pl353 smc nand interface Punnaiah Choudary Kalluri
2015-06-15  4:21   ` punnaiah choudary kalluri
2016-10-21 20:33   ` [v7, " Jason Gunthorpe
2016-10-21 21:46     ` Boris Brezillon
2016-10-23 12:07       ` punnaiah choudary kalluri
2016-10-24 12:27         ` Boris Brezillon
2016-10-24 22:59         ` Jason Gunthorpe
2016-10-25  3:58           ` Punnaiah Choudary Kalluri
2016-10-25  4:46             ` Jason Gunthorpe
2016-10-25  5:02               ` Punnaiah Choudary Kalluri
2015-06-08 18:08 ` Punnaiah Choudary Kalluri [this message]
2015-06-08 18:08 ` [PATCH v7 3/3] Documentation: nand: pl353: Add documentation for controller and driver Punnaiah Choudary Kalluri
2015-07-08 19:40 ` [PATCH v7 0/3] Add arm pl353 smc nand driver for xilinx zynq soc Josh Cartwright
2015-07-09  5:05   ` Michal Simek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1433786918-21500-3-git-send-email-punnaia@xilinx.com \
    --to=punnaiah.choudary.kalluri@xilinx.com \
    --cc=acourbot@nvidia.com \
    --cc=arnd@arndb.de \
    --cc=artem.bityutskiy@linux.intel.com \
    --cc=computersforpeace@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dwmw2@infradead.org \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=galak@codeaurora.org \
    --cc=grant.likely@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=ivan.khoronzhuk@ti.com \
    --cc=jason@lakedaemon.net \
    --cc=joern@logfs.org \
    --cc=jussi.kivilinna@iki.fi \
    --cc=kalluripunnaiahchoudary@gmail.com \
    --cc=kpc528@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=michal.simek@xilinx.com \
    --cc=pawel.moll@arm.com \
    --cc=punnaia@xilinx.com \
    --cc=rob@landley.net \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®