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

Jagan Teki jagannadh.teki at gmail.com
Mon Jun 17 03:34:54 EDT 2013


On Mon, Jun 17, 2013 at 12:49 PM, Sourav Poddar <sourav.poddar at ti.com> wrote:
> On Monday 17 June 2013 12:44 PM, Jagan Teki wrote:
>>
>> 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.
>>
> Following are the configuration details for spi..
> #define CONFIG_SPI_FLASH_BAR
> #define CONFIG_TI_QSPI

Where can i find this?

> #define CONFIG_SPI_FLASH
> #define CONFIG_SPI_FLASH_SPANSION
> #define CONFIG_CMD_SF
> #define CONFIG_CMD_SPI
> #define CONFIG_SF_DEFAULT_SPEED         12000000
> #define CONFIG_DEFAULT_SPI_MODE         SPI_MODE_3
>
> /* SPI SPL */
> #define CONFIG_SPL_SPI_SUPPORT
> #define CONFIG_SPL_SPI_LOAD
> #define CONFIG_SPL_SPI_FLASH_SUPPORT
> #define CONFIG_SPL_SPI_BUS              0
> #define CONFIG_SPL_SPI_CS               0
> #define CONFIG_SYS_SPI_U_BOOT_OFFS      0x20000

--
Thanks,
Jagan.



More information about the linux-mtd mailing list