Commit 345309fa authored by Kamal Dasu's avatar Kamal Dasu Committed by Mark Brown

spi: bcm-qspi: Fix bcm_qspi_bspi_read() performance

Let bcm_qspi_bspi_flash_read() return all the requested bytes by breaking
up the reads for BSPI block into optimal chunks size that a BSPI block can
handle.
Signed-off-by: default avatarKamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 81ab52fd
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
#define BSPI_BPP_MODE_SELECT_MASK BIT(8) #define BSPI_BPP_MODE_SELECT_MASK BIT(8)
#define BSPI_BPP_ADDR_SELECT_MASK BIT(16) #define BSPI_BPP_ADDR_SELECT_MASK BIT(16)
#define BSPI_READ_LENGTH 256 #define BSPI_READ_LENGTH 512
/* MSPI register offsets */ /* MSPI register offsets */
#define MSPI_SPCR0_LSB 0x000 #define MSPI_SPCR0_LSB 0x000
...@@ -824,7 +824,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, ...@@ -824,7 +824,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
struct spi_flash_read_message *msg) struct spi_flash_read_message *msg)
{ {
struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
u32 addr = 0, len, len_words; u32 addr = 0, len, rdlen, len_words;
int ret = 0; int ret = 0;
unsigned long timeo = msecs_to_jiffies(100); unsigned long timeo = msecs_to_jiffies(100);
struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
...@@ -837,7 +837,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, ...@@ -837,7 +837,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
/* /*
* when using flex mode mode we need to send * when using flex mode we need to send
* the upper address byte to bspi * the upper address byte to bspi
*/ */
if (bcm_qspi_bspi_ver_three(qspi) == false) { if (bcm_qspi_bspi_ver_three(qspi) == false) {
...@@ -851,47 +851,56 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi, ...@@ -851,47 +851,56 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
else else
addr = msg->from & 0x00ffffff; addr = msg->from & 0x00ffffff;
/* set BSPI RAF buffer max read length */
len = msg->len;
if (len > BSPI_READ_LENGTH)
len = BSPI_READ_LENGTH;
if (bcm_qspi_bspi_ver_three(qspi) == true) if (bcm_qspi_bspi_ver_three(qspi) == true)
addr = (addr + 0xc00000) & 0xffffff; addr = (addr + 0xc00000) & 0xffffff;
reinit_completion(&qspi->bspi_done); /*
bcm_qspi_enable_bspi(qspi); * read into the entire buffer by breaking the reads
len_words = (len + 3) >> 2; * into RAF buffer read lengths
qspi->bspi_rf_msg = msg; */
qspi->bspi_rf_msg_status = 0; len = msg->len;
qspi->bspi_rf_msg_idx = 0; qspi->bspi_rf_msg_idx = 0;
qspi->bspi_rf_msg_len = len;
dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
if (qspi->soc_intc) { do {
/* if (len > BSPI_READ_LENGTH)
* clear soc MSPI and BSPI interrupts and enable rdlen = BSPI_READ_LENGTH;
* BSPI interrupts. else
*/ rdlen = len;
soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE);
soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true); reinit_completion(&qspi->bspi_done);
} bcm_qspi_enable_bspi(qspi);
len_words = (rdlen + 3) >> 2;
qspi->bspi_rf_msg = msg;
qspi->bspi_rf_msg_status = 0;
qspi->bspi_rf_msg_len = rdlen;
dev_dbg(&qspi->pdev->dev,
"bspi xfr addr 0x%x len 0x%x", addr, rdlen);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
if (qspi->soc_intc) {
/*
* clear soc MSPI and BSPI interrupts and enable
* BSPI interrupts.
*/
soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE);
soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true);
}
/* Must flush previous writes before starting BSPI operation */ /* Must flush previous writes before starting BSPI operation */
mb(); mb();
bcm_qspi_bspi_lr_start(qspi);
if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {
dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n");
ret = -ETIMEDOUT;
break;
}
bcm_qspi_bspi_lr_start(qspi); /* set msg return length */
if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { msg->retlen += rdlen;
dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); addr += rdlen;
ret = -ETIMEDOUT; len -= rdlen;
} else { } while (len);
/* set the return length for the caller */
msg->retlen = len;
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment