]>
Commit | Line | Data |
---|---|---|
6576bf00 FE |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // | |
3 | // Copyright 2013 Freescale Semiconductor, Inc. | |
dc234825 | 4 | // Copyright 2020 NXP |
6576bf00 FE |
5 | // |
6 | // Freescale DSPI driver | |
7 | // This file contains a driver for the Freescale DSPI | |
349ad66c | 8 | |
a3108360 XL |
9 | #include <linux/clk.h> |
10 | #include <linux/delay.h> | |
90ba3703 SM |
11 | #include <linux/dmaengine.h> |
12 | #include <linux/dma-mapping.h> | |
a3108360 | 13 | #include <linux/interrupt.h> |
349ad66c CF |
14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | |
749396cb RH |
16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> | |
432a17d7 | 18 | #include <linux/pinctrl/consumer.h> |
1acbdeb9 | 19 | #include <linux/regmap.h> |
349ad66c | 20 | #include <linux/spi/spi.h> |
ec7ed770 | 21 | #include <linux/spi/spi-fsl-dspi.h> |
349ad66c | 22 | |
50fcd847 | 23 | #define DRIVER_NAME "fsl-dspi" |
349ad66c | 24 | |
50fcd847 | 25 | #define SPI_MCR 0x00 |
6230d6ca | 26 | #define SPI_MCR_HOST BIT(31) |
4fcc7c22 | 27 | #define SPI_MCR_PCSIS(x) ((x) << 16) |
b2655196 VO |
28 | #define SPI_MCR_CLR_TXF BIT(11) |
29 | #define SPI_MCR_CLR_RXF BIT(10) | |
30 | #define SPI_MCR_XSPI BIT(3) | |
dc234825 PM |
31 | #define SPI_MCR_DIS_TXF BIT(13) |
32 | #define SPI_MCR_DIS_RXF BIT(12) | |
33 | #define SPI_MCR_HALT BIT(0) | |
50fcd847 VO |
34 | |
35 | #define SPI_TCR 0x08 | |
b2655196 VO |
36 | #define SPI_TCR_GET_TCNT(x) (((x) & GENMASK(31, 16)) >> 16) |
37 | ||
38 | #define SPI_CTAR(x) (0x0c + (((x) & GENMASK(1, 0)) * 4)) | |
39 | #define SPI_CTAR_FMSZ(x) (((x) << 27) & GENMASK(30, 27)) | |
06d5dd29 VO |
40 | #define SPI_CTAR_CPOL BIT(26) |
41 | #define SPI_CTAR_CPHA BIT(25) | |
42 | #define SPI_CTAR_LSBFE BIT(24) | |
b2655196 VO |
43 | #define SPI_CTAR_PCSSCK(x) (((x) << 22) & GENMASK(23, 22)) |
44 | #define SPI_CTAR_PASC(x) (((x) << 20) & GENMASK(21, 20)) | |
45 | #define SPI_CTAR_PDT(x) (((x) << 18) & GENMASK(19, 18)) | |
46 | #define SPI_CTAR_PBR(x) (((x) << 16) & GENMASK(17, 16)) | |
47 | #define SPI_CTAR_CSSCK(x) (((x) << 12) & GENMASK(15, 12)) | |
48 | #define SPI_CTAR_ASC(x) (((x) << 8) & GENMASK(11, 8)) | |
49 | #define SPI_CTAR_DT(x) (((x) << 4) & GENMASK(7, 4)) | |
50 | #define SPI_CTAR_BR(x) ((x) & GENMASK(3, 0)) | |
50fcd847 VO |
51 | #define SPI_CTAR_SCALE_BITS 0xf |
52 | ||
53 | #define SPI_CTAR0_SLAVE 0x0c | |
54 | ||
55 | #define SPI_SR 0x2c | |
b2655196 | 56 | #define SPI_SR_TCFQF BIT(31) |
9e6f784e VO |
57 | #define SPI_SR_TFUF BIT(27) |
58 | #define SPI_SR_TFFF BIT(25) | |
59 | #define SPI_SR_CMDTCF BIT(23) | |
60 | #define SPI_SR_SPEF BIT(21) | |
61 | #define SPI_SR_RFOF BIT(19) | |
62 | #define SPI_SR_TFIWF BIT(18) | |
63 | #define SPI_SR_RFDF BIT(17) | |
64 | #define SPI_SR_CMDFFF BIT(16) | |
20c05a05 | 65 | #define SPI_SR_CLEAR (SPI_SR_TCFQF | \ |
9e6f784e VO |
66 | SPI_SR_TFUF | SPI_SR_TFFF | \ |
67 | SPI_SR_CMDTCF | SPI_SR_SPEF | \ | |
68 | SPI_SR_RFOF | SPI_SR_TFIWF | \ | |
69 | SPI_SR_RFDF | SPI_SR_CMDFFF) | |
50fcd847 VO |
70 | |
71 | #define SPI_RSER_TFFFE BIT(25) | |
72 | #define SPI_RSER_TFFFD BIT(24) | |
73 | #define SPI_RSER_RFDFE BIT(17) | |
74 | #define SPI_RSER_RFDFD BIT(16) | |
75 | ||
76 | #define SPI_RSER 0x30 | |
b2655196 | 77 | #define SPI_RSER_TCFQE BIT(31) |
d59c90a2 | 78 | #define SPI_RSER_CMDTCFE BIT(23) |
50fcd847 VO |
79 | |
80 | #define SPI_PUSHR 0x34 | |
b2655196 VO |
81 | #define SPI_PUSHR_CMD_CONT BIT(15) |
82 | #define SPI_PUSHR_CMD_CTAS(x) (((x) << 12 & GENMASK(14, 12))) | |
83 | #define SPI_PUSHR_CMD_EOQ BIT(11) | |
84 | #define SPI_PUSHR_CMD_CTCNT BIT(10) | |
85 | #define SPI_PUSHR_CMD_PCS(x) (BIT(x) & GENMASK(5, 0)) | |
50fcd847 VO |
86 | |
87 | #define SPI_PUSHR_SLAVE 0x34 | |
88 | ||
89 | #define SPI_POPR 0x38 | |
50fcd847 VO |
90 | |
91 | #define SPI_TXFR0 0x3c | |
92 | #define SPI_TXFR1 0x40 | |
93 | #define SPI_TXFR2 0x44 | |
94 | #define SPI_TXFR3 0x48 | |
95 | #define SPI_RXFR0 0x7c | |
96 | #define SPI_RXFR1 0x80 | |
97 | #define SPI_RXFR2 0x84 | |
98 | #define SPI_RXFR3 0x88 | |
99 | ||
b2655196 | 100 | #define SPI_CTARE(x) (0x11c + (((x) & GENMASK(1, 0)) * 4)) |
50fcd847 VO |
101 | #define SPI_CTARE_FMSZE(x) (((x) & 0x1) << 16) |
102 | #define SPI_CTARE_DTCP(x) ((x) & 0x7ff) | |
103 | ||
104 | #define SPI_SREX 0x13c | |
105 | ||
106 | #define SPI_FRAME_BITS(bits) SPI_CTAR_FMSZ((bits) - 1) | |
50fcd847 | 107 | #define SPI_FRAME_EBITS(bits) SPI_CTARE_FMSZE(((bits) - 1) >> 4) |
51d583ae | 108 | |
50fcd847 | 109 | #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) |
90ba3703 | 110 | |
349ad66c | 111 | struct chip_data { |
50fcd847 | 112 | u32 ctar_val; |
349ad66c CF |
113 | }; |
114 | ||
d1f4a38c | 115 | enum dspi_trans_mode { |
d59c90a2 | 116 | DSPI_XSPI_MODE, |
90ba3703 | 117 | DSPI_DMA_MODE, |
d1f4a38c HW |
118 | }; |
119 | ||
120 | struct fsl_dspi_devtype_data { | |
50fcd847 VO |
121 | enum dspi_trans_mode trans_mode; |
122 | u8 max_clock_factor; | |
1d8b4c95 | 123 | int fifo_size; |
d1f4a38c HW |
124 | }; |
125 | ||
d3505401 VO |
126 | enum { |
127 | LS1021A, | |
128 | LS1012A, | |
138f56ef | 129 | LS1028A, |
d3505401 VO |
130 | LS1043A, |
131 | LS1046A, | |
132 | LS2080A, | |
133 | LS2085A, | |
134 | LX2160A, | |
135 | MCF5441X, | |
136 | VF610, | |
d1f4a38c HW |
137 | }; |
138 | ||
d3505401 VO |
139 | static const struct fsl_dspi_devtype_data devtype_data[] = { |
140 | [VF610] = { | |
141 | .trans_mode = DSPI_DMA_MODE, | |
142 | .max_clock_factor = 2, | |
1d8b4c95 | 143 | .fifo_size = 4, |
d3505401 VO |
144 | }, |
145 | [LS1021A] = { | |
0feaf8f5 | 146 | /* Has A-011218 DMA erratum */ |
d59c90a2 | 147 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 148 | .max_clock_factor = 8, |
1d8b4c95 | 149 | .fifo_size = 4, |
d3505401 VO |
150 | }, |
151 | [LS1012A] = { | |
0feaf8f5 | 152 | /* Has A-011218 DMA erratum */ |
d59c90a2 | 153 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 154 | .max_clock_factor = 8, |
1d8b4c95 | 155 | .fifo_size = 16, |
d3505401 | 156 | }, |
138f56ef VO |
157 | [LS1028A] = { |
158 | .trans_mode = DSPI_XSPI_MODE, | |
159 | .max_clock_factor = 8, | |
160 | .fifo_size = 4, | |
161 | }, | |
d3505401 | 162 | [LS1043A] = { |
0feaf8f5 | 163 | /* Has A-011218 DMA erratum */ |
d59c90a2 | 164 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 165 | .max_clock_factor = 8, |
1d8b4c95 | 166 | .fifo_size = 16, |
d3505401 VO |
167 | }, |
168 | [LS1046A] = { | |
0feaf8f5 | 169 | /* Has A-011218 DMA erratum */ |
d59c90a2 | 170 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 171 | .max_clock_factor = 8, |
1d8b4c95 | 172 | .fifo_size = 16, |
d3505401 VO |
173 | }, |
174 | [LS2080A] = { | |
505623a2 | 175 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 176 | .max_clock_factor = 8, |
1d8b4c95 | 177 | .fifo_size = 4, |
d3505401 VO |
178 | }, |
179 | [LS2085A] = { | |
505623a2 | 180 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 181 | .max_clock_factor = 8, |
1d8b4c95 | 182 | .fifo_size = 4, |
d3505401 VO |
183 | }, |
184 | [LX2160A] = { | |
505623a2 | 185 | .trans_mode = DSPI_XSPI_MODE, |
d3505401 | 186 | .max_clock_factor = 8, |
1d8b4c95 | 187 | .fifo_size = 4, |
d3505401 VO |
188 | }, |
189 | [MCF5441X] = { | |
b09058bb | 190 | .trans_mode = DSPI_DMA_MODE, |
d3505401 | 191 | .max_clock_factor = 8, |
1d8b4c95 | 192 | .fifo_size = 16, |
d3505401 | 193 | }, |
ec7ed770 AD |
194 | }; |
195 | ||
90ba3703 | 196 | struct fsl_dspi_dma { |
50fcd847 VO |
197 | u32 *tx_dma_buf; |
198 | struct dma_chan *chan_tx; | |
199 | dma_addr_t tx_dma_phys; | |
200 | struct completion cmd_tx_complete; | |
201 | struct dma_async_tx_descriptor *tx_desc; | |
202 | ||
203 | u32 *rx_dma_buf; | |
204 | struct dma_chan *chan_rx; | |
205 | dma_addr_t rx_dma_phys; | |
206 | struct completion cmd_rx_complete; | |
207 | struct dma_async_tx_descriptor *rx_desc; | |
90ba3703 SM |
208 | }; |
209 | ||
349ad66c | 210 | struct fsl_dspi { |
3a11ea66 | 211 | struct spi_controller *ctlr; |
50fcd847 VO |
212 | struct platform_device *pdev; |
213 | ||
214 | struct regmap *regmap; | |
215 | struct regmap *regmap_pushr; | |
216 | int irq; | |
217 | struct clk *clk; | |
218 | ||
219 | struct spi_transfer *cur_transfer; | |
220 | struct spi_message *cur_msg; | |
221 | struct chip_data *cur_chip; | |
862dd2a9 | 222 | size_t progress; |
50fcd847 VO |
223 | size_t len; |
224 | const void *tx; | |
225 | void *rx; | |
50fcd847 | 226 | u16 tx_cmd; |
50fcd847 VO |
227 | const struct fsl_dspi_devtype_data *devtype_data; |
228 | ||
4f5ee75e | 229 | struct completion xfer_done; |
50fcd847 VO |
230 | |
231 | struct fsl_dspi_dma *dma; | |
d59c90a2 | 232 | |
6c1c26ec VO |
233 | int oper_word_size; |
234 | int oper_bits_per_word; | |
235 | ||
d59c90a2 | 236 | int words_in_flight; |
6c1c26ec | 237 | |
671ffde1 VO |
238 | /* |
239 | * Offsets for CMD and TXDATA within SPI_PUSHR when accessed | |
240 | * individually (in XSPI mode) | |
241 | */ | |
242 | int pushr_cmd; | |
243 | int pushr_tx; | |
244 | ||
6c1c26ec VO |
245 | void (*host_to_dev)(struct fsl_dspi *dspi, u32 *txdata); |
246 | void (*dev_to_host)(struct fsl_dspi *dspi, u32 rxdata); | |
349ad66c CF |
247 | }; |
248 | ||
6c1c26ec VO |
249 | static void dspi_native_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) |
250 | { | |
263b81dc AD |
251 | switch (dspi->oper_word_size) { |
252 | case 1: | |
253 | *txdata = *(u8 *)dspi->tx; | |
254 | break; | |
255 | case 2: | |
256 | *txdata = *(u16 *)dspi->tx; | |
257 | break; | |
258 | case 4: | |
259 | *txdata = *(u32 *)dspi->tx; | |
260 | break; | |
261 | } | |
6c1c26ec VO |
262 | dspi->tx += dspi->oper_word_size; |
263 | } | |
264 | ||
265 | static void dspi_native_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | |
266 | { | |
263b81dc AD |
267 | switch (dspi->oper_word_size) { |
268 | case 1: | |
269 | *(u8 *)dspi->rx = rxdata; | |
270 | break; | |
271 | case 2: | |
272 | *(u16 *)dspi->rx = rxdata; | |
273 | break; | |
274 | case 4: | |
275 | *(u32 *)dspi->rx = rxdata; | |
276 | break; | |
277 | } | |
6c1c26ec VO |
278 | dspi->rx += dspi->oper_word_size; |
279 | } | |
280 | ||
281 | static void dspi_8on32_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | |
282 | { | |
283 | *txdata = cpu_to_be32(*(u32 *)dspi->tx); | |
284 | dspi->tx += sizeof(u32); | |
285 | } | |
286 | ||
287 | static void dspi_8on32_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | |
288 | { | |
289 | *(u32 *)dspi->rx = be32_to_cpu(rxdata); | |
290 | dspi->rx += sizeof(u32); | |
291 | } | |
292 | ||
293 | static void dspi_8on16_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | |
294 | { | |
295 | *txdata = cpu_to_be16(*(u16 *)dspi->tx); | |
296 | dspi->tx += sizeof(u16); | |
297 | } | |
298 | ||
299 | static void dspi_8on16_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | |
300 | { | |
301 | *(u16 *)dspi->rx = be16_to_cpu(rxdata); | |
302 | dspi->rx += sizeof(u16); | |
303 | } | |
304 | ||
305 | static void dspi_16on32_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | |
306 | { | |
307 | u16 hi = *(u16 *)dspi->tx; | |
308 | u16 lo = *(u16 *)(dspi->tx + 2); | |
309 | ||
310 | *txdata = (u32)hi << 16 | lo; | |
311 | dspi->tx += sizeof(u32); | |
312 | } | |
313 | ||
314 | static void dspi_16on32_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | |
315 | { | |
316 | u16 hi = rxdata & 0xffff; | |
317 | u16 lo = rxdata >> 16; | |
318 | ||
319 | *(u16 *)dspi->rx = lo; | |
320 | *(u16 *)(dspi->rx + 2) = hi; | |
321 | dspi->rx += sizeof(u32); | |
322 | } | |
323 | ||
8f8303ee VO |
324 | /* |
325 | * Pop one word from the TX buffer for pushing into the | |
326 | * PUSHR register (TX FIFO) | |
327 | */ | |
8fcd151d | 328 | static u32 dspi_pop_tx(struct fsl_dspi *dspi) |
dadcf4ab | 329 | { |
8fcd151d | 330 | u32 txdata = 0; |
dadcf4ab | 331 | |
6c1c26ec VO |
332 | if (dspi->tx) |
333 | dspi->host_to_dev(dspi, &txdata); | |
334 | dspi->len -= dspi->oper_word_size; | |
dadcf4ab EH |
335 | return txdata; |
336 | } | |
ccf7d8ee | 337 | |
8f8303ee | 338 | /* Prepare one TX FIFO entry (txdata plus cmd) */ |
dadcf4ab | 339 | static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi) |
349ad66c | 340 | { |
dadcf4ab | 341 | u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi); |
349ad66c | 342 | |
6230d6ca | 343 | if (spi_controller_is_target(dspi->ctlr)) |
5ce3cc56 LM |
344 | return data; |
345 | ||
dadcf4ab EH |
346 | if (dspi->len > 0) |
347 | cmd |= SPI_PUSHR_CMD_CONT; | |
348 | return cmd << 16 | data; | |
349 | } | |
350 | ||
8f8303ee | 351 | /* Push one word to the RX buffer from the POPR register (RX FIFO) */ |
dadcf4ab EH |
352 | static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata) |
353 | { | |
354 | if (!dspi->rx) | |
355 | return; | |
6c1c26ec | 356 | dspi->dev_to_host(dspi, rxdata); |
349ad66c CF |
357 | } |
358 | ||
90ba3703 SM |
359 | static void dspi_tx_dma_callback(void *arg) |
360 | { | |
361 | struct fsl_dspi *dspi = arg; | |
362 | struct fsl_dspi_dma *dma = dspi->dma; | |
363 | ||
364 | complete(&dma->cmd_tx_complete); | |
365 | } | |
366 | ||
367 | static void dspi_rx_dma_callback(void *arg) | |
368 | { | |
369 | struct fsl_dspi *dspi = arg; | |
370 | struct fsl_dspi_dma *dma = dspi->dma; | |
1eaccf21 | 371 | int i; |
90ba3703 | 372 | |
4779f23d | 373 | if (dspi->rx) { |
a957499b | 374 | for (i = 0; i < dspi->words_in_flight; i++) |
dadcf4ab | 375 | dspi_push_rx(dspi, dspi->dma->rx_dma_buf[i]); |
90ba3703 SM |
376 | } |
377 | ||
378 | complete(&dma->cmd_rx_complete); | |
379 | } | |
380 | ||
381 | static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) | |
382 | { | |
90ba3703 | 383 | struct device *dev = &dspi->pdev->dev; |
d6bdfa6c | 384 | struct fsl_dspi_dma *dma = dspi->dma; |
90ba3703 | 385 | int time_left; |
1eaccf21 | 386 | int i; |
90ba3703 | 387 | |
a957499b | 388 | for (i = 0; i < dspi->words_in_flight; i++) |
dadcf4ab | 389 | dspi->dma->tx_dma_buf[i] = dspi_pop_tx_pushr(dspi); |
90ba3703 | 390 | |
90ba3703 SM |
391 | dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, |
392 | dma->tx_dma_phys, | |
a957499b | 393 | dspi->words_in_flight * |
1eaccf21 SM |
394 | DMA_SLAVE_BUSWIDTH_4_BYTES, |
395 | DMA_MEM_TO_DEV, | |
90ba3703 SM |
396 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
397 | if (!dma->tx_desc) { | |
398 | dev_err(dev, "Not able to get desc for DMA xfer\n"); | |
399 | return -EIO; | |
400 | } | |
401 | ||
402 | dma->tx_desc->callback = dspi_tx_dma_callback; | |
403 | dma->tx_desc->callback_param = dspi; | |
404 | if (dma_submit_error(dmaengine_submit(dma->tx_desc))) { | |
405 | dev_err(dev, "DMA submit failed\n"); | |
406 | return -EINVAL; | |
407 | } | |
408 | ||
409 | dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx, | |
410 | dma->rx_dma_phys, | |
a957499b | 411 | dspi->words_in_flight * |
1eaccf21 SM |
412 | DMA_SLAVE_BUSWIDTH_4_BYTES, |
413 | DMA_DEV_TO_MEM, | |
90ba3703 SM |
414 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
415 | if (!dma->rx_desc) { | |
416 | dev_err(dev, "Not able to get desc for DMA xfer\n"); | |
417 | return -EIO; | |
418 | } | |
419 | ||
420 | dma->rx_desc->callback = dspi_rx_dma_callback; | |
421 | dma->rx_desc->callback_param = dspi; | |
422 | if (dma_submit_error(dmaengine_submit(dma->rx_desc))) { | |
423 | dev_err(dev, "DMA submit failed\n"); | |
424 | return -EINVAL; | |
425 | } | |
426 | ||
427 | reinit_completion(&dspi->dma->cmd_rx_complete); | |
428 | reinit_completion(&dspi->dma->cmd_tx_complete); | |
429 | ||
430 | dma_async_issue_pending(dma->chan_rx); | |
431 | dma_async_issue_pending(dma->chan_tx); | |
432 | ||
6230d6ca | 433 | if (spi_controller_is_target(dspi->ctlr)) { |
5ce3cc56 LM |
434 | wait_for_completion_interruptible(&dspi->dma->cmd_rx_complete); |
435 | return 0; | |
436 | } | |
437 | ||
90ba3703 | 438 | time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete, |
50fcd847 | 439 | DMA_COMPLETION_TIMEOUT); |
90ba3703 SM |
440 | if (time_left == 0) { |
441 | dev_err(dev, "DMA tx timeout\n"); | |
442 | dmaengine_terminate_all(dma->chan_tx); | |
443 | dmaengine_terminate_all(dma->chan_rx); | |
444 | return -ETIMEDOUT; | |
445 | } | |
446 | ||
447 | time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete, | |
50fcd847 | 448 | DMA_COMPLETION_TIMEOUT); |
90ba3703 SM |
449 | if (time_left == 0) { |
450 | dev_err(dev, "DMA rx timeout\n"); | |
451 | dmaengine_terminate_all(dma->chan_tx); | |
452 | dmaengine_terminate_all(dma->chan_rx); | |
453 | return -ETIMEDOUT; | |
454 | } | |
455 | ||
456 | return 0; | |
457 | } | |
458 | ||
a957499b VO |
459 | static void dspi_setup_accel(struct fsl_dspi *dspi); |
460 | ||
90ba3703 SM |
461 | static int dspi_dma_xfer(struct fsl_dspi *dspi) |
462 | { | |
5f8f8035 | 463 | struct spi_message *message = dspi->cur_msg; |
d6bdfa6c | 464 | struct device *dev = &dspi->pdev->dev; |
90ba3703 SM |
465 | int ret = 0; |
466 | ||
a957499b VO |
467 | /* |
468 | * dspi->len gets decremented by dspi_pop_tx_pushr in | |
469 | * dspi_next_xfer_dma_submit | |
470 | */ | |
471 | while (dspi->len) { | |
472 | /* Figure out operational bits-per-word for this chunk */ | |
473 | dspi_setup_accel(dspi); | |
474 | ||
475 | dspi->words_in_flight = dspi->len / dspi->oper_word_size; | |
476 | if (dspi->words_in_flight > dspi->devtype_data->fifo_size) | |
477 | dspi->words_in_flight = dspi->devtype_data->fifo_size; | |
478 | ||
479 | message->actual_length += dspi->words_in_flight * | |
480 | dspi->oper_word_size; | |
90ba3703 SM |
481 | |
482 | ret = dspi_next_xfer_dma_submit(dspi); | |
483 | if (ret) { | |
484 | dev_err(dev, "DMA transfer failed\n"); | |
a957499b | 485 | break; |
90ba3703 SM |
486 | } |
487 | } | |
488 | ||
90ba3703 SM |
489 | return ret; |
490 | } | |
491 | ||
492 | static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) | |
493 | { | |
a957499b | 494 | int dma_bufsize = dspi->devtype_data->fifo_size * 2; |
90ba3703 | 495 | struct device *dev = &dspi->pdev->dev; |
d6bdfa6c VO |
496 | struct dma_slave_config cfg; |
497 | struct fsl_dspi_dma *dma; | |
90ba3703 SM |
498 | int ret; |
499 | ||
500 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); | |
501 | if (!dma) | |
502 | return -ENOMEM; | |
503 | ||
b5756b77 | 504 | dma->chan_rx = dma_request_chan(dev, "rx"); |
51b8e79c | 505 | if (IS_ERR(dma->chan_rx)) |
506 | return dev_err_probe(dev, PTR_ERR(dma->chan_rx), "rx dma channel not available\n"); | |
90ba3703 | 507 | |
b5756b77 PU |
508 | dma->chan_tx = dma_request_chan(dev, "tx"); |
509 | if (IS_ERR(dma->chan_tx)) { | |
51b8e79c | 510 | ret = dev_err_probe(dev, PTR_ERR(dma->chan_tx), "tx dma channel not available\n"); |
90ba3703 SM |
511 | goto err_tx_channel; |
512 | } | |
513 | ||
22ee9de1 | 514 | dma->tx_dma_buf = dma_alloc_coherent(dma->chan_tx->device->dev, |
a957499b VO |
515 | dma_bufsize, &dma->tx_dma_phys, |
516 | GFP_KERNEL); | |
90ba3703 SM |
517 | if (!dma->tx_dma_buf) { |
518 | ret = -ENOMEM; | |
519 | goto err_tx_dma_buf; | |
520 | } | |
521 | ||
22ee9de1 | 522 | dma->rx_dma_buf = dma_alloc_coherent(dma->chan_rx->device->dev, |
a957499b VO |
523 | dma_bufsize, &dma->rx_dma_phys, |
524 | GFP_KERNEL); | |
90ba3703 SM |
525 | if (!dma->rx_dma_buf) { |
526 | ret = -ENOMEM; | |
527 | goto err_rx_dma_buf; | |
528 | } | |
529 | ||
209ab223 | 530 | memset(&cfg, 0, sizeof(cfg)); |
90ba3703 SM |
531 | cfg.src_addr = phy_addr + SPI_POPR; |
532 | cfg.dst_addr = phy_addr + SPI_PUSHR; | |
533 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | |
534 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | |
535 | cfg.src_maxburst = 1; | |
536 | cfg.dst_maxburst = 1; | |
537 | ||
538 | cfg.direction = DMA_DEV_TO_MEM; | |
539 | ret = dmaengine_slave_config(dma->chan_rx, &cfg); | |
540 | if (ret) { | |
51b8e79c | 541 | dev_err_probe(dev, ret, "can't configure rx dma channel\n"); |
90ba3703 SM |
542 | goto err_slave_config; |
543 | } | |
544 | ||
545 | cfg.direction = DMA_MEM_TO_DEV; | |
546 | ret = dmaengine_slave_config(dma->chan_tx, &cfg); | |
547 | if (ret) { | |
51b8e79c | 548 | dev_err_probe(dev, ret, "can't configure tx dma channel\n"); |
90ba3703 SM |
549 | goto err_slave_config; |
550 | } | |
551 | ||
552 | dspi->dma = dma; | |
553 | init_completion(&dma->cmd_tx_complete); | |
554 | init_completion(&dma->cmd_rx_complete); | |
555 | ||
556 | return 0; | |
557 | ||
558 | err_slave_config: | |
22ee9de1 | 559 | dma_free_coherent(dma->chan_rx->device->dev, |
a957499b | 560 | dma_bufsize, dma->rx_dma_buf, dma->rx_dma_phys); |
90ba3703 | 561 | err_rx_dma_buf: |
22ee9de1 | 562 | dma_free_coherent(dma->chan_tx->device->dev, |
a957499b | 563 | dma_bufsize, dma->tx_dma_buf, dma->tx_dma_phys); |
90ba3703 SM |
564 | err_tx_dma_buf: |
565 | dma_release_channel(dma->chan_tx); | |
566 | err_tx_channel: | |
567 | dma_release_channel(dma->chan_rx); | |
568 | ||
569 | devm_kfree(dev, dma); | |
570 | dspi->dma = NULL; | |
571 | ||
572 | return ret; | |
573 | } | |
574 | ||
575 | static void dspi_release_dma(struct fsl_dspi *dspi) | |
576 | { | |
a957499b | 577 | int dma_bufsize = dspi->devtype_data->fifo_size * 2; |
90ba3703 | 578 | struct fsl_dspi_dma *dma = dspi->dma; |
90ba3703 | 579 | |
abbd0ef1 VO |
580 | if (!dma) |
581 | return; | |
90ba3703 | 582 | |
abbd0ef1 | 583 | if (dma->chan_tx) { |
03fe7aaf KK |
584 | dma_free_coherent(dma->chan_tx->device->dev, dma_bufsize, |
585 | dma->tx_dma_buf, dma->tx_dma_phys); | |
abbd0ef1 VO |
586 | dma_release_channel(dma->chan_tx); |
587 | } | |
588 | ||
589 | if (dma->chan_rx) { | |
03fe7aaf KK |
590 | dma_free_coherent(dma->chan_rx->device->dev, dma_bufsize, |
591 | dma->rx_dma_buf, dma->rx_dma_phys); | |
abbd0ef1 | 592 | dma_release_channel(dma->chan_rx); |
90ba3703 SM |
593 | } |
594 | } | |
595 | ||
349ad66c | 596 | static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, |
50fcd847 | 597 | unsigned long clkrate) |
349ad66c CF |
598 | { |
599 | /* Valid baud rate pre-scaler values */ | |
600 | int pbr_tbl[4] = {2, 3, 5, 7}; | |
601 | int brs[16] = { 2, 4, 6, 8, | |
50fcd847 VO |
602 | 16, 32, 64, 128, |
603 | 256, 512, 1024, 2048, | |
604 | 4096, 8192, 16384, 32768 }; | |
6fd63087 AB |
605 | int scale_needed, scale, minscale = INT_MAX; |
606 | int i, j; | |
607 | ||
608 | scale_needed = clkrate / speed_hz; | |
e689d6df AB |
609 | if (clkrate % speed_hz) |
610 | scale_needed++; | |
6fd63087 AB |
611 | |
612 | for (i = 0; i < ARRAY_SIZE(brs); i++) | |
613 | for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) { | |
614 | scale = brs[i] * pbr_tbl[j]; | |
615 | if (scale >= scale_needed) { | |
616 | if (scale < minscale) { | |
617 | minscale = scale; | |
618 | *br = i; | |
619 | *pbr = j; | |
620 | } | |
621 | break; | |
349ad66c CF |
622 | } |
623 | } | |
349ad66c | 624 | |
6fd63087 AB |
625 | if (minscale == INT_MAX) { |
626 | pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld, we use the max prescaler value.\n", | |
627 | speed_hz, clkrate); | |
628 | *pbr = ARRAY_SIZE(pbr_tbl) - 1; | |
629 | *br = ARRAY_SIZE(brs) - 1; | |
630 | } | |
349ad66c | 631 | } |
349ad66c | 632 | |
95bf15f3 | 633 | static void ns_delay_scale(char *psc, char *sc, int delay_ns, |
50fcd847 | 634 | unsigned long clkrate) |
95bf15f3 | 635 | { |
95bf15f3 | 636 | int scale_needed, scale, minscale = INT_MAX; |
d6bdfa6c | 637 | int pscale_tbl[4] = {1, 3, 5, 7}; |
95bf15f3 | 638 | u32 remainder; |
d6bdfa6c | 639 | int i, j; |
95bf15f3 AB |
640 | |
641 | scale_needed = div_u64_rem((u64)delay_ns * clkrate, NSEC_PER_SEC, | |
50fcd847 | 642 | &remainder); |
95bf15f3 AB |
643 | if (remainder) |
644 | scale_needed++; | |
645 | ||
646 | for (i = 0; i < ARRAY_SIZE(pscale_tbl); i++) | |
647 | for (j = 0; j <= SPI_CTAR_SCALE_BITS; j++) { | |
648 | scale = pscale_tbl[i] * (2 << j); | |
649 | if (scale >= scale_needed) { | |
650 | if (scale < minscale) { | |
651 | minscale = scale; | |
652 | *psc = i; | |
653 | *sc = j; | |
654 | } | |
655 | break; | |
349ad66c CF |
656 | } |
657 | } | |
658 | ||
95bf15f3 AB |
659 | if (minscale == INT_MAX) { |
660 | pr_warn("Cannot find correct scale values for %dns delay at clkrate %ld, using max prescaler value", | |
661 | delay_ns, clkrate); | |
662 | *psc = ARRAY_SIZE(pscale_tbl) - 1; | |
663 | *sc = SPI_CTAR_SCALE_BITS; | |
664 | } | |
349ad66c CF |
665 | } |
666 | ||
ea93ed4c | 667 | static void dspi_pushr_cmd_write(struct fsl_dspi *dspi, u16 cmd) |
8fcd151d | 668 | { |
d59c90a2 VO |
669 | /* |
670 | * The only time when the PCS doesn't need continuation after this word | |
671 | * is when it's last. We need to look ahead, because we actually call | |
672 | * dspi_pop_tx (the function that decrements dspi->len) _after_ | |
673 | * dspi_pushr_cmd_write with XSPI mode. As for how much in advance? One | |
674 | * word is enough. If there's more to transmit than that, | |
675 | * dspi_xspi_write will know to split the FIFO writes in 2, and | |
676 | * generate a new PUSHR command with the final word that will have PCS | |
677 | * deasserted (not continued) here. | |
678 | */ | |
6c1c26ec | 679 | if (dspi->len > dspi->oper_word_size) |
8fcd151d | 680 | cmd |= SPI_PUSHR_CMD_CONT; |
671ffde1 | 681 | regmap_write(dspi->regmap_pushr, dspi->pushr_cmd, cmd); |
8fcd151d EH |
682 | } |
683 | ||
547248fb | 684 | static void dspi_pushr_txdata_write(struct fsl_dspi *dspi, u16 txdata) |
8fcd151d | 685 | { |
671ffde1 | 686 | regmap_write(dspi->regmap_pushr, dspi->pushr_tx, txdata); |
8fcd151d EH |
687 | } |
688 | ||
0dedf901 | 689 | static void dspi_xspi_fifo_write(struct fsl_dspi *dspi, int num_words) |
d1f4a38c | 690 | { |
0dedf901 | 691 | int num_bytes = num_words * dspi->oper_word_size; |
ea93ed4c | 692 | u16 tx_cmd = dspi->tx_cmd; |
8fcd151d | 693 | |
0dedf901 VO |
694 | /* |
695 | * If the PCS needs to de-assert (i.e. we're at the end of the buffer | |
696 | * and cs_change does not want the PCS to stay on), then we need a new | |
697 | * PUSHR command, since this one (for the body of the buffer) | |
698 | * necessarily has the CONT bit set. | |
699 | * So send one word less during this go, to force a split and a command | |
700 | * with a single word next time, when CONT will be unset. | |
701 | */ | |
702 | if (!(dspi->tx_cmd & SPI_PUSHR_CMD_CONT) && num_bytes == dspi->len) | |
ea93ed4c VO |
703 | tx_cmd |= SPI_PUSHR_CMD_EOQ; |
704 | ||
6c1c26ec | 705 | /* Update CTARE */ |
d59c90a2 | 706 | regmap_write(dspi->regmap, SPI_CTARE(0), |
6c1c26ec | 707 | SPI_FRAME_EBITS(dspi->oper_bits_per_word) | |
0dedf901 | 708 | SPI_CTARE_DTCP(num_words)); |
8fcd151d | 709 | |
d59c90a2 VO |
710 | /* |
711 | * Write the CMD FIFO entry first, and then the two | |
712 | * corresponding TX FIFO entries (or one...). | |
713 | */ | |
ea93ed4c | 714 | dspi_pushr_cmd_write(dspi, tx_cmd); |
d59c90a2 VO |
715 | |
716 | /* Fill TX FIFO with as many transfers as possible */ | |
0dedf901 | 717 | while (num_words--) { |
8fcd151d EH |
718 | u32 data = dspi_pop_tx(dspi); |
719 | ||
547248fb | 720 | dspi_pushr_txdata_write(dspi, data & 0xFFFF); |
6c1c26ec | 721 | if (dspi->oper_bits_per_word > 16) |
d59c90a2 | 722 | dspi_pushr_txdata_write(dspi, data >> 16); |
8fcd151d | 723 | } |
d1f4a38c | 724 | } |
349ad66c | 725 | |
d59c90a2 | 726 | static u32 dspi_popr_read(struct fsl_dspi *dspi) |
d1f4a38c | 727 | { |
d59c90a2 | 728 | u32 rxdata = 0; |
d1f4a38c | 729 | |
d59c90a2 VO |
730 | regmap_read(dspi->regmap, SPI_POPR, &rxdata); |
731 | return rxdata; | |
732 | } | |
d1f4a38c | 733 | |
d59c90a2 VO |
734 | static void dspi_fifo_read(struct fsl_dspi *dspi) |
735 | { | |
0dedf901 VO |
736 | int num_fifo_entries = dspi->words_in_flight; |
737 | ||
20617530 | 738 | /* Read one FIFO entry and push to rx buffer */ |
0dedf901 | 739 | while (num_fifo_entries--) |
547248fb | 740 | dspi_push_rx(dspi, dspi_popr_read(dspi)); |
349ad66c CF |
741 | } |
742 | ||
6c1c26ec | 743 | static void dspi_setup_accel(struct fsl_dspi *dspi) |
a63af99f | 744 | { |
6c1c26ec | 745 | struct spi_transfer *xfer = dspi->cur_transfer; |
6365504d | 746 | bool odd = !!(dspi->len & 1); |
12fb61a9 | 747 | |
6365504d VO |
748 | /* No accel for frames not multiple of 8 bits at the moment */ |
749 | if (xfer->bits_per_word % 8) | |
750 | goto no_accel; | |
d6b71dfa | 751 | |
6365504d VO |
752 | if (!odd && dspi->len <= dspi->devtype_data->fifo_size * 2) { |
753 | dspi->oper_bits_per_word = 16; | |
754 | } else if (odd && dspi->len <= dspi->devtype_data->fifo_size) { | |
755 | dspi->oper_bits_per_word = 8; | |
756 | } else { | |
757 | /* Start off with maximum supported by hardware */ | |
758 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) | |
759 | dspi->oper_bits_per_word = 32; | |
760 | else | |
761 | dspi->oper_bits_per_word = 16; | |
762 | ||
763 | /* | |
764 | * And go down only if the buffer can't be sent with | |
765 | * words this big | |
766 | */ | |
767 | do { | |
768 | if (dspi->len >= DIV_ROUND_UP(dspi->oper_bits_per_word, 8)) | |
769 | break; | |
6c1c26ec | 770 | |
6365504d VO |
771 | dspi->oper_bits_per_word /= 2; |
772 | } while (dspi->oper_bits_per_word > 8); | |
773 | } | |
6c1c26ec VO |
774 | |
775 | if (xfer->bits_per_word == 8 && dspi->oper_bits_per_word == 32) { | |
776 | dspi->dev_to_host = dspi_8on32_dev_to_host; | |
777 | dspi->host_to_dev = dspi_8on32_host_to_dev; | |
778 | } else if (xfer->bits_per_word == 8 && dspi->oper_bits_per_word == 16) { | |
779 | dspi->dev_to_host = dspi_8on16_dev_to_host; | |
780 | dspi->host_to_dev = dspi_8on16_host_to_dev; | |
781 | } else if (xfer->bits_per_word == 16 && dspi->oper_bits_per_word == 32) { | |
782 | dspi->dev_to_host = dspi_16on32_dev_to_host; | |
783 | dspi->host_to_dev = dspi_16on32_host_to_dev; | |
784 | } else { | |
6365504d | 785 | no_accel: |
6c1c26ec VO |
786 | dspi->dev_to_host = dspi_native_dev_to_host; |
787 | dspi->host_to_dev = dspi_native_host_to_dev; | |
788 | dspi->oper_bits_per_word = xfer->bits_per_word; | |
789 | } | |
790 | ||
791 | dspi->oper_word_size = DIV_ROUND_UP(dspi->oper_bits_per_word, 8); | |
792 | ||
793 | /* | |
20c05a05 | 794 | * Update CTAR here (code is common for XSPI and DMA modes). |
6c1c26ec VO |
795 | * We will update CTARE in the portion specific to XSPI, when we |
796 | * also know the preload value (DTCP). | |
12fb61a9 | 797 | */ |
6c1c26ec VO |
798 | regmap_write(dspi->regmap, SPI_CTAR(0), |
799 | dspi->cur_chip->ctar_val | | |
800 | SPI_FRAME_BITS(dspi->oper_bits_per_word)); | |
801 | } | |
802 | ||
d59c90a2 VO |
803 | static void dspi_fifo_write(struct fsl_dspi *dspi) |
804 | { | |
0dedf901 | 805 | int num_fifo_entries = dspi->devtype_data->fifo_size; |
e9bac900 VO |
806 | struct spi_transfer *xfer = dspi->cur_transfer; |
807 | struct spi_message *msg = dspi->cur_msg; | |
0dedf901 | 808 | int num_words, num_bytes; |
e9bac900 | 809 | |
6c1c26ec VO |
810 | dspi_setup_accel(dspi); |
811 | ||
0dedf901 VO |
812 | /* In XSPI mode each 32-bit word occupies 2 TX FIFO entries */ |
813 | if (dspi->oper_word_size == 4) | |
814 | num_fifo_entries /= 2; | |
815 | ||
816 | /* | |
817 | * Integer division intentionally trims off odd (or non-multiple of 4) | |
818 | * numbers of bytes at the end of the buffer, which will be sent next | |
819 | * time using a smaller oper_word_size. | |
820 | */ | |
821 | num_words = dspi->len / dspi->oper_word_size; | |
822 | if (num_words > num_fifo_entries) | |
823 | num_words = num_fifo_entries; | |
824 | ||
825 | /* Update total number of bytes that were transferred */ | |
826 | num_bytes = num_words * dspi->oper_word_size; | |
827 | msg->actual_length += num_bytes; | |
828 | dspi->progress += num_bytes / DIV_ROUND_UP(xfer->bits_per_word, 8); | |
829 | ||
830 | /* | |
831 | * Update shared variable for use in the next interrupt (both in | |
832 | * dspi_fifo_read and in dspi_fifo_write). | |
833 | */ | |
834 | dspi->words_in_flight = num_words; | |
835 | ||
e9bac900 VO |
836 | spi_take_timestamp_pre(dspi->ctlr, xfer, dspi->progress, !dspi->irq); |
837 | ||
20c05a05 | 838 | dspi_xspi_fifo_write(dspi, num_words); |
0dedf901 VO |
839 | /* |
840 | * Everything after this point is in a potential race with the next | |
841 | * interrupt, so we must never use dspi->words_in_flight again since it | |
842 | * might already be modified by the next dspi_fifo_write. | |
843 | */ | |
12fb61a9 | 844 | |
d6b71dfa | 845 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, |
862dd2a9 | 846 | dspi->progress, !dspi->irq); |
e9bac900 | 847 | } |
d6b71dfa | 848 | |
e9bac900 VO |
849 | static int dspi_rxtx(struct fsl_dspi *dspi) |
850 | { | |
d59c90a2 | 851 | dspi_fifo_read(dspi); |
a63af99f | 852 | |
c55be305 VO |
853 | if (!dspi->len) |
854 | /* Success! */ | |
855 | return 0; | |
a63af99f | 856 | |
d59c90a2 | 857 | dspi_fifo_write(dspi); |
a63af99f | 858 | |
c55be305 VO |
859 | return -EINPROGRESS; |
860 | } | |
861 | ||
862 | static int dspi_poll(struct fsl_dspi *dspi) | |
863 | { | |
864 | int tries = 1000; | |
865 | u32 spi_sr; | |
866 | ||
867 | do { | |
868 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | |
869 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | |
870 | ||
20c05a05 | 871 | if (spi_sr & SPI_SR_CMDTCF) |
c55be305 VO |
872 | break; |
873 | } while (--tries); | |
874 | ||
875 | if (!tries) | |
876 | return -ETIMEDOUT; | |
877 | ||
878 | return dspi_rxtx(dspi); | |
879 | } | |
880 | ||
881 | static irqreturn_t dspi_interrupt(int irq, void *dev_id) | |
882 | { | |
883 | struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; | |
884 | u32 spi_sr; | |
885 | ||
886 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | |
887 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | |
888 | ||
20c05a05 | 889 | if (!(spi_sr & SPI_SR_CMDTCF)) |
c55be305 VO |
890 | return IRQ_NONE; |
891 | ||
4f5ee75e VO |
892 | if (dspi_rxtx(dspi) == 0) |
893 | complete(&dspi->xfer_done); | |
c55be305 | 894 | |
a63af99f VO |
895 | return IRQ_HANDLED; |
896 | } | |
897 | ||
84b60f2b RPNO |
898 | static void dspi_assert_cs(struct spi_device *spi, bool *cs) |
899 | { | |
9e264f3f | 900 | if (!spi_get_csgpiod(spi, 0) || *cs) |
84b60f2b RPNO |
901 | return; |
902 | ||
9e264f3f | 903 | gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), true); |
84b60f2b RPNO |
904 | *cs = true; |
905 | } | |
906 | ||
907 | static void dspi_deassert_cs(struct spi_device *spi, bool *cs) | |
908 | { | |
9e264f3f | 909 | if (!spi_get_csgpiod(spi, 0) || !*cs) |
84b60f2b RPNO |
910 | return; |
911 | ||
9e264f3f | 912 | gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), false); |
84b60f2b RPNO |
913 | *cs = false; |
914 | } | |
915 | ||
3a11ea66 | 916 | static int dspi_transfer_one_message(struct spi_controller *ctlr, |
50fcd847 | 917 | struct spi_message *message) |
349ad66c | 918 | { |
3a11ea66 | 919 | struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); |
9298bc72 CF |
920 | struct spi_device *spi = message->spi; |
921 | struct spi_transfer *transfer; | |
84b60f2b | 922 | bool cs = false; |
9298bc72 | 923 | int status = 0; |
d1f4a38c | 924 | |
9298bc72 CF |
925 | message->actual_length = 0; |
926 | ||
927 | list_for_each_entry(transfer, &message->transfers, transfer_list) { | |
928 | dspi->cur_transfer = transfer; | |
929 | dspi->cur_msg = message; | |
930 | dspi->cur_chip = spi_get_ctldata(spi); | |
84b60f2b RPNO |
931 | |
932 | dspi_assert_cs(spi, &cs); | |
933 | ||
9e1dc9bd | 934 | /* Prepare command word for CMD FIFO */ |
84b60f2b | 935 | dspi->tx_cmd = SPI_PUSHR_CMD_CTAS(0); |
9e264f3f AKMA |
936 | if (!spi_get_csgpiod(spi, 0)) |
937 | dspi->tx_cmd |= SPI_PUSHR_CMD_PCS(spi_get_chipselect(spi, 0)); | |
84b60f2b | 938 | |
92dc20d8 | 939 | if (list_is_last(&dspi->cur_transfer->transfer_list, |
9e1dc9bd EH |
940 | &dspi->cur_msg->transfers)) { |
941 | /* Leave PCS activated after last transfer when | |
942 | * cs_change is set. | |
943 | */ | |
944 | if (transfer->cs_change) | |
945 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | |
946 | } else { | |
947 | /* Keep PCS active between transfers in same message | |
948 | * when cs_change is not set, and de-activate PCS | |
949 | * between transfers in the same message when | |
950 | * cs_change is set. | |
951 | */ | |
952 | if (!transfer->cs_change) | |
953 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | |
954 | } | |
955 | ||
dadcf4ab | 956 | dspi->tx = transfer->tx_buf; |
9298bc72 | 957 | dspi->rx = transfer->rx_buf; |
9298bc72 | 958 | dspi->len = transfer->len; |
862dd2a9 | 959 | dspi->progress = 0; |
9298bc72 | 960 | |
9298bc72 | 961 | regmap_update_bits(dspi->regmap, SPI_MCR, |
d87e08f1 EH |
962 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, |
963 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | |
349ad66c | 964 | |
d6b71dfa | 965 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
862dd2a9 | 966 | dspi->progress, !dspi->irq); |
d6b71dfa | 967 | |
5b342c5a | 968 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
90ba3703 | 969 | status = dspi_dma_xfer(dspi); |
5b342c5a VO |
970 | } else { |
971 | dspi_fifo_write(dspi); | |
1acbdeb9 | 972 | |
826b3a6a VO |
973 | if (dspi->irq) { |
974 | wait_for_completion(&dspi->xfer_done); | |
975 | reinit_completion(&dspi->xfer_done); | |
976 | } else { | |
977 | do { | |
978 | status = dspi_poll(dspi); | |
979 | } while (status == -EINPROGRESS); | |
980 | } | |
98114304 | 981 | } |
5b342c5a VO |
982 | if (status) |
983 | break; | |
349ad66c | 984 | |
e74dc5c7 | 985 | spi_transfer_delay_exec(transfer); |
84b60f2b RPNO |
986 | |
987 | if (!(dspi->tx_cmd & SPI_PUSHR_CMD_CONT)) | |
988 | dspi_deassert_cs(spi, &cs); | |
349ad66c CF |
989 | } |
990 | ||
9298bc72 | 991 | message->status = status; |
3a11ea66 | 992 | spi_finalize_current_message(ctlr); |
9298bc72 CF |
993 | |
994 | return status; | |
349ad66c CF |
995 | } |
996 | ||
9298bc72 | 997 | static int dspi_setup(struct spi_device *spi) |
349ad66c | 998 | { |
3a11ea66 | 999 | struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller); |
c5c31fb7 | 1000 | u32 period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->max_speed_hz); |
95bf15f3 | 1001 | unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0; |
c5c31fb7 | 1002 | u32 quarter_period_ns = DIV_ROUND_UP(period_ns, 4); |
d6bdfa6c VO |
1003 | u32 cs_sck_delay = 0, sck_cs_delay = 0; |
1004 | struct fsl_dspi_platform_data *pdata; | |
dadcf4ab | 1005 | unsigned char pasc = 0, asc = 0; |
d6bdfa6c | 1006 | struct chip_data *chip; |
95bf15f3 | 1007 | unsigned long clkrate; |
84b60f2b | 1008 | bool cs = true; |
52e78777 | 1009 | int val; |
349ad66c CF |
1010 | |
1011 | /* Only alloc on first setup */ | |
1012 | chip = spi_get_ctldata(spi); | |
1013 | if (chip == NULL) { | |
973fbce6 | 1014 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); |
349ad66c CF |
1015 | if (!chip) |
1016 | return -ENOMEM; | |
1017 | } | |
1018 | ||
ec7ed770 | 1019 | pdata = dev_get_platdata(&dspi->pdev->dev); |
95bf15f3 | 1020 | |
ec7ed770 | 1021 | if (!pdata) { |
52e78777 FL |
1022 | val = spi_delay_to_ns(&spi->cs_setup, NULL); |
1023 | cs_sck_delay = val >= 0 ? val : 0; | |
1024 | if (!cs_sck_delay) | |
1025 | of_property_read_u32(spi->dev.of_node, | |
1026 | "fsl,spi-cs-sck-delay", | |
1027 | &cs_sck_delay); | |
1028 | ||
1029 | val = spi_delay_to_ns(&spi->cs_hold, NULL); | |
1030 | sck_cs_delay = val >= 0 ? val : 0; | |
1031 | if (!sck_cs_delay) | |
1032 | of_property_read_u32(spi->dev.of_node, | |
1033 | "fsl,spi-sck-cs-delay", | |
1034 | &sck_cs_delay); | |
ec7ed770 AD |
1035 | } else { |
1036 | cs_sck_delay = pdata->cs_sck_delay; | |
1037 | sck_cs_delay = pdata->sck_cs_delay; | |
1038 | } | |
95bf15f3 | 1039 | |
c5c31fb7 VO |
1040 | /* Since tCSC and tASC apply to continuous transfers too, avoid SCK |
1041 | * glitches of half a cycle by never allowing tCSC + tASC to go below | |
1042 | * half a SCK period. | |
1043 | */ | |
1044 | if (cs_sck_delay < quarter_period_ns) | |
1045 | cs_sck_delay = quarter_period_ns; | |
1046 | if (sck_cs_delay < quarter_period_ns) | |
1047 | sck_cs_delay = quarter_period_ns; | |
1048 | ||
1049 | dev_dbg(&spi->dev, | |
1050 | "DSPI controller timing params: CS-to-SCK delay %u ns, SCK-to-CS delay %u ns\n", | |
1051 | cs_sck_delay, sck_cs_delay); | |
1052 | ||
95bf15f3 AB |
1053 | clkrate = clk_get_rate(dspi->clk); |
1054 | hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate); | |
1055 | ||
1056 | /* Set PCS to SCK delay scale values */ | |
1057 | ns_delay_scale(&pcssck, &cssck, cs_sck_delay, clkrate); | |
1058 | ||
1059 | /* Set After SCK delay scale values */ | |
1060 | ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate); | |
349ad66c | 1061 | |
06d5dd29 VO |
1062 | chip->ctar_val = 0; |
1063 | if (spi->mode & SPI_CPOL) | |
1064 | chip->ctar_val |= SPI_CTAR_CPOL; | |
1065 | if (spi->mode & SPI_CPHA) | |
1066 | chip->ctar_val |= SPI_CTAR_CPHA; | |
5ce3cc56 | 1067 | |
6230d6ca | 1068 | if (!spi_controller_is_target(dspi->ctlr)) { |
06d5dd29 VO |
1069 | chip->ctar_val |= SPI_CTAR_PCSSCK(pcssck) | |
1070 | SPI_CTAR_CSSCK(cssck) | | |
1071 | SPI_CTAR_PASC(pasc) | | |
1072 | SPI_CTAR_ASC(asc) | | |
1073 | SPI_CTAR_PBR(pbr) | | |
1074 | SPI_CTAR_BR(br); | |
1075 | ||
1076 | if (spi->mode & SPI_LSB_FIRST) | |
1077 | chip->ctar_val |= SPI_CTAR_LSBFE; | |
5ce3cc56 | 1078 | } |
349ad66c | 1079 | |
9e264f3f | 1080 | gpiod_direction_output(spi_get_csgpiod(spi, 0), false); |
84b60f2b RPNO |
1081 | dspi_deassert_cs(spi, &cs); |
1082 | ||
349ad66c CF |
1083 | spi_set_ctldata(spi, chip); |
1084 | ||
1085 | return 0; | |
1086 | } | |
1087 | ||
973fbce6 BD |
1088 | static void dspi_cleanup(struct spi_device *spi) |
1089 | { | |
9c8400e3 | 1090 | struct chip_data *chip = spi_get_ctldata(spi); |
973fbce6 BD |
1091 | |
1092 | dev_dbg(&spi->dev, "spi_device %u.%u cleanup\n", | |
9e264f3f | 1093 | spi->controller->bus_num, spi_get_chipselect(spi, 0)); |
973fbce6 BD |
1094 | |
1095 | kfree(chip); | |
1096 | } | |
1097 | ||
790d1902 | 1098 | static const struct of_device_id fsl_dspi_dt_ids[] = { |
d3505401 VO |
1099 | { |
1100 | .compatible = "fsl,vf610-dspi", | |
1101 | .data = &devtype_data[VF610], | |
1102 | }, { | |
1103 | .compatible = "fsl,ls1021a-v1.0-dspi", | |
1104 | .data = &devtype_data[LS1021A], | |
1105 | }, { | |
1106 | .compatible = "fsl,ls1012a-dspi", | |
1107 | .data = &devtype_data[LS1012A], | |
138f56ef VO |
1108 | }, { |
1109 | .compatible = "fsl,ls1028a-dspi", | |
1110 | .data = &devtype_data[LS1028A], | |
d3505401 VO |
1111 | }, { |
1112 | .compatible = "fsl,ls1043a-dspi", | |
1113 | .data = &devtype_data[LS1043A], | |
1114 | }, { | |
1115 | .compatible = "fsl,ls1046a-dspi", | |
1116 | .data = &devtype_data[LS1046A], | |
1117 | }, { | |
1118 | .compatible = "fsl,ls2080a-dspi", | |
1119 | .data = &devtype_data[LS2080A], | |
1120 | }, { | |
1121 | .compatible = "fsl,ls2085a-dspi", | |
1122 | .data = &devtype_data[LS2085A], | |
1123 | }, { | |
1124 | .compatible = "fsl,lx2160a-dspi", | |
1125 | .data = &devtype_data[LX2160A], | |
1126 | }, | |
349ad66c CF |
1127 | { /* sentinel */ } |
1128 | }; | |
1129 | MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); | |
1130 | ||
1131 | #ifdef CONFIG_PM_SLEEP | |
1132 | static int dspi_suspend(struct device *dev) | |
1133 | { | |
9bd77a9c | 1134 | struct fsl_dspi *dspi = dev_get_drvdata(dev); |
349ad66c | 1135 | |
3d87b613 KK |
1136 | if (dspi->irq) |
1137 | disable_irq(dspi->irq); | |
9bd77a9c | 1138 | spi_controller_suspend(dspi->ctlr); |
349ad66c CF |
1139 | clk_disable_unprepare(dspi->clk); |
1140 | ||
432a17d7 MK |
1141 | pinctrl_pm_select_sleep_state(dev); |
1142 | ||
349ad66c CF |
1143 | return 0; |
1144 | } | |
1145 | ||
1146 | static int dspi_resume(struct device *dev) | |
1147 | { | |
9bd77a9c | 1148 | struct fsl_dspi *dspi = dev_get_drvdata(dev); |
1c5ea2b4 | 1149 | int ret; |
349ad66c | 1150 | |
432a17d7 MK |
1151 | pinctrl_pm_select_default_state(dev); |
1152 | ||
1c5ea2b4 FE |
1153 | ret = clk_prepare_enable(dspi->clk); |
1154 | if (ret) | |
1155 | return ret; | |
9bd77a9c | 1156 | spi_controller_resume(dspi->ctlr); |
3d87b613 KK |
1157 | if (dspi->irq) |
1158 | enable_irq(dspi->irq); | |
349ad66c CF |
1159 | |
1160 | return 0; | |
1161 | } | |
1162 | #endif /* CONFIG_PM_SLEEP */ | |
1163 | ||
ba811add | 1164 | static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); |
349ad66c | 1165 | |
8570043e EH |
1166 | static const struct regmap_range dspi_volatile_ranges[] = { |
1167 | regmap_reg_range(SPI_MCR, SPI_TCR), | |
1168 | regmap_reg_range(SPI_SR, SPI_SR), | |
1169 | regmap_reg_range(SPI_PUSHR, SPI_RXFR3), | |
1170 | }; | |
1171 | ||
1172 | static const struct regmap_access_table dspi_volatile_table = { | |
50fcd847 VO |
1173 | .yes_ranges = dspi_volatile_ranges, |
1174 | .n_yes_ranges = ARRAY_SIZE(dspi_volatile_ranges), | |
8570043e EH |
1175 | }; |
1176 | ||
409851c3 | 1177 | static const struct regmap_config dspi_regmap_config = { |
50fcd847 VO |
1178 | .reg_bits = 32, |
1179 | .val_bits = 32, | |
1180 | .reg_stride = 4, | |
1181 | .max_register = 0x88, | |
1182 | .volatile_table = &dspi_volatile_table, | |
349ad66c CF |
1183 | }; |
1184 | ||
58ba07ec EH |
1185 | static const struct regmap_range dspi_xspi_volatile_ranges[] = { |
1186 | regmap_reg_range(SPI_MCR, SPI_TCR), | |
1187 | regmap_reg_range(SPI_SR, SPI_SR), | |
1188 | regmap_reg_range(SPI_PUSHR, SPI_RXFR3), | |
1189 | regmap_reg_range(SPI_SREX, SPI_SREX), | |
1190 | }; | |
1191 | ||
1192 | static const struct regmap_access_table dspi_xspi_volatile_table = { | |
50fcd847 VO |
1193 | .yes_ranges = dspi_xspi_volatile_ranges, |
1194 | .n_yes_ranges = ARRAY_SIZE(dspi_xspi_volatile_ranges), | |
58ba07ec EH |
1195 | }; |
1196 | ||
1197 | static const struct regmap_config dspi_xspi_regmap_config[] = { | |
1198 | { | |
50fcd847 VO |
1199 | .reg_bits = 32, |
1200 | .val_bits = 32, | |
1201 | .reg_stride = 4, | |
1202 | .max_register = 0x13c, | |
1203 | .volatile_table = &dspi_xspi_volatile_table, | |
58ba07ec EH |
1204 | }, |
1205 | { | |
50fcd847 VO |
1206 | .name = "pushr", |
1207 | .reg_bits = 16, | |
1208 | .val_bits = 16, | |
1209 | .reg_stride = 2, | |
1210 | .max_register = 0x2, | |
58ba07ec EH |
1211 | }, |
1212 | }; | |
1213 | ||
5b342c5a | 1214 | static int dspi_init(struct fsl_dspi *dspi) |
5ee67b58 | 1215 | { |
4fcc7c22 VO |
1216 | unsigned int mcr; |
1217 | ||
1218 | /* Set idle states for all chip select signals to high */ | |
2c2b3ad2 | 1219 | mcr = SPI_MCR_PCSIS(GENMASK(dspi->ctlr->max_native_cs - 1, 0)); |
5ce3cc56 | 1220 | |
d59c90a2 | 1221 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
06d5dd29 | 1222 | mcr |= SPI_MCR_XSPI; |
6230d6ca YY |
1223 | if (!spi_controller_is_target(dspi->ctlr)) |
1224 | mcr |= SPI_MCR_HOST; | |
5ce3cc56 LM |
1225 | |
1226 | regmap_write(dspi->regmap, SPI_MCR, mcr); | |
5ee67b58 | 1227 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); |
5b342c5a VO |
1228 | |
1229 | switch (dspi->devtype_data->trans_mode) { | |
5b342c5a VO |
1230 | case DSPI_XSPI_MODE: |
1231 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_CMDTCFE); | |
1232 | break; | |
1233 | case DSPI_DMA_MODE: | |
1234 | regmap_write(dspi->regmap, SPI_RSER, | |
1235 | SPI_RSER_TFFFE | SPI_RSER_TFFFD | | |
1236 | SPI_RSER_RFDFE | SPI_RSER_RFDFD); | |
1237 | break; | |
1238 | default: | |
1239 | dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n", | |
1240 | dspi->devtype_data->trans_mode); | |
1241 | return -EINVAL; | |
1242 | } | |
1243 | ||
1244 | return 0; | |
5ee67b58 YY |
1245 | } |
1246 | ||
6230d6ca | 1247 | static int dspi_target_abort(struct spi_controller *host) |
f4b32390 | 1248 | { |
6230d6ca | 1249 | struct fsl_dspi *dspi = spi_controller_get_devdata(host); |
f4b32390 LM |
1250 | |
1251 | /* | |
1252 | * Terminate all pending DMA transactions for the SPI working | |
6230d6ca | 1253 | * in TARGET mode. |
f4b32390 | 1254 | */ |
3d6224e6 VO |
1255 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
1256 | dmaengine_terminate_sync(dspi->dma->chan_rx); | |
1257 | dmaengine_terminate_sync(dspi->dma->chan_tx); | |
1258 | } | |
f4b32390 LM |
1259 | |
1260 | /* Clear the internal DSPI RX and TX FIFO buffers */ | |
1261 | regmap_update_bits(dspi->regmap, SPI_MCR, | |
1262 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, | |
1263 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | |
1264 | ||
1265 | return 0; | |
1266 | } | |
1267 | ||
349ad66c CF |
1268 | static int dspi_probe(struct platform_device *pdev) |
1269 | { | |
1270 | struct device_node *np = pdev->dev.of_node; | |
d6bdfa6c VO |
1271 | const struct regmap_config *regmap_config; |
1272 | struct fsl_dspi_platform_data *pdata; | |
3a11ea66 | 1273 | struct spi_controller *ctlr; |
29d2daf2 | 1274 | int ret, cs_num, bus_num = -1; |
349ad66c CF |
1275 | struct fsl_dspi *dspi; |
1276 | struct resource *res; | |
1acbdeb9 | 1277 | void __iomem *base; |
671ffde1 | 1278 | bool big_endian; |
349ad66c | 1279 | |
530b5aff SH |
1280 | dspi = devm_kzalloc(&pdev->dev, sizeof(*dspi), GFP_KERNEL); |
1281 | if (!dspi) | |
1282 | return -ENOMEM; | |
1283 | ||
6230d6ca | 1284 | ctlr = spi_alloc_host(&pdev->dev, 0); |
3a11ea66 | 1285 | if (!ctlr) |
349ad66c CF |
1286 | return -ENOMEM; |
1287 | ||
6e383766 MW |
1288 | spi_controller_set_devdata(ctlr, dspi); |
1289 | platform_set_drvdata(pdev, dspi); | |
1290 | ||
349ad66c | 1291 | dspi->pdev = pdev; |
3a11ea66 | 1292 | dspi->ctlr = ctlr; |
9298bc72 | 1293 | |
3a11ea66 VO |
1294 | ctlr->setup = dspi_setup; |
1295 | ctlr->transfer_one_message = dspi_transfer_one_message; | |
1296 | ctlr->dev.of_node = pdev->dev.of_node; | |
349ad66c | 1297 | |
3a11ea66 | 1298 | ctlr->cleanup = dspi_cleanup; |
6230d6ca | 1299 | ctlr->target_abort = dspi_target_abort; |
3a11ea66 | 1300 | ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; |
84b60f2b | 1301 | ctlr->use_gpio_descriptors = true; |
349ad66c | 1302 | |
ec7ed770 AD |
1303 | pdata = dev_get_platdata(&pdev->dev); |
1304 | if (pdata) { | |
2c2b3ad2 | 1305 | ctlr->num_chipselect = ctlr->max_native_cs = pdata->cs_num; |
3a11ea66 | 1306 | ctlr->bus_num = pdata->bus_num; |
349ad66c | 1307 | |
d3505401 VO |
1308 | /* Only Coldfire uses platform data */ |
1309 | dspi->devtype_data = &devtype_data[MCF5441X]; | |
671ffde1 | 1310 | big_endian = true; |
ec7ed770 | 1311 | } else { |
349ad66c | 1312 | |
ec7ed770 AD |
1313 | ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num); |
1314 | if (ret < 0) { | |
1315 | dev_err(&pdev->dev, "can't get spi-num-chipselects\n"); | |
3a11ea66 | 1316 | goto out_ctlr_put; |
ec7ed770 | 1317 | } |
2c2b3ad2 | 1318 | ctlr->num_chipselect = ctlr->max_native_cs = cs_num; |
ec7ed770 | 1319 | |
29d2daf2 | 1320 | of_property_read_u32(np, "bus-num", &bus_num); |
3a11ea66 | 1321 | ctlr->bus_num = bus_num; |
ec7ed770 | 1322 | |
5ce3cc56 | 1323 | if (of_property_read_bool(np, "spi-slave")) |
6230d6ca | 1324 | ctlr->target = true; |
5ce3cc56 | 1325 | |
ec7ed770 AD |
1326 | dspi->devtype_data = of_device_get_match_data(&pdev->dev); |
1327 | if (!dspi->devtype_data) { | |
1328 | dev_err(&pdev->dev, "can't get devtype_data\n"); | |
1329 | ret = -EFAULT; | |
3a11ea66 | 1330 | goto out_ctlr_put; |
ec7ed770 | 1331 | } |
671ffde1 VO |
1332 | |
1333 | big_endian = of_device_is_big_endian(np); | |
1334 | } | |
1335 | if (big_endian) { | |
1336 | dspi->pushr_cmd = 0; | |
1337 | dspi->pushr_tx = 2; | |
1338 | } else { | |
1339 | dspi->pushr_cmd = 2; | |
1340 | dspi->pushr_tx = 0; | |
d1f4a38c HW |
1341 | } |
1342 | ||
d59c90a2 | 1343 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
3a11ea66 | 1344 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
35c9d461 | 1345 | else |
3a11ea66 | 1346 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
35c9d461 | 1347 | |
f96087a3 | 1348 | base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
1acbdeb9 CF |
1349 | if (IS_ERR(base)) { |
1350 | ret = PTR_ERR(base); | |
3a11ea66 | 1351 | goto out_ctlr_put; |
349ad66c CF |
1352 | } |
1353 | ||
d59c90a2 | 1354 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
58ba07ec EH |
1355 | regmap_config = &dspi_xspi_regmap_config[0]; |
1356 | else | |
1357 | regmap_config = &dspi_regmap_config; | |
1358 | dspi->regmap = devm_regmap_init_mmio(&pdev->dev, base, regmap_config); | |
1acbdeb9 CF |
1359 | if (IS_ERR(dspi->regmap)) { |
1360 | dev_err(&pdev->dev, "failed to init regmap: %ld\n", | |
1361 | PTR_ERR(dspi->regmap)); | |
fbad6c24 | 1362 | ret = PTR_ERR(dspi->regmap); |
3a11ea66 | 1363 | goto out_ctlr_put; |
1acbdeb9 CF |
1364 | } |
1365 | ||
d59c90a2 | 1366 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) { |
58ba07ec EH |
1367 | dspi->regmap_pushr = devm_regmap_init_mmio( |
1368 | &pdev->dev, base + SPI_PUSHR, | |
1369 | &dspi_xspi_regmap_config[1]); | |
1370 | if (IS_ERR(dspi->regmap_pushr)) { | |
1371 | dev_err(&pdev->dev, | |
1372 | "failed to init pushr regmap: %ld\n", | |
1373 | PTR_ERR(dspi->regmap_pushr)); | |
80dc12cd | 1374 | ret = PTR_ERR(dspi->regmap_pushr); |
3a11ea66 | 1375 | goto out_ctlr_put; |
58ba07ec EH |
1376 | } |
1377 | } | |
1378 | ||
4812bc31 | 1379 | dspi->clk = devm_clk_get_enabled(&pdev->dev, "dspi"); |
d8ffee2f KK |
1380 | if (IS_ERR(dspi->clk)) { |
1381 | ret = PTR_ERR(dspi->clk); | |
1382 | dev_err(&pdev->dev, "unable to get clock\n"); | |
3a11ea66 | 1383 | goto out_ctlr_put; |
d8ffee2f | 1384 | } |
d8ffee2f | 1385 | |
5b342c5a VO |
1386 | ret = dspi_init(dspi); |
1387 | if (ret) | |
4812bc31 | 1388 | goto out_ctlr_put; |
c55be305 | 1389 | |
349ad66c | 1390 | dspi->irq = platform_get_irq(pdev, 0); |
c55be305 VO |
1391 | if (dspi->irq <= 0) { |
1392 | dev_info(&pdev->dev, | |
1393 | "can't get platform irq, using poll mode\n"); | |
1394 | dspi->irq = 0; | |
1395 | goto poll_mode; | |
349ad66c CF |
1396 | } |
1397 | ||
f148915f KK |
1398 | init_completion(&dspi->xfer_done); |
1399 | ||
3d87b613 KK |
1400 | ret = request_threaded_irq(dspi->irq, dspi_interrupt, NULL, |
1401 | IRQF_SHARED, pdev->name, dspi); | |
349ad66c CF |
1402 | if (ret < 0) { |
1403 | dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); | |
4812bc31 | 1404 | goto out_ctlr_put; |
349ad66c CF |
1405 | } |
1406 | ||
c55be305 | 1407 | poll_mode: |
d6b71dfa | 1408 | |
90ba3703 | 1409 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
cddebdd1 NY |
1410 | ret = dspi_request_dma(dspi, res->start); |
1411 | if (ret < 0) { | |
90ba3703 | 1412 | dev_err(&pdev->dev, "can't get dma channels\n"); |
3d87b613 | 1413 | goto out_free_irq; |
90ba3703 SM |
1414 | } |
1415 | } | |
1416 | ||
3a11ea66 | 1417 | ctlr->max_speed_hz = |
9419b200 BD |
1418 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; |
1419 | ||
63669902 VO |
1420 | if (dspi->devtype_data->trans_mode != DSPI_DMA_MODE) |
1421 | ctlr->ptp_sts_supported = true; | |
d6b71dfa | 1422 | |
3a11ea66 | 1423 | ret = spi_register_controller(ctlr); |
349ad66c | 1424 | if (ret != 0) { |
3a11ea66 | 1425 | dev_err(&pdev->dev, "Problem registering DSPI ctlr\n"); |
680ec054 | 1426 | goto out_release_dma; |
349ad66c CF |
1427 | } |
1428 | ||
349ad66c CF |
1429 | return ret; |
1430 | ||
680ec054 CJ |
1431 | out_release_dma: |
1432 | dspi_release_dma(dspi); | |
3d87b613 KK |
1433 | out_free_irq: |
1434 | if (dspi->irq) | |
1435 | free_irq(dspi->irq, dspi); | |
3a11ea66 VO |
1436 | out_ctlr_put: |
1437 | spi_controller_put(ctlr); | |
349ad66c CF |
1438 | |
1439 | return ret; | |
1440 | } | |
1441 | ||
1bcab55f | 1442 | static void dspi_remove(struct platform_device *pdev) |
349ad66c | 1443 | { |
530b5aff | 1444 | struct fsl_dspi *dspi = platform_get_drvdata(pdev); |
349ad66c CF |
1445 | |
1446 | /* Disconnect from the SPI framework */ | |
7684580d KK |
1447 | spi_unregister_controller(dspi->ctlr); |
1448 | ||
1449 | /* Disable RX and TX */ | |
1450 | regmap_update_bits(dspi->regmap, SPI_MCR, | |
1451 | SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF, | |
1452 | SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF); | |
1453 | ||
1454 | /* Stop Running */ | |
1455 | regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, SPI_MCR_HALT); | |
1456 | ||
90ba3703 | 1457 | dspi_release_dma(dspi); |
3d87b613 KK |
1458 | if (dspi->irq) |
1459 | free_irq(dspi->irq, dspi); | |
349ad66c CF |
1460 | } |
1461 | ||
dc234825 PM |
1462 | static void dspi_shutdown(struct platform_device *pdev) |
1463 | { | |
3c525b69 | 1464 | dspi_remove(pdev); |
dc234825 PM |
1465 | } |
1466 | ||
349ad66c | 1467 | static struct platform_driver fsl_dspi_driver = { |
50fcd847 VO |
1468 | .driver.name = DRIVER_NAME, |
1469 | .driver.of_match_table = fsl_dspi_dt_ids, | |
50fcd847 VO |
1470 | .driver.pm = &dspi_pm, |
1471 | .probe = dspi_probe, | |
1bcab55f | 1472 | .remove_new = dspi_remove, |
dc234825 | 1473 | .shutdown = dspi_shutdown, |
349ad66c CF |
1474 | }; |
1475 | module_platform_driver(fsl_dspi_driver); | |
1476 | ||
1477 | MODULE_DESCRIPTION("Freescale DSPI Controller Driver"); | |
b444d1df | 1478 | MODULE_LICENSE("GPL"); |
349ad66c | 1479 | MODULE_ALIAS("platform:" DRIVER_NAME); |