From patchwork Sat Feb 20 16:52:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: mtd: cfi_cmdset_0002: add CFI detection for SST 39VF3201 chips Date: Sat, 20 Feb 2010 06:52:52 -0000 From: Guillaume LECERF X-Patchwork-Id: 45924 Message-Id: <20100220165252.11347.54609.stgit@shiryu.yomgui.biz> To: David Woodhouse Cc: linux-mtd SST 39VF0201 chips use the 0x0701 command set, fully compatible with the AMD one. This patch adds support for detecting them in CFI mode. Signed-off-by: Guillaume Lecerf --- drivers/mtd/chips/cfi_cmdset_0002.c | 24 ++++++++++++++++++++++++ drivers/mtd/chips/gen_probe.c | 1 + 2 files changed, 25 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 3df6056..94452c1 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -43,6 +43,7 @@ #define MAX_WORD_RETRIES 3 +#define SST39VF3201 0x235b #define SST49LF004B 0x0060 #define SST49LF040B 0x0050 #define SST49LF008A 0x005a @@ -246,6 +247,19 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) } /* + * SST 39VF3201 chips report 2 erase regions while they actually + * only have 1. Patch this on the fly. + */ +static void fixup_sst39vf3201_erase_regions(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + cfi->cfiq->NumEraseRegions = 1; + pr_warning("%s: Bad SST39VF3201 CFI data, adjust from 2 to 1 erase region\n", mtd->name); +} + +/* * Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors * locked by default. */ @@ -314,6 +328,7 @@ static struct cfi_fixup fixup_table[] = { */ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL }, + { CFI_MFR_SST, SST39VF3201, fixup_sst39vf3201_erase_regions, NULL }, { 0, 0, NULL, NULL } }; @@ -352,6 +367,14 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) mtd->writesize = 1; if (cfi->cfi_mode==CFI_MODE_CFI){ + /* + * SST 39VF3201 chips do not have a real PRI. + */ + if (cfi->mfr == CFI_MFR_SST && cfi->id == SST39VF3201) { + cfi->addr_unlock1 = 0x5555; + cfi->addr_unlock2 = 0x2AAA; + } + else { unsigned char bootloc; /* * It's a real CFI chip, not one for which the probe @@ -412,6 +435,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) /* Set the default CFI lock/unlock addresses */ cfi->addr_unlock1 = 0x555; cfi->addr_unlock2 = 0x2aa; + } } /* CFI mode */ else if (cfi->cfi_mode == CFI_MODE_JEDEC) { diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index 991c457..599c259 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c @@ -249,6 +249,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary) #endif #ifdef CONFIG_MTD_CFI_AMDSTD case P_ID_AMD_STD: + case P_ID_SST_OLD: return cfi_cmdset_0002(map, primary); #endif #ifdef CONFIG_MTD_CFI_STAA