Hi,

Thank you for your feedback.



> -----Original Message-----
> From: Jagan Teki [mailto:[email protected]]
> Sent: Monday, June 03, 2013 12:14 PM
> To: Insop Song
> Cc: [email protected]; [email protected]
> Subject: Re: [U-Boot] [PATCH] Add SPI Flash STMicro's N25Q512A & add flag
> status check during SPI Flash write
> 
> 
> I don't know may be you sent these changes intentionally.
> I personally not encouraging these as you sent all changes in one patch,
> attached a patch series to mail and did n't follow commit message header.
> http://www.denx.de/wiki/view/U-
> Boot/Patches#Commit_message_conventions
> 

I've put two changes in one patch because flag status check is needed for 
Micron's device.
This is already started mailing thread, so I will keep as it is, but I will 
follow the patch convention as the link you told me.


> On Mon, Jun 3, 2013 at 10:16 PM, Insop Song <[email protected]>
> wrote:
> > Hi,
> >
> > I've made two changes while I was working on STMidro's SPI Flash
> > N25Q512A
> > - add the device entry for STMidro's SPI Flash N25Q512A
> > - add Flag status check during
> >         Without this flag checking "sf write" will fail and SPI flash
> > is locked up
> >
> > Please see the patch and let me know your feedback.
> > -------------------------------------
> > From 97572b32c49d06ca6f8548ed88e6e381fb719a08 Mon Sep 17 00:00:00
> 2001
> > From: Insop Song <[email protected]>
> > Date: Sun, 2 Jun 2013 13:33:37 -0700
> > Subject: [PATCH] Add SPI Flash STMicro's N25Q512A & add flag status
> > check  during SPI Flash write
> >
> > Signed-off-by: Insop Song <[email protected]>
> > ---
> >  drivers/mtd/spi/spi_flash.c          |   25 +++++++++++++++++++++++++
> >  drivers/mtd/spi/spi_flash_internal.h |    1 +
> >  drivers/mtd/spi/stmicro.c            |    6 ++++++
> >  3 files changed, 32 insertions(+)
> >
> > diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
> > index 00aece9..f53756d 100644
> > --- a/drivers/mtd/spi/spi_flash.c
> > +++ b/drivers/mtd/spi/spi_flash.c
> > @@ -72,6 +72,7 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash,
> u32 offset,
> >         size_t chunk_len, actual;
> >         int ret;
> >         u8 cmd[4];
> > +       u8 flag_status;
> >
> >         page_size = flash->page_size;
> >         page_addr = offset / page_size; @@ -83,6 +84,18 @@ int
> > spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
> >                 return ret;
> >         }
> >
> > +wait_flag:
> > +       ret = spi_flash_cmd(flash->spi, CMD_READ_FLAG_STATUS,
> &flag_status, sizeof(flag_status));
> > +       if (ret < 0) {
> > +               printf("SF: reading flag failed\n");
> > +               return ret;
> > +       }
> > +       debug("flag_status %d\n", flag_status);
> > +       if ((flag_status & 0x80) == 0) {
> > +                       udelay(10);
> > +                       goto wait_flag;
> > +       }
> > +
> >         cmd[0] = CMD_PAGE_PROGRAM;
> >         for (actual = 0; actual < len; actual += chunk_len) {
> >                 chunk_len = min(len - actual, page_size - byte_addr);
> > @@ -106,6 +119,18 @@ int spi_flash_cmd_write_multi(struct spi_flash
> *flash, u32 offset,
> >                         debug("SF: write failed\n");
> >                         break;
> >                 }
> > +               /* check status */
> > +flag_check:
> > +               ret = spi_flash_cmd(flash->spi, CMD_READ_FLAG_STATUS,
> &flag_status, sizeof(flag_status));
> > +               if (ret < 0) {
> > +                       printf("SF: reading flag failed\n");
> > +                       break;
> > +               }
> > +               debug("flag_status %d\n", flag_status);
> > +               if (!(flag_status & 0x80)) {
> > +                       udelay(100);
> > +                       goto flag_check;
> > +               }
> 
> Instead doing this poll on actaual write, may be do it on
> spi_flash_cmd_wait_ready()
> for code compatibility.
> Did you tested these changes, i think the same Flag_status must require on
> erase as well.
> 

I've made a change and add spi_flash_cmd_wait_program to align with existing 
code structure.
Please see the patch below.
Erase is okay without checking, so I didn't add the check.


> >
> >                 ret = spi_flash_cmd_wait_ready(flash,
> SPI_FLASH_PROG_TIMEOUT);
> >                 if (ret)
> > diff --git a/drivers/mtd/spi/spi_flash_internal.h
> > b/drivers/mtd/spi/spi_flash_internal.h
> > index 141cfa8..90b6993 100644
> > --- a/drivers/mtd/spi/spi_flash_internal.h
> > +++ b/drivers/mtd/spi/spi_flash_internal.h
> > @@ -22,6 +22,7 @@
> >  #define CMD_PAGE_PROGRAM               0x02
> >  #define CMD_WRITE_DISABLE              0x04
> >  #define CMD_READ_STATUS                        0x05
> > +#define CMD_READ_FLAG_STATUS   0x70
> >  #define CMD_WRITE_ENABLE               0x06
> >  #define CMD_ERASE_4K                   0x20
> >  #define CMD_ERASE_32K                  0x52
> > diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c
> > index 30b626a..ad94ad2 100644
> > --- a/drivers/mtd/spi/stmicro.c
> > +++ b/drivers/mtd/spi/stmicro.c
> > @@ -110,6 +110,12 @@ static const struct stmicro_spi_flash_params
> stmicro_spi_flash_table[] = {
> >                 .nr_sectors = 512,
> >                 .name = "N25Q256",
> >         },
> > +       {
> > +               .id = 0xba20,
> 
> This is wrong, 0xba20 is for N25Q512, 0xbb20 is for N25Q512A., agree?
> 

I think that it is correct, it is 0xba20 not 0xbb20.
Here is from the datasheet from the Micron chip N25Q512A

JEDEC-standard 2-byte signature (BA20h)


> Please see there is a patch available in spi bucket
> http://patchwork.ozlabs.org/patch/247953/
> 
> The main agenda about this patch is trying to use same wait_poll func which
> is used for read_status register, to make code reliable and modular.
> 
> Please test the above patch http://patchwork.ozlabs.org/patch/247953/
> Let me know if you have any concerns/issues.
> 

I am not sure I'd agree with you on that you are putting the device check in 
spi_flash_cmd_poll_bit().
I am more inclined to make the change at the level where we call 
spi_flash_cmd_poll_bit() if we have to distinguish per devices.

Please let me know what do you think.

Thank you,

IS

----------------------------------------------------

>From 86f1d778caea02029f58706d4614c28c08ffd937 Mon Sep 17 00:00:00 2001
From: Insop Song <[email protected]>
Date: Mon, 3 Jun 2013 21:55:19 -0700
Subject: [PATCH] Add flag status during SPI Flash write

Add spi_flash_cmd_wait_program() to align with existing code structure
Use existing spi_flash_cmd_poll_bit to check flag status for program is done
Update spi_flash_cmd_poll_bit() so that it can check against check_bit instead 
of zero

Tested SPI flash: STMicro's N25Q512A

Signed-off-by: Insop Song <[email protected]>
---
 drivers/mtd/spi/spi_flash.c          |   25 +++++++++++++++++++++----
 drivers/mtd/spi/spi_flash_internal.h |   10 +++++++++-
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 00aece9..4240e9d 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -83,6 +83,10 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
offset,
                return ret;
        }
 
+       ret = spi_flash_cmd_wait_program(flash, SPI_FLASH_PROG_TIMEOUT);
+       if (ret)
+               return ret;
+
        cmd[0] = CMD_PAGE_PROGRAM;
        for (actual = 0; actual < len; actual += chunk_len) {
                chunk_len = min(len - actual, page_size - byte_addr);
@@ -107,6 +111,13 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
offset,
                        break;
                }
 
+               /*
+                * check flag status for program is done
+                */
+               ret = spi_flash_cmd_wait_program(flash, SPI_FLASH_PROG_TIMEOUT);
+               if (ret)
+                       break;
+
                ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
                if (ret)
                        break;
@@ -148,7 +159,7 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 
offset,
 }
 
 int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
