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

Sourav Poddar sourav.poddar at ti.com
Mon Jun 17 03:19:54 EDT 2013


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
#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