diff options
author | Brian Norris <norris@broadcom.com> | 2010-07-13 18:13:00 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-08-02 04:08:52 -0400 |
commit | c7b28e25cb9beb943aead770ff14551b55fa8c79 (patch) | |
tree | e51adab05413609c059daa827b454c66f1a207b7 /drivers/mtd/nand/nand_base.c | |
parent | 78d1022439e501bc4a1a32bfaad5a321b8a9d5d6 (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.c | 24 |
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) |