Skip to content

Commit

Permalink
spi: STIG Mode Fixes for spi-cadence-qspi driver
Browse files Browse the repository at this point in the history
Merge series from Dhruva Gole <d-gole@ti.com>:

* Reset the CMD_CTRL Register, without which read/writes in STIG mode
were failing in some cases. The issue came to light while using STIG
Mode for small reads.
* Also add a flag that can allow us to do direct reads but distinguish
direct writes, thus enabling us to disable writes in DAC mode in some
cases that require it. (Like to write to some connected Flash registers)
* Fix register reads in STIG mode and also use STIG mode while reading flash
registers.
Currently if you try to read a register while in STIG mode there is no
support for ADDR and thus naturally a register never gets read from the
flash.

This patch series has been tested on a TI AM625-SK-EVM with both a quad
spi nor flash (s25hs) and OSPI NOR Flash (s28hs).

Output of ltp-ddt test, "DD_RW_ERASESIZE_UBIFS" run with s25hs512t flash:
...
[    2.334068] spi-nor spi0.0: s25hs512t (65536 Kbytes)
[    2.339185] 7 fixed-partitions partitions found on MTD device
fc40000.spi.0
[    2.346158] Creating 7 MTD partitions on "fc40000.spi.0":
[    2.351555] 0x000000000000-0x000000080000 : "ospi.tiboot3"
[    2.358344] 0x000000080000-0x000000280000 : "ospi.tispl"
[    2.364788] 0x000000280000-0x000000680000 : "ospi.u-boot"
[    2.371311] 0x000000680000-0x0000006c0000 : "ospi.env"
[    2.377519] 0x0000006c0000-0x000000700000 : "ospi.env.backup"
[    2.384419] 0x000000800000-0x000003fc0000 : "ospi.rootfs"
[    2.390890] 0x000003fc0000-0x000004000000 : "ospi.phypattern"
..snip..
Test Start Time: Wed Jan 11 21:14:31 2023
-----------------------------------------
Testcase                                           Result     Exit Value
--------                                           ------     ----------
OSPI_S_FUNC_DD_RW_ERASESIZE_UBIFS                  PASS       0

-----------------------------------------------
Total Tests: 1
Total Skipped Tests: 0
Total Failures: 0
Kernel Version: 6.2.0-rc1-00040-g700d796a94e0-dirty
Machine Architecture: aarch64
Hostname: am62xx-evm
  • Loading branch information
Mark Brown committed Feb 14, 2023
2 parents 7ec844a + d403fb6 commit e976222
Showing 1 changed file with 38 additions and 4 deletions.
42 changes: 38 additions & 4 deletions drivers/spi/spi-cadence-quadspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct cqspi_st {
u32 trigger_address;
u32 wr_delay;
bool use_direct_mode;
bool use_direct_mode_wr;
struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
bool use_dma_read;
u32 pd_dev_id;
Expand Down Expand Up @@ -531,6 +532,17 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
/* 0 means 1 byte. */
reg |= (((n_rx - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK)
<< CQSPI_REG_CMDCTRL_RD_BYTES_LSB);

/* setup ADDR BIT field */
if (op->addr.nbytes) {
reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
reg |= ((op->addr.nbytes - 1) &
CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;

writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
}

status = cqspi_exec_flash_cmd(cqspi, reg);
if (status)
return status;
Expand All @@ -549,6 +561,9 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
memcpy(rxbuf, &reg, read_len);
}

/* Reset CMD_CTRL Reg once command read completes */
writel(0, reg_base + CQSPI_REG_CMDCTRL);

return 0;
}

Expand Down Expand Up @@ -613,7 +628,12 @@ static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
}
}

return cqspi_exec_flash_cmd(cqspi, reg);
ret = cqspi_exec_flash_cmd(cqspi, reg);

/* Reset CMD_CTRL Reg once command write completes */
writel(0, reg_base + CQSPI_REG_CMDCTRL);

return ret;
}

static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
Expand Down Expand Up @@ -937,6 +957,12 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
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);
/*
* DAC mode require auto polling as flash needs to be polled
* for write completion in case of bubble in SPI transaction
* due to slow CPU/DMA master.
*/
cqspi->use_direct_mode_wr = false;
}

reg = readl(reg_base + CQSPI_REG_SIZE);
Expand Down Expand Up @@ -1222,7 +1248,7 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
* data.
*/
if (!op->cmd.dtr && cqspi->use_direct_mode &&
((to + len) <= cqspi->ahb_size)) {
cqspi->use_direct_mode_wr && ((to + len) <= cqspi->ahb_size)) {
memcpy_toio(cqspi->ahb_base + to, buf, len);
return cqspi_wait_idle(cqspi);
}
Expand Down Expand Up @@ -1333,7 +1359,13 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
cqspi_configure(f_pdata, mem->spi->max_speed_hz);

if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
if (!op->addr.nbytes)
/*
* Performing reads in DAC mode forces to read minimum 4 bytes
* which is unsupported on some flash devices during register
* reads, prefer STIG mode for such small reads.
*/
if (!op->addr.nbytes ||
op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
return cqspi_command_read(f_pdata, op);

return cqspi_read(f_pdata, op);
Expand Down Expand Up @@ -1692,8 +1724,10 @@ static int cqspi_probe(struct platform_device *pdev)
cqspi->master_ref_clk_hz);
if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
cqspi->use_direct_mode = true;
cqspi->use_direct_mode_wr = true;
}
if (ddata->quirks & CQSPI_SUPPORT_EXTERNAL_DMA)
cqspi->use_dma_read = true;
if (ddata->quirks & CQSPI_NO_SUPPORT_WR_COMPLETION)
Expand Down

0 comments on commit e976222

Please sign in to comment.