[U-Boot] U-boot: Erase/read/write issue with S25fl256S flash device
Sourav Poddar
sourav.poddar at ti.com
Mon Jun 17 08:58:51 CEST 2013
HI Jagan,
On Monday 17 June 2013 12:17 PM, Jagan Teki wrote:
> Hi Sourav,
>
> On Mon, Jun 17, 2013 at 11:44 AM, Sourav Poddar<sourav.poddar at ti.com> wrote:
>> Hi Jagan,
>>
>> On Saturday 15 June 2013 09:47 PM, Jagan Teki wrote:
>>> On 14-06-2013 20:13, Sourav Poddar wrote:
>>>> Hi Jagan,
>>>> On Friday 14 June 2013 08:08 PM, Jagan Teki wrote:
>>>>> On 14-06-2013 20:03, Sourav Poddar wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Wednesday 12 June 2013 01:00 PM, Sourav Poddar wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> I am working on qspi flash device S25FL256S at u-boot level. I am
>>>>>>> trying to
>>>>>>> make use of the existing spi_flash.c framework available at u-boot for
>>>>>>> erasing/reading/writing
>>>>>>> into the flash device.
>>>>>>>
>>>>>>> There are several issues(mentioned below), which I faced while using
>>>>>>> S25FL256s flash device
>>>>>>> with my dra7xx board which has a qspi controller to which the above
>>>>>>> mentioned flash device is attached.
>>>>>>>
>>>>>>> 1. Erase (spi_flash_cmd_erase)
>>>>>>>
>>>>>>> Issuing a command something like this..
>>>>>>>
>>>>>>> sf erase 0x0 0x50000
>>>>>>> - erases only first 0x20000 bytes of flash device, anything above
>>>>>>> that is not erase. I need to
>>>>>>> issue separate commands after 0x20000 for every 0x10000 bytes.
>>>>>>>
>>>>>>> Am i missing anything here?
>>>>>>>
>>>>>>> 2. read
>>>>>>>
>>>>>>> sf read 81000000 0 0x10000
>>>>>>>
>>>>>>> Read is not happening properly. The last few byte along the 4k
>>>>>>> boundary always shows zero.
>>>>>>> Above 4k bytes, read is not happening.
>>>>>>>
>>>>>>> For ex:
>>>>>>> DRA752 EVM # md 81000f00
>>>>>>> 81000f00: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f10: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f20: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f30: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f40: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f50: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f60: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f70: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f80: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000f90: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000fa0: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000fb0: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000fc0: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000fd0: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000fe0: ffffffff ffffffff ffffffff ffffffff ................
>>>>>>> 81000ff0: ffffffff ffffffff 00ffffff 00000000 ................
>>>>>>>
>>>>>>> In this dump, if you see 81000ff0 the last column shows 000000 which
>>>>>>> is
>>>>>>> not expected. and it happens along every 4k bytes.
>>>>>>>
>>>>>>>
>>>>>>> So, to get rid of the above issue, I switched to page read with the
>>>>>>> below patch[1],
>>>>>>> which is giving me the correct result.
>>>>>>> [1]:
>>>>>>> @@ -147,17 +153,40 @@ int spi_flash_read_common(struct spi_flash
>>>>>>> *flash, const u8 *cmd,
>>>>>>> int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
>>>>>>> size_t len, void *data)
>>>>>>> {
>>>>>>> - u8 cmd[5];
>>>>>>> + unsigned long page_addr, byte_addr, page_size;
>>>>>>> + size_t chunk_len, actual;
>>>>>>> + int ret = 0;
>>>>>>> + u8 cmd[4];
>>>>>>>
>>>>>>> /* Handle memory-mapped SPI */
>>>>>>> if (flash->memory_map)
>>>>>>> memcpy(data, flash->memory_map + offset, len);
>>>>>>> + page_size = flash->page_size;
>>>>>>> + page_addr = offset / page_size;
>>>>>>> + byte_addr = offset % page_size;
>>>>>>> +
>>>>>>> + cmd[0] = CMD_READ_ARRAY_SLOW;
>>>>>>> + for (actual = 0; actual< len; actual += chunk_len) {
>>>>>>> + chunk_len = min(len - actual, page_size - byte_addr);
>>>>>>> +
>>>>>>> + cmd[1] = page_addr>> 8;
>>>>>>> + cmd[2] = page_addr;
>>>>>>> + cmd[3] = byte_addr;
>>>>>>> +
>>>>>>> + ret = spi_flash_read_common(flash, cmd, sizeof(cmd),
>>>>>>> data + actual, chunk_len);
>>>>>>> + if (ret< 0) {
>>>>>>> + debug("SF: read failed");
>>>>>>> + break;
>>>>>>> + }
>>>>>>>
>>>>>>> - cmd[0] = CMD_READ_ARRAY_FAST;
>>>>>>> - spi_flash_addr(offset, cmd);
>>>>>>> - cmd[4] = 0x00;
>>>>>>> + byte_addr += chunk_len;
>>>>>>> + if (byte_addr == page_size) {
>>>>>>> + page_addr++;
>>>>>>> + byte_addr = 0;
>>>>>>> + }
>>>>>>> + }
>>>>>>>
>>>>>>> - return spi_flash_read_common(flash, cmd, sizeof(cmd), data,
>>>>>>> len);
>>>>>>> + return ret;
>>>>>>> }
>>>>>>>
>>>>>>> Any idea about this?
>>>>>>>
>>>>>>> 3. write (spi_flash_cmd_write_multi)
>>>>>>> write not happening properly.
>>>>>>>
>>>>>>> observations: only able to write single page, anything after a page is
>>>>>>> not getting
>>>>>>> written.
>>>>>>> Workaround:
>>>>>>> I did a write disable latch at the end of every write cycle(page
>>>>>>> program) and enable it
>>>>>>> again for the next loop. With this, I see I get rid of the above
>>>>>>> issue.
>>>>>>>
>>>>>>> @@ -117,6 +117,12 @@ int spi_flash_cmd_write_multi(struct spi_flash
>>>>>>> *flash, u32 offset,
>>>>>>> if (ret)
>>>>>>> break;
>>>>>>>
>>>>>>> + ret = spi_flash_cmd_write_disable(flash);
>>>>>>> + if (ret< 0) {
>>>>>>> + printf("SF: disabling write failed\n");
>>>>>>> + break;
>>>>>>> + }
>>>>>>> +
>>>>>>>
>>>>>>>
>>>>>>> Have anyone seen the above mentioned issues regarding
>>>>>>> read/write/erase? OR is there any
>>>>>>> configurations that I might be missing ?
>>>>>>>
>>>>>> Any Input on this?
>>>>>
>>>>> Please wait, I am pushing some changes tonight or so.
>>>>>
>>>>> We will continue this thread, after testing your part with these new
>>>>> changes.
>>>>>
>>>>> I will intimate you once the push done.
>>>>>
>>>>> --
>>>>> Thanks,
>>>>> Jagan.
>>>>>
>>>>>
>>>> Thanks a lot for the reply.
>>>> Sure, will wait for your changes to go in.
>>>
>>> Will take some time go these changes on master.
>>>
>>> Please checkout master-work branch in u-boot-spi repo
>>> git://git.denx.de/u-boot-spi.git
>>>
>>> and try to test 256S parts, fyi: I tested the same part got the
>>> +ve result.
>>>
>> Tested the above tree on my board.
>> But, still the issues remain the same for me in all the three
>> cases(erase/read/write).
>>
>> Here is the short log of the read command..
>> DRA752 EVM # sf probe 0
>> SF: Detected S25FL256S_64K with page size 64 KiB, total 32 MiB
>> SF: Warning - Only lower 16MiB accessible, Full access #define
>> CONFIG_SPI_FLASH_BAR
>> DRA752 EVM # sf erase 0x0 0x10000
>> SF: 65536 bytes @ 0x0 Erased: OK
>> DRA752 EVM # mw.b 0x81000100 0xff 0x10000
>> DRA752 EVM # sf read 0x81003000 0x0 0x10000
>> SF: 65536 bytes @ 0x0 Read: OK
>> DRA752 EVM # cmp.b 0x81003000 0x81000100 0x10000
>> byte at 0x81003ffb (0x0) != byte at 0x810010fb (0xff)
>> Total of 4091 byte(s) were the same
>>
>>
>> Erase: not able to do with a single command, need to issue for every 0x10000
>> bytes.
>>
>> Write: Need to disable latch after every write to make it properly work.
>>
>> Is it possible for you to give me basic commands which you might have ran
>> to confirm
>> the read/write and erase ??
> I tested the same part - for me i couldn't see the issues with SL256S
>
> OK! can enable the log on poll function, spi_flash_cmd_wait_ready()
> make debug -> printf.
> Do the same test.! and send the log file.
>
> --
> Thanks,
> Jagan.
Here is the output log, no change..
DRA752 EVM # sf probe 0
SF: Detected S25FL256S_64K with page size 64 KiB, total 32 MiB
DRA752 EVM # sf erase 0x0 0x10000
SF: 65536 bytes @ 0x0 Erased: OK
DRA752 EVM # mw.b 0x81000100 0xff 0x10000
DRA752 EVM # sf read 0x81003000 0x0 0x10000
SF: 65536 bytes @ 0x0 Read: OK
DRA752 EVM # cmp.b 0x81003000 0x81000100 0x10000
byte at 0x81003ffb (0x0) != byte at 0x810010fb (0xff)
Total of 4091 byte(s) were the same
DRA752 EVM #
Code change: for above output.
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -85,7 +85,7 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash,
unsigned long timeout)
ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
if (ret) {
- debug("SF: fail to read %s status register\n",
+ printf("SF: fail to read %s status register\n",
cmd == CMD_READ_STATUS ? "read" : "flag");
return ret;
}
@@ -109,7 +109,7 @@ int spi_flash_cmd_wait_ready(struct spi_flash
*flash, unsigned long timeout)
return 0;
/* Timed out */
- debug("SF: time out!\n");
+ printf("SF: time out!\n");
return -1;
}
~Sourav
More information about the U-Boot
mailing list