Răsfoiți Sursa

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 <[email protected]>
Rafał Miłecki 7 ani în urmă
părinte
comite
0417b08b06

+ 146 - 0
target/linux/bcm53xx/patches-4.14/800-Revert-spi-bcm-qspi-Fix-bcm_qspi_bspi_read-performan.patch

@@ -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;
+ }