Skip to content

Commit

Permalink
spi: cadence-quadspi: fix write completion support
Browse files Browse the repository at this point in the history
commit 98d948e upstream.

Some versions of the Cadence QSPI controller does not have the write
completion register implemented(CQSPI_REG_WR_COMPLETION_CTRL). On the
Intel SoCFPGA platform the CQSPI_REG_WR_COMPLETION_CTRL register is
not configured.

Add a quirk to not write to the CQSPI_REG_WR_COMPLETION_CTRL register.

Fixes: 9cb2ff1 ("spi: cadence-quadspi: Disable Auto-HW polling)
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211108200854.3616121-1-dinguyen@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
[IA: backported for linux=5.15.y]
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dinh Nguyen authored and gregkh committed May 1, 2022
1 parent 8c39925 commit e8749d6
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions drivers/spi/spi-cadence-quadspi.c
Expand Up @@ -36,6 +36,7 @@
/* Quirks */
#define CQSPI_NEEDS_WR_DELAY BIT(0)
#define CQSPI_DISABLE_DAC_MODE BIT(1)
#define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3)

/* Capabilities */
#define CQSPI_SUPPORTS_OCTAL BIT(0)
Expand Down Expand Up @@ -83,6 +84,7 @@ struct cqspi_st {
u32 wr_delay;
bool use_direct_mode;
struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
bool wr_completion;
};

struct cqspi_driver_platdata {
Expand Down Expand Up @@ -797,9 +799,11 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
* polling on the controller's side. spinand and spi-nor will take
* care of polling the status register.
*/
reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
if (cqspi->wr_completion) {
reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
}

reg = readl(reg_base + CQSPI_REG_SIZE);
reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
Expand Down Expand Up @@ -1532,6 +1536,10 @@ static int cqspi_probe(struct platform_device *pdev)

cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
master->max_speed_hz = cqspi->master_ref_clk_hz;

/* write completion is supported by default */
cqspi->wr_completion = true;

ddata = of_device_get_match_data(dev);
if (ddata) {
if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
Expand All @@ -1541,6 +1549,8 @@ static int cqspi_probe(struct platform_device *pdev)
master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
cqspi->use_direct_mode = true;
if (ddata->quirks & CQSPI_NO_SUPPORT_WR_COMPLETION)
cqspi->wr_completion = false;
}

ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
Expand Down Expand Up @@ -1649,6 +1659,10 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = {
.quirks = CQSPI_DISABLE_DAC_MODE,
};

static const struct cqspi_driver_platdata socfpga_qspi = {
.quirks = CQSPI_NO_SUPPORT_WR_COMPLETION,
};

static const struct of_device_id cqspi_dt_ids[] = {
{
.compatible = "cdns,qspi-nor",
Expand All @@ -1666,6 +1680,10 @@ static const struct of_device_id cqspi_dt_ids[] = {
.compatible = "intel,lgm-qspi",
.data = &intel_lgm_qspi,
},
{
.compatible = "intel,socfpga-qspi",
.data = (void *)&socfpga_qspi,
},
{ /* end of table */ }
};

Expand Down

0 comments on commit e8749d6

Please sign in to comment.