|
@@ -0,0 +1,146 @@
|
|
|
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
|
|
|
+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 <[email protected]>
|
|
|
+---
|
|
|
+
|
|
|
+--- 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;
|
|
|
+ }
|