First partition is not erasing in the NOR flash S29GL064N (S29GL-N MirrorBit)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Dear Sir/Madam,

           I am using the Octeon CN66XX processor, with following detail's.

we created three partition of the flash as uboot, cfpag and uboot-backup.
For upgrading the uboot i want to erase first partition i.e. uboot and then
copying new uboot binary to this partition. Problem is that first block in
this partition is not getting erased. where all other partition are
successfully erasing.


1) Spansion Parallel NOR flash S29GL064N/ S29GL032N
CFI conformant flash (16 x 16) Size: 8 MB in 135 Sectors
AMD Standard command set

2) Linux kernel 2.6.32.27

3) processor - OCTEONCN66XX (mips)

Details of the problem.


1) we are making the partition for MTD flash by command line from u-boot as
following
"linux=linuxboot 0x20000000 0:3;bootoctlinux 0x20000000
coremask=$(core_mask) isolcpus=2,3,4,5,6,7 mem=0xFF800000 root=/dev/msda1
mtdparts=phys_mapped_flash:
1024k(bootloader),1536k(fpga),1024k(ubootbackup)
console=ttyS1,57600\0"

2) in the log the partitions is created as

Bootbus flash: Setting flash for 8MB flash at 0x1fc00000
phys_mapped_flash: Found 1 x16 devices at 0x0 in 16-bit bank
Amd/Fujitsu Extended Query Table at 0x0040
phys_mapped_flash: Swapping erase regions for broken CFI table.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
3 cmdlinepart partitions found on MTD device phys_mapped_flash
Creating 3 MTD partitions on "phys_mapped_flash":
0x000000000000-0x000000100000 : "bootloader"
0x000000100000-0x000000280000 : "fpga"
0x000000280000-0x000000380000 : "ubootbackup"
 

   

3) Linux shows the partitions as
bash-4.0# cat /proc/mtd
dev: size erasesize name
mtd0: 00100000 00010000 "bootloader"
mtd1: 00180000 00010000 "fpga"
mtd2: 00100000 00010000 "ubootbackup"

4) After giving command, flash_eraseall /dev/mtd2 and flash_eraseall /dev/mtd1

are getting successfully erased
, but when i erase mtd0 partition it gives
the following error
bash-4.0# flash_eraseall /dev/mtd0
Erasing 64 Kibyte @ 0 -- 0 % complete.
flash_eraseall: /dev/mtd0: MTD Erase failure: Input/output error
Erasing 64 Kibyte @ f0000 -- 93 % complete.

from error log observation is that the 1st block is not getting erased and
remaining blocks are getting successfully erased in /dev/mtd0.


5) I tried following method's to resolve this but not helped

a) first i tried, making all the sectors of flash to un-protect in u-boot
(by making changes in u-boot). Then boot Linux and tried to flash_eraseall
/dev/mtd0.

b) in file kernel_2.6/linux/arch/mips/cavium-octeon/octeon_68xx.dts.

   

Removed the bootloader as ro (readonly)
flash0: nor@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x800000>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader";
reg = <0 0x200000>;
//read-only;
};
partition@200000 {
label = "kernel";
reg = <0x200000 0x200000>;
};
partition@400000 {
label = "cramfs";
reg = <0x400000 0x3fe000>;
};
partition@7fe000 {
label = "environment";
reg = <0x7fe000 0x2000>;
//read-only;
};
};

c) I cross checked for the each partition's mtd->flag it is
MTD_CAP_NORFLASH (i.e. writable)

d) i debugged
the file linux/kernel_2.6/linux/drivers/mtd/chips/cfi_cmdset_0002.c. In this file
after flash_eraseall /dev/mtd0
in API - static int __xipram do_erase_oneblock(struct map_info *map, struct
flchip *chip, unsigned long adr, int len, void *thunk)
chip_good(map, adr, datum) is failed.

e) before calling the do_erase_oneblock i invoked the API static int
do_atmel_unlock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk);
in @@ -1683,10 +1694,16 @@ static int cfi_amdstd_erase_varsize(struct
mtd_info *mtd, struct erase_info *ins
to unlock all the sectors in the block

   

e) I introduced some delay before chip_good(map, adr, datum). For giving
time to reflect the erase changes.

d) the diff of cfi_cmdset_0002.c as follows

--- a/OCTEON-SDK/linux/kernel_2.6/
linux/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/OCTEON-SDK/linux/kernel_2.6/linux/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -74,6 +74,9 @@ static void put_chip(struct map_info *map, struct flchip
*chip, unsigned long ad
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);

