summaryrefslogtreecommitdiff
path: root/drivers/spi/cadence_qspi_apb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/cadence_qspi_apb.c')
-rw-r--r--drivers/spi/cadence_qspi_apb.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index 00abd7c11f..0f6941ec3f 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -639,6 +639,8 @@ static int cadence_qspi_apb_exec_flash_cmd(void *reg_base,
if (!cadence_qspi_wait_idle(reg_base))
return -EIO;
+ /* Flush the CMDCTRL reg after the execution */
+ writel(0, reg_base + CQSPI_REG_CMDCTRL);
return 0;
}
@@ -725,11 +727,6 @@ int cadence_qspi_apb_command_read(struct cadence_spi_platdata *plat,
unsigned int dummy_clk;
u8 opcode;
- if (rxlen > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
- printf("QSPI: Invalid input arguments rxlen %u\n", rxlen);
- return -EINVAL;
- }
-
if (plat->dtr)
opcode = op->cmd.opcode >> 8;
else
@@ -737,6 +734,18 @@ int cadence_qspi_apb_command_read(struct cadence_spi_platdata *plat,
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+ /* setup ADDR BIT field */
+ if (op->addr.nbytes) {
+ writel(op->addr.val, plat->regbase + CQSPI_REG_CMDADDRESS);
+ /*
+ * address bytes are zero indexed
+ */
+ reg |= (((op->addr.nbytes - 1) &
+ CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
+ CQSPI_REG_CMDCTRL_ADD_BYTES_LSB);
+ reg |= CQSPI_REG_CMDCTRL_ADDR_EN;
+ }
+
/* Set up dummy cycles. */
dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr);
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
@@ -752,18 +761,6 @@ int cadence_qspi_apb_command_read(struct cadence_spi_platdata *plat,
reg |= (((rxlen - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK)
<< CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
- /* setup ADDR BIT field */
- if (op->addr.nbytes) {
- writel(op->addr.val, plat->regbase + CQSPI_REG_CMDADDRESS);
- /*
- * address bytes are zero indexed
- */
- reg |= (((op->addr.nbytes - 1) &
- CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
- CQSPI_REG_CMDCTRL_ADD_BYTES_LSB);
- reg |= CQSPI_REG_CMDCTRL_ADDR_EN;
- }
-
status = cadence_qspi_apb_exec_flash_cmd(reg_base, reg);
if (status != 0)
return status;
@@ -812,25 +809,12 @@ int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
unsigned int reg = 0;
unsigned int wr_data;
unsigned int wr_len;
+ unsigned int dummy_clk;
unsigned int txlen = op->data.nbytes;
const void *txbuf = op->data.buf.out;
void *reg_base = plat->regbase;
- u32 addr;
u8 opcode;
- /* Reorder address to SPI bus order if only transferring address */
- if (!txlen) {
- addr = cpu_to_be32(op->addr.val);
- if (op->addr.nbytes == 3)
- addr >>= 8;
- txbuf = &addr;
- txlen = op->addr.nbytes;
- }
-
- if (txlen > CQSPI_STIG_DATA_LEN_MAX) {
- printf("QSPI: Invalid input arguments txlen %u\n", txlen);
- return -EINVAL;
- }
if (plat->dtr)
opcode = op->cmd.opcode >> 8;
@@ -839,6 +823,27 @@ int cadence_qspi_apb_command_write(struct cadence_spi_platdata *plat,
reg |= opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+ /* setup ADDR BIT field */
+ if (op->addr.nbytes) {
+ writel(op->addr.val, plat->regbase + CQSPI_REG_CMDADDRESS);
+ /*
+ * address bytes are zero indexed
+ */
+ reg |= (((op->addr.nbytes - 1) &
+ CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
+ CQSPI_REG_CMDCTRL_ADD_BYTES_LSB);
+ reg |= CQSPI_REG_CMDCTRL_ADDR_EN;
+ }
+
+ /* Set up dummy cycles. */
+ dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr);
+ if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
+ return -ENOTSUPP;
+
+ if (dummy_clk)
+ reg |= (dummy_clk & CQSPI_REG_CMDCTRL_DUMMY_MASK)
+ << CQSPI_REG_CMDCTRL_DUMMY_LSB;
+
if (txlen) {
/* writing data = yes */
reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);