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

Tolunay Orkun
2007-01-31T09:01:44Z

Wang Haiying-r54964 wrote:
>
>> The current code works because most CPU Bus Interface Unit
>> will execute
>> buswide cycles and discard the unused byte(s).
>>
>> I understand that you would like to convert this code to use memcpy()
>> and pick various bytes from local ram instead of directly from flash.
>> Right? What exactly you are experiencing when you use current code.
>> Could you refresh my memory?
>
> The problem we experienced here is that the flash(am29lv641d) could not
> get the correct size during boot up(the error message like "FLASH:
> ....255 erase regions found, only 4 used...0kB" is printed out), could
> not be read correctly by flinfo, could not erased or written etc.
> It is because the num_erase_regions got a wrong value by
> flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS)in line 1204.
> It happened only after the latest update of cfi_flash driver after
> u-boot 1.1.6 released. This update added a flash_read_jedec_ids before
> reading num_erase_resions. We suspect that reset command in
> flash_read_jedec_ids()may cause the problem. After the last reset in

Could you add some printfs and print the following variables right after
the flash_detect_cfi() call in flash_get_size() function.

printf("chipwidth = %d\n", info->chipwidth);
printf("portwidth = %d\n", info->portwidth);
printf("interface = %d\n", info->interface);
printf("vendor = %d\n", info->vendor);
printf("cfi_offset= %d\n", info->cfi_offset);

And the following printf right after flash_read_jedec_ids() in
flash_get_size();

printf("manufacturer_id = %d\n", info->manufacturer_id);
printf("device_id = %d\n", info->device_id);
printf("device_id2 = %d\n", info->device_id2);

Please collect the output and post to the list and cc to me.

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);

I would like to see if this change makes any difference as well.

From your description, I have the feeling that you did not have
debugged the problem fully.

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().

> is executed directly after. This flash_read_uchar returns a wrong
> number(124, 255 for num_erase_regions etc.). If this flash_read_uchar
> here reads some other flash info other than
> FLASH_OFFSET_NUM_ERASE_REGIONS by uchar, it also returns wrong value.

Please do the checks I've provided above and collect the logs and send
it to me. If flash does not switch to cfi query mode properly the read
will fetch whatever content that was available in read mode. If the
flash was completely blank (all 1s) you will get 255 which is matching
with the symptoms you are facing.

>> My proposal for you to try: Do not depend on bus interface unit doing
>> buswide reads, explicitly read buswide chunks after doing the bus-wide
>> read into a temporary variable, pick the usable bytes from that
>> temporary variable. This should eliminate the bus interface unit
>> dependency of the CPU and possible board designer interfacing gimmicks.
> Thanks a lot. :)

Please do the checks before you even bother with such a patch. The
problem could be elsewhere.

>
>> Let us know how it goes (can you post your patch too so I can
>> verify it).
> Zhang Wei is on vacation this week, he had generated a new patch to
> implement it with the similar idea last week. He will post his new patch
> after he is back.
>
> Thanks.
>
> Haiying