+static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
+ unsigned long adr, int len, void *thunk);
+
static struct mtd_chip_driver cfi_amdstd_chipdrv = {
.probe = NULL, /* Not usable directly */
.destroy = cfi_amdstd_destroy,
@@ -1596,12 +1599,14 @@ static int __xipram do_erase_oneblock(struct
map_info *map, struct flchip *chip,
unsigned long timeo = jiffies + HZ;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
-
+ printk(KERN_DEBUG "ENTERED in %s()",__func__);
adr += chip->start;

spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_ERASING);
if (ret) {
+
+ printk(KERN_DEBUG "get_chip failed in %s() at line= 1607",__func__);
spin_unlock(chip->mutex);
return ret;
}
@@ -1663,11 +1668,17 @@ static int __xipram do_erase_oneblock(struct
map_info *map, struct flchip *chip,
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1000000/HZ);
}
+ /* MTD debug */
+ printk(KERN_DEBUG "delay for chip good");
+ UDELAY(map, chip, adr, 1000000/HZ);
+ UDELAY(map, chip, adr, 1000000/HZ);
/* Did we succeed? */
if (!chip_good(map, adr, map_word_ff(map))) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
+
+ printk(KERN_DEBUG "chip_good failed in %s() at line=1675",__func__);

ret = -EIO;
}
@@ -1683,10 +1694,16 @@ static int cfi_amdstd_erase_varsize(
struct mtd_info
*mtd, struct erase_info *ins
{
unsigned long ofs, len;
int ret;
-
+ printk(KERN_ALERT "Entered in cfi_amdstd_erase_varsize\n");
ofs = instr->addr;
len = instr->len;
-
+
+ ret = cfi_varsize_frob(mtd, do_atmel_unlock, ofs, len, NULL);
+ if(ret)
+ {
+ printk(KERN_ALERT "Failed to do_atmel_unlock with ret = %d \n",ret);
+ }
+ printk(KERN_ALERT "Success to do_atmel_unlock with ret = %d \n",ret);
ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
if (ret)
return ret;
@@ -1765,11 +1782,18 @@ static int do_atmel_unlock(struct map_info *map,
struct flchip *chip,
spin_lock(chip->mutex);
ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING);
if (ret)
+ {
+ printk(" %s(): get_chip failed ",
+ __func__);
+
goto out_unlock;
- chip->state = FL_UNLOCKING;
+ }
+ chip->state = FL_UNLOCKING;

DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
__func__, adr, len);
+ printk("MTD %s(): LOCK 0x%08lx len %d\n",
+ __func__, adr, len);

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);

Please help me to understand this problem and to resolve

   

Thank you,
MS
 

0 Likes
1 Solution
Anonymous
Not applicable

Hi,

   

 

   

Please check following items  in function do_erase_oneblock in cfi_cmdset_0002.c.

   

 

   

1. Do you see software timeout warning in following code when failure happens?

   

  if (time_after(jiffies, timeo)) {
   xip_enable(map, chip, adr);
   printk(KERN_WARNING "MTD %s(): software timeout\n",
    __func__ );
   break;
  }
 

   

2. In following if condition, please add map_read 3 times before map_write( map, CMD(0xF0), chip->start ); and print out read data.

   

 

   

 /* Did we succeed? */
 if (!chip_good(map, adr, map_word_ff(map))) {
  /* reset on all failures. */
  map_write( map, CMD(0xF0), chip->start );
  /* FIXME - should have reset delay before continuing */

   

  ret = -EIO;
 }

   

 

   

3. Print out input variable adr and len at the beginning of do_erase_oneblock.

   

 

   

Best Regards,

   

Clement

View solution in original post

0 Likes
1 Reply
Anonymous
Not applicable

Hi,

   

 

   

Please check following items  in function do_erase_oneblock in cfi_cmdset_0002.c.

   

 

   

1. Do you see software timeout warning in following code when failure happens?

   

  if (time_after(jiffies, timeo)) {
   xip_enable(map, chip, adr);
   printk(KERN_WARNING "MTD %s(): software timeout\n",
    __func__ );
   break;
  }
 

   

2. In following if condition, please add map_read 3 times before map_write( map, CMD(0xF0), chip->start ); and print out read data.

   

 

   

 /* Did we succeed? */
 if (!chip_good(map, adr, map_word_ff(map))) {
  /* reset on all failures. */
  map_write( map, CMD(0xF0), chip->start );
  /* FIXME - should have reset delay before continuing */

   

  ret = -EIO;
 }

   

 

   

3. Print out input variable adr and len at the beginning of do_erase_oneblock.

   

 

   

Best Regards,

   

Clement

0 Likes