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:
committed by
Michal Simek
parent
04447beb4b
commit
c879ab6c71
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user