[U-Boot] U-boot: Erase/read/write issue with S25fl256S flash device

Jagan Teki jagannadh.teki at gmail.com
Mon Jun 17 03:05:48 EDT 2013


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?
- please send the paths for config file for this board?

--
Thanks,
Jagan.



More information about the linux-mtd mailing list