aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
authorBrian Norris <norris@broadcom.com>2010-07-13 18:13:00 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-08-02 04:08:52 -0400
commitc7b28e25cb9beb943aead770ff14551b55fa8c79 (patch)
treee51adab05413609c059daa827b454c66f1a207b7 /drivers/mtd/nand/nand_base.c
parent78d1022439e501bc4a1a32bfaad5a321b8a9d5d6 (diff)
mtd: nand: refactor BB marker detection
Some level of support for various scanning locations was already built in, but this required clean-up. First, BB marker location cannot be determined _only_ by the page size. Instead, I implemented some heuristic detection based on data sheets from various manufacturers (all found in nand_base.c:nand_get_flash_type()). Second, once these options were identified, they were not handled properly by nand_bbt.c:nand_default_bbt(). I updated the static nand_bbt_desc structs to reflect the need for more combinations of detection. The memory allocation here probably needs to be done dynamically in the very near future (see next patches). Signed-off-by: Brian Norris <norris@broadcom.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e6cf9aefef13..bd697909db53 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2920,9 +2920,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
2920 chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; 2920 chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1;
2921 2921
2922 /* Set the bad block position */ 2922 /* Set the bad block position */
2923 chip->badblockpos = mtd->writesize > 512 ? 2923 if (!(busw & NAND_BUSWIDTH_16) && (*maf_id == NAND_MFR_STMICRO ||
2924 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; 2924 (*maf_id == NAND_MFR_SAMSUNG &&
2925 chip->badblockbits = 8; 2925 mtd->writesize == 512) ||
2926 *maf_id == NAND_MFR_AMD))
2927 chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
2928 else
2929 chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
2930
2926 2931
2927 /* Get chip options, preserve non chip based options */ 2932 /* Get chip options, preserve non chip based options */
2928 chip->options &= ~NAND_CHIPOPTIONS_MSK; 2933 chip->options &= ~NAND_CHIPOPTIONS_MSK;
@@ -2941,12 +2946,23 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
2941 2946
2942 /* 2947 /*
2943 * Bad block marker is stored in the last page of each block 2948 * Bad block marker is stored in the last page of each block
2944 * on Samsung and Hynix MLC devices 2949 * on Samsung and Hynix MLC devices; stored in first two pages
2950 * of each block on Micron devices with 2KiB pages and on
2951 * SLC Samsung, Hynix, and AMD/Spansion. All others scan only
2952 * the first page.
2945 */ 2953 */
2946 if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) && 2954 if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
2947 (*maf_id == NAND_MFR_SAMSUNG || 2955 (*maf_id == NAND_MFR_SAMSUNG ||
2948 *maf_id == NAND_MFR_HYNIX)) 2956 *maf_id == NAND_MFR_HYNIX))
2949 chip->options |= NAND_BBT_SCANLASTPAGE; 2957 chip->options |= NAND_BBT_SCANLASTPAGE;
2958 else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
2959 (*maf_id == NAND_MFR_SAMSUNG ||
2960 *maf_id == NAND_MFR_HYNIX ||
2961 *maf_id == NAND_MFR_AMD)) ||
2962 (mtd->writesize == 2048 &&
2963 *maf_id == NAND_MFR_MICRON))
2964 chip->options |= NAND_BBT_SCAN2NDPAGE;
2965
2950 2966
2951 /* Check for AND chips with 4 page planes */ 2967 /* Check for AND chips with 4 page planes */
2952 if (chip->options & NAND_4PAGE_ARRAY) 2968 if (chip->options & NAND_4PAGE_ARRAY)