|
|
@@ -3,7 +3,9 @@
|
|
|
#include "board.h"
|
|
|
#include "pinctrl.h"
|
|
|
#include "os_adapt.h"
|
|
|
-
|
|
|
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
|
|
|
+#include "sfud_def.h"
|
|
|
+#endif
|
|
|
#include <string.h>
|
|
|
|
|
|
/* Register offsets */
|
|
|
@@ -629,7 +631,7 @@ static int dw_spi_transfer_one(struct spi_slave *slave, struct spi_message *mess
|
|
|
}
|
|
|
|
|
|
end:
|
|
|
- if (message->cs_release)
|
|
|
+ if (message->cs_release || ret)
|
|
|
dw_spi_chipselect(dws, 0);
|
|
|
return ret;
|
|
|
}
|
|
|
@@ -644,9 +646,12 @@ static int dw_qspi_read(struct spi_slave *slave, struct qspi_message *qspi_messa
|
|
|
u32 cr0, qspi_cr0, ndf;
|
|
|
u32 bits_per_word = 0;
|
|
|
u32 addr;
|
|
|
+ u32 dummy_cycles;
|
|
|
+ u8 cmd;
|
|
|
unsigned long transfer_timeout;
|
|
|
u32 xfer_len = 0;
|
|
|
int ret = 0;
|
|
|
+ int hasmode = 0;
|
|
|
|
|
|
chip->tmode = SPI_TMOD_RO;
|
|
|
|
|
|
@@ -685,9 +690,9 @@ xfer_continue:
|
|
|
|
|
|
spi_set_clk(dws, chip->qspi_clk_div);
|
|
|
|
|
|
- if (dws->current_freq >= 63500000)
|
|
|
+ if (dws->current_qspi_freq >= 63500000)
|
|
|
dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, 2);
|
|
|
- else if (dws->current_freq >= 50000000)
|
|
|
+ else if (dws->current_qspi_freq >= 50000000)
|
|
|
dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, 1);
|
|
|
|
|
|
if (message->cs_take)
|
|
|
@@ -708,9 +713,24 @@ xfer_continue:
|
|
|
|
|
|
dw_writel(dws, DW_SPI_CTRL1, ndf);
|
|
|
|
|
|
- qspi_cr0 = ((qspi_message->dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
|
|
|
+ cmd = qspi_message->instruction.content;
|
|
|
+ dummy_cycles = qspi_message->dummy_cycles;
|
|
|
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
|
|
|
+ if (((cmd == SFUD_CMD_DUAL_IO_READ_DATA)
|
|
|
+ || (cmd == (SFUD_CMD_DUAL_IO_READ_DATA + 1)))
|
|
|
+ && (dummy_cycles >= 4)) {
|
|
|
+ dummy_cycles -= 4;
|
|
|
+ hasmode = 1;
|
|
|
+ } else if (((cmd == SFUD_CMD_QUAD_IO_READ_DATA)
|
|
|
+ || (cmd == (SFUD_CMD_QUAD_IO_READ_DATA + 1)))
|
|
|
+ && (dummy_cycles >= 2)) {
|
|
|
+ dummy_cycles -= 2;
|
|
|
+ hasmode = 1;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ qspi_cr0 = ((dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
|
|
|
(2 << SPI_INST_LENGTH_OFFSET) |
|
|
|
- ((qspi_message->address.size >> 2) << SPI_ADDR_LENGTH_OFFSET);
|
|
|
+ (((qspi_message->address.size >> 2) + (hasmode ? 2 : 0)) << SPI_ADDR_LENGTH_OFFSET);
|
|
|
if (qspi_message->instruction.qspi_lines == 1 && qspi_message->address.qspi_lines > 1)
|
|
|
qspi_cr0 |= 1;
|
|
|
else if (qspi_message->instruction.qspi_lines > 1 && qspi_message->address.qspi_lines > 1)
|
|
|
@@ -763,10 +783,14 @@ xfer_continue:
|
|
|
(((addr >> 8) & 0xff) << 16) | ((addr & 0xff) << 24);
|
|
|
} else {
|
|
|
addr = ((addr >> 16) & 0xff) | (((addr >> 8) & 0xff) << 8) | ((addr & 0xff) << 16);
|
|
|
+ if (hasmode)
|
|
|
+ addr |= 0xffU << 24;
|
|
|
}
|
|
|
|
|
|
- dw_write_io_reg(dws, DW_SPI_DR, qspi_message->instruction.content);
|
|
|
+ dw_write_io_reg(dws, DW_SPI_DR, cmd);
|
|
|
dw_write_io_reg(dws, DW_SPI_DR, addr);
|
|
|
+ if (qspi_message->address.size == 32 && hasmode)
|
|
|
+ dw_write_io_reg(dws, DW_SPI_DR, 0xff); //send the M7-0 of dummy cycles
|
|
|
|
|
|
transfer_timeout = dw_spi_calculate_timeout(dws, message->length);
|
|
|
if (xQueueReceive(dws->xfer_done, NULL, transfer_timeout) != pdTRUE) {
|
|
|
@@ -816,7 +840,7 @@ xfer_continue:
|
|
|
}
|
|
|
|
|
|
end:
|
|
|
- if (message->cs_release)
|
|
|
+ if (message->cs_release || ret)
|
|
|
dw_spi_chipselect(dws, 0);
|
|
|
return ret;
|
|
|
}
|