[U-Boot] U-boot: Erase/read/write issue with S25fl256S flash device
Jagan Teki
jagannadh.teki at gmail.com
Mon Jun 17 03:14:44 EDT 2013
On Mon, Jun 17, 2013 at 12:41 PM, Sourav Poddar <sourav.poddar at ti.com> wrote:
> On Monday 17 June 2013 12:35 PM, Jagan Teki wrote:
>>
>> On Mon, Jun 17, 2013 at 12:28 PM, Sourav Poddar<sourav.poddar at ti.com>
>> wrote:
>>>
>>> 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;
>>> }
>>>
>> Ohh..
>>
>> - What if you erase the entire flash and read back, same result is it?
>
> Yes.
>
>> - please send the paths for config file for this board?
>
> include/configs/dra7xx_evm.h
I couldn't find any SPI flash configs on above config file,
Can you point me the relevant configurations.
--
Thanks,
Jagan.
More information about the linux-mtd
mailing list