summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBin Meng2021-01-29 14:23:23 +0100
committerPeter Maydell2021-02-02 18:00:55 +0100
commit8c495d1379211554208c58be75736e3be5ad60e8 (patch)
tree28a5a013828ccb6e3e797dfb392dd2d92e075262
parenthw/ssi: imx_spi: Correct the burst length > 32 bit transfer logic (diff)
downloadqemu-8c495d1379211554208c58be75736e3be5ad60e8.tar.gz
qemu-8c495d1379211554208c58be75736e3be5ad60e8.tar.xz
qemu-8c495d1379211554208c58be75736e3be5ad60e8.zip
hw/ssi: imx_spi: Correct tx and rx fifo endianness
The endianness of data exchange between tx and rx fifo is incorrect. Earlier bytes are supposed to show up on MSB and later bytes on LSB, ie: in big endian. The manual does not explicitly say this, but the U-Boot and Linux driver codes have a swap on the data transferred to tx fifo and from rx fifo. With this change, U-Boot read from / write to SPI flash tests pass. => sf test 1ff000 1000 SPI flash test: 0 erase: 0 ticks, 4096000 KiB/s 32768.000 Mbps 1 check: 3 ticks, 1333 KiB/s 10.664 Mbps 2 write: 235 ticks, 17 KiB/s 0.136 Mbps 3 read: 2 ticks, 2000 KiB/s 16.000 Mbps Test passed 0 erase: 0 ticks, 4096000 KiB/s 32768.000 Mbps 1 check: 3 ticks, 1333 KiB/s 10.664 Mbps 2 write: 235 ticks, 17 KiB/s 0.136 Mbps 3 read: 2 ticks, 2000 KiB/s 16.000 Mbps Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller") Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20210129132323.30946-11-bmeng.cn@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/ssi/imx_spi.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index a34194c1b0..189423bb3a 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -169,7 +169,6 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
while (!fifo32_is_empty(&s->tx_fifo)) {
int tx_burst = 0;
- int index = 0;
if (s->burst_length <= 0) {
s->burst_length = imx_spi_burst_length(s);
@@ -190,7 +189,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
rx = 0;
while (tx_burst > 0) {
- uint8_t byte = tx & 0xff;
+ uint8_t byte = tx >> (tx_burst - 8);
DPRINTF("writing 0x%02x\n", (uint32_t)byte);
@@ -199,13 +198,11 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
DPRINTF("0x%02x read\n", (uint32_t)byte);
- tx = tx >> 8;
- rx |= (byte << (index * 8));
+ rx = (rx << 8) | byte;
/* Remove 8 bits from the actual burst */
tx_burst -= 8;
s->burst_length -= 8;
- index++;
}
DPRINTF("data rx:0x%08x\n", rx);