summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2019-09-11 06:15:30 -0400
committerMark Brown <broonie@kernel.org>2019-09-11 10:56:30 -0400
commit571e31fa60b3697d5db26140e16d5c45c51c9815 (patch)
tree12c3905bb0ca9519a3e7156eaccf61f014e38181
parentc3ef8207833206f53b1ea433dc25c0c9b30d4424 (diff)
spi: bcm2835: Cache CS register value for ->prepare_message()
The BCM2835 SPI driver needs to set up the clock polarity in its ->prepare_message() hook before spi_transfer_one_message() asserts chip select to avoid a gratuitous clock signal edge (cf. commit acace73df2c1 ("spi: bcm2835: set up spi-mode before asserting cs-gpio")). Precalculate the CS register value (which selects the clock polarity) once in ->setup() and use that cached value in ->prepare_message() and ->transfer_one(). This avoids one MMIO read per message and one per transfer, yielding a small latency improvement. Additionally, a forthcoming commit will use the precalculated value to derive the register value for clearing the RX FIFO, which will eliminate the need for an RX dummy buffer when performing TX-only DMA transfers. Tested-by: Nuno Sá <nuno.sa@analog.com> Tested-by: Noralf Trønnes <noralf@tronnes.org> Signed-off-by: Lukas Wunner <lukas@wunner.de> Acked-by: Stefan Wahren <wahrenst@gmx.net> Acked-by: Martin Sperl <kernel@martin.sperl.org> Link: https://lore.kernel.org/r/d17c1d7fcdc97fffa961b8737cfd80eeb14f9416.1568187525.git.lukas@wunner.de Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-bcm2835.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index 60255ac837f5..f01d18d521f2 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -68,6 +68,7 @@
68#define BCM2835_SPI_FIFO_SIZE 64 68#define BCM2835_SPI_FIFO_SIZE 64
69#define BCM2835_SPI_FIFO_SIZE_3_4 48 69#define BCM2835_SPI_FIFO_SIZE_3_4 48
70#define BCM2835_SPI_DMA_MIN_LENGTH 96 70#define BCM2835_SPI_DMA_MIN_LENGTH 96
71#define BCM2835_SPI_NUM_CS 3 /* raise as necessary */
71#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ 72#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
72 | SPI_NO_CS | SPI_3WIRE) 73 | SPI_NO_CS | SPI_3WIRE)
73 74
@@ -94,6 +95,8 @@ MODULE_PARM_DESC(polling_limit_us,
94 * @rx_prologue: bytes received without DMA if first RX sglist entry's 95 * @rx_prologue: bytes received without DMA if first RX sglist entry's
95 * length is not a multiple of 4 (to overcome hardware limitation) 96 * length is not a multiple of 4 (to overcome hardware limitation)
96 * @tx_spillover: whether @tx_prologue spills over to second TX sglist entry 97 * @tx_spillover: whether @tx_prologue spills over to second TX sglist entry
98 * @prepare_cs: precalculated CS register value for ->prepare_message()
99 * (uses slave-specific clock polarity and phase settings)
97 * @debugfs_dir: the debugfs directory - neede to remove debugfs when 100 * @debugfs_dir: the debugfs directory - neede to remove debugfs when
98 * unloading the module 101 * unloading the module
99 * @count_transfer_polling: count of how often polling mode is used 102 * @count_transfer_polling: count of how often polling mode is used
@@ -116,6 +119,7 @@ struct bcm2835_spi {
116 int tx_prologue; 119 int tx_prologue;
117 int rx_prologue; 120 int rx_prologue;
118 unsigned int tx_spillover; 121 unsigned int tx_spillover;
122 u32 prepare_cs[BCM2835_SPI_NUM_CS];
119 123
120 struct dentry *debugfs_dir; 124 struct dentry *debugfs_dir;
121 u64 count_transfer_polling; 125 u64 count_transfer_polling;
@@ -808,7 +812,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
808 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); 812 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
809 unsigned long spi_hz, clk_hz, cdiv, spi_used_hz; 813 unsigned long spi_hz, clk_hz, cdiv, spi_used_hz;
810 unsigned long hz_per_byte, byte_limit; 814 unsigned long hz_per_byte, byte_limit;
811 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); 815 u32 cs = bs->prepare_cs[spi->chip_select];
812 816
813 /* set clock */ 817 /* set clock */
814 spi_hz = tfr->speed_hz; 818 spi_hz = tfr->speed_hz;
@@ -833,15 +837,6 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
833 if (spi->mode & SPI_3WIRE && tfr->rx_buf && 837 if (spi->mode & SPI_3WIRE && tfr->rx_buf &&
834 tfr->rx_buf != ctlr->dummy_rx) 838 tfr->rx_buf != ctlr->dummy_rx)
835 cs |= BCM2835_SPI_CS_REN; 839 cs |= BCM2835_SPI_CS_REN;
836 else
837 cs &= ~BCM2835_SPI_CS_REN;
838
839 /*
840 * The driver always uses software-controlled GPIO Chip Select.
841 * Set the hardware-controlled native Chip Select to an invalid
842 * value to prevent it from interfering.
843 */
844 cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
845 840
846 /* set transmit buffers and length */ 841 /* set transmit buffers and length */
847 bs->tx_buf = tfr->tx_buf; 842 bs->tx_buf = tfr->tx_buf;
@@ -878,7 +873,6 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
878{ 873{
879 struct spi_device *spi = msg->spi; 874 struct spi_device *spi = msg->spi;
880 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); 875 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
881 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
882 int ret; 876 int ret;
883 877
884 if (ctlr->can_dma) { 878 if (ctlr->can_dma) {
@@ -893,14 +887,11 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
893 return ret; 887 return ret;
894 } 888 }
895 889
896 cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA); 890 /*
897 891 * Set up clock polarity before spi_transfer_one_message() asserts
898 if (spi->mode & SPI_CPOL) 892 * chip select to avoid a gratuitous clock signal edge.
899 cs |= BCM2835_SPI_CS_CPOL; 893 */
900 if (spi->mode & SPI_CPHA) 894 bcm2835_wr(bs, BCM2835_SPI_CS, bs->prepare_cs[spi->chip_select]);
901 cs |= BCM2835_SPI_CS_CPHA;
902
903 bcm2835_wr(bs, BCM2835_SPI_CS, cs);
904 895
905 return 0; 896 return 0;
906} 897}
@@ -926,8 +917,23 @@ static int chip_match_name(struct gpio_chip *chip, void *data)
926 917
927static int bcm2835_spi_setup(struct spi_device *spi) 918static int bcm2835_spi_setup(struct spi_device *spi)
928{ 919{
920 struct bcm2835_spi *bs = spi_controller_get_devdata(spi->controller);
929 struct gpio_chip *chip; 921 struct gpio_chip *chip;
930 enum gpio_lookup_flags lflags; 922 enum gpio_lookup_flags lflags;
923 u32 cs;
924
925 /*
926 * Precalculate SPI slave's CS register value for ->prepare_message():
927 * The driver always uses software-controlled GPIO chip select, hence
928 * set the hardware-controlled native chip select to an invalid value
929 * to prevent it from interfering.
930 */
931 cs = BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
932 if (spi->mode & SPI_CPOL)
933 cs |= BCM2835_SPI_CS_CPOL;
934 if (spi->mode & SPI_CPHA)
935 cs |= BCM2835_SPI_CS_CPHA;
936 bs->prepare_cs[spi->chip_select] = cs;
931 937
932 /* 938 /*
933 * sanity checking the native-chipselects 939 * sanity checking the native-chipselects
@@ -1005,7 +1011,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
1005 ctlr->use_gpio_descriptors = true; 1011 ctlr->use_gpio_descriptors = true;
1006 ctlr->mode_bits = BCM2835_SPI_MODE_BITS; 1012 ctlr->mode_bits = BCM2835_SPI_MODE_BITS;
1007 ctlr->bits_per_word_mask = SPI_BPW_MASK(8); 1013 ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
1008 ctlr->num_chipselect = 3; 1014 ctlr->num_chipselect = BCM2835_SPI_NUM_CS;
1009 ctlr->setup = bcm2835_spi_setup; 1015 ctlr->setup = bcm2835_spi_setup;
1010 ctlr->transfer_one = bcm2835_spi_transfer_one; 1016 ctlr->transfer_one = bcm2835_spi_transfer_one;
1011 ctlr->handle_err = bcm2835_spi_handle_err; 1017 ctlr->handle_err = bcm2835_spi_handle_err;