* Add i.MX51 support to mxc_nand
@ 2010-08-06 13:53 Sascha Hauer
2010-08-06 13:53 ` [PATCH 1/8] mxc_nand: remove 0xe00 offset from registers Sascha Hauer
` (8 more replies)
0 siblings, 9 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
The following series adds v3 (found on i.MX51) support to the i.MX nand
controller. auto mode is not supported, but if I understand correctly
the auto mode is only of use when more than one nand chip is connected.
Without the auto mode the v3 controller behaves very similar to the v2
controller, but unfortunately it has a completely different register
layout. For this reason this series has some preparation patches before
the v3 support is added as the last patch.
This series conflicts with the series John Ogness recently posted, so
it has probably to be reworked a bit.
I'll post the nand platform support for i.MX51 in a seperate series.
Sascha
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 1/8] mxc_nand: remove 0xe00 offset from registers
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-06 13:53 ` [PATCH 2/8] mxc_nand: rework get_dev_status Sascha Hauer
` (7 subsequent siblings)
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
Add the offset to the register base instead. This is done
in preparation for v3 controller support.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 36 ++++++++++++++++++------------------
1 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 0d76b16..abec73a 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -41,22 +41,22 @@
#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
/* Addresses for NFC registers */
-#define NFC_BUF_SIZE 0xE00
-#define NFC_BUF_ADDR 0xE04
-#define NFC_FLASH_ADDR 0xE06
-#define NFC_FLASH_CMD 0xE08
-#define NFC_CONFIG 0xE0A
-#define NFC_ECC_STATUS_RESULT 0xE0C
-#define NFC_RSLTMAIN_AREA 0xE0E
-#define NFC_RSLTSPARE_AREA 0xE10
-#define NFC_WRPROT 0xE12
-#define NFC_V1_UNLOCKSTART_BLKADDR 0xe14
-#define NFC_V1_UNLOCKEND_BLKADDR 0xe16
-#define NFC_V21_UNLOCKSTART_BLKADDR 0xe20
-#define NFC_V21_UNLOCKEND_BLKADDR 0xe22
-#define NFC_NF_WRPRST 0xE18
-#define NFC_CONFIG1 0xE1A
-#define NFC_CONFIG2 0xE1C
+#define NFC_BUF_SIZE 0x00
+#define NFC_BUF_ADDR 0x04
+#define NFC_FLASH_ADDR 0x06
+#define NFC_FLASH_CMD 0x08
+#define NFC_CONFIG 0x0a
+#define NFC_ECC_STATUS_RESULT 0x0c
+#define NFC_RSLTMAIN_AREA 0x0e
+#define NFC_RSLTSPARE_AREA 0x10
+#define NFC_WRPROT 0x12
+#define NFC_V1_UNLOCKSTART_BLKADDR 0x14
+#define NFC_V1_UNLOCKEND_BLKADDR 0x16
+#define NFC_V21_UNLOCKSTART_BLKADDR 0x20
+#define NFC_V21_UNLOCKEND_BLKADDR 0x22
+#define NFC_NF_WRPRST 0x18
+#define NFC_CONFIG1 0x1a
+#define NFC_CONFIG2 0x1c
/* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
* for Command operation */
@@ -764,14 +764,14 @@ static int __init mxcnd_probe(struct platform_device *pdev)
host->main_area1 = host->base + 0x200;
if (nfc_is_v21()) {
- host->regs = host->base + 0x1000;
+ host->regs = host->base + 0x1e00;
host->spare0 = host->base + 0x1000;
host->spare_len = 64;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
this->ecc.bytes = 9;
} else if (nfc_is_v1()) {
- host->regs = host->base;
+ host->regs = host->base + 0xe00;
host->spare0 = host->base + 0x800;
host->spare_len = 16;
oob_smallpage = &nandv1_hw_eccoob_smallpage;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 2/8] mxc_nand: rework get_dev_status
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
2010-08-06 13:53 ` [PATCH 1/8] mxc_nand: remove 0xe00 offset from registers Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-06 13:53 ` [PATCH 3/8] mxc_nand: make some internally used functions overwriteable Sascha Hauer
` (6 subsequent siblings)
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
We save/restore the value in the buffer anyway, so it makes
no difference whether we use main_area0 or main_area1. So,
we can use main_area0 and remove main_area1 from the driver
which is otherwise unused. Also, clean up the comments in
get_dev_status.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 21 +++++++++------------
1 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index abec73a..6654446 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -102,7 +102,6 @@ struct mxc_nand_host {
void *spare0;
void *main_area0;
- void *main_area1;
void __iomem *base;
void __iomem *regs;
@@ -305,25 +304,24 @@ static void send_read_id(struct mxc_nand_host *host)
* NAND device status and returns the current status. */
static uint16_t get_dev_status(struct mxc_nand_host *host)
{
- void __iomem *main_buf = host->main_area1;
+ void __iomem *main_buf = host->main_area0;
uint32_t store;
uint16_t ret;
- /* Issue status request to NAND device */
- /* store the main area1 first word, later do recovery */
+ writew(0x0, NFC_V1_V2_BUF_ADDR);
+
+ /*
+ * The device status is stored in main_area0. To
+ * prevent corruption of the buffer save the value
+ * and restore it afterwards.
+ */
store = readl(main_buf);
- /* NANDFC buffer 1 is used for device status to prevent
- * corruption of read/write buffer on status requests. */
- writew(1, host->regs + NFC_BUF_ADDR);
writew(NFC_STATUS, host->regs + NFC_CONFIG2);
-
- /* Wait for operation to complete */
wait_op_done(host, true);
- /* Status is placed in first word of main buffer */
- /* get status, then recovery area 1 data */
ret = readw(main_buf);
+
writel(store, main_buf);
return ret;
@@ -761,7 +759,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
}
host->main_area0 = host->base;
- host->main_area1 = host->base + 0x200;
if (nfc_is_v21()) {
host->regs = host->base + 0x1e00;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 3/8] mxc_nand: make some internally used functions overwriteable
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
2010-08-06 13:53 ` [PATCH 1/8] mxc_nand: remove 0xe00 offset from registers Sascha Hauer
2010-08-06 13:53 ` [PATCH 2/8] mxc_nand: rework get_dev_status Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-06 13:53 ` [PATCH 4/8] mxc_nand: factor out a check_int function Sascha Hauer
` (5 subsequent siblings)
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
This patch prepares the driver to add v3 controller support
later. The v3 controller is basically the same controller as v1
and v2, but with a completely different register layout.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 72 ++++++++++++++++++++++++++----------------
1 files changed, 44 insertions(+), 28 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 6654446..2d2e2e7 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -115,6 +115,13 @@ struct mxc_nand_host {
uint8_t *data_buf;
unsigned int buf_start;
int spare_len;
+
+ void (*preset)(struct mtd_info *);
+ void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
+ void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
+ void (*send_page)(struct mtd_info *, unsigned int);
+ void (*send_read_id)(struct mxc_nand_host *);
+ uint16_t (*get_dev_status)(struct mxc_nand_host *);
};
/* OOB placement block for use with hardware ecc generation */
@@ -212,7 +219,7 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
/* This function issues the specified command to the NAND device and
* waits for completion. */
-static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
+static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
{
DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
@@ -241,7 +248,7 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
/* This function sends an address (or partial address) to the
* NAND device. The address is used to select the source/destination for
* a NAND command. */
-static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast)
+static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast)
{
DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
@@ -252,7 +259,7 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast)
wait_op_done(host, islast);
}
-static void send_page(struct mtd_info *mtd, unsigned int ops)
+static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
{
struct nand_chip *nand_chip = mtd->priv;
struct mxc_nand_host *host = nand_chip->priv;
@@ -276,7 +283,7 @@ static void send_page(struct mtd_info *mtd, unsigned int ops)
}
/* Request the NANDFC to perform a read of the NAND device ID. */
-static void send_read_id(struct mxc_nand_host *host)
+static void send_read_id_v1_v2(struct mxc_nand_host *host)
{
struct nand_chip *this = &host->nand;
@@ -302,7 +309,7 @@ static void send_read_id(struct mxc_nand_host *host)
/* This function requests the NANDFC to perform a read of the
* NAND device status and returns the current status. */
-static uint16_t get_dev_status(struct mxc_nand_host *host)
+static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
{
void __iomem *main_buf = host->main_area0;
uint32_t store;
@@ -381,7 +388,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd)
/* Check for status request */
if (host->status_request)
- return get_dev_status(host) & 0xFF;
+ return host->get_dev_status(host) & 0xFF;
ret = *(uint8_t *)(host->data_buf + host->buf_start);
host->buf_start++;
@@ -517,39 +524,39 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
* we will used the saved column address to index into
* the full page.
*/
- send_addr(host, 0, page_addr == -1);
+ host->send_addr(host, 0, page_addr == -1);
if (mtd->writesize > 512)
/* another col addr cycle for 2k page */
- send_addr(host, 0, false);
+ host->send_addr(host, 0, false);
}
/* Write out page address, if necessary */
if (page_addr != -1) {
/* paddr_0 - p_addr_7 */
- send_addr(host, (page_addr & 0xff), false);
+ host->send_addr(host, (page_addr & 0xff), false);
if (mtd->writesize > 512) {
if (mtd->size >= 0x10000000) {
/* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, false);
- send_addr(host, (page_addr >> 16) & 0xff, true);
+ host->send_addr(host, (page_addr >> 8) & 0xff, false);
+ host->send_addr(host, (page_addr >> 16) & 0xff, true);
} else
/* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, true);
+ host->send_addr(host, (page_addr >> 8) & 0xff, true);
} else {
/* One more address cycle for higher density devices */
if (mtd->size >= 0x4000000) {
/* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, false);
- send_addr(host, (page_addr >> 16) & 0xff, true);
+ host->send_addr(host, (page_addr >> 8) & 0xff, false);
+ host->send_addr(host, (page_addr >> 16) & 0xff, true);
} else
/* paddr_8 - paddr_15 */
- send_addr(host, (page_addr >> 8) & 0xff, true);
+ host->send_addr(host, (page_addr >> 8) & 0xff, true);
}
}
}
-static void preset(struct mtd_info *mtd)
+static void preset_v1_v2(struct mtd_info *mtd)
{
struct nand_chip *nand_chip = mtd->priv;
struct mxc_nand_host *host = nand_chip->priv;
@@ -602,15 +609,15 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
/* Command pre-processing step */
switch (command) {
case NAND_CMD_RESET:
- send_cmd(host, command, false);
- preset(mtd);
+ host->send_cmd(host, command, false);
+ host->preset(mtd);
break;
case NAND_CMD_STATUS:
host->buf_start = 0;
host->status_request = true;
- send_cmd(host, command, true);
+ host->send_cmd(host, command, true);
mxc_do_addr_cycle(mtd, column, page_addr);
break;
@@ -623,13 +630,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
command = NAND_CMD_READ0; /* only READ0 is valid */
- send_cmd(host, command, false);
+ host->send_cmd(host, command, false);
mxc_do_addr_cycle(mtd, column, page_addr);
if (mtd->writesize > 512)
- send_cmd(host, NAND_CMD_READSTART, true);
+ host->send_cmd(host, NAND_CMD_READSTART, true);
- send_page(mtd, NFC_OUTPUT);
+ host->send_page(mtd, NFC_OUTPUT);
memcpy(host->data_buf, host->main_area0, mtd->writesize);
copy_spare(mtd, true);
@@ -642,28 +649,28 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
host->buf_start = column;
- send_cmd(host, command, false);
+ host->send_cmd(host, command, false);
mxc_do_addr_cycle(mtd, column, page_addr);
break;
case NAND_CMD_PAGEPROG:
memcpy(host->main_area0, host->data_buf, mtd->writesize);
copy_spare(mtd, false);
- send_page(mtd, NFC_INPUT);
- send_cmd(host, command, true);
+ host->send_page(mtd, NFC_INPUT);
+ host->send_cmd(host, command, true);
mxc_do_addr_cycle(mtd, column, page_addr);
break;
case NAND_CMD_READID:
- send_cmd(host, command, true);
+ host->send_cmd(host, command, true);
mxc_do_addr_cycle(mtd, column, page_addr);
- send_read_id(host);
+ host->send_read_id(host);
host->buf_start = column;
break;
case NAND_CMD_ERASE1:
case NAND_CMD_ERASE2:
- send_cmd(host, command, false);
+ host->send_cmd(host, command, false);
mxc_do_addr_cycle(mtd, column, page_addr);
break;
@@ -760,6 +767,15 @@ static int __init mxcnd_probe(struct platform_device *pdev)
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;
+ host->send_read_id = send_read_id_v1_v2;
+ host->get_dev_status = get_dev_status_v1_v2;
+ }
+
if (nfc_is_v21()) {
host->regs = host->base + 0x1e00;
host->spare0 = host->base + 0x1000;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 4/8] mxc_nand: factor out a check_int function
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
` (2 preceding siblings ...)
2010-08-06 13:53 ` [PATCH 3/8] mxc_nand: make some internally used functions overwriteable Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-06 13:53 ` [PATCH 5/8] mxc_nand: add V1_V2 namespace to registers Sascha Hauer
` (4 subsequent siblings)
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 32 +++++++++++++++++++-------------
1 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 2d2e2e7..70f64dc 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -122,6 +122,7 @@ struct mxc_nand_host {
void (*send_page)(struct mtd_info *, unsigned int);
void (*send_read_id)(struct mxc_nand_host *);
uint16_t (*get_dev_status)(struct mxc_nand_host *);
+ int (*check_int)(struct mxc_nand_host *);
};
/* OOB placement block for use with hardware ecc generation */
@@ -181,34 +182,38 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int check_int_v1_v2(struct mxc_nand_host *host)
+{
+ uint32_t tmp;
+
+ tmp = readw(host->regs + NFC_CONFIG2);
+ if (!(tmp & NFC_INT))
+ return 0;
+
+ writew(tmp & ~NFC_INT, NFC_CONFIG2);
+
+ return 1;
+}
+
/* This function polls the NANDFC to wait for the basic operation to
* complete by checking the INT bit of config2 register.
*/
static void wait_op_done(struct mxc_nand_host *host, int useirq)
{
- uint16_t tmp;
int max_retries = 8000;
if (useirq) {
- if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
+ if (!host->check_int(host)) {
enable_irq(host->irq);
- wait_event(host->irq_waitq,
- readw(host->regs + NFC_CONFIG2) & NFC_INT);
-
- tmp = readw(host->regs + NFC_CONFIG2);
- tmp &= ~NFC_INT;
- writew(tmp, host->regs + NFC_CONFIG2);
+ wait_event(host->irq_waitq, host->check_int(host));
}
} else {
while (max_retries-- > 0) {
- if (readw(host->regs + NFC_CONFIG2) & NFC_INT) {
- tmp = readw(host->regs + NFC_CONFIG2);
- tmp &= ~NFC_INT;
- writew(tmp, host->regs + NFC_CONFIG2);
+ if (host->check_int(host))
break;
- }
+
udelay(1);
}
if (max_retries < 0)
@@ -774,6 +779,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
host->send_page = send_page_v1_v2;
host->send_read_id = send_read_id_v1_v2;
host->get_dev_status = get_dev_status_v1_v2;
+ host->check_int = check_int_v1_v2;
}
if (nfc_is_v21()) {
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 5/8] mxc_nand: add V1_V2 namespace to registers
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
` (3 preceding siblings ...)
2010-08-06 13:53 ` [PATCH 4/8] mxc_nand: factor out a check_int function Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-06 13:53 ` [PATCH 6/8] mxc_nand: fix correct_data function Sascha Hauer
` (3 subsequent siblings)
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
This prepares the driver for v3 support. The v3 controller
has a completely different register layout, so add a V1_V2_
namespace to the register defines to avoid confusion with
the v3 regs.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 141 +++++++++++++++++++------------------------
1 files changed, 63 insertions(+), 78 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 70f64dc..48b6dca 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -41,58 +41,43 @@
#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
/* Addresses for NFC registers */
-#define NFC_BUF_SIZE 0x00
-#define NFC_BUF_ADDR 0x04
-#define NFC_FLASH_ADDR 0x06
-#define NFC_FLASH_CMD 0x08
-#define NFC_CONFIG 0x0a
-#define NFC_ECC_STATUS_RESULT 0x0c
-#define NFC_RSLTMAIN_AREA 0x0e
-#define NFC_RSLTSPARE_AREA 0x10
-#define NFC_WRPROT 0x12
-#define NFC_V1_UNLOCKSTART_BLKADDR 0x14
-#define NFC_V1_UNLOCKEND_BLKADDR 0x16
-#define NFC_V21_UNLOCKSTART_BLKADDR 0x20
-#define NFC_V21_UNLOCKEND_BLKADDR 0x22
-#define NFC_NF_WRPRST 0x18
-#define NFC_CONFIG1 0x1a
-#define NFC_CONFIG2 0x1c
-
-/* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
- * for Command operation */
-#define NFC_CMD 0x1
-
-/* Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register
- * for Address operation */
-#define NFC_ADDR 0x2
-
-/* Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register
- * for Input operation */
-#define NFC_INPUT 0x4
-
-/* Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register
- * for Data Output operation */
-#define NFC_OUTPUT 0x8
-
-/* Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register
- * for Read ID operation */
-#define NFC_ID 0x10
-
-/* Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register
- * for Read Status operation */
-#define NFC_STATUS 0x20
-
-/* Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read
- * Status operation */
-#define NFC_INT 0x8000
-
-#define NFC_SP_EN (1 << 2)
-#define NFC_ECC_EN (1 << 3)
-#define NFC_INT_MSK (1 << 4)
-#define NFC_BIG (1 << 5)
-#define NFC_RST (1 << 6)
-#define NFC_CE (1 << 7)
-#define NFC_ONE_CYCLE (1 << 8)
+#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
+#define NFC_V1_V2_BUF_ADDR (host->regs + 0x04)
+#define NFC_V1_V2_FLASH_ADDR (host->regs + 0x06)
+#define NFC_V1_V2_FLASH_CMD (host->regs + 0x08)
+#define NFC_V1_V2_CONFIG (host->regs + 0x0a)
+#define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
+#define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
+#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10)
+#define NFC_V1_V2_WRPROT (host->regs + 0x12)
+#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
+#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
+#define NFC_V21_UNLOCKSTART_BLKADDR (host->regs + 0x20)
+#define NFC_V21_UNLOCKEND_BLKADDR (host->regs + 0x22)
+#define NFC_V1_V2_NF_WRPRST (host->regs + 0x18)
+#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
+#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
+
+#define NFC_V1_V2_CONFIG1_SP_EN (1 << 2)
+#define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3)
+#define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4)
+#define NFC_V1_V2_CONFIG1_BIG (1 << 5)
+#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_V1_V2_CONFIG2_INT (1 << 15)
+
+/*
+ * Operation modes for the NFC. Valid for v1, v2 and v3
+ * type controllers.
+ */
+#define NFC_CMD (1 << 0)
+#define NFC_ADDR (1 << 1)
+#define NFC_INPUT (1 << 2)
+#define NFC_OUTPUT (1 << 3)
+#define NFC_ID (1 << 4)
+#define NFC_STATUS (1 << 5)
struct mxc_nand_host {
struct mtd_info mtd;
@@ -186,11 +171,11 @@ static int check_int_v1_v2(struct mxc_nand_host *host)
{
uint32_t tmp;
- tmp = readw(host->regs + NFC_CONFIG2);
- if (!(tmp & NFC_INT))
+ tmp = readw(NFC_V1_V2_CONFIG2);
+ if (!(tmp & NFC_V1_V2_CONFIG2_INT))
return 0;
- writew(tmp & ~NFC_INT, NFC_CONFIG2);
+ writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2);
return 1;
}
@@ -228,15 +213,15 @@ static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
{
DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
- writew(cmd, host->regs + NFC_FLASH_CMD);
- writew(NFC_CMD, host->regs + NFC_CONFIG2);
+ writew(cmd, NFC_V1_V2_FLASH_CMD);
+ writew(NFC_CMD, NFC_V1_V2_CONFIG2);
if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) {
int max_retries = 100;
/* Reset completion is indicated by NFC_CONFIG2 */
/* being set to 0 */
while (max_retries-- > 0) {
- if (readw(host->regs + NFC_CONFIG2) == 0) {
+ if (readw(NFC_V1_V2_CONFIG2) == 0) {
break;
}
udelay(1);
@@ -257,8 +242,8 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas
{
DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
- writew(addr, host->regs + NFC_FLASH_ADDR);
- writew(NFC_ADDR, host->regs + NFC_CONFIG2);
+ writew(addr, NFC_V1_V2_FLASH_ADDR);
+ writew(NFC_ADDR, NFC_V1_V2_CONFIG2);
/* Wait for operation to complete */
wait_op_done(host, islast);
@@ -278,9 +263,9 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
for (i = 0; i < bufs; i++) {
/* NANDFC buffer 0 is used for page read/write */
- writew(i, host->regs + NFC_BUF_ADDR);
+ writew(i, NFC_V1_V2_BUF_ADDR);
- writew(ops, host->regs + NFC_CONFIG2);
+ writew(ops, NFC_V1_V2_CONFIG2);
/* Wait for operation to complete */
wait_op_done(host, true);
@@ -293,9 +278,9 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
struct nand_chip *this = &host->nand;
/* NANDFC buffer 0 is used for device ID output */
- writew(0x0, host->regs + NFC_BUF_ADDR);
+ writew(0x0, NFC_V1_V2_BUF_ADDR);
- writew(NFC_ID, host->regs + NFC_CONFIG2);
+ writew(NFC_ID, NFC_V1_V2_CONFIG2);
/* Wait for operation to complete */
wait_op_done(host, true);
@@ -329,7 +314,7 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
*/
store = readl(main_buf);
- writew(NFC_STATUS, host->regs + NFC_CONFIG2);
+ writew(NFC_STATUS, NFC_V1_V2_CONFIG2);
wait_op_done(host, true);
ret = readw(main_buf);
@@ -368,7 +353,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
* additional correction. 2-Bit errors cannot be corrected by
* HW ECC, so we need to return failure
*/
- uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT);
+ uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT);
if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
DEBUG(MTD_DEBUG_LEVEL0,
@@ -568,32 +553,32 @@ static void preset_v1_v2(struct mtd_info *mtd)
uint16_t tmp;
/* enable interrupt, disable spare enable */
- tmp = readw(host->regs + NFC_CONFIG1);
- tmp &= ~NFC_INT_MSK;
- tmp &= ~NFC_SP_EN;
+ tmp = readw(NFC_V1_V2_CONFIG1);
+ tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK;
+ tmp &= ~NFC_V1_V2_CONFIG1_SP_EN;
if (nand_chip->ecc.mode == NAND_ECC_HW) {
- tmp |= NFC_ECC_EN;
+ tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
} else {
- tmp &= ~NFC_ECC_EN;
+ tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
}
- writew(tmp, host->regs + NFC_CONFIG1);
+ writew(tmp, NFC_V1_V2_CONFIG1);
/* preset operation */
/* Unlock the internal RAM Buffer */
- writew(0x2, host->regs + NFC_CONFIG);
+ writew(0x2, 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);
+ writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR);
+ writew(0xffff, 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);
+ writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
+ writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
} else
BUG();
/* Unlock Block Command for given address range */
- writew(0x4, host->regs + NFC_WRPROT);
+ writew(0x4, NFC_V1_V2_WRPROT);
}
/* Used by the upper layer to write command to NAND Flash for
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
` (4 preceding siblings ...)
2010-08-06 13:53 ` [PATCH 5/8] mxc_nand: add V1_V2 namespace to registers Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-08 6:19 ` Baruch Siach
2010-08-08 8:19 ` Russell King - ARM Linux
2010-08-06 13:53 ` [PATCH 7/8] mxc_nand: support 8bit ecc Sascha Hauer
` (2 subsequent siblings)
8 siblings, 2 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
The v2 controller has a totally different mechanism to check
whether the data we read had ecc errors or not. Implement this.
The mechanism in the v2 controller happens to be identical to
the v3 controller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 42 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 48b6dca..a6dc5a5 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -94,6 +94,7 @@ struct mxc_nand_host {
struct clk *clk;
int clk_act;
int irq;
+ int eccsize;
wait_queue_head_t irq_waitq;
@@ -342,7 +343,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
*/
}
-static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
struct nand_chip *nand_chip = mtd->priv;
@@ -364,6 +365,40 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
return 0;
}
+static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ u32 ecc_stat, err;
+ int no_subpages = 1;
+ int ret = 0;
+ u8 ecc_bit_mask, err_limit;
+
+ ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
+ err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
+
+ no_subpages = mtd->writesize >> 9;
+
+ ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
+
+ do {
+ err = ecc_stat & ecc_bit_mask;
+ if (err > err_limit) {
+ printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
+ return -1;
+ } else {
+ ret += err;
+ }
+ ecc_stat >>= 4;
+ } while (--no_subpages);
+
+ mtd->ecc_stats.corrected += ret;
+ pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
+
+ return ret;
+}
+
static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
u_char *ecc_code)
{
@@ -790,7 +825,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
if (pdata->hw_ecc) {
this->ecc.calculate = mxc_nand_calculate_ecc;
this->ecc.hwctl = mxc_nand_enable_hwecc;
- this->ecc.correct = mxc_nand_correct_data;
+ if (nfc_is_v1())
+ this->ecc.correct = mxc_nand_correct_data_v1;
+ else
+ this->ecc.correct = mxc_nand_correct_data_v2_v3;
this->ecc.mode = NAND_ECC_HW;
} else {
this->ecc.mode = NAND_ECC_SOFT;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 7/8] mxc_nand: support 8bit ecc
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
` (5 preceding siblings ...)
2010-08-06 13:53 ` [PATCH 6/8] mxc_nand: fix correct_data function Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-06 13:53 ` [PATCH 8/8] mxc_nand: Add v3 (i.MX51) Support Sascha Hauer
2010-08-09 11:38 ` [PATCH 0/2] mxc_nand: fixes for purposed updates Baruch Siach
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
Nand devices with at least 26 bytes of oob data per 512 byte block
can have 8bit ecc on v2 type controllers. This is currently not tested,
but at least this patch puts the ECC_MODE bit into a well defined state.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/mxc_nand.c | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index a6dc5a5..030da08 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -58,6 +58,7 @@
#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
+#define NFC_V2_CONFIG1_ECC_MODE_4 (1 << 0)
#define NFC_V1_V2_CONFIG1_SP_EN (1 << 2)
#define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3)
#define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4)
@@ -581,6 +582,23 @@ 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@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;
@@ -596,6 +614,15 @@ static void preset_v1_v2(struct mtd_info *mtd)
} else {
tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
}
+
+ if (nfc_is_v21() && mtd->writesize) {
+ host->eccsize = get_eccsize(mtd);
+ if (host->eccsize == 4)
+ tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
+ } else {
+ host->eccsize = 1;
+ }
+
writew(tmp, NFC_V1_V2_CONFIG1);
/* preset operation */
@@ -859,6 +886,9 @@ static int __init mxcnd_probe(struct platform_device *pdev)
goto escan;
}
+ /* Call preset again, with correct writesize this time */
+ host->preset(mtd);
+
if (mtd->writesize == 2048)
this->ecc.layout = oob_largepage;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 8/8] mxc_nand: Add v3 (i.MX51) Support
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
` (6 preceding siblings ...)
2010-08-06 13:53 ` [PATCH 7/8] mxc_nand: support 8bit ecc Sascha Hauer
@ 2010-08-06 13:53 ` Sascha Hauer
2010-08-09 11:38 ` [PATCH 0/2] mxc_nand: fixes for purposed updates Baruch Siach
8 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-06 13:53 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/Kconfig | 2 +-
drivers/mtd/nand/mxc_nand.c | 222 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 222 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 362d177..b8a03bd 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -482,7 +482,7 @@ config MTD_NAND_MPC5121_NFC
config MTD_NAND_MXC
tristate "MXC NAND support"
- depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3
+ depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
help
This enables the driver for the NAND flash controller on the
MXC processors.
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 030da08..d88f0fa 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -39,6 +39,8 @@
#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35())
#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
+#define nfc_is_v3_2() cpu_is_mx51()
+#define nfc_is_v3() nfc_is_v3_2()
/* Addresses for NFC registers */
#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
@@ -80,6 +82,54 @@
#define NFC_ID (1 << 4)
#define NFC_STATUS (1 << 5)
+#define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
+#define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04)
+
+#define NFC_V3_CONFIG1 (host->regs_axi + 0x34)
+#define NFC_V3_CONFIG1_SP_EN (1 << 0)
+#define NFC_V3_CONFIG1_RBA(x) (((x) & 0x7 ) << 4)
+
+#define NFC_V3_ECC_STATUS_RESULT (host->regs_axi + 0x38)
+
+#define NFC_V3_LAUNCH (host->regs_axi + 0x40)
+
+#define NFC_V3_WRPROT (host->regs_ip + 0x0)
+#define NFC_V3_WRPROT_LOCK_TIGHT (1 << 0)
+#define NFC_V3_WRPROT_LOCK (1 << 1)
+#define NFC_V3_WRPROT_UNLOCK (1 << 2)
+#define NFC_V3_WRPROT_BLS_UNLOCK (2 << 6)
+
+#define NFC_V3_WRPROT_UNLOCK_BLK_ADD0 (host->regs_ip + 0x04)
+
+#define NFC_V3_CONFIG2 (host->regs_ip + 0x24)
+#define NFC_V3_CONFIG2_PS_512 (0 << 0)
+#define NFC_V3_CONFIG2_PS_2048 (1 << 0)
+#define NFC_V3_CONFIG2_PS_4096 (2 << 0)
+#define NFC_V3_CONFIG2_ONE_CYCLE (1 << 2)
+#define NFC_V3_CONFIG2_ECC_EN (1 << 3)
+#define NFC_V3_CONFIG2_2CMD_PHASES (1 << 4)
+#define NFC_V3_CONFIG2_NUM_ADDR_PHASE0 (1 << 5)
+#define NFC_V3_CONFIG2_ECC_MODE_8 (1 << 6)
+#define NFC_V3_CONFIG2_PPB(x) (((x) & 0x3) << 7)
+#define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x) (((x) & 0x3) << 12)
+#define NFC_V3_CONFIG2_INT_MSK (1 << 15)
+#define NFC_V3_CONFIG2_ST_CMD(x) (((x) & 0xff) << 24)
+#define NFC_V3_CONFIG2_SPAS(x) (((x) & 0xff) << 16)
+
+#define NFC_V3_CONFIG3 (host->regs_ip + 0x28)
+#define NFC_V3_CONFIG3_ADD_OP(x) (((x) & 0x3) << 0)
+#define NFC_V3_CONFIG3_FW8 (1 << 3)
+#define NFC_V3_CONFIG3_SBB(x) (((x) & 0x7) << 8)
+#define NFC_V3_CONFIG3_NUM_OF_DEVICES(x) (((x) & 0x7) << 12)
+#define NFC_V3_CONFIG3_RBB_MODE (1 << 15)
+#define NFC_V3_CONFIG3_NO_SDMA (1 << 20)
+
+#define NFC_V3_IPC (host->regs_ip + 0x2C)
+#define NFC_V3_IPC_CREQ (1 << 0)
+#define NFC_V3_IPC_INT (1 << 31)
+
+#define NFC_V3_DELAY_LINE (host->regs_ip + 0x34)
+
struct mxc_nand_host {
struct mtd_info mtd;
struct nand_chip nand;
@@ -91,6 +141,8 @@ struct mxc_nand_host {
void __iomem *base;
void __iomem *regs;
+ void __iomem *regs_axi;
+ void __iomem *regs_ip;
int status_request;
struct clk *clk;
int clk_act;
@@ -169,6 +221,20 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int check_int_v3(struct mxc_nand_host *host)
+{
+ uint32_t tmp;
+
+ tmp = readl(NFC_V3_IPC);
+ if (!(tmp & NFC_V3_IPC_INT))
+ return 0;
+
+ tmp &= ~NFC_V3_IPC_INT;
+ writel(tmp, NFC_V3_IPC);
+
+ return 1;
+}
+
static int check_int_v1_v2(struct mxc_nand_host *host)
{
uint32_t tmp;
@@ -209,6 +275,18 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
}
}
+static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)
+{
+ /* fill command */
+ writel(cmd, NFC_V3_FLASH_CMD);
+
+ /* send out command */
+ writel(NFC_CMD, NFC_V3_LAUNCH);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, useirq);
+}
+
/* This function issues the specified command to the NAND device and
* waits for completion. */
static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
@@ -237,6 +315,17 @@ static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
}
}
+static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast)
+{
+ /* fill address */
+ writel(addr, NFC_V3_FLASH_ADDR0);
+
+ /* send out address */
+ writel(NFC_ADDR, NFC_V3_LAUNCH);
+
+ wait_op_done(host, 0);
+}
+
/* This function sends an address (or partial address) to the
* NAND device. The address is used to select the source/destination for
* a NAND command. */
@@ -251,6 +340,22 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas
wait_op_done(host, islast);
}
+static void send_page_v3(struct mtd_info *mtd, unsigned int ops)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ uint32_t tmp;
+
+ tmp = readl(NFC_V3_CONFIG1);
+ tmp &= ~(7 << 4);
+ writel(tmp, NFC_V3_CONFIG1);
+
+ /* transfer data from NFC ram to nand */
+ writel(ops, NFC_V3_LAUNCH);
+
+ wait_op_done(host, false);
+}
+
static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
{
struct nand_chip *nand_chip = mtd->priv;
@@ -274,6 +379,16 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
}
}
+static void send_read_id_v3(struct mxc_nand_host *host)
+{
+ /* Read ID into main buffer */
+ writel(NFC_ID, NFC_V3_LAUNCH);
+
+ wait_op_done(host, true);
+
+ memcpy(host->data_buf, host->main_area0, 16);
+}
+
/* Request the NANDFC to perform a read of the NAND device ID. */
static void send_read_id_v1_v2(struct mxc_nand_host *host)
{
@@ -299,6 +414,14 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
memcpy(host->data_buf, host->main_area0, 16);
}
+static uint16_t get_dev_status_v3(struct mxc_nand_host *host)
+{
+ writew(NFC_STATUS, NFC_V3_LAUNCH);
+ wait_op_done(host, true);
+
+ return readl(NFC_V3_CONFIG1) >> 16;
+}
+
/* This function requests the NANDFC to perform a read of the
* NAND device status and returns the current status. */
static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
@@ -381,7 +504,10 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
no_subpages = mtd->writesize >> 9;
- ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
+ if (nfc_is_v21())
+ ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
+ else
+ ecc_stat = readl(NFC_V3_ECC_STATUS_RESULT);
do {
err = ecc_stat & ecc_bit_mask;
@@ -643,6 +769,72 @@ static void preset_v1_v2(struct mtd_info *mtd)
writew(0x4, NFC_V1_V2_WRPROT);
}
+static void preset_v3(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct mxc_nand_host *host = chip->priv;
+ uint32_t config2, config3;
+ int i, addr_phases;
+
+ writel(NFC_V3_CONFIG1_RBA(0), NFC_V3_CONFIG1);
+ writel(NFC_V3_IPC_CREQ, NFC_V3_IPC);
+
+ /* Unlock the internal RAM Buffer */
+ writel(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK,
+ NFC_V3_WRPROT);
+
+ /* Blocks to be unlocked */
+ for (i = 0; i < NAND_MAX_CHIPS; i++)
+ writel(0x0 | (0xffff << 16),
+ NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2));
+
+ writel(0, NFC_V3_IPC);
+
+ config2 = NFC_V3_CONFIG2_ONE_CYCLE |
+ NFC_V3_CONFIG2_2CMD_PHASES |
+ NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) |
+ NFC_V3_CONFIG2_ST_CMD(0x70) |
+ NFC_V3_CONFIG2_NUM_ADDR_PHASE0;
+
+ if (chip->ecc.mode == NAND_ECC_HW)
+ config2 |= NFC_V3_CONFIG2_ECC_EN;
+
+ addr_phases = fls(chip->pagemask) >> 3;
+
+ if (mtd->writesize == 2048) {
+ config2 |= NFC_V3_CONFIG2_PS_2048;
+ config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
+ } else if (mtd->writesize == 4096) {
+ config2 |= NFC_V3_CONFIG2_PS_4096;
+ config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
+ } else {
+ config2 |= NFC_V3_CONFIG2_PS_512;
+ config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1);
+ }
+
+ if (mtd->writesize) {
+ config2 |= NFC_V3_CONFIG2_PPB(ffs(mtd->erasesize / mtd->writesize) - 6);
+ host->eccsize = get_eccsize(mtd);
+ if (host->eccsize == 8)
+ config2 |= NFC_V3_CONFIG2_ECC_MODE_8;
+ }
+
+ writel(config2, NFC_V3_CONFIG2);
+
+ config3 = NFC_V3_CONFIG3_NUM_OF_DEVICES(0) |
+ NFC_V3_CONFIG3_NO_SDMA |
+ NFC_V3_CONFIG3_RBB_MODE |
+ NFC_V3_CONFIG3_SBB(6) | /* Reset default */
+ NFC_V3_CONFIG3_ADD_OP(0);
+
+ if (!(chip->options & NAND_BUSWIDTH_16))
+ config3 |= NFC_V3_CONFIG3_FW8;
+
+ writel(config3, NFC_V3_CONFIG3);
+
+ writel(0, NFC_V3_DELAY_LINE);
+}
+
/* Used by the upper layer to write command to NAND Flash for
* different operations to be carried out on NAND Flash */
static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
@@ -843,6 +1035,30 @@ static int __init mxcnd_probe(struct platform_device *pdev)
oob_smallpage = &nandv1_hw_eccoob_smallpage;
oob_largepage = &nandv1_hw_eccoob_largepage;
this->ecc.bytes = 3;
+ host->eccsize = 1;
+ } else if (nfc_is_v3_2()) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ err = -ENODEV;
+ goto eirq;
+ }
+ host->regs_ip = ioremap(res->start, resource_size(res));
+ if (!host->regs_ip) {
+ err = -ENOMEM;
+ goto eirq;
+ }
+ host->regs_axi = host->base + 0x1e00;
+ host->spare0 = host->base + 0x1000;
+ host->spare_len = 64;
+ host->preset = preset_v3;
+ host->send_cmd = send_cmd_v3;
+ host->send_addr = send_addr_v3;
+ host->send_page = send_page_v3;
+ host->send_read_id = send_read_id_v3;
+ host->check_int = check_int_v3;
+ host->get_dev_status = get_dev_status_v3;
+ oob_smallpage = &nandv2_hw_eccoob_smallpage;
+ oob_largepage = &nandv2_hw_eccoob_largepage;
} else
BUG();
@@ -920,6 +1136,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
escan:
free_irq(host->irq, host);
eirq:
+ if (host->regs_ip)
+ iounmap(host->regs_ip);
iounmap(host->base);
eres:
clk_put(host->clk);
@@ -939,6 +1157,8 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
nand_release(&host->mtd);
free_irq(host->irq, host);
+ if (host->regs_ip)
+ iounmap(host->regs_ip);
iounmap(host->base);
kfree(host);
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-06 13:53 ` [PATCH 6/8] mxc_nand: fix correct_data function Sascha Hauer
@ 2010-08-08 6:19 ` Baruch Siach
2010-08-08 20:44 ` Sascha Hauer
2010-08-08 8:19 ` Russell King - ARM Linux
1 sibling, 1 reply; 25+ messages in thread
From: Baruch Siach @ 2010-08-08 6:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi Sascha,
On Fri, Aug 06, 2010 at 03:53:09PM +0200, Sascha Hauer wrote:
> The v2 controller has a totally different mechanism to check
> whether the data we read had ecc errors or not. Implement this.
> The mechanism in the v2 controller happens to be identical to
> the v3 controller.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/mtd/nand/mxc_nand.c | 42 ++++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 48b6dca..a6dc5a5 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -94,6 +94,7 @@ struct mxc_nand_host {
> struct clk *clk;
> int clk_act;
> int irq;
> + int eccsize;
This new mxc_nand_host field doesn't get initialized in this patch, although
it is used in the .correct implementation. The next patch in this series
includes the eccsize initialization code. This might break bisect. Won't it be
safer to switch the order of these patches?
baruch
> wait_queue_head_t irq_waitq;
>
> @@ -342,7 +343,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
> */
> }
>
> -static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
> +static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
> u_char *read_ecc, u_char *calc_ecc)
> {
> struct nand_chip *nand_chip = mtd->priv;
> @@ -364,6 +365,40 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
> return 0;
> }
>
> +static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
> + u_char *read_ecc, u_char *calc_ecc)
> +{
> + struct nand_chip *nand_chip = mtd->priv;
> + struct mxc_nand_host *host = nand_chip->priv;
> + u32 ecc_stat, err;
> + int no_subpages = 1;
> + int ret = 0;
> + u8 ecc_bit_mask, err_limit;
> +
> + ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
> + err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
> +
> + no_subpages = mtd->writesize >> 9;
> +
> + ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
> +
> + do {
> + err = ecc_stat & ecc_bit_mask;
> + if (err > err_limit) {
> + printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
> + return -1;
> + } else {
> + ret += err;
> + }
> + ecc_stat >>= 4;
> + } while (--no_subpages);
> +
> + mtd->ecc_stats.corrected += ret;
> + pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
> +
> + return ret;
> +}
> +
> static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
> u_char *ecc_code)
> {
> @@ -790,7 +825,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
> if (pdata->hw_ecc) {
> this->ecc.calculate = mxc_nand_calculate_ecc;
> this->ecc.hwctl = mxc_nand_enable_hwecc;
> - this->ecc.correct = mxc_nand_correct_data;
> + if (nfc_is_v1())
> + this->ecc.correct = mxc_nand_correct_data_v1;
> + else
> + this->ecc.correct = mxc_nand_correct_data_v2_v3;
> this->ecc.mode = NAND_ECC_HW;
> } else {
> this->ecc.mode = NAND_ECC_SOFT;
--
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-06 13:53 ` [PATCH 6/8] mxc_nand: fix correct_data function Sascha Hauer
2010-08-08 6:19 ` Baruch Siach
@ 2010-08-08 8:19 ` Russell King - ARM Linux
2010-08-08 8:32 ` Baruch Siach
1 sibling, 1 reply; 25+ messages in thread
From: Russell King - ARM Linux @ 2010-08-08 8:19 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Aug 06, 2010 at 03:53:09PM +0200, Sascha Hauer wrote:
> + err = ecc_stat & ecc_bit_mask;
> + if (err > err_limit) {
> + printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
> + return -1;
Someone's being lazy.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-08 8:19 ` Russell King - ARM Linux
@ 2010-08-08 8:32 ` Baruch Siach
2010-08-08 20:43 ` Sascha Hauer
0 siblings, 1 reply; 25+ messages in thread
From: Baruch Siach @ 2010-08-08 8:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi Russell,
On Sun, Aug 08, 2010 at 09:19:56AM +0100, Russell King - ARM Linux wrote:
> On Fri, Aug 06, 2010 at 03:53:09PM +0200, Sascha Hauer wrote:
> > + err = ecc_stat & ecc_bit_mask;
> > + if (err > err_limit) {
> > + printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
> > + return -1;
>
> Someone's being lazy.
The code at nand_read_subpage() (drivers/mtd/nand/nand_base.c) expects the
.correct callback to return -1 on an uncorrectable error:
stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
if (stat == -1)
mtd->ecc_stats.failed++;
else
mtd->ecc_stats.corrected += stat;
baruch
--
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-08 8:32 ` Baruch Siach
@ 2010-08-08 20:43 ` Sascha Hauer
2010-08-08 22:10 ` Russell King - ARM Linux
2010-08-09 4:20 ` [PATCH] nand: fix .correct callback return value check Baruch Siach
0 siblings, 2 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-08 20:43 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Aug 08, 2010 at 11:32:44AM +0300, Baruch Siach wrote:
> Hi Russell,
>
> On Sun, Aug 08, 2010 at 09:19:56AM +0100, Russell King - ARM Linux wrote:
> > On Fri, Aug 06, 2010 at 03:53:09PM +0200, Sascha Hauer wrote:
> > > + err = ecc_stat & ecc_bit_mask;
> > > + if (err > err_limit) {
> > > + printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
> > > + return -1;
> >
> > Someone's being lazy.
>
> The code at nand_read_subpage() (drivers/mtd/nand/nand_base.c) expects the
> .correct callback to return -1 on an uncorrectable error:
>
> stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
> if (stat == -1)
> mtd->ecc_stats.failed++;
> else
> mtd->ecc_stats.corrected += stat;
Then this should be changed to check for stat < 0. I found some drivers
in the tree returning an errno value in their .correct function instead
of -1.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-08 6:19 ` Baruch Siach
@ 2010-08-08 20:44 ` Sascha Hauer
0 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-08 20:44 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Aug 08, 2010 at 09:19:50AM +0300, Baruch Siach wrote:
> Hi Sascha,
>
> On Fri, Aug 06, 2010 at 03:53:09PM +0200, Sascha Hauer wrote:
> > The v2 controller has a totally different mechanism to check
> > whether the data we read had ecc errors or not. Implement this.
> > The mechanism in the v2 controller happens to be identical to
> > the v3 controller.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/mtd/nand/mxc_nand.c | 42 ++++++++++++++++++++++++++++++++++++++++--
> > 1 files changed, 40 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > index 48b6dca..a6dc5a5 100644
> > --- a/drivers/mtd/nand/mxc_nand.c
> > +++ b/drivers/mtd/nand/mxc_nand.c
> > @@ -94,6 +94,7 @@ struct mxc_nand_host {
> > struct clk *clk;
> > int clk_act;
> > int irq;
> > + int eccsize;
>
> This new mxc_nand_host field doesn't get initialized in this patch, although
> it is used in the .correct implementation. The next patch in this series
> includes the eccsize initialization code. This might break bisect. Won't it be
> safer to switch the order of these patches?
Ok, will fix.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 6/8] mxc_nand: fix correct_data function
2010-08-08 20:43 ` Sascha Hauer
@ 2010-08-08 22:10 ` Russell King - ARM Linux
2010-08-09 4:20 ` [PATCH] nand: fix .correct callback return value check Baruch Siach
1 sibling, 0 replies; 25+ messages in thread
From: Russell King - ARM Linux @ 2010-08-08 22:10 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Aug 08, 2010 at 10:43:41PM +0200, Sascha Hauer wrote:
> On Sun, Aug 08, 2010 at 11:32:44AM +0300, Baruch Siach wrote:
> > Hi Russell,
> >
> > On Sun, Aug 08, 2010 at 09:19:56AM +0100, Russell King - ARM Linux wrote:
> > > On Fri, Aug 06, 2010 at 03:53:09PM +0200, Sascha Hauer wrote:
> > > > + err = ecc_stat & ecc_bit_mask;
> > > > + if (err > err_limit) {
> > > > + printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
> > > > + return -1;
> > >
> > > Someone's being lazy.
> >
> > The code at nand_read_subpage() (drivers/mtd/nand/nand_base.c) expects the
> > .correct callback to return -1 on an uncorrectable error:
> >
> > stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
> > if (stat == -1)
> > mtd->ecc_stats.failed++;
> > else
> > mtd->ecc_stats.corrected += stat;
>
> Then this should be changed to check for stat < 0. I found some drivers
> in the tree returning an errno value in their .correct function instead
> of -1.
That's the whole danger of the whole 'return -1' evilness in the kernel.
The long established convention in the kernel is that negative numbers
returned from functions are negative errno codes.
As soon as you decide that you want a function to return -1 to indicate
an error rather than a real errno code, you lose clarity on which
functions need '-1' and which are proper negative errno codes, and then
you end up with people returning negative errno codes for functions
which should be -1, and people returning -1 for functions which should
be negative errno codes.
If you want a function to return -1 for error, then it probably makes
sense to create a ECC_CORRECT_FAILED definition which happens to be -1.
Or some other number. But don't use plain '-1' - it looks far too much
like "I was lazy, I couldn't be bothered to look up a proper errno."
We know full well that _lots_ of people submit stuff with 'return -1'
statements where they should be proper negative errno codes, so it's
something people are having a great deal of trouble with already. Let's
not further confuse everyone by having functions expecting called methods
to do a plain "return -1;" on error.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH] nand: fix .correct callback return value check
2010-08-08 20:43 ` Sascha Hauer
2010-08-08 22:10 ` Russell King - ARM Linux
@ 2010-08-09 4:20 ` Baruch Siach
2010-08-12 5:42 ` Baruch Siach
2010-08-29 11:01 ` Artem Bityutskiy
1 sibling, 2 replies; 25+ messages in thread
From: Baruch Siach @ 2010-08-09 4:20 UTC (permalink / raw)
To: linux-arm-kernel
Drivers may (and do) return negative errno values other than -1 from the
.correct callback.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/mtd/nand/nand_base.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 4a7b864..080f551 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1210,7 +1210,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
int stat;
stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
- if (stat == -1)
+ if (stat < 0)
mtd->ecc_stats.failed++;
else
mtd->ecc_stats.corrected += stat;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 0/2] mxc_nand: fixes for purposed updates
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
` (7 preceding siblings ...)
2010-08-06 13:53 ` [PATCH 8/8] mxc_nand: Add v3 (i.MX51) Support Sascha Hauer
@ 2010-08-09 11:38 ` Baruch Siach
2010-08-09 11:38 ` [PATCH 1/2] mxc_nand: fix build error Baruch Siach
` (2 more replies)
8 siblings, 3 replies; 25+ messages in thread
From: Baruch Siach @ 2010-08-09 11:38 UTC (permalink / raw)
To: linux-arm-kernel
With these patches applied I've tested mxc-nand-pu on a i.MX25 based system.
Baruch Siach (2):
mxc_nand: fix build error
mxc_nand: remove unused variables
drivers/mtd/nand/mxc_nand.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 1/2] mxc_nand: fix build error
2010-08-09 11:38 ` [PATCH 0/2] mxc_nand: fixes for purposed updates Baruch Siach
@ 2010-08-09 11:38 ` Baruch Siach
2010-08-09 12:28 ` Sascha Hauer
2010-08-09 11:38 ` [PATCH 2/2] mxc_nand: remove unused variables Baruch Siach
2010-08-09 11:53 ` [PATCH 0/2] mxc_nand: fixes for purposed updates David Woodhouse
2 siblings, 1 reply; 25+ messages in thread
From: Baruch Siach @ 2010-08-09 11:38 UTC (permalink / raw)
To: linux-arm-kernel
drivers/mtd/nand/mxc_nand.c: In function 'mxc_nand_command':
drivers/mtd/nand/mxc_nand.c:908: error: implicit declaration of function 'send_cmd'
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/mtd/nand/mxc_nand.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 4032e0b..3092240 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -905,13 +905,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
/* Set program pointer to spare region */
if (mtd->writesize == 512)
- send_cmd(host, NAND_CMD_READOOB, false);
+ host->send_cmd(host, NAND_CMD_READOOB, false);
} else {
host->buf_start = column;
/* Set program pointer to page start */
if (mtd->writesize == 512)
- send_cmd(host, NAND_CMD_READ0, false);
+ host->send_cmd(host, NAND_CMD_READ0, false);
}
host->send_cmd(host, command, false);
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 2/2] mxc_nand: remove unused variables
2010-08-09 11:38 ` [PATCH 0/2] mxc_nand: fixes for purposed updates Baruch Siach
2010-08-09 11:38 ` [PATCH 1/2] mxc_nand: fix build error Baruch Siach
@ 2010-08-09 11:38 ` Baruch Siach
2010-08-09 12:34 ` Lothar Waßmann
2010-08-09 11:53 ` [PATCH 0/2] mxc_nand: fixes for purposed updates David Woodhouse
2 siblings, 1 reply; 25+ messages in thread
From: Baruch Siach @ 2010-08-09 11:38 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/mtd/nand/mxc_nand.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 3092240..dfa8311 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1210,15 +1210,12 @@ static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
static int mxcnd_resume(struct platform_device *pdev)
{
struct mtd_info *mtd = platform_get_drvdata(pdev);
- struct nand_chip *nand_chip = mtd->priv;
- struct mxc_nand_host *host = nand_chip->priv;
- int ret = 0;
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
mtd->resume(mtd);
- return ret;
+ return 0;
}
#else
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 0/2] mxc_nand: fixes for purposed updates
2010-08-09 11:38 ` [PATCH 0/2] mxc_nand: fixes for purposed updates Baruch Siach
2010-08-09 11:38 ` [PATCH 1/2] mxc_nand: fix build error Baruch Siach
2010-08-09 11:38 ` [PATCH 2/2] mxc_nand: remove unused variables Baruch Siach
@ 2010-08-09 11:53 ` David Woodhouse
2010-08-09 12:19 ` Baruch Siach
2 siblings, 1 reply; 25+ messages in thread
From: David Woodhouse @ 2010-08-09 11:53 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, 2010-08-09 at 14:38 +0300, Baruch Siach wrote:
> With these patches applied I've tested mxc-nand-pu on a i.MX25 based system.
>
> Baruch Siach (2):
> mxc_nand: fix build error
> mxc_nand: remove unused variables
>
> drivers/mtd/nand/mxc_nand.c | 9 +++------
> 1 files changed, 3 insertions(+), 6 deletions(-)
These patches don't apply to the mtd-2.6.git tree.
--
David Woodhouse Open Source Technology Centre
David.Woodhouse at intel.com Intel Corporation
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 0/2] mxc_nand: fixes for purposed updates
2010-08-09 11:53 ` [PATCH 0/2] mxc_nand: fixes for purposed updates David Woodhouse
@ 2010-08-09 12:19 ` Baruch Siach
0 siblings, 0 replies; 25+ messages in thread
From: Baruch Siach @ 2010-08-09 12:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi David,
On Mon, Aug 09, 2010 at 12:53:25PM +0100, David Woodhouse wrote:
> On Mon, 2010-08-09 at 14:38 +0300, Baruch Siach wrote:
> > With these patches applied I've tested mxc-nand-pu on a i.MX25 based system.
> >
> > Baruch Siach (2):
> > mxc_nand: fix build error
> > mxc_nand: remove unused variables
> >
> > drivers/mtd/nand/mxc_nand.c | 9 +++------
> > 1 files changed, 3 insertions(+), 6 deletions(-)
>
> These patches don't apply to the mtd-2.6.git tree.
These patches apply on top of the mxc-nand-pu branch of Sascha Hauer at
git://git.pengutronix.de/git/imx/linux-2.6.git. Sorry for not mentioning this.
baruch
--
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 1/2] mxc_nand: fix build error
2010-08-09 11:38 ` [PATCH 1/2] mxc_nand: fix build error Baruch Siach
@ 2010-08-09 12:28 ` Sascha Hauer
0 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2010-08-09 12:28 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Aug 09, 2010 at 02:38:13PM +0300, Baruch Siach wrote:
> drivers/mtd/nand/mxc_nand.c: In function 'mxc_nand_command':
> drivers/mtd/nand/mxc_nand.c:908: error: implicit declaration of function 'send_cmd'
This is because you based my series on 2.6.35. With current master this
patch is not necessary.
Sascha
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> drivers/mtd/nand/mxc_nand.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 4032e0b..3092240 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -905,13 +905,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
>
> /* Set program pointer to spare region */
> if (mtd->writesize == 512)
> - send_cmd(host, NAND_CMD_READOOB, false);
> + host->send_cmd(host, NAND_CMD_READOOB, false);
> } else {
> host->buf_start = column;
>
> /* Set program pointer to page start */
> if (mtd->writesize == 512)
> - send_cmd(host, NAND_CMD_READ0, false);
> + host->send_cmd(host, NAND_CMD_READ0, false);
> }
>
> host->send_cmd(host, command, false);
> --
> 1.7.1
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 2/2] mxc_nand: remove unused variables
2010-08-09 11:38 ` [PATCH 2/2] mxc_nand: remove unused variables Baruch Siach
@ 2010-08-09 12:34 ` Lothar Waßmann
0 siblings, 0 replies; 25+ messages in thread
From: Lothar Waßmann @ 2010-08-09 12:34 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Baruch Siach writes:
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> drivers/mtd/nand/mxc_nand.c | 5 +----
> 1 files changed, 1 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 3092240..dfa8311 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -1210,15 +1210,12 @@ static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
> static int mxcnd_resume(struct platform_device *pdev)
> {
> struct mtd_info *mtd = platform_get_drvdata(pdev);
> - struct nand_chip *nand_chip = mtd->priv;
> - struct mxc_nand_host *host = nand_chip->priv;
> - int ret = 0;
>
> DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
>
> mtd->resume(mtd);
>
There was a patch to remove the whole function mxcnd_resume() because
the call to mtd->resume() is done elsewhere in the MTD layer:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/018243.html
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH] nand: fix .correct callback return value check
2010-08-09 4:20 ` [PATCH] nand: fix .correct callback return value check Baruch Siach
@ 2010-08-12 5:42 ` Baruch Siach
2010-08-29 11:01 ` Artem Bityutskiy
1 sibling, 0 replies; 25+ messages in thread
From: Baruch Siach @ 2010-08-12 5:42 UTC (permalink / raw)
To: linux-arm-kernel
Hi linux-mtd list,
Ping?
At least the atmel_nand and the bf5xx_nand drivers may return -EIO for
uncorrectable errors, so this patch fixes a real bug.
baruch
On Mon, Aug 09, 2010 at 07:20:23AM +0300, Baruch Siach wrote:
> Drivers may (and do) return negative errno values other than -1 from the
> .correct callback.
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> drivers/mtd/nand/nand_base.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 4a7b864..080f551 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -1210,7 +1210,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
> int stat;
>
> stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
> - if (stat == -1)
> + if (stat < 0)
> mtd->ecc_stats.failed++;
> else
> mtd->ecc_stats.corrected += stat;
> --
> 1.7.1
--
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH] nand: fix .correct callback return value check
2010-08-09 4:20 ` [PATCH] nand: fix .correct callback return value check Baruch Siach
2010-08-12 5:42 ` Baruch Siach
@ 2010-08-29 11:01 ` Artem Bityutskiy
1 sibling, 0 replies; 25+ messages in thread
From: Artem Bityutskiy @ 2010-08-29 11:01 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, 2010-08-09 at 07:20 +0300, Baruch Siach wrote:
> Drivers may (and do) return negative errno values other than -1 from the
> .correct callback.
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Pushed to l2-mtd-2.6.git / master, thank you!
Artem.
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2010-08-29 11:01 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-06 13:53 Add i.MX51 support to mxc_nand Sascha Hauer
2010-08-06 13:53 ` [PATCH 1/8] mxc_nand: remove 0xe00 offset from registers Sascha Hauer
2010-08-06 13:53 ` [PATCH 2/8] mxc_nand: rework get_dev_status Sascha Hauer
2010-08-06 13:53 ` [PATCH 3/8] mxc_nand: make some internally used functions overwriteable Sascha Hauer
2010-08-06 13:53 ` [PATCH 4/8] mxc_nand: factor out a check_int function Sascha Hauer
2010-08-06 13:53 ` [PATCH 5/8] mxc_nand: add V1_V2 namespace to registers Sascha Hauer
2010-08-06 13:53 ` [PATCH 6/8] mxc_nand: fix correct_data function Sascha Hauer
2010-08-08 6:19 ` Baruch Siach
2010-08-08 20:44 ` Sascha Hauer
2010-08-08 8:19 ` Russell King - ARM Linux
2010-08-08 8:32 ` Baruch Siach
2010-08-08 20:43 ` Sascha Hauer
2010-08-08 22:10 ` Russell King - ARM Linux
2010-08-09 4:20 ` [PATCH] nand: fix .correct callback return value check Baruch Siach
2010-08-12 5:42 ` Baruch Siach
2010-08-29 11:01 ` Artem Bityutskiy
2010-08-06 13:53 ` [PATCH 7/8] mxc_nand: support 8bit ecc Sascha Hauer
2010-08-06 13:53 ` [PATCH 8/8] mxc_nand: Add v3 (i.MX51) Support Sascha Hauer
2010-08-09 11:38 ` [PATCH 0/2] mxc_nand: fixes for purposed updates Baruch Siach
2010-08-09 11:38 ` [PATCH 1/2] mxc_nand: fix build error Baruch Siach
2010-08-09 12:28 ` Sascha Hauer
2010-08-09 11:38 ` [PATCH 2/2] mxc_nand: remove unused variables Baruch Siach
2010-08-09 12:34 ` Lothar Waßmann
2010-08-09 11:53 ` [PATCH 0/2] mxc_nand: fixes for purposed updates David Woodhouse
2010-08-09 12:19 ` Baruch Siach
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).