diff options
author | Brian Norris <computersforpeace@gmail.com> | 2012-09-24 20:40:54 -0700 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-09-29 15:58:15 +0100 |
commit | 73ca392f7d4a175dcf7b56a3c35efc92a55a5473 (patch) | |
tree | 0eb2d8ebab3bb62714cb0123b03f90246aaeabdf /drivers/mtd | |
parent | b9e48534d8f4eb17d531f54d2cb3b9138db13ccb (diff) |
mtd: nand: decode Hynix MLC, 6-byte ID length
Hynix has introduced a new ID decoding scheme for their newer MLC, some of
which don't support ONFI. The following devices all follow the pattern given in
the datasheet for Hynix H27UBG8T2B, p.22:
Hynix H27UAG8T2A
Hynix H27UBG8T2A
Hynix H27UBG8T2B
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5365ad569f5a..304765140634 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2984,8 +2984,10 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) * New style (6 byte ID): Samsung K9GBG08U0M (p.40) + * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * - * Check for ID length + Samsung ID to decide what to do. + * Check for ID length, cell type, and Hynix/Samsung ID to decide what + * to do. */ if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { @@ -3012,6 +3014,47 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); *busw = 0; + } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && + (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { + unsigned int tmp; + + /* Calc pagesize */ + mtd->writesize = 2048 << (extid & 0x03); + extid >>= 2; + /* Calc oobsize */ + switch (((extid >> 2) & 0x04) | (extid & 0x03)) { + case 0: + mtd->oobsize = 128; + break; + case 1: + mtd->oobsize = 224; + break; + case 2: + mtd->oobsize = 448; + break; + case 3: + mtd->oobsize = 64; + break; + case 4: + mtd->oobsize = 32; + break; + case 5: + mtd->oobsize = 16; + break; + default: + mtd->oobsize = 640; + break; + } + extid >>= 2; + /* Calc blocksize */ + tmp = ((extid >> 1) & 0x04) | (extid & 0x03); + if (tmp < 0x03) + mtd->erasesize = (128 * 1024) << tmp; + else if (tmp == 0x03) + mtd->erasesize = 768 * 1024; + else + mtd->erasesize = (64 * 1024) << tmp; + *busw = 0; } else { /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); |