diff mbox series

imx_spi: Unset XCH when TX FIFO becomes empty

Message ID 20180731201056.29257-1-tpiepho@impinj.com (mailing list archive)
State New, archived
Headers show
Series imx_spi: Unset XCH when TX FIFO becomes empty | expand

Commit Message

Denis V. Lunev" via July 31, 2018, 8:10 p.m. UTC
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>
---
 hw/ssi/imx_spi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

Peter Maydell Aug. 16, 2018, 12:43 p.m. UTC | #1
On 31 July 2018 at 21:10, Trent Piepho via Qemu-arm <qemu-arm@nongnu.org> wrote:
> 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>

Applied to target-arm.next. Thanks for the detailed commit message,
it made the patch much easier to review.

-- PMM
diff mbox series

Patch

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index b66505ca49..02c38c9e47 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 */