mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 09/13] imx nand: move initialization to preset function
Date: Wed, 10 Nov 2010 15:53:55 +0100	[thread overview]
Message-ID: <1289400839-5937-10-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1289400839-5937-1-git-send-email-s.hauer@pengutronix.de>

This has two purposes. First we need to factor out initialization
to be able to do something different on v3 type controllers,
second with this patch we are independent of preinitialized register
values.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_imx.c |  110 +++++++++++++++++++++++++++---------------
 1 files changed, 71 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index 214f391..b3191a7 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -64,6 +64,8 @@
 #define NFC_V1_V2_CONFIG1_RST		(1 << 6)
 #define NFC_V1_V2_CONFIG1_CE		(1 << 7)
 #define NFC_V1_V2_CONFIG1_ONE_CYCLE	(1 << 8)
+#define NFC_V2_CONFIG1_PPB(x)		(((x) & 0x3) << 9)
+#define NFC_V2_CONFIG1_FP_INT		(1 << 11)
 
 #define NFC_V1_V2_CONFIG2_INT		(1 << 15)
 
@@ -640,6 +642,67 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
 }
 
 /*
+ * v2 and v3 type controllers can do 4bit or 8bit ecc depending
+ * on how much oob the nand chip has. For 8bit ecc we need at least
+ * 26 bytes of oob data per 512 byte block.
+ */
+static int get_eccsize(struct mtd_info *mtd)
+{
+	int oobbytes_per_512 = 0;
+
+	oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize;
+
+	if (oobbytes_per_512 < 26)
+		return 4;
+	else
+		return 8;
+}
+
+static void preset_v1_v2(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct imx_nand_host *host = nand_chip->priv;
+	uint16_t config1 = 0;
+
+	if (nand_chip->ecc.mode == NAND_ECC_HW)
+		config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+
+	if (nfc_is_v21())
+		config1 |= NFC_V2_CONFIG1_FP_INT;
+
+	if (nfc_is_v21() && mtd->writesize) {
+		uint16_t pages_per_block = mtd->erasesize / mtd->writesize;
+
+		host->eccsize = get_eccsize(mtd);
+		if (host->eccsize == 4)
+			config1 |= NFC_V2_CONFIG1_ECC_MODE_4;
+
+		config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6);
+	} else {
+		host->eccsize = 1;
+	}
+
+	writew(config1, host->regs + NFC_V1_V2_CONFIG1);
+	/* preset operation */
+
+	/* Unlock the internal RAM Buffer */
+	writew(0x2, host->regs + NFC_V1_V2_CONFIG);
+
+	/* Blocks to be unlocked */
+	if (nfc_is_v21()) {
+		writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
+		writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
+	} else if (nfc_is_v1()) {
+		writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
+		writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
+	} else
+		BUG();
+
+	/* Unlock Block Command for given address range */
+	writew(0x4, host->regs + NFC_V1_V2_WRPROT);
+}
+
+/*
  * This function is used by the upper layer to write command to NAND Flash for
  * different operations to be carried out on NAND Flash
  *
@@ -667,6 +730,10 @@ static void imx_nand_command(struct mtd_info *mtd, unsigned command,
 	 * Command pre-processing step
 	 */
 	switch (command) {
+	case NAND_CMD_RESET:
+		host->preset(mtd);
+		host->send_cmd(host, command);
+		break;
 
 	case NAND_CMD_STATUS:
 		host->buf_start = 0;
@@ -745,7 +812,6 @@ static void imx_nand_command(struct mtd_info *mtd, unsigned command,
 
 	case NAND_CMD_ERASE1:
 	case NAND_CMD_ERASE2:
-	case NAND_CMD_RESET:
 		host->send_cmd(host, command);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
@@ -821,7 +887,6 @@ static int __init imxnd_probe(struct device_d *dev)
 	struct imx_nand_platform_data *pdata = dev->platform_data;
 	struct imx_nand_host *host;
 	struct nand_ecclayout *oob_smallpage, *oob_largepage;
-	u16 tmp;
 	int err = 0;
 
 #ifdef CONFIG_ARCH_IMX27
@@ -842,6 +907,7 @@ static int __init imxnd_probe(struct device_d *dev)
 	host->main_area0 = host->base;
 
 	if (nfc_is_v1() || nfc_is_v21()) {
+		host->preset = preset_v1_v2;
 		host->send_cmd = send_cmd_v1_v2;
 		host->send_addr = send_addr_v1_v2;
 		host->send_page = send_page_v1_v2;
@@ -853,14 +919,12 @@ static int __init imxnd_probe(struct device_d *dev)
 		host->regs = host->base + 0x1e00;
 		host->spare0 = host->base + 0x1000;
 		host->spare_len = 64;
-		host->eccsize = 1;
 		oob_smallpage = &nandv2_hw_eccoob_smallpage;
 		oob_largepage = &nandv2_hw_eccoob_largepage;
 	} else if (nfc_is_v1()) {
 		host->regs = host->base + 0xe00;
 		host->spare0 = host->base + 0x800;
 		host->spare_len = 16;
-		host->eccsize = 4;
 		oob_smallpage = &nandv1_hw_eccoob_smallpage;
 		oob_largepage = &nandv1_hw_eccoob_largepage;
 	}
@@ -891,14 +955,6 @@ static int __init imxnd_probe(struct device_d *dev)
 	clk_enable(host->clk);
 #endif
 
-	tmp = readw(host->regs + NFC_V1_V2_CONFIG1);
-	tmp |= NFC_V1_V2_CONFIG1_INT_MSK;
-	tmp &= ~NFC_V1_V2_CONFIG1_SP_EN;
-	if (nfc_is_v21())
-		/* currently no support for 218 byte OOB with stronger ECC */
-		tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
-	writew(tmp, host->regs + NFC_V1_V2_CONFIG1);
-
 	if (pdata->hw_ecc) {
 		this->ecc.calculate = imx_nand_calculate_ecc;
 		this->ecc.hwctl = imx_nand_enable_hwecc;
@@ -908,38 +964,11 @@ static int __init imxnd_probe(struct device_d *dev)
 			this->ecc.correct = imx_nand_correct_data_v2_v3;
 		this->ecc.mode = NAND_ECC_HW;
 		this->ecc.size = 512;
-		tmp = readw(host->regs + NFC_V1_V2_CONFIG1);
-		tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
-		writew(tmp, host->regs + NFC_V1_V2_CONFIG1);
 	} else {
 		this->ecc.size = 512;
 		this->ecc.mode = NAND_ECC_SOFT;
-		tmp = readw(host->regs + NFC_V1_V2_CONFIG1);
-		tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
-		writew(tmp, host->regs + NFC_V1_V2_CONFIG1);
 	}
 
-	/* Reset NAND */
-	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
-	/* preset operation */
-	/* Unlock the internal RAM Buffer */
-	writew(0x2, host->regs + NFC_V1_V2_CONFIG);
-
-	/* Blocks to be unlocked */
-	if (nfc_is_v21()) {
-		writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
-		writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
-		this->ecc.bytes = 9;
-	} else if (nfc_is_v1()) {
-		writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
-		writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
-		this->ecc.bytes = 3;
-	}
-
-	/* Unlock Block Command for given address range */
-	writew(0x4, host->regs + NFC_V1_V2_WRPROT);
-
 	this->ecc.layout = oob_smallpage;
 
 	/* NAND bus width determines access funtions used by upper layer */
@@ -962,6 +991,9 @@ static int __init imxnd_probe(struct device_d *dev)
 		goto escan;
 	}
 
+	/* Call preset again, with correct writesize this time */
+	host->preset(mtd);
+
 	imx_nand_set_layout(mtd->writesize, pdata->width == 2 ? 16 : 8);
 
 	if (mtd->writesize == 2048) {
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2010-11-10 14:54 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-10 14:53 add i.MX51 Nand support Sascha Hauer
2010-11-10 14:53 ` [PATCH 01/13] NAND: reset chips before usage like the kernel does Sascha Hauer
2010-11-10 14:53 ` [PATCH 02/13] imx_nand: remove 0xe00 offset from registers Sascha Hauer
2010-11-10 14:53 ` [PATCH 03/13] imx_nand: rework get_dev_status Sascha Hauer
2010-11-10 14:53 ` [PATCH 04/13] imx nand: remove unnecessary register write Sascha Hauer
2010-11-10 14:53 ` [PATCH 05/13] imx_nand: make some internally used functions overwriteable Sascha Hauer
2010-11-10 14:53 ` [PATCH 06/13] imx nand: do not read-modify-write SPAS register Sascha Hauer
2010-11-10 14:53 ` [PATCH 07/13] imx nand: add V1_V2 namespace to registers Sascha Hauer
2010-11-10 14:53 ` [PATCH 08/13] mxc_nand: fix correct_data function Sascha Hauer
2010-11-11  5:25   ` Baruch Siach
2010-11-11 10:32     ` Sascha Hauer
2010-11-15 12:08       ` [PATCH] " Baruch Siach
2010-11-10 14:53 ` Sascha Hauer [this message]
2010-11-10 14:53 ` [PATCH 10/13] imx nand: introduce overwritable check_int function Sascha Hauer
2010-11-10 14:53 ` [PATCH 11/13] imx nand: Add v3 (i.MX51) support Sascha Hauer
2010-11-10 14:53 ` [PATCH 12/13] fb: set id for framebuffer device correctly Sascha Hauer
2010-11-10 14:55   ` Sascha Hauer
2010-11-10 14:53 ` [PATCH 13/13] ARM i.MX51: Add nand device Sascha Hauer
2010-11-11  5:26 ` add i.MX51 Nand support Jean-Christophe PLAGNIOL-VILLARD

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=1289400839-5937-10-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.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