From: Siva Durga Prasad Paladugu Date: Thu, 25 Apr 2019 13:12:32 +0000 (+0530) Subject: spi: cadence_qspi: Fix stig write issue X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c879ab6c7133fdeb1195bcee4d538594561d9f01;p=thirdparty%2Fu-boot.git spi: cadence_qspi: Fix stig write issue 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 --- diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index ac71fbb8d19..179b817ab5b 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -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; diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index ddcacd8876b..6358bf9fd75 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -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, diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 7413d52ecfb..f02ad009b15 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -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); diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index de57c7def8f..a2716b67e36 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -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); diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index 7b932b695fc..519ab0f4f1c 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -30,8 +30,10 @@ #include #include #include +#include #include #include "cadence_qspi.h" +#include #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; diff --git a/include/spi_flash.h b/include/spi_flash.h index feea9a90624..e6de815e85e 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -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) {