[U-Boot-Users] [PATCH] Fixed cfi flash read uchar bug.

Tolunay Orkun listmember at orkun.us
Thu Feb 1 06:26:08 CET 2007


Haiying Wang wrote:
> ------------
> U-Boot 1.2.0 (Jan 31 2007 - 13:12:04)
> 
> Freescale PowerPC
> CPU:
>     Core: E600, Version: 0.2, (0x80040202)
>     System: 8641D, Version: 2.0, (0x80900120)
>     Clocks: CPU:1000 MHz, MPX: 400 MHz, DDR: 200 MHz, LBC:  50 MHz
>     L2: Enabled

Pretty fast CPU you've got here :)

> Board: MPC8641HPCN
> PCI-EXPRESS1: Disabled
> I2C:   ready
> DRAM:      DDR: 256 MB
> FLASH: ## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB

It looks like you inserted the debug prints in wrong place. The output 
below should have been after the debug stuff. Anyway...

> chipwidth = 2
> portwidth = 2
> interface = 1
> vendor    = 0
> cfi_offset= 85
> manufacturer_id = 1
> device_id       = 126
> device_id2      = 4865

Except for "vendor" everything looks OK here. I should have asked you to 
print vendor right before flash_read_jedec_ids() call. It was not yet 
initialized when printed. It must be correctly set as well since 
flash_read_jedec_ids() uses it would not have returned correct data 
otherwise.

You have a 16-bit flash accessible on 16-bit bus. The flash manufacturer 
is "AMD/Spansion" or compatible and device id is 7E1301 which is correct 
for your part:

http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25538a1.pdf

Please note that flash_read_jedec_ids() is used for manufacturer id and 
device_ids and this function in turn is using flash_read_uchar() which 
worked just fine for you.

> 124 erase regions found, only 4 used

This is not correct. This is why you are blaming the flash_read_uchar() 
function. But since it worked correctly before the failure to read the 
number of erase regions is probably not due to the function.

>> Also try replacing following line in flash_detect_cfi() function:
>>
>> flash_write_cmd (info, 0, 0, info->cmd_reset);
>>
>> with the following two lines:
>>
>> flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
>> flash_write_cmd(info, 0, 0, AMD_CMD_RESET);

You demonstrated that this did not affect you because the output was the 
same. The problem with this line was that info->cmd_reset was not yet 
initialized when flash_detect_cfi() was called. This is a minor bug 
since the flash was not in query mode yet. I think we can safely remove 
this call as well or replace it both amd anf intel reset commands back 
to back. But anyway, back to your issue.

