summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_imx.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2015-02-05 22:21:30 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2015-02-11 09:49:30 +0100
commita6eacb9b33e3473582604f8119fec3efeba62daa (patch)
tree1e156d51c72c2deaf7b61bcbc26219f27a5e205f /drivers/mtd/nand/nand_imx.c
parentd7dc46d5d6f2c80d1719ef877df728457790ac45 (diff)
downloadbarebox-a6eacb9b33e3473582604f8119fec3efeba62daa.tar.gz
barebox-a6eacb9b33e3473582604f8119fec3efeba62daa.tar.xz
mtd: nand-imx: fix byte reading in x16 mode
There are a few NAND commands that make the chip only respond on I/O lines 0 to 7 even for x16 devices. READID (90h) is one such command which was already handled fine in the driver (at least for NFC v1 and v2). Other commands (like PARAM (ECh) to read out ONFI parameters) however were not handled properly. Instead of adding another callback make the read_byte callback handle the holes added by the NFC and depend on the nand-base support to call read_byte when necessary instead of read_buf. This fixes reading the ONFI parameter page on an i.MX25 with an x16 NAND and probably[1] also the result of READID on i.MX51/i.MX53 with x16 NAND. [1] untested because no matching machine available Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mtd/nand/nand_imx.c')
-rw-r--r--drivers/mtd/nand/nand_imx.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index e2aaa153eb..6857509913 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -377,8 +377,6 @@ static void send_read_param_v3(struct imx_nand_host *host)
static void send_read_id_v1_v2(struct imx_nand_host *host)
{
- struct nand_chip *this = &host->nand;
-
/* NANDFC buffer 0 is used for device ID output */
writew(0x0, host->regs + NFC_V1_V2_BUF_ADDR);
@@ -387,20 +385,11 @@ static void send_read_id_v1_v2(struct imx_nand_host *host)
/* Wait for operation to complete */
wait_op_done(host);
- if (this->options & NAND_BUSWIDTH_16) {
- volatile u16 *mainbuf = host->main_area0;
-
- /*
- * Pack the every-other-byte result for 16-bit ID reads
- * into every-byte as the generic code expects and various
- * chips implement.
- */
-
- mainbuf[0] = (mainbuf[0] & 0xff) | ((mainbuf[1] & 0xff) << 8);
- mainbuf[1] = (mainbuf[2] & 0xff) | ((mainbuf[3] & 0xff) << 8);
- mainbuf[2] = (mainbuf[4] & 0xff) | ((mainbuf[5] & 0xff) << 8);
- }
- memcpy32(host->data_buf, host->main_area0, 16);
+ /*
+ * NFC_ID results in reading 6 bytes or words (depending on data width),
+ * so copying 3 32-bit values is just fine.
+ */
+ memcpy32(host->data_buf, host->main_area0, 12);
}
static void send_read_param_v1_v2(struct imx_nand_host *host)
@@ -572,8 +561,16 @@ static u_char imx_nand_read_byte(struct mtd_info *mtd)
if (host->status_request)
return host->get_dev_status(host) & 0xFF;
- ret = *(uint8_t *)(host->data_buf + host->buf_start);
- host->buf_start++;
+ if (nand_chip->options & NAND_BUSWIDTH_16) {
+ /* only take the lower byte of each word */
+ BUG_ON(host->buf_start & 1);
+ ret = *(uint16_t *)(host->data_buf + host->buf_start);
+
+ host->buf_start += 2;
+ } else {
+ ret = *(uint8_t *)(host->data_buf + host->buf_start);
+ host->buf_start++;
+ }
return ret;
}