diff mbox

[v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Message ID 4C4F3691.9020505@broadcom.com
State New, archived
Headers show

Commit Message

Brian Norris July 27, 2010, 7:42 p.m. UTC
I found some newer Micron parts that introduce an 8K page size, and so
need a modification on the algorithm. Here's the updated list and a
revision to my patch.

Part			ID String		Block	Page	OOB
MT29F16G08ABABA		2C 48 00 26 89 00 00	512K	4K	224
MT29F16G08CBABA		2C 48 04 46 85 00 00	1024K	4K	224
MT29F16G08MAA		2C D5 94 3E 74 00 00	512K	4K	218
MT29F32G08CBACA		2C 68 04 4A A9 00 00	1024K	4K	224
MT29F64G08CBAAA		2C 88 04 4B A9 00 00	2048K	8K	448
MT29F256G08CJAAA	2C A8 05 CB A9 00 00	2048K	8K	448

Signed-off-by: Brian Norris <norris@broadcom.com>
---
 drivers/mtd/nand/nand_base.c |   37 ++++++++++++++++++++++++++++---------
 drivers/mtd/nand/nand_ids.c  |   10 ++++++++++
 2 files changed, 38 insertions(+), 9 deletions(-)

Comments

Artem Bityutskiy Aug. 22, 2010, 8:20 a.m. UTC | #1
On Tue, 2010-07-27 at 12:42 -0700, Brian Norris wrote:
> I found some newer Micron parts that introduce an 8K page size, and so
> need a modification on the algorithm. Here's the updated list and a
> revision to my patch.
> 
> Part			ID String		Block	Page	OOB
> MT29F16G08ABABA		2C 48 00 26 89 00 00	512K	4K	224
> MT29F16G08CBABA		2C 48 04 46 85 00 00	1024K	4K	224
> MT29F16G08MAA		2C D5 94 3E 74 00 00	512K	4K	218
> MT29F32G08CBACA		2C 68 04 4A A9 00 00	1024K	4K	224
> MT29F64G08CBAAA		2C 88 04 4B A9 00 00	2048K	8K	448
> MT29F256G08CJAAA	2C A8 05 CB A9 00 00	2048K	8K	448
> 
> Signed-off-by: Brian Norris <norris@broadcom.com>

I'm not picking this patch to my l2-mtd-2.6.git, since AFAICS the chips
support ONFI should be detected properly.

The "older chips" which do not support reading ONFI data can then be
detected using special quirks. But using heuristics even for the chips
which do support reading ONFI data sounds bad.

Is this ok? :-)

Artem.
Kevin Cernekee Aug. 22, 2010, 10:20 p.m. UTC | #2
On Sun, Aug 22, 2010 at 1:20 AM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> I'm not picking this patch to my l2-mtd-2.6.git, since AFAICS the chips
> support ONFI should be detected properly.
>
> The "older chips" which do not support reading ONFI data can then be
> detected using special quirks. But using heuristics even for the chips
> which do support reading ONFI data sounds bad.

The NAND controllers on certain legacy SoCs are not able to read the
ONFI parameter page, even if the flash device itself supports ONFI.
Consequently, heuristics or a lookup table would need to be used to
determine the device parameters.

Worst case, I guess the Micron ID decoding logic could just be moved
into the low-level driver.
Matthieu CASTET Aug. 23, 2010, 8:22 a.m. UTC | #3
hi,

Kevin Cernekee a écrit :
> On Sun, Aug 22, 2010 at 1:20 AM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
>> I'm not picking this patch to my l2-mtd-2.6.git, since AFAICS the chips
>> support ONFI should be detected properly.
>>
>> The "older chips" which do not support reading ONFI data can then be
>> detected using special quirks. But using heuristics even for the chips
>> which do support reading ONFI data sounds bad.
> 
> The NAND controllers on certain legacy SoCs are not able to read the
> ONFI parameter page, even if the flash device itself supports ONFI.
Why ?
Are there controllers that doesn't allow to send custom command ?

