]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spi: cadence_qspi: Fix stig write issue
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Thu, 25 Apr 2019 13:12:32 +0000 (18:42 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 4 Jun 2019 10:47:15 +0000 (12:47 +0200)
This patch fixes the stig programming issue by checking
the status and flag status register register for every
write.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
drivers/mtd/spi/spi_flash.c
drivers/spi/cadence_ospi_versal.c
drivers/spi/cadence_qspi.c
drivers/spi/cadence_qspi.h
drivers/spi/cadence_qspi_apb.c
include/spi_flash.h

index ac71fbb8d191f7086cd9a2e03d6744a8919ec5e4..179b817ab5b8c4a384c7c8889624307833d51620 100644 (file)
@@ -393,7 +393,7 @@ static int spi_flash_ready(struct spi_flash *flash)
        return sr && fsr;
 }
 
-static int spi_flash_wait_till_ready(struct spi_flash *flash,
+int spi_flash_wait_till_ready(struct spi_flash *flash,
                                     unsigned long timeout)
 {
        unsigned long timebase;
index ddcacd8876b82a743510e926bf43d3a6a249b481..6358bf9fd75ace558abf749b32937e5bb6656d53 100644 (file)
@@ -41,7 +41,7 @@ void cadence_qspi_apb_dma_read(struct cadence_spi_platdata *plat,
        writel(CQSPI_DFLT_DMA_PERIPH_CFG,
               plat->regbase + CQSPI_REG_DMA_PERIPH_CFG);
        writel((unsigned long)rxbuf, plat->regbase + CQSPI_DMA_DST_ADDR_REG);
-       writel(0x0, plat->regbase + CQSPI_DMA_SRC_RD_ADDR_REG);
+       writel(plat->trigger_address, plat->regbase + CQSPI_DMA_SRC_RD_ADDR_REG);
        writel(roundup(n_rx, 4), plat->regbase + CQSPI_DMA_DST_SIZE_REG);
        flush_dcache_range((unsigned long)rxbuf, (unsigned long)rxbuf + n_rx);
        writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
index 7413d52ecfb5f11024ae157ca4ddf6ff323f8783..f02ad009b152fb2c461657a9fc27aa708f7c7cb2 100644 (file)
@@ -242,7 +242,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
                break;
                case CQSPI_STIG_WRITE:
-                       err = cadence_qspi_apb_command_write(plat,
+                       err = cadence_qspi_apb_command_write(dev,
                                                             priv->cmd_len,
                                                             cmd_buf,
                                                             data_bytes, dout);
index de57c7def8f1d166d32aa3d18a92f1eb84fe4f3b..a2716b67e36777d15fdea146d74b179feb4e967b 100644 (file)
@@ -53,7 +53,7 @@ void cadence_qspi_apb_controller_disable(void *reg_base_addr);
 
 int cadence_qspi_apb_command_read(void *reg_base_addr,
        unsigned int cmdlen, const u8 *cmdbuf, unsigned int rxlen, u8 *rxbuf);
-int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
+int cadence_qspi_apb_command_write(struct udevice *dev,
                                   unsigned int cmdlen, const u8 *cmdbuf,
                                   unsigned int txlen,  const u8 *txbuf);
 
index 7b932b695fcc3a979085a72adfcc0b13ccdbd8a6..519ab0f4f1c2191c2b045345942865586757cbe0 100644 (file)
 #include <linux/errno.h>
 #include <wait_bit.h>
 #include <spi.h>
+#include <spi_flash.h>
 #include <malloc.h>
 #include "cadence_qspi.h"
+#include <dm.h>
 
 #define CQSPI_REG_POLL_US                      1 /* 1us */
 #define CQSPI_REG_RETRY                                10000
@@ -494,10 +496,12 @@ int cadence_qspi_apb_command_read(void *reg_base,
 }
 
 /* For commands: WRSR, WREN, WRDI, CHIP_ERASE, BE, etc. */
-int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
-                                  unsigned int cmdlen, const u8 *cmdbuf,
+int cadence_qspi_apb_command_write(struct udevice *dev,
+                                  unsigned int cmdlen, const u8 *cmd,
                                   unsigned int txlen,  const u8 *txbuf)
 {
+       struct udevice *bus = (struct udevice *) dev->parent;
+       struct cadence_spi_platdata *plat = bus->platdata;
        void *reg_base = plat->regbase;
        unsigned int reg = 0;
        unsigned int addr_value = 0;
@@ -506,7 +510,11 @@ int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
        bool pageprgm = false;
        unsigned int pgmlen = 0;
        int ret;
+       struct spi_flash *flash;
+       u8 cmdbuf[32];
 
+       memcpy(cmdbuf, cmd, cmdlen);
+       flash = dev_get_uclass_priv(dev);
        if (!cmdlen || cmdlen > 5 || cmdbuf == NULL) {
                printf("QSPI: Invalid input arguments cmdlen %d txlen %d\n",
                       cmdlen, txlen);
@@ -570,6 +578,12 @@ int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
        if (ret)
                return ret;
 
+       ret = spi_flash_wait_till_ready(flash, 20000);
+       if (ret < 0) {
+               printf("%s: Program timeout\n", __func__);
+               return ret;
+       }
+
        while (pgmlen) {
                reg = 0x6 << CQSPI_REG_CMDCTRL_OPCODE_LSB;
                ret = cadence_qspi_apb_exec_flash_cmd(reg_base, reg);
@@ -606,6 +620,13 @@ int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
                ret =  cadence_qspi_apb_exec_flash_cmd(reg_base, reg);
                if (ret)
                        return ret;
+
+               ret = spi_flash_wait_till_ready(flash, 20000);
+               if (ret < 0) {
+                       printf("%s: Program timeout\n", __func__);
+                       return ret;
+               }
+
        }
 
        return 0;
index feea9a9062479720ae3bf9e8bf798f80ffd8d89e..e6de815e85e396338b19168bdc75b769849656ba 100644 (file)
@@ -194,6 +194,10 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
 /* Compatibility function - this is the old U-Boot API */
 void spi_flash_free(struct spi_flash *flash);
 
+int spi_flash_wait_till_ready(struct spi_flash *flash,
+                             unsigned long timeout);
+
+
 static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
                                 size_t len, void *buf)
 {