From 2db4015285018fa728133e6a3965d4ed9c35f4e1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 11 Oct 2018 10:01:45 +0200 Subject: [PATCH] bcm53xx: replace SPI revert with a fix sent upstream MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Instead of reverting whole commit it's enough to just revert a single line change. It seems the real problem with the regressing commit was a bump of read chunk size. Switching back to 256 B chunks is enough to fix the problem/regression. Signed-off-by: Rafał Miłecki (cherry picked from commit 92de28b751a473655fd0cf3d3a8b81ca1d27d758) --- ...tch-back-to-reading-flash-using-smal.patch | 42 +++++ ...spi-Fix-bcm_qspi_bspi_read-performan.patch | 146 ------------------ 2 files changed, 42 insertions(+), 146 deletions(-) create mode 100644 target/linux/bcm53xx/patches-4.14/180-spi-bcm-qspi-switch-back-to-reading-flash-using-smal.patch delete mode 100644 target/linux/bcm53xx/patches-4.14/800-Revert-spi-bcm-qspi-Fix-bcm_qspi_bspi_read-performan.patch diff --git a/target/linux/bcm53xx/patches-4.14/180-spi-bcm-qspi-switch-back-to-reading-flash-using-smal.patch b/target/linux/bcm53xx/patches-4.14/180-spi-bcm-qspi-switch-back-to-reading-flash-using-smal.patch new file mode 100644 index 0000000000..4b3056591e --- /dev/null +++ b/target/linux/bcm53xx/patches-4.14/180-spi-bcm-qspi-switch-back-to-reading-flash-using-smal.patch @@ -0,0 +1,42 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 11 Oct 2018 09:07:31 +0200 +Subject: [PATCH FIX] spi: bcm-qspi: switch back to reading flash using smaller + chunks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixing/optimizing bcm_qspi_bspi_read() performance introduced two +changes: +1) It added a loop to read all requested data using multiple BSPI ops. +2) It bumped max size of a single BSPI block request from 256 to 512 B. + +The later change resulted in occasional BSPI timeouts causing a +regression. + +For some unknown reason hardware doesn't always handle reads as expected +when using 512 B chunks. In such cases it may happen that BSPI returns +amount of requested bytes without the last 1-3 ones. It provides the +remaining bytes later but doesn't raise an interrupt until another LR +start. + +Switching back to 256 B reads fixes that problem and regression. + +Fixes: 345309fa7c0c ("spi: bcm-qspi: Fix bcm_qspi_bspi_read() performance") +Signed-off-by: Rafał Miłecki +Cc: stable@vger.kernel.org # 4.11+ +--- + drivers/spi/spi-bcm-qspi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- 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 diff --git a/target/linux/bcm53xx/patches-4.14/800-Revert-spi-bcm-qspi-Fix-bcm_qspi_bspi_read-performan.patch b/target/linux/bcm53xx/patches-4.14/800-Revert-spi-bcm-qspi-Fix-bcm_qspi_bspi_read-performan.patch deleted file mode 100644 index 64f971d349..0000000000 --- a/target/linux/bcm53xx/patches-4.14/800-Revert-spi-bcm-qspi-Fix-bcm_qspi_bspi_read-performan.patch +++ /dev/null @@ -1,146 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -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 ---- - ---- 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; - } -- 2.30.2