mtd: cfi_util: add support for switching SST 39VF640xB chips into QRY mode
PATCH 1/4 mtd: cfi_util: add support for switching SST 39VF640xB chips into QRY mode
--- drivers/mtd/chips/cfi_util.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/mtd/chips/cfi_util.c +7 -0
@@ -77,6 +77,13 @@ int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,cfi_send_gen_cmd (0x98 ,0x5555 , base, map, cfi, cfi->device_type,NULL );if (cfi_qry_present (map, base, cfi))return 1 ; +/* SST 39VF640xB */ +cfi_send_gen_cmd (0xF0 ,0 , base, map, cfi, cfi->device_type,NULL ); +cfi_send_gen_cmd (0xAA ,0x555 , base, map, cfi, cfi->device_type,NULL ); +cfi_send_gen_cmd (0x55 ,0x2AA , base, map, cfi, cfi->device_type,NULL ); +cfi_send_gen_cmd (0x98 ,0x555 , base, map, cfi, cfi->device_type,NULL ); +if (cfi_qry_present (map, base, cfi)) +return 1 ;/* QRY not found */ return 0 ; }
PATCH 2/4 mtd: cfi_cmdset_0002: make sector erase command variable
Some old SST chips use 0x50 as sector erase command, instead of 0x30. Make this value variable to handle such chips.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +5 -4
@@ -78,6 +78,7 @@ static struct mtd_chip_driver cfi_amdstd_chipdrv = { .module = THIS_MODULE }; +static map_word sector_erase_cmd =CMD (0x30 );/* #define DEBUG_CFI_FEATURES */
@@ -674,7 +675,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr* there was an error (so leave the erase * routine to recover from it) or we trying to * use the erase-in-progress sector. */ -map_write (map,CMD (0x30 ), chip->in_progress_block_addr); +map_write (map, sector_erase_cmd, chip->in_progress_block_addr); chip->state =FL_ERASING ; chip->oldstate =FL_READY ;printk (KERN_ERR "MTD %s(): chip not ready after erase suspend\n" , __func__);
@@ -727,7 +728,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adswitch (chip->oldstate) {case FL_ERASING : chip->state = chip->oldstate; -map_write (map,CMD (0x30 ), chip->in_progress_block_addr); +map_write (map, sector_erase_cmd, chip->in_progress_block_addr); chip->oldstate =FL_READY ; chip->state =FL_ERASING ;break ;
@@ -870,7 +871,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,local_irq_disable ();/* Resume the write or erase operation */ -map_write (map,CMD (0x30 ), adr); +map_write (map, sector_erase_cmd, adr); chip->state = oldstate; start =xip_currtime (); }else if (usec >=1000000 /HZ ) {
@@ -1675,7 +1676,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,cfi_send_gen_cmd (0x80 , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0xAA , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x55 , cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type,NULL ); -map_write (map,CMD (0x30 ), adr); +map_write (map, sector_erase_cmd, adr); chip->state =FL_ERASING ; chip->erase_suspended =0 ;
Re: [PATCH 2/4] mtd: cfi_cmdset_0002: make sector erase command variable
Quoted 13 lines · Guillaume LECERF
Some old SST chips use
0x50as sector erase command, instead of0x30. Make this value variable to handle such chips.Signed-off-by Guillaume LECERF <[email protected]>--- drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-)drivers/mtd/chips/cfi_cmdset_0002.c +0
-0
drivers/mtd/chips/cfi_cmdset_0002.c static struct mtd_chip_driver cfi_amdstd_chipdrv = { · line 81
Quoted 4 lines
drivers/mtd/chips/cfi_cmdset_0002.c +1
-0@@ -78,6 +78,7 @@ static struct mtd_chip_driver cfi_amdstd_chipdrv = { .module = THIS_MODULE }; +static map_word sector_erase_cmd =CMD (0x30 );
Uh? A static one? Why not per device?
I'd also suggest to fold the next patch into this one, so the need for the change is more obvious.
Signature · 2 lines
Pengutronix e.K. | Wolfram Sang | Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH 2/4] mtd: cfi_cmdset_0002: make sector erase command variable
2010/10/23 Wolfram Sang <[email protected]>:
Quoted 3 lines
Quoted 1 line
+static
map_wordsector_erase_cmd= CMD(0x30);Uh? A static one? Why not per device?
Hi Wolfram.
I knew it was ugly, but where would you store this value ?
Quoted 2 lines
I'd also suggest to fold the next patch into this one, so the need for the change is more obvious.
Done locally.
Signature · 2 lines
Guillaume LECERF GeeXboX developer - www.geexbox.org
Re: [PATCH 2/4] mtd: cfi_cmdset_0002: make sector erase command variable
In reply to Wolfram Sang2010/10/23 Wolfram Sang <[email protected]>:
Quoted 3 lines
Quoted 1 line
+static
map_wordsector_erase_cmd= CMD(0x30);Uh? A static one? Why not per device?
Something like that ?
Signature · 2 lines
Guillaume LECERF GeeXboX developer - www.geexbox.org
mtd: cfi_cmdset_0002: make sector erase command variable
From: Guillaume LECERF <[email protected]>
Some old SST chips use 0x50 as sector erase command, instead of 0x30. Make this value variable to handle such chips.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 10 ++++++---- drivers/mtd/chips/cfi_probe.c | 2 ++ include/linux/mtd/cfi.h | 1 + 3 files changed, 9 insertions(+), 4 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +6 -4
@@ -291,6 +291,8 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) cfi->addr_unlock1 =0x555 ; cfi->addr_unlock2 =0x2AA ; + + cfi->sector_erase_cmd =0x50 ; }static void fixup_s29gl064n_sectors (struct mtd_info *mtd,void *param)
@@ -674,7 +676,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr* there was an error (so leave the erase * routine to recover from it) or we trying to * use the erase-in-progress sector. */ -map_write (map,CMD (0x30 ), chip->in_progress_block_addr); +map_write (map,CMD (cfi->sector_erase_cmd), chip->in_progress_block_addr); chip->state =FL_ERASING ; chip->oldstate =FL_READY ;printk (KERN_ERR "MTD %s(): chip not ready after erase suspend\n" , __func__);
@@ -727,7 +729,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adswitch (chip->oldstate) {case FL_ERASING : chip->state = chip->oldstate; -map_write (map,CMD (0x30 ), chip->in_progress_block_addr); +map_write (map,CMD (cfi->sector_erase_cmd), chip->in_progress_block_addr); chip->oldstate =FL_READY ; chip->state =FL_ERASING ;break ;
@@ -870,7 +872,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,local_irq_disable ();/* Resume the write or erase operation */ -map_write (map,CMD (0x30 ), adr); +map_write (map,CMD (cfi->sector_erase_cmd), adr); chip->state = oldstate; start =xip_currtime (); }else if (usec >=1000000 /HZ ) {
@@ -1675,7 +1677,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,cfi_send_gen_cmd (0x80 , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0xAA , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x55 , cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type,NULL ); -map_write (map,CMD (0x30 ), adr); +map_write (map,CMD (cfi->sector_erase_cmd), adr); chip->state =FL_ERASING ; chip->erase_suspended =0 ;
drivers/mtd/chips/cfi_probe.c +2 -0
@@ -177,6 +177,8 @@ static int __xipram cfi_chip_setup(struct map_info *map, cfi->cfi_mode =CFI_MODE_CFI ; + cfi->sector_erase_cmd =0x30 ; +/* Read the CFI info structure */ xip_disable_qry (base, map, cfi);for (i=0 ; i<(sizeof (struct cfi_ident ) + num_erase_regions *4 ); i++)
include/linux/mtd/cfi.h +1 -0
@@ -289,6 +289,7 @@ struct cfi_private {must be of the same type. */ int mfr, id;int numchips; +int sector_erase_cmd;unsigned long chipshift;/* Because they're of the same type */ const char *im_name;/* inter_module name for cmdset_setup */ struct flchip chips[0 ];/* per-chip data structure for each chip */
PATCH 3/4 mtd: cfi_cmdset_0002: use 0x50 erase command for SST 39VFxxxxB chips
In reply to Guillaume LECERF--- drivers/mtd/chips/cfi_cmdset_0002.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +2 -0
@@ -292,6 +292,8 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) cfi->addr_unlock1 =0x555 ; cfi->addr_unlock2 =0x2AA ; + + sector_erase_cmd =CMD (0x50 ); }static void fixup_s29gl064n_sectors (struct mtd_info *mtd,void *param)
PATCH 4/4 mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
In reply to Guillaume LECERFAdd support for SST38VF640x chips in CFI mode.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +19 -0
@@ -296,6 +296,21 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) sector_erase_cmd =CMD (0x50 ); } +static void fixup_sst38vf640x_sectorsize (struct mtd_info *mtd,void *param) +{ +struct map_info *map = mtd->priv; +struct cfi_private *cfi = map->fldrv_priv; + +fixup_sst39vf_rev_b (mtd, param); + +/* +* CFI reports 1024 sectors (0x03ff +1) of 64KBytes (0x0100 *256) where +* it should report a size of 8KBytes (0x0020 *256). +*/ + cfi->cfiq->EraseRegionInfo[0 ] =0x002003ff ; +pr_warning ("%s: Bad 38VF640x CFI data, adjust sector size from 64 to 8KBytes\n" , mtd->name); +} +static void fixup_s29gl064n_sectors (struct mtd_info *mtd,void *param) {struct map_info *map = mtd->priv;
@@ -347,6 +362,10 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, + { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */ + { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */ + { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */ + { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */ #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, #endif
Re: [PATCH 4/4] mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
Quoted 35 lines · Guillaume LECERF
Add support for SST38VF640x chips in CFI mode.
Signed-off-by Guillaume LECERF <[email protected]>Signed-off-by yidong zhang <[email protected]>---
drivers/mtd/chips/cfi_cmdset_0002.c | 19 +++++++++++++++++++1 files changed, 19 insertions(+), 0 deletions(-)drivers/mtd/chips/cfi_cmdset_0002.c +15
-0@@ -296,6 +296,21 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) sector_erase_cmd = CMD(0x50); } +static void fixup_sst38vf640x_sectorsize (struct mtd_info *mtd,void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + fixup_sst39vf_rev_b(mtd, param); + + /* + * CFI reports 1024 sectors (0x03ff +1) of 64KBytes (0x0100 *256) where + * it should report a size of 8KBytes (0x0020 *256). + */ + cfi->cfiq->EraseRegionInfo[0] = 0x002003ff; + pr_warning("%s: Bad 38VF640x CFI data, adjust sector size from 64 to 8KBytes\n", mtd->name); +} + static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) { struct map_info *map = mtd->priv;
drivers/mtd/chips/cfi_cmdset_0002.c static struct cfi_fixup cfi_fixup_table[] = { · line 371
Quoted 10 lines
drivers/mtd/chips/cfi_cmdset_0002.c +4
-0@@ -347,6 +362,10 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, + { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */ + { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */ + { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */ + { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */ #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, #endif
The SST38VF640x chips have no Extended Query table. I think we should move them to the
cfi_nopri_fixup_table.
Quoted 2 lines
Re: [PATCH 4/4] mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
2010/10/25 yidong zhang <[email protected]>:
Quoted 3 lines
The SST38VF640x chips have no Extended Query table. I think we should move them to the
cfi_nopri_fixup_table.
According to the datasheet [1], it has.
[1] http://www.sst.com/dotAsset/39749.pdf, table 13
Signature · 2 lines
Guillaume LECERF GeeXboX developer - www.geexbox.org
Re: [PATCH 4/4] mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
Quoted 8 lines · Guillaume LECERF
2010/10/25 yidong zhang <[email protected]>:
Quoted 3 lines
The SST38VF640x chips have no Extended Query table. I think we should move them to the
cfi_nopri_fixup_table.According to the datasheet [1], it has.
[1] http://www.sst.com/dotAsset/39749.pdf, table 13
Oh, sorry, my mistake. I tested the patch right now. But it didn't work, please the logs below.
Amd/Fujitsu Extended Query Table at 0x0040
Unknown Amd/Fujitsu Extended Query version . (0xff/0xff).
Quoted 4 lines
--
Guillaume LECERF
GeeXboX developer - www.geexbox.org
Re: [PATCH 4/4] mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
2010/10/25 yidong zhang <[email protected]>:
Quoted 5 lines
Oh, sorry, my mistake. I tested the patch right now. But it didn't work, please the logs below.
Amd/Fujitsu Extended Query Table at
0x0040
Unknown Amd/Fujitsu Extended Query version . (0xff/0xff).
This chip does not have a valid Major/MinorVersion. Could you please try the attached patch ?
Signature · 2 lines
Guillaume LECERF GeeXboX developer - www.geexbox.org
mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
From: Guillaume LECERF <[email protected]>
Add support for SST38VF640x chips in CFI mode.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +23 -0
@@ -296,6 +296,21 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) sector_erase_cmd =CMD (0x50 ); } +static void fixup_sst38vf640x_sectorsize (struct mtd_info *mtd,void *param) +{ +struct map_info *map = mtd->priv; +struct cfi_private *cfi = map->fldrv_priv; + +fixup_sst39vf_rev_b (mtd, param); + +/* +* CFI reports 1024 sectors (0x03ff +1) of 64KBytes (0x0100 *256) where +* it should report a size of 8KBytes (0x0020 *256). +*/ + cfi->cfiq->EraseRegionInfo[0 ] =0x002003ff ; +pr_warning ("%s: Bad 38VF640x CFI data, adjust sector size from 64 to 8KBytes\n" , mtd->name); +} +static void fixup_s29gl064n_sectors (struct mtd_info *mtd,void *param) {struct map_info *map = mtd->priv;
@@ -347,6 +362,10 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, + { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */ + { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */ + { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */ + { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */ #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, #endif
@@ -377,6 +396,10 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,if (cfi->mfr ==CFI_MFR_SAMSUNG && cfi->id ==0x257e && extp->MajorVersion =='0' ) extp->MajorVersion ='1' ; +if (cfi->mfr ==CFI_MFR_SST && (cfi->id >>4 ) ==0x0536 ) { + extp->MajorVersion ='1' ; + extp->MinorVersion ='0' ; + } }struct mtd_info *cfi_cmdset_0002 (struct map_info *map,int primary)
Re: [PATCH 4/4] mtd: cfi_cmdset_0002: add CFI detection for SST 38VF640x chips
Quoted 9 lines · Guillaume LECERF
2010/10/25 yidong zhang <[email protected]>:
Quoted 5 lines
Oh, sorry, my mistake. I tested the patch right now. But it didn't work, please the logs below.
Amd/Fujitsu Extended Query Table at
0x0040
Unknown Amd/Fujitsu Extended Query version . (0xff/0xff).This chip does not have a valid Major/MinorVersion. Could you please try the attached patch ?
Passed my test. Using this patch, the driver can support the chips now.
Quoted 5 lines
--
Guillaume LECERF
GeeXboX developer - www.geexbox.org