[U-Boot] [PATCH 1/1] NAND Re: mtdparts fails with NAND >= 4GB - Second try

Aaron Williams Aaron.Williams at caviumnetworks.com
Sat Feb 12 01:15:28 CET 2011


I think I found  the problem. The cfi code does not work properly in x8 mode.

In x8 mode, according to the datasheet, the addresses should be doubled for 
all of the commands. Additionally, according to my correspondence with 
Spansion, there needs to be at least a 500ns delay after a reset command.

The cfi code is incorrectly detecting the port width as FLASH_CFI_16BIT when 
it is actually 8-bits. Currently things just happen to work because the bus is 
being incorrectly detected as 16-bits, 

The 16-bit bus detection, however, breaks in x8 mode when it issues the 
commands for the manufacturer ID.

In this case, the following takes place:

In cmdset_amd_read_jedec_ids                                                                             
fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bit                                                              
flash_write16: Wrote 0xf0f0 to address 1f400000                                                          
funlock writing 0xaa to address 0xaaa                                                                    
fwc addr 1f401554 cmd aa aaaa 16bit x 8 bit                                                              
flash_write16: Wrote 0xaaaa to address 1f401554                                                          
funlock writing 0xaa to address 0x555                                                                    
fwc addr 1f400aaa cmd 55 5555 16bit x 8 bit                                                              
flash_write16: Wrote 0x5555 to address 1f400aaa                                                          
fwc addr 1f401554 cmd 90 9090 16bit x 8 bit                                                              
flash_write16: Wrote 0x9090 to address 1f401554                                                          
flash_read8: Read 0x0 from address 1f400001                                                              
flash_read8: Read 0x3f from address 1f400003             

This does not work.

If the proper sequence is written, then it works fine.

The proper sequence, according to the datasheet, is to do the following:

write 0xf0 to address 0x0000
write 0xaa to address 0xaaa
write 0x55 to address 0x555
write 0x90 to address 0xaaa
read address 0 (returns 1 as expected)
read address 2 (returns 0x7e as expected)
...

So the cfi code is broken in the x8 case.

-Aaron Williams

On Thursday, February 10, 2011 08:05:37 pm Aaron Williams wrote:
> On Thursday, February 10, 2011 07:27:12 pm Aaron Williams wrote:
> > On Thursday, February 10, 2011 07:24:54 pm Aaron Williams wrote:
> > > On Thursday, February 10, 2011 07:08:01 am Andrew Dyer wrote:
> > > > On Thu, Feb 10, 2011 at 00:28, Aaron Williams
> > > > 
> > > > <Aaron.Williams at caviumnetworks.com> wrote:
> > > > >> I would suggest to make sure any caching/prefetching stuff is off,
> > > > >> hardware is doing one flash bus access per CPU read/write.
> > > > >> 
> > > > >> In cmdset_amd_read_jedec_ids() after this line:
> > > > >> 
> > > > >> manuId = flash_read_uchar (info, FLASH_OFFSET_MANUFACTURER_ID);
> > > > >> 
> > > > >> add something like
> > > > >> 
> > > > >> printf("test manf id word = %04x\n", *(volatile uint16_t
> > > > >> *)0x1f400000); printf("test device id word = %04x\n", *(volatile
> > > > >> uint16_t
> > > > >> *)0x1f400002); printf("test device id word = %04x\n", *(volatile
> > > > >> uint16_t *)0x1f40001c); printf("test device id word = %04x\n",
> > > > >> *(volatile uint16_t *)0x1f40001e);
> > > > >> 
> > > > >> and see what you get.
> > > > > 
> > > > > fwc addr 1f400000 cmd f0 f0f0 16bit x 8 bit
> > > > > flash_write16: address: 1f400000, value: 0xf0f0
> > > > > fwc addr 1f401554 cmd aa aaaa 16bit x 8 bit
> > > > > flash_write16: address: 1f401554, value: 0xaaaa
> > > > > fwc addr 1f400aaa cmd 55 5555 16bit x 8 bit
> > > > > flash_write16: address: 1f400aaa, value: 0x5555
> > > > > fwc addr 1f401554 cmd 90 9090 16bit x 8 bit
> > > > > flash_write16: address: 1f401554, value: 0x9090
> > > > > flash_read8: address: 1f400001, value: 0x0
> > > > > test manf id word = 1000
> > > > > test device id word = 013f
> > > > > test device id word = da6c
> > > > > test device id word = 2926
> > > > 
> > > > looks like garbage :-(  What's in the flash at those addresses? 
> > > > Maybe something is happening to mess up the unlock sequence and
> > > > you're reading the memory data instead of the device codes.
> > > > 
> > > > It's odd that earlier in the sequence when the CFI query data is read
> > > > the byte data is mirrored across both bytes of the response, here the
> > > > two bytes are different.
> > > 
> > > I received an email back from Spansion about this problem. They
> > > suggested that instead of the following:
> > > 
> > > fwc addr 1f401554 cmd aa aaaa 16bit x 8 bit
> > > flash_write16: Wrote 0xaaaa to address 1f401554
> > > funlock writing 0xaa to address 0x555
> > > fwc addr 1f400aaa cmd 55 5555 16bit x 8 bit
> > > flash_write16: Wrote 0x5555 to address 1f400aaa
> > > fwc addr 1f401554 cmd 90 9090 16bit x 8 bit
> > > flash_write16: Wrote 0x9090 to address 1f401554
> > > 
> > > to instead do the following:
> > > write 0xAA to 0x1F400AAA
> > > write 0x55 to 0x1F400555
> > > write 0x90 to 0x1F400AAA
> > > 
> > > read 0x1F400001 returns 0x01
> > > read 0x1F400003 returns 0x7e
> > > 
> > > This looks correct.
> > > 
> > > I found two things I need to do to work around the problem. First, in
> > > flash_write_cmd I use info->chipwidth instead of info->portwidth for
> > > the write commands, and second, in __flash_detect_cfi I don't modify
> > > the address in compatibility mode. This works. If either of those
> > > steps are left out then reading the manufacturer ID fails.
> > > 
> > > -Aaron
> > 
> > It looks like I spoke too soon. It fixes the manufacturer problem but
> > everything else is now broken.
> > 
> > -Aaron
> 
> It works now, but I had to hard-code cmdset_amd_read_jedec_ids for some
> reason.
> 
> static void cmdset_amd_read_jedec_ids(flash_info_t *info)
> {
> 	ushort bankId = 0;
> 	uchar  manuId;
> 
> 	debug("In %s\n", __func__);
> 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
> 	flash_write_cmd(info, 0, 0x555, AMD_CMD_UNLOCK_START);
> 	flash_write_cmd(info, 0, 0x2AA, AMD_CMD_UNLOCK_ACK);
> 	flash_write_cmd(info, 0, 0x555, FLASH_CMD_READ_ID);
> 	/*flash_unlock_seq(info, 0); */
> 	/*flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);*/
> 
> With this, everything works with my mod to flash_write_cmd to use chipwidth
> instead of portwidth.
> 
> -Aaron
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot


More information about the U-Boot mailing list