linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nikolaus Voss <n.voss@weinmann.de>
To: Artem Bityutskiy <dedekind1@gmail.com>,
	Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH] mtd: atmel_nand: fix access to 16 bit NAND devices
Date: Wed, 18 Jan 2012 10:16:54 +0100	[thread overview]
Message-ID: <201201251217.q0PCHmRe027024@gatekeeper.vosshq.de> (raw)

commit fb5427508abbd635e877fabdf55795488119c2d6 optimizes PIO
NAND accesses by using IO memcpy instead of IO read/write
repeated functions.

This breaks access to 16 bit NAND devices as memcpy_fromio()/toio()
_always_ use byte accesses (see arch/arm/kernel/io.c), so with
16 bit NAND, one byte gets lost per NAND access cycle and NAND
address count is wrong.

Using memcpy() instead of the IO memcpy functions fixes this, but
depends on correct word alignment of the buffer and length has to
be a multiple of four, otherwise it might issue byte accesses and
possibly break 16 bit NAND access (cf arch/arm/lib/copy_template.S).

Memcpy variants seem to be the wrong approach here, since the
NAND controller doesn't make the NAND appear as truely randomly
accessible memory (as opposed to the DRAM controller which does
exactly that).

So, my proposal is to use 32 bit IO read/write (and let SMC
map it to 8 bit or 16 bit NAND accesses) and account for
length % 4 > 0 with two additional IO read/writes.

Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
---
 drivers/mtd/nand/atmel_nand.c |   19 +++++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index a582a0f..7396d4a 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -265,7 +265,12 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 			return;
 
 	/* if no DMA operation possible, use PIO */
-	memcpy_fromio(buf, chip->IO_ADDR_R, len);
+	readsl(chip->IO_ADDR_R, buf, len >> 2);
+	if (len & 2)
+		/* read into buf[len - 2] or buf[len - 3] */
+		*((u16 *)&buf[len & ~3]) = chip->read_word(mtd);
+	if (len & 1)
+		buf[len - 1] = chip->read_byte(mtd);
 }
 
 static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
@@ -278,7 +283,17 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 			return;
 
 	/* if no DMA operation possible, use PIO */
-	memcpy_toio(chip->IO_ADDR_W, buf, len);
+	writesl(chip->IO_ADDR_W, buf, len >> 2);
+	if (len & 2)
+		/* write from buf[len - 2] or buf[len - 3] */
+		writew(*((u16 *)&buf[len & ~3]), chip->IO_ADDR_R);
+	if (len & 1) {
+		/* a single byte cannot be written to 16 bit NAND */
+		if (chip->options & NAND_BUSWIDTH_16)
+			BUG();
+		else
+			writeb(buf[len - 1], chip->IO_ADDR_R);
+	}
 }
 
 /*
-- 
1.7.5.4


             reply	other threads:[~2012-01-25 12:18 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-18  9:16 Nikolaus Voss [this message]
2012-01-27 13:29 ` [PATCH] mtd: atmel_nand: fix access to 16 bit NAND devices Artem Bityutskiy
2012-01-30  7:57   ` Voss, Nikolaus
2012-01-30  8:57     ` Nicolas Ferre
2012-02-01 10:43       ` Eric Bénard
2012-02-02 12:06       ` Artem Bityutskiy
2012-02-03  3:35         ` Venu Byravarasu
2012-02-03  5:32           ` Artem Bityutskiy

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=201201251217.q0PCHmRe027024@gatekeeper.vosshq.de \
    --to=n.voss@weinmann.de \
    --cc=dedekind1@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=nicolas.ferre@atmel.com \
    /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;
as well as URLs for NNTP newsgroup(s).