openwrtv4/target/linux/bcm53xx/patches-4.14/800-Revert-spi-bcm-qspi-Fix-bcm_qspi_bspi_read-performan.patch
Rafał Miłecki 0417b08b06 bcm53xx: revert SPI controller commit breaking flash reads
That upstream commit caused instability in flash reads. It was reported
but there isn't any proper fix as for now.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2018-07-29 11:02:57 +02:00

146 lines
4.4 KiB
Diff

From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Subject: [PATCH] Revert "spi: bcm-qspi: Fix bcm_qspi_bspi_read() performance"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit 345309fa7c0c9206a5344d379b174499952d79d9.
BSPI reads became unstable starting with above commit. There are BSPI
timeouts like this:
[ 15.637809] bcm_iproc 18029200.spi: timeout waiting for BSPI
(...)
[ 15.997809] bcm_iproc 18029200.spi: timeout waiting for BSPI
which cause filesystem stability problems.
Before above commit every time that bcm_qspi_bspi_lr_l2_isr() called
bcm_qspi_bspi_lr_l2_isr() it was resulting in bspi_rf_msg_len becoming
0.
With that change it's not the case anymore which suggests there may be
some bug around that code.
It has changed and the new behavior seems to be causing problems.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -88,7 +88,7 @@
#define BSPI_BPP_MODE_SELECT_MASK BIT(8)
#define BSPI_BPP_ADDR_SELECT_MASK BIT(16)
-#define BSPI_READ_LENGTH 512
+#define BSPI_READ_LENGTH 256
/* MSPI register offsets */
#define MSPI_SPCR0_LSB 0x000
@@ -806,7 +806,7 @@ static int bcm_qspi_bspi_flash_read(stru
struct spi_flash_read_message *msg)
{
struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
- u32 addr = 0, len, rdlen, len_words;
+ u32 addr = 0, len, len_words;
int ret = 0;
unsigned long timeo = msecs_to_jiffies(100);
struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
@@ -819,7 +819,7 @@ static int bcm_qspi_bspi_flash_read(stru
bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
/*
- * when using flex mode we need to send
+ * when using flex mode mode we need to send
* the upper address byte to bspi
*/
if (bcm_qspi_bspi_ver_three(qspi) == false) {
@@ -833,56 +833,47 @@ static int bcm_qspi_bspi_flash_read(stru
else
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)
addr = (addr + 0xc00000) & 0xffffff;
- /*
- * read into the entire buffer by breaking the reads
- * into RAF buffer read lengths
- */
- len = msg->len;
+ reinit_completion(&qspi->bspi_done);
+ bcm_qspi_enable_bspi(qspi);
+ len_words = (len + 3) >> 2;
+ qspi->bspi_rf_msg = msg;
+ qspi->bspi_rf_msg_status = 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);
- do {
- if (len > BSPI_READ_LENGTH)
- rdlen = BSPI_READ_LENGTH;
- else
- rdlen = len;
-
- 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);
- }
+ 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 */
- 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;
- }
+ /* Must flush previous writes before starting BSPI operation */
+ mb();
- /* set msg return length */
- msg->retlen += rdlen;
- addr += rdlen;
- len -= rdlen;
- } while (len);
+ 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;
+ } else {
+ /* set the return length for the caller */
+ msg->retlen = len;
+ }
return ret;
}