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: c906a3a015 ("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>
This commit is contained in:
Bin Meng 2021-01-29 21:23:23 +08:00 committed by Peter Maydell
parent 6ed924823c
commit 8c495d1379

View File

@ -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);