>> If you are suspecting that the flash is not in array read mode after 
>> flash_read_jedec_ids() you can easily dump the first 256 bytes of flash 
>> right after [write a simple hexdump routine].
>>
>>> this function, a flash_write_cmd() follows it, then the flash_read_uchar
>> After this command, the flash should be in cfi_read mode. Hexdump the 
>> first 256 bytes again. You should be able to spot easily if you landed 
>> in cfi query mode or not. These are crucial before you put the blame on 
>> flash_read_uchar().
> Then I dump the first 256bytes of flash, first after
> flash_read_jedec_ids(), then after flash_write_cmd(), see log:
> 
> -------
> U-Boot 1.2.0 (Jan 31 2007 - 13:46:59)
> 
> Freescale PowerPC
> CPU:
>     Core: E600, Version: 0.2, (0x80040202)
>     System: 8641D, Version: 2.0, (0x80900120)
>     Clocks: CPU:1000 MHz, MPX: 400 MHz, DDR: 200 MHz, LBC:  50 MHz
>     L2: Enabled
> Board: MPC8641HPCN
> PCI-EXPRESS1: Disabled
> I2C:   ready
> DRAM:      DDR: 256 MB
> FLASH: ## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB
> chipwidth = 2
> portwidth = 2
> interface = 1
> vendor    = 0
> cfi_offset= 85
> 
> Dump the first 256 byte of flash
> 27 05 19 56 26 6c 3d b3 44 e4 ae 15 00 2b 05 33
> 00 00 00 00 00 00 00 00 35 b6 3f 82 05 07 03 01
> 75 62 6f 6f 74 20 65 78 74 32 20 72 61 6d 64 69
> 73 6b 20 72 6f 6f 74 66 73 00 00 00 00 00 00 00
> 1f 8b 08 08 14 ae e4 44 00 03 72 6f 6f 74 66 73
> 2e 65 78 74 32 00 ec 9d 09 7c 15 d5 bd c7 cf dc
> dc dc 24 17 ac 97 a5 42 2b 68 dc 65 11 90 35 09
> 01 c2 22 6a 45 45 dc 00 17 92 90 00 d1 6c 26 81
> 62 ab 08 56 ad 5a 17 5a ad 5b 7d 16 7d f6 55 5b
> b5 58 ab e0 52 1b 97 56 6c 51 41 01 51 2c 82 62
> b5 28 02 ae d4 2e be ef ff ce 19 e6 04 6e ca e4
> 35 e3 f4 d5 f3 e7 f3 e5 cc ff ce b9 f3 9b 73 ce
> ff 2c 73 73 ef 8c 52 d6 ac 59 fb b2 5a 2a 4b a9
> 1e 87 29 f5 91 a3 d4 7d b9 4a fd 95 d7 1c 63 ff
> c2 2e 2e 97 9b 2f aa ae ea e4 ad 8e b2 66 cd da
> ff 6f a3 fb ab 38 64 a7 bd 79 6a df 5d f6 5f 47
> manufacturer_id = 1
> device_id       = 126
> device_id2      = 4865
> 
> Dump the first 256 byte of flash
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 51 00 52 00 59 00 02 00 00 00 40 00 00 00 00
> 00 00 00 00 00 00 00 27 00 36 00 00 00 00 00 07
> 00 07 00 0a 00 00 00 01 00 05 00 04 00 00 00 17
> 00 01 00 00 00 05 00 00 00 01 00 7f 00 00 00 00
> 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 50 00 52 00 49 00 31 00 33 00 08 00 02 00 04
> 00 01 00 04 00 00 00 00 00 01 00 b5 00 c5 00 05
> 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01

Guess what this looks like a valid CFI table now. I can definitely see Q 
= 0x51, R = 0x52, Y = 0x59 etc. in the correct places.

>  8 MB

It looks like the rest of the commands worked as well :) All without 
changing flash_read_uchar() functionality!

> Using default environment
> 
> In:    serial
> Out:   serial
> Err:   serial
> Net:   eTSEC1, eTSEC2, eTSEC3, eTSEC4
> Hit any key to stop autoboot:  0
> =>
> -------
> This time, the flash got the correct size and can be accessed. I think
> the second dump()function I added made it work, as it worked when I
> inserted a udelay after flash_write_cmd(). 

At this point, all data indicates that flash_read_uchar() is just fine.

I am suspecting two things:

1) Your CPU might be trying to re-order writes and reads to optimize 
performance. Since the command write and data read are from different 
addresses it could do this but the write command should really finish 
before we access the table data. So, we might need to add powerpc "sync" 
instructions in flash_write_cmd() function. Apparently CONFIG_BLACKFIN 
has a similar need as well. I would add a generic "sync" for the whole 
PowerPC family but there is not a conveninent CONFIG_POWERPC macro as 
far as I can see. Anyway, try adding:

asm("sync;");

statements in that function. Use Blackfin as an example.

2) Because you have a rather fast CPU it is possible that we are not 
allowing enough time after reset command is executed before array is in 
read mode. According to the datasheet of your flash part if external 
reset signal was asserted you could need up to 20usec before flash 
returns to read mode. I am not sure if this delay is needed for issued 
reset commands as well. We might need to add some delay after flash 
reset commands. Try adding udelay(100); right after flash reset command 
is sent. You can locate flash reset commands by searching 
flash_write_cmd() statements that passes FLASH_CMD_RESET, AMD_CMD_RESET 
or cfi->cmd_reset as the last argument.

> Please shed some lights. Thanks a lot!

I hope this helps.

Best regards,
Tolunay





More information about the U-Boot mailing list