Matthieu
Kevin Cernekee Aug. 23, 2010, 9:48 p.m. UTC | #4
On Mon, Aug 23, 2010 at 1:22 AM, Matthieu CASTET
<matthieu.castet@parrot.com> wrote:
>> The NAND controllers on certain legacy SoCs are not able to read the
>> ONFI parameter page, even if the flash device itself supports ONFI.
>
> Why ?
> Are there controllers that doesn't allow to send custom command ?

Yes.  The controllers I have here operate at a relatively high level
(read page, write page, erase block).  Part of the reason for this is
because the controller is designed for XIP and DMA - operations where
it is not practical to have the CPU involved in building command
sequences or wiggling ALE/CLE.

Newer versions of the hardware do have the ability to issue custom
commands and perform ONFI queries, but the versions in the field right
now do not.
Artem Bityutskiy Aug. 24, 2010, 6:10 a.m. UTC | #5
On Mon, 2010-08-23 at 14:48 -0700, Kevin Cernekee wrote:
> On Mon, Aug 23, 2010 at 1:22 AM, Matthieu CASTET
> <matthieu.castet@parrot.com> wrote:
> >> The NAND controllers on certain legacy SoCs are not able to read the
> >> ONFI parameter page, even if the flash device itself supports ONFI.
> >
> > Why ?
> > Are there controllers that doesn't allow to send custom command ?
> 
> Yes.  The controllers I have here operate at a relatively high level
> (read page, write page, erase block).  Part of the reason for this is
> because the controller is designed for XIP and DMA - operations where
> it is not practical to have the CPU involved in building command
> sequences or wiggling ALE/CLE.
> 
> Newer versions of the hardware do have the ability to issue custom
> commands and perform ONFI queries, but the versions in the field right
> now do not.

Sorry for my ignorance. Correct me if I'm wrong. I think this should
work as follows:

1. First we add the ONFI detection to MTD, and make it work.
2. If we have an ONFI device which nevertheless does not allow us
reading ONFI data, then we run a 'onfi_broken_devices_quirk()' or
something like this. And this quirk tries to use whatever heuristics.

So, I was thinking that adding strange heuristics and quirks to generic
code is bad. We should _first_ add proper ONFI code, and _then_ add
exception for strange devices like you have.

Do I miss something?
Kevin Cernekee Aug. 26, 2010, 12:43 a.m. UTC | #6
On Mon, Aug 23, 2010 at 11:10 PM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> 1. First we add the ONFI detection to MTD, and make it work.

OK

> 2. If we have an ONFI device which nevertheless does not allow us
> reading ONFI data, then we run a 'onfi_broken_devices_quirk()' or
> something like this. And this quirk tries to use whatever heuristics.

OK

It's more of a "broken controller quirk" than a "broken flash device
quirk," though.

It would be helpful to know if there are any other controller designs
that are unable to read the ONFI parameter page.  i.e. is this a
problem to be solved in the common code, or a driver-specific
situation?

> So, I was thinking that adding strange heuristics and quirks to generic
> code is bad. We should _first_ add proper ONFI code, and _then_ add
> exception for strange devices like you have.

Unfortunately, I think the heuristic/quirk logic is unavoidable for
Samsung and other non-ONFI vendors.

So the question becomes: if nand_base.c already has to have
heuristic/quirk code anyway, and some controller(s) can't speak ONFI
so they need even MORE heuristic/quirk code than the others - do we
add the latter code into nand_base.c or just put it in the driver?
Artem Bityutskiy Aug. 30, 2010, 12:32 p.m. UTC | #7
On Wed, 2010-08-25 at 17:43 -0700, Kevin Cernekee wrote:
> > So, I was thinking that adding strange heuristics and quirks to generic
> > code is bad. We should _first_ add proper ONFI code, and _then_ add
> > exception for strange devices like you have.
> 
> Unfortunately, I think the heuristic/quirk logic is unavoidable for
> Samsung and other non-ONFI vendors.
> 
> So the question becomes: if nand_base.c already has to have
> heuristic/quirk code anyway, and some controller(s) can't speak ONFI
> so they need even MORE heuristic/quirk code than the others - do we
> add the latter code into nand_base.c or just put it in the driver?

