aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-bcm2835.c107
1 files changed, 36 insertions, 71 deletions
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index 419a782ab6d5..3f93718aad3f 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -67,7 +67,8 @@
67#define BCM2835_SPI_CS_CS_01 0x00000001 67#define BCM2835_SPI_CS_CS_01 0x00000001
68 68
69#define BCM2835_SPI_TIMEOUT_MS 30000 69#define BCM2835_SPI_TIMEOUT_MS 30000
70#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS) 70#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
71 | SPI_NO_CS | SPI_3WIRE)
71 72
72#define DRV_NAME "spi-bcm2835" 73#define DRV_NAME "spi-bcm2835"
73 74
@@ -91,25 +92,23 @@ static inline void bcm2835_wr(struct bcm2835_spi *bs, unsigned reg, u32 val)
91 writel(val, bs->regs + reg); 92 writel(val, bs->regs + reg);
92} 93}
93 94
94static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs, int len) 95static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs)
95{ 96{
96 u8 byte; 97 u8 byte;
97 98
98 while (len--) { 99 while (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD) {
99 byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); 100 byte = bcm2835_rd(bs, BCM2835_SPI_FIFO);
100 if (bs->rx_buf) 101 if (bs->rx_buf)
101 *bs->rx_buf++ = byte; 102 *bs->rx_buf++ = byte;
102 } 103 }
103} 104}
104 105
105static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs, int len) 106static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs)
106{ 107{
107 u8 byte; 108 u8 byte;
108 109
109 if (len > bs->len) 110 while ((bs->len) &&
110 len = bs->len; 111 (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) {
111
112 while (len--) {
113 byte = bs->tx_buf ? *bs->tx_buf++ : 0; 112 byte = bs->tx_buf ? *bs->tx_buf++ : 0;
114 bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); 113 bcm2835_wr(bs, BCM2835_SPI_FIFO, byte);
115 bs->len--; 114 bs->len--;
@@ -122,64 +121,28 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
122 struct bcm2835_spi *bs = spi_master_get_devdata(master); 121 struct bcm2835_spi *bs = spi_master_get_devdata(master);
123 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); 122 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
124 123
125 /* 124 /* Read as many bytes as possible from FIFO */
126 * RXR - RX needs Reading. This means 12 (or more) bytes have been 125 bcm2835_rd_fifo(bs);
127 * transmitted and hence 12 (or more) bytes have been received.
128 *
129 * The FIFO is 16-bytes deep. We check for this interrupt to keep the
130 * FIFO full; we have a 4-byte-time buffer for IRQ latency. We check
131 * this before DONE (TX empty) just in case we delayed processing this
132 * interrupt for some reason.
133 *
134 * We only check for this case if we have more bytes to TX; at the end
135 * of the transfer, we ignore this pipelining optimization, and let
136 * bcm2835_spi_finish_transfer() drain the RX FIFO.
137 */
138 if (bs->len && (cs & BCM2835_SPI_CS_RXR)) {
139 /* Read 12 bytes of data */
140 bcm2835_rd_fifo(bs, 12);
141 126
142 /* Write up to 12 bytes */ 127 if (bs->len) { /* there is more data to transmit */
143 bcm2835_wr_fifo(bs, 12); 128 bcm2835_wr_fifo(bs);
129 } else { /* Transfer complete */
130 /* Disable SPI interrupts */
131 cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD);
132 bcm2835_wr(bs, BCM2835_SPI_CS, cs);
144 133
145 /* 134 /*
146 * We must have written something to the TX FIFO due to the 135 * Wake up bcm2835_spi_transfer_one(), which will call
147 * bs->len check above, so cannot be DONE. Hence, return 136 * bcm2835_spi_finish_transfer(), to drain the RX FIFO.
148 * early. Note that DONE could also be set if we serviced an
149 * RXR interrupt really late.
150 */ 137 */
151 return IRQ_HANDLED; 138 complete(&bs->done);
152 } 139 }
153 140
154 /* 141 return IRQ_HANDLED;
155 * DONE - TX empty. This occurs when we first enable the transfer
156 * since we do not pre-fill the TX FIFO. At any other time, given that
157 * we refill the TX FIFO above based on RXR, and hence ignore DONE if
158 * RXR is set, DONE really does mean end-of-transfer.
159 */
160 if (cs & BCM2835_SPI_CS_DONE) {
161 if (bs->len) { /* First interrupt in a transfer */
162 bcm2835_wr_fifo(bs, 16);
163 } else { /* Transfer complete */
164 /* Disable SPI interrupts */
165 cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD);
166 bcm2835_wr(bs, BCM2835_SPI_CS, cs);
167
168 /*
169 * Wake up bcm2835_spi_transfer_one(), which will call
170 * bcm2835_spi_finish_transfer(), to drain the RX FIFO.
171 */
172 complete(&bs->done);
173 }
174
175 return IRQ_HANDLED;
176 }
177
178 return IRQ_NONE;
179} 142}
180 143
181static int bcm2835_spi_start_transfer(struct spi_device *spi, 144static int bcm2835_spi_start_transfer(struct spi_device *spi,
182 struct spi_transfer *tfr) 145 struct spi_transfer *tfr)
183{ 146{
184 struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); 147 struct bcm2835_spi *bs = spi_master_get_devdata(spi->master);
185 unsigned long spi_hz, clk_hz, cdiv; 148 unsigned long spi_hz, clk_hz, cdiv;
@@ -191,13 +154,18 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi,
191 if (spi_hz >= clk_hz / 2) { 154 if (spi_hz >= clk_hz / 2) {
192 cdiv = 2; /* clk_hz/2 is the fastest we can go */ 155 cdiv = 2; /* clk_hz/2 is the fastest we can go */
193 } else if (spi_hz) { 156 } else if (spi_hz) {
194 /* CDIV must be a power of two */ 157 /* CDIV must be a multiple of two */
195 cdiv = roundup_pow_of_two(DIV_ROUND_UP(clk_hz, spi_hz)); 158 cdiv = DIV_ROUND_UP(clk_hz, spi_hz);
159 cdiv += (cdiv % 2);
196 160
197 if (cdiv >= 65536) 161 if (cdiv >= 65536)
198 cdiv = 0; /* 0 is the slowest we can go */ 162 cdiv = 0; /* 0 is the slowest we can go */
199 } else 163 } else {
200 cdiv = 0; /* 0 is the slowest we can go */ 164 cdiv = 0; /* 0 is the slowest we can go */
165 }
166
167 if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf))
168 cs |= BCM2835_SPI_CS_REN;
201 169
202 if (spi->mode & SPI_CPOL) 170 if (spi->mode & SPI_CPOL)
203 cs |= BCM2835_SPI_CS_CPOL; 171 cs |= BCM2835_SPI_CS_CPOL;
@@ -231,17 +199,12 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi,
231} 199}
232 200
233static int bcm2835_spi_finish_transfer(struct spi_device *spi, 201static int bcm2835_spi_finish_transfer(struct spi_device *spi,
234 struct spi_transfer *tfr, bool cs_change) 202 struct spi_transfer *tfr,
203 bool cs_change)
235{ 204{
236 struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); 205 struct bcm2835_spi *bs = spi_master_get_devdata(spi->master);
237 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); 206 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
238 207
239 /* Drain RX FIFO */
240 while (cs & BCM2835_SPI_CS_RXD) {
241 bcm2835_rd_fifo(bs, 1);
242 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
243 }
244
245 if (tfr->delay_usecs) 208 if (tfr->delay_usecs)
246 udelay(tfr->delay_usecs); 209 udelay(tfr->delay_usecs);
247 210
@@ -253,7 +216,7 @@ static int bcm2835_spi_finish_transfer(struct spi_device *spi,
253} 216}
254 217
255static int bcm2835_spi_transfer_one(struct spi_master *master, 218static int bcm2835_spi_transfer_one(struct spi_master *master,
256 struct spi_message *mesg) 219 struct spi_message *mesg)
257{ 220{
258 struct bcm2835_spi *bs = spi_master_get_devdata(master); 221 struct bcm2835_spi *bs = spi_master_get_devdata(master);
259 struct spi_transfer *tfr; 222 struct spi_transfer *tfr;
@@ -267,8 +230,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
267 if (err) 230 if (err)
268 goto out; 231 goto out;
269 232
270 timeout = wait_for_completion_timeout(&bs->done, 233 timeout = wait_for_completion_timeout(
271 msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS)); 234 &bs->done,
235 msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS)
236 );
272 if (!timeout) { 237 if (!timeout) {
273 err = -ETIMEDOUT; 238 err = -ETIMEDOUT;
274 goto out; 239 goto out;
@@ -343,7 +308,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
343 clk_prepare_enable(bs->clk); 308 clk_prepare_enable(bs->clk);
344 309
345 err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, 310 err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0,
346 dev_name(&pdev->dev), master); 311 dev_name(&pdev->dev), master);
347 if (err) { 312 if (err) {
348 dev_err(&pdev->dev, "could not request IRQ: %d\n", err); 313 dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
349 goto out_clk_disable; 314 goto out_clk_disable;