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 <siva.durga.paladugu@xilinx.com>
This commit is contained in:
Siva Durga Prasad Paladugu
2019-04-25 18:42:32 +05:30
committed by Michal Simek
parent 04447beb4b
commit c879ab6c71
6 changed files with 31 additions and 6 deletions

View 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;

View 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,

View 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);

View 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);

View File

@@ -30,8 +30,10 @@
#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;

View 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)
{