• Lukas Wunner's avatar
    spi: bcm2835: Speed up FIFO access if fill level is known · 2e0733bc
    Lukas Wunner authored
    The RX and TX FIFO of the BCM2835 SPI master each accommodate 64 bytes
    (16 32-bit dwords).  The CS register provides hints on their fill level:
    
       "Bit 19  RXR - RX FIFO needs Reading ([¾] full)
        0 = RX FIFO is less than [¾] full (or not active TA = 0).
        1 = RX FIFO is [¾] or more full. Cleared by reading sufficient
            data from the RX FIFO or setting TA to 0."
    
       "Bit 16  DONE - Transfer Done
        0 = Transfer is in progress (or not active TA = 0).
        1 = Transfer is complete. Cleared by writing more data to the
            TX FIFO or setting TA to 0."
    
       "If DONE is set [...], write up to 16 [dwords] to SPI_FIFO. [...]
        If RXR is set read 12 [dwords] data from SPI_FIFO."
    
       [Source: Pages 153, 154 and 158 of
        https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
        Note: The spec is missing the "¾" character, presumably due to
        copy-pasting from a different charset.  It also incorrectly
        refers to 16 and 12 "bytes" instead of 32-bit dwords.]
    
    In short, the RXR bit indicates that 48 bytes can be read and the DONE
    bit indicates 64 bytes can be written.  Leverage this knowledge to read
    or write bytes blindly to the FIFO, without polling whether data can be
    read or free space is available to write.  Moreover, when a transfer is
    starting, the TX FIFO is known to be empty, likewise allowing a blind
    write of 64 bytes.
    
    This cuts the number of bus accesses in half if the fill level is known.
    Also, the (posted) write accesses can be pipelined on the AXI bus since
    they are no longer interleaved with (non-posted) reads.
    
    bcm2835_spi_transfer_one_poll() switches to interrupt mode when a time
    limit is exceeded by calling bcm2835_spi_transfer_one_irq().  The TX
    FIFO may contain data in this case, but is known to be empty when the
    function is called from bcm2835_spi_transfer_one().  Hence only blindly
    fill the TX FIFO in the latter case but not the former.
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Tested-by: default avatarEric Anholt <eric@anholt.net>
    Cc: Frank Pavlic <f.pavlic@kunbus.de>
    Cc: Martin Sperl <kernel@martin.sperl.org>
    Cc: Noralf Trønnes <noralf@tronnes.org>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    2e0733bc
spi-bcm2835.c 29.1 KB