AG-AND requested changes
Thomas:
I've been working on a couple of issues using the HN29V1G91T-30 (AG-AND) chips, and have a possible solution (patch attached). The issues are:
1) if a block contains static data (not rewritten), but other blocks in the same 256 block group are rewritten many times, some of the bits in the static data may be flipped resulting in data loss. I believe the wear leveling in JFFS2 will prevent this from occurring on the file system partition, but not for the Bad Block Table.
To address this, I have set up a 'mask' that will match other blocks in the same 256 block group as the Bad Block Table, and added code to rewrite the Bad Block Table when any of these blocks is erased. This should ensure that the Bad Block Table is also rewritten periodically so as not to lose data.
2) according to the chip documentation, if power is suddenly removed during an erase operation, a 'device recovery' procedure must be performed when power is reapplied in order to ensure correct device operation. This procedure involves applying a command sequence at a specific address.
To facilitate this, I have added some additional command definitions, and modified the nand_command_lp routine to use them.
Note: I have two additional comments regarding the proposed solutions.
1) The code changes use an array of bad block table addresses (one for each chip) in case the erase spans multiple chips and BBT per chip is used. Based on my testing I don't think this ever occurs (at least for this device). If we could assume that it would never occur, the code for this could be simplified (no array or loops required).
2) The command for 'device recovery' is a two cycle command, but the first command byte is 0x00 (same as for READ0). Since the process requires that we can distinguish between a recovery and a read operation, I added a high order bit to the initial command (0x100) to make it unique and masked it off when actually sending the command. Please let me know if you have a more elegant (or acceptable) solution.
Thank you,
d.marlin
Index: include/linux/mtd/nand.h
===================================================================
RCS file: /home/cvs/mtd/include/linux/mtd/nand.h,v retrieving revision 1.68
linux/mtd/nand.h +19 -0
@@ -115,6 +115,25 @@#define NAND_CMD_READSTART 0x30#define NAND_CMD_CACHEDPROG 0x15 +/* Extended commands for AG-AND device */ +/* +* Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but +* there is no way to distinguish that from NAND_CMD_READ0 +* until the remaining sequence of commands has been completed +* so add a high order bit and mask it off in the command. +*/ +#define NAND_CMD_DEPLETE1 0x100 +#define NAND_CMD_DEPLETE2 0x38 +#define NAND_CMD_STATUS_MULTI 0x71 +#define NAND_CMD_STATUS_ERROR 0x72 +/* multi-bank error status (banks 0-3) */ +#define NAND_CMD_STATUS_ERROR0 0x73 +#define NAND_CMD_STATUS_ERROR1 0x74 +#define NAND_CMD_STATUS_ERROR2 0x75 +#define NAND_CMD_STATUS_ERROR3 0x76 +#define NAND_CMD_STATUS_RESET 0x7f +#define NAND_CMD_STATUS_CLEAR 0xff +/* Status bits */ #define NAND_STATUS_FAIL 0x01#define NAND_STATUS_FAIL_N1 0x02
Index: drivers/mtd/nand/nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v retrieving revision 1.126
mtd/nand/nand_base.c +67 -5
146 lines not on this page · raw message
Hi David,
Quoted 8 lines · David A. Marlin
Thomas:
Note: I have two additional comments regarding the proposed solutions.1) The code changes use an array of bad block table addresses (one for each chip) in case the erase spans multiple chips and BBT per chip is used. Based on my testing I don't think this ever occurs (at least for this device). If we could assume that it would never occur, the code for this could be simplified (no array or loops required).
Let it this way, so all possible combinations are covered. Please do not make it dependend on NAND_IS_AND, invent a new option like BBT_AUTO_REFRESH or what ever nice symbol you imagine.
So in case other chips suffer from the same problem we have the solution handy without touching the code. The trend is going to those multibit cells so I expect this to be neccecary for other devices too.
Quoted 6 lines
2) The command for 'device recovery' is a two cycle command, but the first command byte is
0x00(same as for READ0). Since the process requires that we can distinguish between a recovery and a read operation, I added a high order bit to the initial command (0x100) to make it unique and masked it off when actually sending the command. Please let me know if you have a more elegant (or acceptable) solution.
Looks sane. You call this from the board driver I guess ?
tglx
Quoted 3 lines · Thomas Gleixner
1) . . . Please do not
make it dependent onNAND_IS_AND, invent a new option likeBBT_AUTO_REFRESHor what ever nice symbol you imagine.
Will do.
Quoted 2 lines
2) . . .
Looks sane. You call this from the board driver I guess ?
Yes, I call it from the driver's init routine, after performing nand_scan.
I'll update the code and post a revised patch.
Thank you,
d.marlin
Updated patch attached.
d.marlin
=========
Quoted 12 lines · David A. Marlin
Quoted 3 lines · Thomas Gleixner
1) . . . Please do not
make it dependent onNAND_IS_AND, invent a new option likeBBT_AUTO_REFRESHor what ever nice symbol you imagine.Will do.
Quoted 2 lines
2) . . .
Looks sane. You call this from the board driver I guess ?
Quoted 8 lines
Yes, I call it from the driver's init routine, after performing
nand_scan.I'll update the code and post a revised patch.
Thank you,
d.marlin
Index: include/linux/mtd/nand.h
===================================================================
RCS file: /home/cvs/mtd/include/linux/mtd/nand.h,v retrieving revision 1.68
linux/mtd/nand.h +23 -0
@@ -115,6 +115,25 @@#define NAND_CMD_READSTART 0x30#define NAND_CMD_CACHEDPROG 0x15 +/* Extended commands for AG-AND device */ +/* +* Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but +* there is no way to distinguish that from NAND_CMD_READ0 +* until the remaining sequence of commands has been completed +* so add a high order bit and mask it off in the command. +*/ +#define NAND_CMD_DEPLETE1 0x100 +#define NAND_CMD_DEPLETE2 0x38 +#define NAND_CMD_STATUS_MULTI 0x71 +#define NAND_CMD_STATUS_ERROR 0x72 +/* multi-bank error status (banks 0-3) */ +#define NAND_CMD_STATUS_ERROR0 0x73 +#define NAND_CMD_STATUS_ERROR1 0x74 +#define NAND_CMD_STATUS_ERROR2 0x75 +#define NAND_CMD_STATUS_ERROR3 0x76 +#define NAND_CMD_STATUS_RESET 0x7f +#define NAND_CMD_STATUS_CLEAR 0xff +/* Status bits */ #define NAND_STATUS_FAIL 0x01#define NAND_STATUS_FAIL_N1 0x02
@@ -170,6 +189,10 @@/* Chip has a array of 4 pages which can be read without * additional ready /busy waits */ #define NAND_4PAGE_ARRAY 0x00000040 +/* Chip requires that BBT is periodically rewritten to prevent +* bits from adjacent blocks from 'leaking' and altering data. +* This happens with the Renesas AG-AND chips, possibly others. */ +#define BBT_AUTO_REFRESH 0x00000080/* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS \
Index: drivers/mtd/nand/nand_ids.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_ids.c,v retrieving revision 1.10
mtd/nand/nand_ids.c +1 -1
@@ -103,7 +103,7 @@* Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go * There are more speed improvements for reads and writes possible, but not implemented now */ - {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, + {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, {NULL,} };
Index: drivers/mtd/nand/nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v retrieving revision 1.126
mtd/nand/nand_base.c +68 -4
140 lines not on this page · raw message