aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPratyush Yadav2022-02-01 11:54:35 -0600
committerVignesh Raghavendra2022-02-01 23:54:18 -0600
commit027f03a8512086e5ef05dc4e4ff53b2628848f95 (patch)
tree43d6440e2c3c1687e8b90f614779bf8ddc348277 /drivers/spi/spi-cadence-quadspi.c
parent110abe1c9c615cfa47791f5e97142a703e514c34 (diff)
downloadti-linux-kernel-027f03a8512086e5ef05dc4e4ff53b2628848f95.tar.gz
ti-linux-kernel-027f03a8512086e5ef05dc4e4ff53b2628848f95.tar.xz
ti-linux-kernel-027f03a8512086e5ef05dc4e4ff53b2628848f95.zip
spi: cadence-quadspi: flush posted register writes before INDAC access
cqspi_indirect_read_execute() and cqspi_indirect_write_execute() first set the enable bit on APB region and then start reading/writing to the AHB region. On TI K3 SoCs these regions lie on different endpoints. This means that the order of the two operations is not guaranteed, and they might be reordered at the interconnect level. It is possible for the AHB write to be executed before the APB write to enable the indirect controller, causing the transaction to be invalid and the write erroring out. Read back the APB region write before accessing the AHB region to make sure the write got flushed and the race condition is eliminated. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Diffstat (limited to 'drivers/spi/spi-cadence-quadspi.c')
-rw-r--r--drivers/spi/spi-cadence-quadspi.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 53ba8502b988..a19292818006 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1294,6 +1294,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
1294 reinit_completion(&cqspi->transfer_complete); 1294 reinit_completion(&cqspi->transfer_complete);
1295 writel(CQSPI_REG_INDIRECTRD_START_MASK, 1295 writel(CQSPI_REG_INDIRECTRD_START_MASK,
1296 reg_base + CQSPI_REG_INDIRECTRD); 1296 reg_base + CQSPI_REG_INDIRECTRD);
1297 readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */
1297 1298
1298 while (remaining > 0) { 1299 while (remaining > 0) {
1299 if (!wait_for_completion_timeout(&cqspi->transfer_complete, 1300 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
@@ -1432,6 +1433,8 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
1432 reinit_completion(&cqspi->transfer_complete); 1433 reinit_completion(&cqspi->transfer_complete);
1433 writel(CQSPI_REG_INDIRECTWR_START_MASK, 1434 writel(CQSPI_REG_INDIRECTWR_START_MASK,
1434 reg_base + CQSPI_REG_INDIRECTWR); 1435 reg_base + CQSPI_REG_INDIRECTWR);
1436 readl(reg_base + CQSPI_REG_INDIRECTWR); /* Flush posted write. */
1437
1435 /* 1438 /*
1436 * As per 66AK2G02 TRM SPRUHY8F section 11.15.5.3 Indirect Access 1439 * As per 66AK2G02 TRM SPRUHY8F section 11.15.5.3 Indirect Access
1437 * Controller programming sequence, couple of cycles of 1440 * Controller programming sequence, couple of cycles of