-                          u8 cmd, u8 poll_bit)
+                          u8 cmd, u8 poll_bit, u8 check_bit)
 {
        struct spi_slave *spi = flash->spi;
        unsigned long timebase;
@@ -169,14 +180,14 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, 
unsigned long timeout,
                if (ret)
                        return -1;
 
-               if ((status & poll_bit) == 0)
+               if ((status & poll_bit) == check_bit)
                        break;
 
        } while (get_timer(timebase) < timeout);
 
        spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
 
-       if ((status & poll_bit) == 0)
+       if ((status & poll_bit) == check_bit)
                return 0;
 
        /* Timed out */
@@ -187,7 +198,13 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, 
unsigned long timeout,
 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
 {
        return spi_flash_cmd_poll_bit(flash, timeout,
-               CMD_READ_STATUS, STATUS_WIP);
+               CMD_READ_STATUS, STATUS_WIP, 0);
+}
+
+int spi_flash_cmd_wait_program(struct spi_flash *flash, unsigned long timeout)
+{
+       return spi_flash_cmd_poll_bit(flash, timeout,
+               CMD_READ_FLAG_STATUS, STATUS_PEC, STATUS_PEC);
 }
 
 int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
diff --git a/drivers/mtd/spi/spi_flash_internal.h 
b/drivers/mtd/spi/spi_flash_internal.h
index 141cfa8..670a722 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -22,6 +22,7 @@
 #define CMD_PAGE_PROGRAM               0x02
 #define CMD_WRITE_DISABLE              0x04
 #define CMD_READ_STATUS                        0x05
+#define CMD_READ_FLAG_STATUS   0x70
 #define CMD_WRITE_ENABLE               0x06
 #define CMD_ERASE_4K                   0x20
 #define CMD_ERASE_32K                  0x52
@@ -30,6 +31,7 @@
 
 /* Common status */
 #define STATUS_WIP                     0x01
+#define STATUS_PEC                     0x80    /* program or erase controller 
*/
 
 /* Send a single-byte command to the device and read the response */
 int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
@@ -86,7 +88,7 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 
*cmd,
 
 /* Send a command to the device and wait for some bit to clear itself. */
 int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
-                          u8 cmd, u8 poll_bit);
+                          u8 cmd, u8 poll_bit, u8 check_bit);
 
 /*
  * Send the read status command to the device and wait for the wip
@@ -94,6 +96,12 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned 
long timeout,
  */
 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout);
 
+/*
+ * Send the read flag status command to the device and wait for the program
+ * is done and ready
+ */
+int spi_flash_cmd_wait_program(struct spi_flash *flash, unsigned long timeout);
+
 /* Erase sectors. */
 int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
 
-- 
1.7.9.5
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to