OK, I can apply it to the dunno branch and let dwmw2 decide. But this
patch does not apply anymore to to my tree. Brian, would you refresh and
resend? Also, Florian said he is going to send ONFI support soon, may be
it'll make sens to wait a bit and re-send the patch on top of ONFI
support?
diff mbox

Patch

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 4a7b864..a9216af 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2846,6 +2846,9 @@  static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		 * Field definitions are in the following datasheets:
 		 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
 		 * New style   (6 byte ID): Samsung K9GAG08U0D (p.40)
+		 * Micron      (5 byte ID): Micron MT29F16G08MAA (p.24)
+		 *      Note: Micron rule is based on heuristics for
+		 *            newer chips
 		 *
 		 * Check for wraparound + Samsung ID + nonzero 6th byte
 		 * to decide what to do.
@@ -2867,15 +2870,31 @@  static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 			/* Calc pagesize */
 			mtd->writesize = 1024 << (extid & 0x03);
 			extid >>= 2;
-			/* Calc oobsize */
-			mtd->oobsize = (8 << (extid & 0x01)) *
-				(mtd->writesize >> 9);
-			extid >>= 2;
-			/* Calc blocksize. Blocksize is multiples of 64KiB */
-			mtd->erasesize = (64 * 1024) << (extid & 0x03);
-			extid >>= 2;
-			/* Get buswidth information */
-			busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			/* Check for 5 byte ID + Micron + read more 0x00 */
+			if (id_data[0] == NAND_MFR_MICRON && id_data[4] != 0x00
+					&& mtd->writesize >= 4096
+					&& id_data[5] == 0x00
+					&& id_data[6] == 0x00) {
+				/* OOB is 218B/224B per 4KiB pagesize */
+				mtd->oobsize = ((extid & 0x03) == 0x03 ? 218 :
+						224) << (mtd->writesize >> 13);
+				extid >>= 3;
+				/* Blocksize is multiple of 64KiB */
+				mtd->erasesize = mtd->writesize <<
+					(extid & 0x03) << 6;
+				/* All Micron have busw x8? */
+				busw = 0;
+			} else {
+				/* Calc oobsize */
+				mtd->oobsize = (8 << (extid & 0x01)) *
+					(mtd->writesize >> 9);
+				extid >>= 2;
+				/* Calc blocksize (multiples of 64KiB) */
+				mtd->erasesize = (64 * 1024) << (extid & 0x03);
+				extid >>= 2;
+				/* Get buswidth information */
+				busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			}
 		}
 	} else {
 		/*
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 89907ed..4f6e59a 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -107,9 +107,19 @@  struct nand_flash_dev nand_flash_ids[] = {
 	/* 16 Gigabit */
 	{"NAND 2GiB 1,8V 8-bit",	0xA5, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 3,3V 8-bit",	0xD5, 0, 2048, 0, LP_OPTIONS},
+	{"NAND 2GiB 3,3V 8-bit",	0x48, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 1,8V 16-bit",	0xB5, 0, 2048, 0, LP_OPTIONS16},
 	{"NAND 2GiB 3,3V 16-bit",	0xC5, 0, 2048, 0, LP_OPTIONS16},
 
+	/* 32 Gigabit */
+	{"NAND 4GiB 3,3V 8-bit",	0x68, 0, 4096, 0, LP_OPTIONS},
+
+	/* 64 Gigabit */
+	{"NAND 8GiB 3,3V 8-bit",	0x88, 0, 8192, 0, LP_OPTIONS},
+
+	/* 256 Gigabit */
+	{"NAND 32GiB 3,3V 8-bit",	0xA8, 0, 32768, 0, LP_OPTIONS},
+
 	/*
 	 * Renesas AND 1 Gigabit. Those chips do not support extended id and
 	 * have a strange page/block layout !  The chosen minimum erasesize is