aboutsummaryrefslogtreecommitdiff
path: root/hw/ssi
diff options
context:
space:
mode:
authorTrent Piepho <tpiepho@impinj.com>2018-08-16 14:05:29 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-08-16 14:29:57 +0100
commit016d4b0127bc8c76f1385c398ac7506e83b5ab39 (patch)
treea1094385fc05dd7632886e5aa4b9df5c9ed4de06 /hw/ssi
parent645d3cbebb10b4ba3a3f25da7f3ad8a1f79fd1cc (diff)
downloadqemu-016d4b0127bc8c76f1385c398ac7506e83b5ab39.zip
qemu-016d4b0127bc8c76f1385c398ac7506e83b5ab39.tar.gz
qemu-016d4b0127bc8c76f1385c398ac7506e83b5ab39.tar.bz2
imx_spi: Unset XCH when TX FIFO becomes empty
The current emulation will clear the XCH bit when a burst finishes. This is not quite correct. According to the i.MX7d referemce manual, Rev 0.1, ยง10.1.7.3: This bit [XCH] is cleared automatically when all data in the TXFIFO and the shift register has been shifted out. So XCH should be cleared when the FIFO empties, not on completion of a burst. The FIFO is 64 x 32 bits = 2048 bits, while the max burst size is larger at 4096 bits. So it's possible that the burst is not finished after the TXFIFO empties. Sending a large block (> 2048 bits) with the Linux driver will use a burst that is larger than the TXFIFO. After the TXFIFO has emptied XCH does not become unset, as the burst is not yet finished. What should happen after the TXFIFO empties is the driver will refill it and set XCH. The rising edge of XCH will trigger another transfer to begin. However, since the emulation does not set XCH to 0, there is no rising edge and the next trasfer never begins. Signed-off-by: Trent Piepho <tpiepho@impinj.com> Message-id: 20180731201056.29257-1-tpiepho@impinj.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ssi')
-rw-r--r--hw/ssi/imx_spi.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index b66505c..02c38c9 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -208,8 +208,6 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
}
if (s->burst_length <= 0) {
- s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
-
if (!imx_spi_is_multiple_master_burst(s)) {
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
break;
@@ -219,6 +217,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
if (fifo32_is_empty(&s->tx_fifo)) {
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
+ s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
}
/* TODO: We should also use TDR and RDR bits */