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 PU |
504 | dma->chan_rx = dma_request_chan(dev, "rx"); |
505 | if (IS_ERR(dma->chan_rx)) { | |
908e5a3d MD |
506 | return dev_err_probe(dev, PTR_ERR(dma->chan_rx), |
507 | "rx dma channel not available\n"); | |
90ba3703 SM |
508 | } |
509 | ||
b5756b77 PU |
510 | dma->chan_tx = dma_request_chan(dev, "tx"); |
511 | if (IS_ERR(dma->chan_tx)) { | |
b5756b77 | 512 | ret = PTR_ERR(dma->chan_tx); |
908e5a3d | 513 | dev_err_probe(dev, ret, "tx dma channel not available\n"); |
90ba3703 SM |
514 | goto err_tx_channel; |
515 | } | |
516 | ||
22ee9de1 | 517 | dma->tx_dma_buf = dma_alloc_coherent(dma->chan_tx->device->dev, |
a957499b VO |
518 | dma_bufsize, &dma->tx_dma_phys, |
519 | GFP_KERNEL); | |
90ba3703 SM |
520 | if (!dma->tx_dma_buf) { |
521 | ret = -ENOMEM; | |
522 | goto err_tx_dma_buf; | |
523 | } | |
524 | ||
22ee9de1 | 525 | dma->rx_dma_buf = dma_alloc_coherent(dma->chan_rx->device->dev, |
a957499b VO |
526 | dma_bufsize, &dma->rx_dma_phys, |
527 | GFP_KERNEL); | |
90ba3703 SM |
528 | if (!dma->rx_dma_buf) { |
529 | ret = -ENOMEM; | |
530 | goto err_rx_dma_buf; | |
531 | } | |
532 | ||
209ab223 | 533 | memset(&cfg, 0, sizeof(cfg)); |
90ba3703 SM |
534 | cfg.src_addr = phy_addr + SPI_POPR; |
535 | cfg.dst_addr = phy_addr + SPI_PUSHR; | |
536 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | |
537 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | |
538 | cfg.src_maxburst = 1; | |
539 | cfg.dst_maxburst = 1; | |
540 | ||
541 | cfg.direction = DMA_DEV_TO_MEM; | |
542 | ret = dmaengine_slave_config(dma->chan_rx, &cfg); | |
543 | if (ret) { | |
544 | dev_err(dev, "can't configure rx dma channel\n"); | |
545 | ret = -EINVAL; | |
546 | goto err_slave_config; | |
547 | } | |
548 | ||
549 | cfg.direction = DMA_MEM_TO_DEV; | |
550 | ret = dmaengine_slave_config(dma->chan_tx, &cfg); | |
551 | if (ret) { | |
552 | dev_err(dev, "can't configure tx dma channel\n"); | |
553 | ret = -EINVAL; | |
554 | goto err_slave_config; | |
555 | } | |
556 | ||
557 | dspi->dma = dma; | |
558 | init_completion(&dma->cmd_tx_complete); | |
559 | init_completion(&dma->cmd_rx_complete); | |
560 | ||
561 | return 0; | |
562 | ||
563 | err_slave_config: | |
22ee9de1 | 564 | dma_free_coherent(dma->chan_rx->device->dev, |
a957499b | 565 | dma_bufsize, dma->rx_dma_buf, dma->rx_dma_phys); |
90ba3703 | 566 | err_rx_dma_buf: |
22ee9de1 | 567 | dma_free_coherent(dma->chan_tx->device->dev, |
a957499b | 568 | dma_bufsize, dma->tx_dma_buf, dma->tx_dma_phys); |
90ba3703 SM |
569 | err_tx_dma_buf: |
570 | dma_release_channel(dma->chan_tx); | |
571 | err_tx_channel: | |
572 | dma_release_channel(dma->chan_rx); | |
573 | ||
574 | devm_kfree(dev, dma); | |
575 | dspi->dma = NULL; | |
576 | ||
577 | return ret; | |
578 | } | |
579 | ||
580 | static void dspi_release_dma(struct fsl_dspi *dspi) | |
581 | { | |
a957499b | 582 | int dma_bufsize = dspi->devtype_data->fifo_size * 2; |
90ba3703 | 583 | struct fsl_dspi_dma *dma = dspi->dma; |
90ba3703 | 584 | |
abbd0ef1 VO |
585 | if (!dma) |
586 | return; | |
90ba3703 | 587 | |
abbd0ef1 | 588 | if (dma->chan_tx) { |
03fe7aaf KK |
589 | dma_free_coherent(dma->chan_tx->device->dev, dma_bufsize, |
590 | dma->tx_dma_buf, dma->tx_dma_phys); | |
abbd0ef1 VO |
591 | dma_release_channel(dma->chan_tx); |
592 | } | |
593 | ||
594 | if (dma->chan_rx) { | |
03fe7aaf KK |
595 | dma_free_coherent(dma->chan_rx->device->dev, dma_bufsize, |
596 | dma->rx_dma_buf, dma->rx_dma_phys); | |
abbd0ef1 | 597 | dma_release_channel(dma->chan_rx); |
90ba3703 SM |
598 | } |
599 | } | |
600 | ||
349ad66c | 601 | static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, |
50fcd847 | 602 | unsigned long clkrate) |
349ad66c CF |
603 | { |
604 | /* Valid baud rate pre-scaler values */ | |
605 | int pbr_tbl[4] = {2, 3, 5, 7}; | |
606 | int brs[16] = { 2, 4, 6, 8, | |
50fcd847 VO |
607 | 16, 32, 64, 128, |
608 | 256, 512, 1024, 2048, | |
609 | 4096, 8192, 16384, 32768 }; | |
6fd63087 AB |
610 | int scale_needed, scale, minscale = INT_MAX; |
611 | int i, j; | |
612 | ||
613 | scale_needed = clkrate / speed_hz; | |
e689d6df AB |
614 | if (clkrate % speed_hz) |
615 | scale_needed++; | |
6fd63087 AB |
616 | |
617 | for (i = 0; i < ARRAY_SIZE(brs); i++) | |
618 | for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) { | |
619 | scale = brs[i] * pbr_tbl[j]; | |
620 | if (scale >= scale_needed) { | |
621 | if (scale < minscale) { | |
622 | minscale = scale; | |
623 | *br = i; | |
624 | *pbr = j; | |
625 | } | |
626 | break; | |
349ad66c CF |
627 | } |
628 | } | |
349ad66c | 629 | |
6fd63087 AB |
630 | if (minscale == INT_MAX) { |
631 | pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld, we use the max prescaler value.\n", | |
632 | speed_hz, clkrate); | |
633 | *pbr = ARRAY_SIZE(pbr_tbl) - 1; | |
634 | *br = ARRAY_SIZE(brs) - 1; | |
635 | } | |
349ad66c | 636 | } |
349ad66c | 637 | |
95bf15f3 | 638 | static void ns_delay_scale(char *psc, char *sc, int delay_ns, |
50fcd847 | 639 | unsigned long clkrate) |
95bf15f3 | 640 | { |
95bf15f3 | 641 | int scale_needed, scale, minscale = INT_MAX; |
d6bdfa6c | 642 | int pscale_tbl[4] = {1, 3, 5, 7}; |
95bf15f3 | 643 | u32 remainder; |
d6bdfa6c | 644 | int i, j; |
95bf15f3 AB |
645 | |
646 | scale_needed = div_u64_rem((u64)delay_ns * clkrate, NSEC_PER_SEC, | |
50fcd847 | 647 | &remainder); |
95bf15f3 AB |
648 | if (remainder) |
649 | scale_needed++; | |
650 | ||
651 | for (i = 0; i < ARRAY_SIZE(pscale_tbl); i++) | |
652 | for (j = 0; j <= SPI_CTAR_SCALE_BITS; j++) { | |
653 | scale = pscale_tbl[i] * (2 << j); | |
654 | if (scale >= scale_needed) { | |
655 | if (scale < minscale) { | |
656 | minscale = scale; | |
657 | *psc = i; | |
658 | *sc = j; | |
659 | } | |
660 | break; | |
349ad66c CF |
661 | } |
662 | } | |
663 | ||
95bf15f3 AB |
664 | if (minscale == INT_MAX) { |
665 | pr_warn("Cannot find correct scale values for %dns delay at clkrate %ld, using max prescaler value", | |
666 | delay_ns, clkrate); | |
667 | *psc = ARRAY_SIZE(pscale_tbl) - 1; | |
668 | *sc = SPI_CTAR_SCALE_BITS; | |
669 | } | |
349ad66c CF |
670 | } |
671 | ||
ea93ed4c | 672 | static void dspi_pushr_cmd_write(struct fsl_dspi *dspi, u16 cmd) |
8fcd151d | 673 | { |
d59c90a2 VO |
674 | /* |
675 | * The only time when the PCS doesn't need continuation after this word | |
676 | * is when it's last. We need to look ahead, because we actually call | |
677 | * dspi_pop_tx (the function that decrements dspi->len) _after_ | |
678 | * dspi_pushr_cmd_write with XSPI mode. As for how much in advance? One | |
679 | * word is enough. If there's more to transmit than that, | |
680 | * dspi_xspi_write will know to split the FIFO writes in 2, and | |
681 | * generate a new PUSHR command with the final word that will have PCS | |
682 | * deasserted (not continued) here. | |
683 | */ | |
6c1c26ec | 684 | if (dspi->len > dspi->oper_word_size) |
8fcd151d | 685 | cmd |= SPI_PUSHR_CMD_CONT; |
671ffde1 | 686 | regmap_write(dspi->regmap_pushr, dspi->pushr_cmd, cmd); |
8fcd151d EH |
687 | } |
688 | ||
547248fb | 689 | static void dspi_pushr_txdata_write(struct fsl_dspi *dspi, u16 txdata) |
8fcd151d | 690 | { |
671ffde1 | 691 | regmap_write(dspi->regmap_pushr, dspi->pushr_tx, txdata); |
8fcd151d EH |
692 | } |
693 | ||
0dedf901 | 694 | static void dspi_xspi_fifo_write(struct fsl_dspi *dspi, int num_words) |
d1f4a38c | 695 | { |
0dedf901 | 696 | int num_bytes = num_words * dspi->oper_word_size; |
ea93ed4c | 697 | u16 tx_cmd = dspi->tx_cmd; |
8fcd151d | 698 | |
0dedf901 VO |
699 | /* |
700 | * If the PCS needs to de-assert (i.e. we're at the end of the buffer | |
701 | * and cs_change does not want the PCS to stay on), then we need a new | |
702 | * PUSHR command, since this one (for the body of the buffer) | |
703 | * necessarily has the CONT bit set. | |
704 | * So send one word less during this go, to force a split and a command | |
705 | * with a single word next time, when CONT will be unset. | |
706 | */ | |
707 | if (!(dspi->tx_cmd & SPI_PUSHR_CMD_CONT) && num_bytes == dspi->len) | |
ea93ed4c VO |
708 | tx_cmd |= SPI_PUSHR_CMD_EOQ; |
709 | ||
6c1c26ec | 710 | /* Update CTARE */ |
d59c90a2 | 711 | regmap_write(dspi->regmap, SPI_CTARE(0), |
6c1c26ec | 712 | SPI_FRAME_EBITS(dspi->oper_bits_per_word) | |
0dedf901 | 713 | SPI_CTARE_DTCP(num_words)); |
8fcd151d | 714 | |
d59c90a2 VO |
715 | /* |
716 | * Write the CMD FIFO entry first, and then the two | |
717 | * corresponding TX FIFO entries (or one...). | |
718 | */ | |
ea93ed4c | 719 | dspi_pushr_cmd_write(dspi, tx_cmd); |
d59c90a2 VO |
720 | |
721 | /* Fill TX FIFO with as many transfers as possible */ | |
0dedf901 | 722 | while (num_words--) { |
8fcd151d EH |
723 | u32 data = dspi_pop_tx(dspi); |
724 | ||
547248fb | 725 | dspi_pushr_txdata_write(dspi, data & 0xFFFF); |
6c1c26ec | 726 | if (dspi->oper_bits_per_word > 16) |
d59c90a2 | 727 | dspi_pushr_txdata_write(dspi, data >> 16); |
8fcd151d | 728 | } |
d1f4a38c | 729 | } |
349ad66c | 730 | |
d59c90a2 | 731 | static u32 dspi_popr_read(struct fsl_dspi *dspi) |
d1f4a38c | 732 | { |
d59c90a2 | 733 | u32 rxdata = 0; |
d1f4a38c | 734 | |
d59c90a2 VO |
735 | regmap_read(dspi->regmap, SPI_POPR, &rxdata); |
736 | return rxdata; | |
737 | } | |
d1f4a38c | 738 | |
d59c90a2 VO |
739 | static void dspi_fifo_read(struct fsl_dspi *dspi) |
740 | { | |
0dedf901 VO |
741 | int num_fifo_entries = dspi->words_in_flight; |
742 | ||
20617530 | 743 | /* Read one FIFO entry and push to rx buffer */ |
0dedf901 | 744 | while (num_fifo_entries--) |
547248fb | 745 | dspi_push_rx(dspi, dspi_popr_read(dspi)); |
349ad66c CF |
746 | } |
747 | ||
6c1c26ec | 748 | static void dspi_setup_accel(struct fsl_dspi *dspi) |
a63af99f | 749 | { |
6c1c26ec | 750 | struct spi_transfer *xfer = dspi->cur_transfer; |
6365504d | 751 | bool odd = !!(dspi->len & 1); |
12fb61a9 | 752 | |
6365504d VO |
753 | /* No accel for frames not multiple of 8 bits at the moment */ |
754 | if (xfer->bits_per_word % 8) | |
755 | goto no_accel; | |
d6b71dfa | 756 | |
6365504d VO |
757 | if (!odd && dspi->len <= dspi->devtype_data->fifo_size * 2) { |
758 | dspi->oper_bits_per_word = 16; | |
759 | } else if (odd && dspi->len <= dspi->devtype_data->fifo_size) { | |
760 | dspi->oper_bits_per_word = 8; | |
761 | } else { | |
762 | /* Start off with maximum supported by hardware */ | |
763 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) | |
764 | dspi->oper_bits_per_word = 32; | |
765 | else | |
766 | dspi->oper_bits_per_word = 16; | |
767 | ||
768 | /* | |
769 | * And go down only if the buffer can't be sent with | |
770 | * words this big | |
771 | */ | |
772 | do { | |
773 | if (dspi->len >= DIV_ROUND_UP(dspi->oper_bits_per_word, 8)) | |
774 | break; | |
6c1c26ec | 775 | |
6365504d VO |
776 | dspi->oper_bits_per_word /= 2; |
777 | } while (dspi->oper_bits_per_word > 8); | |
778 | } | |
6c1c26ec VO |
779 | |
780 | if (xfer->bits_per_word == 8 && dspi->oper_bits_per_word == 32) { | |
781 | dspi->dev_to_host = dspi_8on32_dev_to_host; | |
782 | dspi->host_to_dev = dspi_8on32_host_to_dev; | |
783 | } else if (xfer->bits_per_word == 8 && dspi->oper_bits_per_word == 16) { | |
784 | dspi->dev_to_host = dspi_8on16_dev_to_host; | |
785 | dspi->host_to_dev = dspi_8on16_host_to_dev; | |
786 | } else if (xfer->bits_per_word == 16 && dspi->oper_bits_per_word == 32) { | |
787 | dspi->dev_to_host = dspi_16on32_dev_to_host; | |
788 | dspi->host_to_dev = dspi_16on32_host_to_dev; | |
789 | } else { | |
6365504d | 790 | no_accel: |
6c1c26ec VO |
791 | dspi->dev_to_host = dspi_native_dev_to_host; |
792 | dspi->host_to_dev = dspi_native_host_to_dev; | |
793 | dspi->oper_bits_per_word = xfer->bits_per_word; | |
794 | } | |
795 | ||
796 | dspi->oper_word_size = DIV_ROUND_UP(dspi->oper_bits_per_word, 8); | |
797 | ||
798 | /* | |
20c05a05 | 799 | * Update CTAR here (code is common for XSPI and DMA modes). |
6c1c26ec VO |
800 | * We will update CTARE in the portion specific to XSPI, when we |
801 | * also know the preload value (DTCP). | |
12fb61a9 | 802 | */ |
6c1c26ec VO |
803 | regmap_write(dspi->regmap, SPI_CTAR(0), |
804 | dspi->cur_chip->ctar_val | | |
805 | SPI_FRAME_BITS(dspi->oper_bits_per_word)); | |
806 | } | |
807 | ||
d59c90a2 VO |
808 | static void dspi_fifo_write(struct fsl_dspi *dspi) |
809 | { | |
0dedf901 | 810 | int num_fifo_entries = dspi->devtype_data->fifo_size; |
e9bac900 VO |
811 | struct spi_transfer *xfer = dspi->cur_transfer; |
812 | struct spi_message *msg = dspi->cur_msg; | |
0dedf901 | 813 | int num_words, num_bytes; |
e9bac900 | 814 | |
6c1c26ec VO |
815 | dspi_setup_accel(dspi); |
816 | ||
0dedf901 VO |
817 | /* In XSPI mode each 32-bit word occupies 2 TX FIFO entries */ |
818 | if (dspi->oper_word_size == 4) | |
819 | num_fifo_entries /= 2; | |
820 | ||
821 | /* | |
822 | * Integer division intentionally trims off odd (or non-multiple of 4) | |
823 | * numbers of bytes at the end of the buffer, which will be sent next | |
824 | * time using a smaller oper_word_size. | |
825 | */ | |
826 | num_words = dspi->len / dspi->oper_word_size; | |
827 | if (num_words > num_fifo_entries) | |
828 | num_words = num_fifo_entries; | |
829 | ||
830 | /* Update total number of bytes that were transferred */ | |
831 | num_bytes = num_words * dspi->oper_word_size; | |
832 | msg->actual_length += num_bytes; | |
833 | dspi->progress += num_bytes / DIV_ROUND_UP(xfer->bits_per_word, 8); | |
834 | ||
835 | /* | |
836 | * Update shared variable for use in the next interrupt (both in | |
837 | * dspi_fifo_read and in dspi_fifo_write). | |
838 | */ | |
839 | dspi->words_in_flight = num_words; | |
840 | ||
e9bac900 VO |
841 | spi_take_timestamp_pre(dspi->ctlr, xfer, dspi->progress, !dspi->irq); |
842 | ||
20c05a05 | 843 | dspi_xspi_fifo_write(dspi, num_words); |
0dedf901 VO |
844 | /* |
845 | * Everything after this point is in a potential race with the next | |
846 | * interrupt, so we must never use dspi->words_in_flight again since it | |
847 | * might already be modified by the next dspi_fifo_write. | |
848 | */ | |
12fb61a9 | 849 | |
d6b71dfa | 850 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, |
862dd2a9 | 851 | dspi->progress, !dspi->irq); |
e9bac900 | 852 | } |
d6b71dfa | 853 | |
e9bac900 VO |
854 | static int dspi_rxtx(struct fsl_dspi *dspi) |
855 | { | |
d59c90a2 | 856 | dspi_fifo_read(dspi); |
a63af99f | 857 | |
c55be305 VO |
858 | if (!dspi->len) |
859 | /* Success! */ | |
860 | return 0; | |
a63af99f | 861 | |
d59c90a2 | 862 | dspi_fifo_write(dspi); |
a63af99f | 863 | |
c55be305 VO |
864 | return -EINPROGRESS; |
865 | } | |
866 | ||
867 | static int dspi_poll(struct fsl_dspi *dspi) | |
868 | { | |
869 | int tries = 1000; | |
870 | u32 spi_sr; | |
871 | ||
872 | do { | |
873 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | |
874 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | |
875 | ||
20c05a05 | 876 | if (spi_sr & SPI_SR_CMDTCF) |
c55be305 VO |
877 | break; |
878 | } while (--tries); | |
879 | ||
880 | if (!tries) | |
881 | return -ETIMEDOUT; | |
882 | ||
883 | return dspi_rxtx(dspi); | |
884 | } | |
885 | ||
886 | static irqreturn_t dspi_interrupt(int irq, void *dev_id) | |
887 | { | |
888 | struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; | |
889 | u32 spi_sr; | |
890 | ||
891 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | |
892 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | |
893 | ||
20c05a05 | 894 | if (!(spi_sr & SPI_SR_CMDTCF)) |
c55be305 VO |
895 | return IRQ_NONE; |
896 | ||
4f5ee75e VO |
897 | if (dspi_rxtx(dspi) == 0) |
898 | complete(&dspi->xfer_done); | |
c55be305 | 899 | |
a63af99f VO |
900 | return IRQ_HANDLED; |
901 | } | |
902 | ||
84b60f2b RPNO |
903 | static void dspi_assert_cs(struct spi_device *spi, bool *cs) |
904 | { | |
9e264f3f | 905 | if (!spi_get_csgpiod(spi, 0) || *cs) |
84b60f2b RPNO |
906 | return; |
907 | ||
9e264f3f | 908 | gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), true); |
84b60f2b RPNO |
909 | *cs = true; |
910 | } | |
911 | ||
912 | static void dspi_deassert_cs(struct spi_device *spi, bool *cs) | |
913 | { | |
9e264f3f | 914 | if (!spi_get_csgpiod(spi, 0) || !*cs) |
84b60f2b RPNO |
915 | return; |
916 | ||
9e264f3f | 917 | gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), false); |
84b60f2b RPNO |
918 | *cs = false; |
919 | } | |
920 | ||
3a11ea66 | 921 | static int dspi_transfer_one_message(struct spi_controller *ctlr, |
50fcd847 | 922 | struct spi_message *message) |
349ad66c | 923 | { |
3a11ea66 | 924 | struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); |
9298bc72 CF |
925 | struct spi_device *spi = message->spi; |
926 | struct spi_transfer *transfer; | |
84b60f2b | 927 | bool cs = false; |
9298bc72 | 928 | int status = 0; |
d1f4a38c | 929 | |
9298bc72 CF |
930 | message->actual_length = 0; |
931 | ||
932 | list_for_each_entry(transfer, &message->transfers, transfer_list) { | |
933 | dspi->cur_transfer = transfer; | |
934 | dspi->cur_msg = message; | |
935 | dspi->cur_chip = spi_get_ctldata(spi); | |
84b60f2b RPNO |
936 | |
937 | dspi_assert_cs(spi, &cs); | |
938 | ||
9e1dc9bd | 939 | /* Prepare command word for CMD FIFO */ |
84b60f2b | 940 | dspi->tx_cmd = SPI_PUSHR_CMD_CTAS(0); |
9e264f3f AKMA |
941 | if (!spi_get_csgpiod(spi, 0)) |
942 | dspi->tx_cmd |= SPI_PUSHR_CMD_PCS(spi_get_chipselect(spi, 0)); | |
84b60f2b | 943 | |
92dc20d8 | 944 | if (list_is_last(&dspi->cur_transfer->transfer_list, |
9e1dc9bd EH |
945 | &dspi->cur_msg->transfers)) { |
946 | /* Leave PCS activated after last transfer when | |
947 | * cs_change is set. | |
948 | */ | |
949 | if (transfer->cs_change) | |
950 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | |
951 | } else { | |
952 | /* Keep PCS active between transfers in same message | |
953 | * when cs_change is not set, and de-activate PCS | |
954 | * between transfers in the same message when | |
955 | * cs_change is set. | |
956 | */ | |
957 | if (!transfer->cs_change) | |
958 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | |
959 | } | |
960 | ||
dadcf4ab | 961 | dspi->tx = transfer->tx_buf; |
9298bc72 | 962 | dspi->rx = transfer->rx_buf; |
9298bc72 | 963 | dspi->len = transfer->len; |
862dd2a9 | 964 | dspi->progress = 0; |
9298bc72 | 965 | |
9298bc72 | 966 | regmap_update_bits(dspi->regmap, SPI_MCR, |
d87e08f1 EH |
967 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, |
968 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | |
349ad66c | 969 | |
d6b71dfa | 970 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
862dd2a9 | 971 | dspi->progress, !dspi->irq); |
d6b71dfa | 972 | |
5b342c5a | 973 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
90ba3703 | 974 | status = dspi_dma_xfer(dspi); |
5b342c5a VO |
975 | } else { |
976 | dspi_fifo_write(dspi); | |
1acbdeb9 | 977 | |
826b3a6a VO |
978 | if (dspi->irq) { |
979 | wait_for_completion(&dspi->xfer_done); | |
980 | reinit_completion(&dspi->xfer_done); | |
981 | } else { | |
982 | do { | |
983 | status = dspi_poll(dspi); | |
984 | } while (status == -EINPROGRESS); | |
985 | } | |
98114304 | 986 | } |
5b342c5a VO |
987 | if (status) |
988 | break; | |
349ad66c | 989 | |
e74dc5c7 | 990 | spi_transfer_delay_exec(transfer); |
84b60f2b RPNO |
991 | |
992 | if (!(dspi->tx_cmd & SPI_PUSHR_CMD_CONT)) | |
993 | dspi_deassert_cs(spi, &cs); | |
349ad66c CF |
994 | } |
995 | ||
9298bc72 | 996 | message->status = status; |
3a11ea66 | 997 | spi_finalize_current_message(ctlr); |
9298bc72 CF |
998 | |
999 | return status; | |
349ad66c CF |
1000 | } |
1001 | ||
9298bc72 | 1002 | static int dspi_setup(struct spi_device *spi) |
349ad66c | 1003 | { |
3a11ea66 | 1004 | struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller); |
c5c31fb7 | 1005 | u32 period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->max_speed_hz); |
95bf15f3 | 1006 | unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0; |
c5c31fb7 | 1007 | u32 quarter_period_ns = DIV_ROUND_UP(period_ns, 4); |
d6bdfa6c VO |
1008 | u32 cs_sck_delay = 0, sck_cs_delay = 0; |
1009 | struct fsl_dspi_platform_data *pdata; | |
dadcf4ab | 1010 | unsigned char pasc = 0, asc = 0; |
d6bdfa6c | 1011 | struct chip_data *chip; |
95bf15f3 | 1012 | unsigned long clkrate; |
84b60f2b | 1013 | bool cs = true; |
349ad66c CF |
1014 | |
1015 | /* Only alloc on first setup */ | |
1016 | chip = spi_get_ctldata(spi); | |
1017 | if (chip == NULL) { | |
973fbce6 | 1018 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); |
349ad66c CF |
1019 | if (!chip) |
1020 | return -ENOMEM; | |
1021 | } | |
1022 | ||
ec7ed770 | 1023 | pdata = dev_get_platdata(&dspi->pdev->dev); |
95bf15f3 | 1024 | |
ec7ed770 AD |
1025 | if (!pdata) { |
1026 | of_property_read_u32(spi->dev.of_node, "fsl,spi-cs-sck-delay", | |
50fcd847 | 1027 | &cs_sck_delay); |
ec7ed770 AD |
1028 | |
1029 | of_property_read_u32(spi->dev.of_node, "fsl,spi-sck-cs-delay", | |
50fcd847 | 1030 | &sck_cs_delay); |
ec7ed770 AD |
1031 | } else { |
1032 | cs_sck_delay = pdata->cs_sck_delay; | |
1033 | sck_cs_delay = pdata->sck_cs_delay; | |
1034 | } | |
95bf15f3 | 1035 | |
c5c31fb7 VO |
1036 | /* Since tCSC and tASC apply to continuous transfers too, avoid SCK |
1037 | * glitches of half a cycle by never allowing tCSC + tASC to go below | |
1038 | * half a SCK period. | |
1039 | */ | |
1040 | if (cs_sck_delay < quarter_period_ns) | |
1041 | cs_sck_delay = quarter_period_ns; | |
1042 | if (sck_cs_delay < quarter_period_ns) | |
1043 | sck_cs_delay = quarter_period_ns; | |
1044 | ||
1045 | dev_dbg(&spi->dev, | |
1046 | "DSPI controller timing params: CS-to-SCK delay %u ns, SCK-to-CS delay %u ns\n", | |
1047 | cs_sck_delay, sck_cs_delay); | |
1048 | ||
95bf15f3 AB |
1049 | clkrate = clk_get_rate(dspi->clk); |
1050 | hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate); | |
1051 | ||
1052 | /* Set PCS to SCK delay scale values */ | |
1053 | ns_delay_scale(&pcssck, &cssck, cs_sck_delay, clkrate); | |
1054 | ||
1055 | /* Set After SCK delay scale values */ | |
1056 | ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate); | |
349ad66c | 1057 | |
06d5dd29 VO |
1058 | chip->ctar_val = 0; |
1059 | if (spi->mode & SPI_CPOL) | |
1060 | chip->ctar_val |= SPI_CTAR_CPOL; | |
1061 | if (spi->mode & SPI_CPHA) | |
1062 | chip->ctar_val |= SPI_CTAR_CPHA; | |
5ce3cc56 | 1063 | |
6230d6ca | 1064 | if (!spi_controller_is_target(dspi->ctlr)) { |
06d5dd29 VO |
1065 | chip->ctar_val |= SPI_CTAR_PCSSCK(pcssck) | |
1066 | SPI_CTAR_CSSCK(cssck) | | |
1067 | SPI_CTAR_PASC(pasc) | | |
1068 | SPI_CTAR_ASC(asc) | | |
1069 | SPI_CTAR_PBR(pbr) | | |
1070 | SPI_CTAR_BR(br); | |
1071 | ||
1072 | if (spi->mode & SPI_LSB_FIRST) | |
1073 | chip->ctar_val |= SPI_CTAR_LSBFE; | |
5ce3cc56 | 1074 | } |
349ad66c | 1075 | |
9e264f3f | 1076 | gpiod_direction_output(spi_get_csgpiod(spi, 0), false); |
84b60f2b RPNO |
1077 | dspi_deassert_cs(spi, &cs); |
1078 | ||
349ad66c CF |
1079 | spi_set_ctldata(spi, chip); |
1080 | ||
1081 | return 0; | |
1082 | } | |
1083 | ||
973fbce6 BD |
1084 | static void dspi_cleanup(struct spi_device *spi) |
1085 | { | |
9c8400e3 | 1086 | struct chip_data *chip = spi_get_ctldata(spi); |
973fbce6 BD |
1087 | |
1088 | dev_dbg(&spi->dev, "spi_device %u.%u cleanup\n", | |
9e264f3f | 1089 | spi->controller->bus_num, spi_get_chipselect(spi, 0)); |
973fbce6 BD |
1090 | |
1091 | kfree(chip); | |
1092 | } | |
1093 | ||
790d1902 | 1094 | static const struct of_device_id fsl_dspi_dt_ids[] = { |
d3505401 VO |
1095 | { |
1096 | .compatible = "fsl,vf610-dspi", | |
1097 | .data = &devtype_data[VF610], | |
1098 | }, { | |
1099 | .compatible = "fsl,ls1021a-v1.0-dspi", | |
1100 | .data = &devtype_data[LS1021A], | |
1101 | }, { | |
1102 | .compatible = "fsl,ls1012a-dspi", | |
1103 | .data = &devtype_data[LS1012A], | |
138f56ef VO |
1104 | }, { |
1105 | .compatible = "fsl,ls1028a-dspi", | |
1106 | .data = &devtype_data[LS1028A], | |
d3505401 VO |
1107 | }, { |
1108 | .compatible = "fsl,ls1043a-dspi", | |
1109 | .data = &devtype_data[LS1043A], | |
1110 | }, { | |
1111 | .compatible = "fsl,ls1046a-dspi", | |
1112 | .data = &devtype_data[LS1046A], | |
1113 | }, { | |
1114 | .compatible = "fsl,ls2080a-dspi", | |
1115 | .data = &devtype_data[LS2080A], | |
1116 | }, { | |
1117 | .compatible = "fsl,ls2085a-dspi", | |
1118 | .data = &devtype_data[LS2085A], | |
1119 | }, { | |
1120 | .compatible = "fsl,lx2160a-dspi", | |
1121 | .data = &devtype_data[LX2160A], | |
1122 | }, | |
349ad66c CF |
1123 | { /* sentinel */ } |
1124 | }; | |
1125 | MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); | |
1126 | ||
1127 | #ifdef CONFIG_PM_SLEEP | |
1128 | static int dspi_suspend(struct device *dev) | |
1129 | { | |
9bd77a9c | 1130 | struct fsl_dspi *dspi = dev_get_drvdata(dev); |
349ad66c | 1131 | |
3d87b613 KK |
1132 | if (dspi->irq) |
1133 | disable_irq(dspi->irq); | |
9bd77a9c | 1134 | spi_controller_suspend(dspi->ctlr); |
349ad66c CF |
1135 | clk_disable_unprepare(dspi->clk); |
1136 | ||
432a17d7 MK |
1137 | pinctrl_pm_select_sleep_state(dev); |
1138 | ||
349ad66c CF |
1139 | return 0; |
1140 | } | |
1141 | ||
1142 | static int dspi_resume(struct device *dev) | |
1143 | { | |
9bd77a9c | 1144 | struct fsl_dspi *dspi = dev_get_drvdata(dev); |
1c5ea2b4 | 1145 | int ret; |
349ad66c | 1146 | |
432a17d7 MK |
1147 | pinctrl_pm_select_default_state(dev); |
1148 | ||
1c5ea2b4 FE |
1149 | ret = clk_prepare_enable(dspi->clk); |
1150 | if (ret) | |
1151 | return ret; | |
9bd77a9c | 1152 | spi_controller_resume(dspi->ctlr); |
3d87b613 KK |
1153 | if (dspi->irq) |
1154 | enable_irq(dspi->irq); | |
349ad66c CF |
1155 | |
1156 | return 0; | |
1157 | } | |
1158 | #endif /* CONFIG_PM_SLEEP */ | |
1159 | ||
ba811add | 1160 | static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); |
349ad66c | 1161 | |
8570043e EH |
1162 | static const struct regmap_range dspi_volatile_ranges[] = { |
1163 | regmap_reg_range(SPI_MCR, SPI_TCR), | |
1164 | regmap_reg_range(SPI_SR, SPI_SR), | |
1165 | regmap_reg_range(SPI_PUSHR, SPI_RXFR3), | |
1166 | }; | |
1167 | ||
1168 | static const struct regmap_access_table dspi_volatile_table = { | |
50fcd847 VO |
1169 | .yes_ranges = dspi_volatile_ranges, |
1170 | .n_yes_ranges = ARRAY_SIZE(dspi_volatile_ranges), | |
8570043e EH |
1171 | }; |
1172 | ||
409851c3 | 1173 | static const struct regmap_config dspi_regmap_config = { |
50fcd847 VO |
1174 | .reg_bits = 32, |
1175 | .val_bits = 32, | |
1176 | .reg_stride = 4, | |
1177 | .max_register = 0x88, | |
1178 | .volatile_table = &dspi_volatile_table, | |
349ad66c CF |
1179 | }; |
1180 | ||
58ba07ec EH |
1181 | static const struct regmap_range dspi_xspi_volatile_ranges[] = { |
1182 | regmap_reg_range(SPI_MCR, SPI_TCR), | |
1183 | regmap_reg_range(SPI_SR, SPI_SR), | |
1184 | regmap_reg_range(SPI_PUSHR, SPI_RXFR3), | |
1185 | regmap_reg_range(SPI_SREX, SPI_SREX), | |
1186 | }; | |
1187 | ||
1188 | static const struct regmap_access_table dspi_xspi_volatile_table = { | |
50fcd847 VO |
1189 | .yes_ranges = dspi_xspi_volatile_ranges, |
1190 | .n_yes_ranges = ARRAY_SIZE(dspi_xspi_volatile_ranges), | |
58ba07ec EH |
1191 | }; |
1192 | ||
1193 | static const struct regmap_config dspi_xspi_regmap_config[] = { | |
1194 | { | |
50fcd847 VO |
1195 | .reg_bits = 32, |
1196 | .val_bits = 32, | |
1197 | .reg_stride = 4, | |
1198 | .max_register = 0x13c, | |
1199 | .volatile_table = &dspi_xspi_volatile_table, | |
58ba07ec EH |
1200 | }, |
1201 | { | |
50fcd847 VO |
1202 | .name = "pushr", |
1203 | .reg_bits = 16, | |
1204 | .val_bits = 16, | |
1205 | .reg_stride = 2, | |
1206 | .max_register = 0x2, | |
58ba07ec EH |
1207 | }, |
1208 | }; | |
1209 | ||
5b342c5a | 1210 | static int dspi_init(struct fsl_dspi *dspi) |
5ee67b58 | 1211 | { |
4fcc7c22 VO |
1212 | unsigned int mcr; |
1213 | ||
1214 | /* Set idle states for all chip select signals to high */ | |
2c2b3ad2 | 1215 | mcr = SPI_MCR_PCSIS(GENMASK(dspi->ctlr->max_native_cs - 1, 0)); |
5ce3cc56 | 1216 | |
d59c90a2 | 1217 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
06d5dd29 | 1218 | mcr |= SPI_MCR_XSPI; |
6230d6ca YY |
1219 | if (!spi_controller_is_target(dspi->ctlr)) |
1220 | mcr |= SPI_MCR_HOST; | |
5ce3cc56 LM |
1221 | |
1222 | regmap_write(dspi->regmap, SPI_MCR, mcr); | |
5ee67b58 | 1223 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); |
5b342c5a VO |
1224 | |
1225 | switch (dspi->devtype_data->trans_mode) { | |
5b342c5a VO |
1226 | case DSPI_XSPI_MODE: |
1227 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_CMDTCFE); | |
1228 | break; | |
1229 | case DSPI_DMA_MODE: | |
1230 | regmap_write(dspi->regmap, SPI_RSER, | |
1231 | SPI_RSER_TFFFE | SPI_RSER_TFFFD | | |
1232 | SPI_RSER_RFDFE | SPI_RSER_RFDFD); | |
1233 | break; | |
1234 | default: | |
1235 | dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n", | |
1236 | dspi->devtype_data->trans_mode); | |
1237 | return -EINVAL; | |
1238 | } | |
1239 | ||
1240 | return 0; | |
5ee67b58 YY |
1241 | } |
1242 | ||
6230d6ca | 1243 | static int dspi_target_abort(struct spi_controller *host) |
f4b32390 | 1244 | { |
6230d6ca | 1245 | struct fsl_dspi *dspi = spi_controller_get_devdata(host); |
f4b32390 LM |
1246 | |
1247 | /* | |
1248 | * Terminate all pending DMA transactions for the SPI working | |
6230d6ca | 1249 | * in TARGET mode. |
f4b32390 | 1250 | */ |
3d6224e6 VO |
1251 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
1252 | dmaengine_terminate_sync(dspi->dma->chan_rx); | |
1253 | dmaengine_terminate_sync(dspi->dma->chan_tx); | |
1254 | } | |
f4b32390 LM |
1255 | |
1256 | /* Clear the internal DSPI RX and TX FIFO buffers */ | |
1257 | regmap_update_bits(dspi->regmap, SPI_MCR, | |
1258 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, | |
1259 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | |
1260 | ||
1261 | return 0; | |
1262 | } | |
1263 | ||
349ad66c CF |
1264 | static int dspi_probe(struct platform_device *pdev) |
1265 | { | |
1266 | struct device_node *np = pdev->dev.of_node; | |
d6bdfa6c VO |
1267 | const struct regmap_config *regmap_config; |
1268 | struct fsl_dspi_platform_data *pdata; | |
3a11ea66 | 1269 | struct spi_controller *ctlr; |
29d2daf2 | 1270 | int ret, cs_num, bus_num = -1; |
349ad66c CF |
1271 | struct fsl_dspi *dspi; |
1272 | struct resource *res; | |
1acbdeb9 | 1273 | void __iomem *base; |
671ffde1 | 1274 | bool big_endian; |
349ad66c | 1275 | |
530b5aff SH |
1276 | dspi = devm_kzalloc(&pdev->dev, sizeof(*dspi), GFP_KERNEL); |
1277 | if (!dspi) | |
1278 | return -ENOMEM; | |
1279 | ||
6230d6ca | 1280 | ctlr = spi_alloc_host(&pdev->dev, 0); |
3a11ea66 | 1281 | if (!ctlr) |
349ad66c CF |
1282 | return -ENOMEM; |
1283 | ||
6e383766 MW |
1284 | spi_controller_set_devdata(ctlr, dspi); |
1285 | platform_set_drvdata(pdev, dspi); | |
1286 | ||
349ad66c | 1287 | dspi->pdev = pdev; |
3a11ea66 | 1288 | dspi->ctlr = ctlr; |
9298bc72 | 1289 | |
3a11ea66 VO |
1290 | ctlr->setup = dspi_setup; |
1291 | ctlr->transfer_one_message = dspi_transfer_one_message; | |
1292 | ctlr->dev.of_node = pdev->dev.of_node; | |
349ad66c | 1293 | |
3a11ea66 | 1294 | ctlr->cleanup = dspi_cleanup; |
6230d6ca | 1295 | ctlr->target_abort = dspi_target_abort; |
3a11ea66 | 1296 | ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; |
84b60f2b | 1297 | ctlr->use_gpio_descriptors = true; |
349ad66c | 1298 | |
ec7ed770 AD |
1299 | pdata = dev_get_platdata(&pdev->dev); |
1300 | if (pdata) { | |
2c2b3ad2 | 1301 | ctlr->num_chipselect = ctlr->max_native_cs = pdata->cs_num; |
3a11ea66 | 1302 | ctlr->bus_num = pdata->bus_num; |
349ad66c | 1303 | |
d3505401 VO |
1304 | /* Only Coldfire uses platform data */ |
1305 | dspi->devtype_data = &devtype_data[MCF5441X]; | |
671ffde1 | 1306 | big_endian = true; |
ec7ed770 | 1307 | } else { |
349ad66c | 1308 | |
ec7ed770 AD |
1309 | ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num); |
1310 | if (ret < 0) { | |
1311 | dev_err(&pdev->dev, "can't get spi-num-chipselects\n"); | |
3a11ea66 | 1312 | goto out_ctlr_put; |
ec7ed770 | 1313 | } |
2c2b3ad2 | 1314 | ctlr->num_chipselect = ctlr->max_native_cs = cs_num; |
ec7ed770 | 1315 | |
29d2daf2 | 1316 | of_property_read_u32(np, "bus-num", &bus_num); |
3a11ea66 | 1317 | ctlr->bus_num = bus_num; |
ec7ed770 | 1318 | |
5ce3cc56 | 1319 | if (of_property_read_bool(np, "spi-slave")) |
6230d6ca | 1320 | ctlr->target = true; |
5ce3cc56 | 1321 | |
ec7ed770 AD |
1322 | dspi->devtype_data = of_device_get_match_data(&pdev->dev); |
1323 | if (!dspi->devtype_data) { | |
1324 | dev_err(&pdev->dev, "can't get devtype_data\n"); | |
1325 | ret = -EFAULT; | |
3a11ea66 | 1326 | goto out_ctlr_put; |
ec7ed770 | 1327 | } |
671ffde1 VO |
1328 | |
1329 | big_endian = of_device_is_big_endian(np); | |
1330 | } | |
1331 | if (big_endian) { | |
1332 | dspi->pushr_cmd = 0; | |
1333 | dspi->pushr_tx = 2; | |
1334 | } else { | |
1335 | dspi->pushr_cmd = 2; | |
1336 | dspi->pushr_tx = 0; | |
d1f4a38c HW |
1337 | } |
1338 | ||
d59c90a2 | 1339 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
3a11ea66 | 1340 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
35c9d461 | 1341 | else |
3a11ea66 | 1342 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
35c9d461 | 1343 | |
f96087a3 | 1344 | base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
1acbdeb9 CF |
1345 | if (IS_ERR(base)) { |
1346 | ret = PTR_ERR(base); | |
3a11ea66 | 1347 | goto out_ctlr_put; |
349ad66c CF |
1348 | } |
1349 | ||
d59c90a2 | 1350 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
58ba07ec EH |
1351 | regmap_config = &dspi_xspi_regmap_config[0]; |
1352 | else | |
1353 | regmap_config = &dspi_regmap_config; | |
1354 | dspi->regmap = devm_regmap_init_mmio(&pdev->dev, base, regmap_config); | |
1acbdeb9 CF |
1355 | if (IS_ERR(dspi->regmap)) { |
1356 | dev_err(&pdev->dev, "failed to init regmap: %ld\n", | |
1357 | PTR_ERR(dspi->regmap)); | |
fbad6c24 | 1358 | ret = PTR_ERR(dspi->regmap); |
3a11ea66 | 1359 | goto out_ctlr_put; |
1acbdeb9 CF |
1360 | } |
1361 | ||
d59c90a2 | 1362 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) { |
58ba07ec EH |
1363 | dspi->regmap_pushr = devm_regmap_init_mmio( |
1364 | &pdev->dev, base + SPI_PUSHR, | |
1365 | &dspi_xspi_regmap_config[1]); | |
1366 | if (IS_ERR(dspi->regmap_pushr)) { | |
1367 | dev_err(&pdev->dev, | |
1368 | "failed to init pushr regmap: %ld\n", | |
1369 | PTR_ERR(dspi->regmap_pushr)); | |
80dc12cd | 1370 | ret = PTR_ERR(dspi->regmap_pushr); |
3a11ea66 | 1371 | goto out_ctlr_put; |
58ba07ec EH |
1372 | } |
1373 | } | |
1374 | ||
4812bc31 | 1375 | dspi->clk = devm_clk_get_enabled(&pdev->dev, "dspi"); |
d8ffee2f KK |
1376 | if (IS_ERR(dspi->clk)) { |
1377 | ret = PTR_ERR(dspi->clk); | |
1378 | dev_err(&pdev->dev, "unable to get clock\n"); | |
3a11ea66 | 1379 | goto out_ctlr_put; |
d8ffee2f | 1380 | } |
d8ffee2f | 1381 | |
5b342c5a VO |
1382 | ret = dspi_init(dspi); |
1383 | if (ret) | |
4812bc31 | 1384 | goto out_ctlr_put; |
c55be305 | 1385 | |
349ad66c | 1386 | dspi->irq = platform_get_irq(pdev, 0); |
c55be305 VO |
1387 | if (dspi->irq <= 0) { |
1388 | dev_info(&pdev->dev, | |
1389 | "can't get platform irq, using poll mode\n"); | |
1390 | dspi->irq = 0; | |
1391 | goto poll_mode; | |
349ad66c CF |
1392 | } |
1393 | ||
f148915f KK |
1394 | init_completion(&dspi->xfer_done); |
1395 | ||
3d87b613 KK |
1396 | ret = request_threaded_irq(dspi->irq, dspi_interrupt, NULL, |
1397 | IRQF_SHARED, pdev->name, dspi); | |
349ad66c CF |
1398 | if (ret < 0) { |
1399 | dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); | |
4812bc31 | 1400 | goto out_ctlr_put; |
349ad66c CF |
1401 | } |
1402 | ||
c55be305 | 1403 | poll_mode: |
d6b71dfa | 1404 | |
90ba3703 | 1405 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
cddebdd1 NY |
1406 | ret = dspi_request_dma(dspi, res->start); |
1407 | if (ret < 0) { | |
90ba3703 | 1408 | dev_err(&pdev->dev, "can't get dma channels\n"); |
3d87b613 | 1409 | goto out_free_irq; |
90ba3703 SM |
1410 | } |
1411 | } | |
1412 | ||
3a11ea66 | 1413 | ctlr->max_speed_hz = |
9419b200 BD |
1414 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; |
1415 | ||
63669902 VO |
1416 | if (dspi->devtype_data->trans_mode != DSPI_DMA_MODE) |
1417 | ctlr->ptp_sts_supported = true; | |
d6b71dfa | 1418 | |
3a11ea66 | 1419 | ret = spi_register_controller(ctlr); |
349ad66c | 1420 | if (ret != 0) { |
3a11ea66 | 1421 | dev_err(&pdev->dev, "Problem registering DSPI ctlr\n"); |
680ec054 | 1422 | goto out_release_dma; |
349ad66c CF |
1423 | } |
1424 | ||
349ad66c CF |
1425 | return ret; |
1426 | ||
680ec054 CJ |
1427 | out_release_dma: |
1428 | dspi_release_dma(dspi); | |
3d87b613 KK |
1429 | out_free_irq: |
1430 | if (dspi->irq) | |
1431 | free_irq(dspi->irq, dspi); | |
3a11ea66 VO |
1432 | out_ctlr_put: |
1433 | spi_controller_put(ctlr); | |
349ad66c CF |
1434 | |
1435 | return ret; | |
1436 | } | |
1437 | ||
1bcab55f | 1438 | static void dspi_remove(struct platform_device *pdev) |
349ad66c | 1439 | { |
530b5aff | 1440 | struct fsl_dspi *dspi = platform_get_drvdata(pdev); |
349ad66c CF |
1441 | |
1442 | /* Disconnect from the SPI framework */ | |
7684580d KK |
1443 | spi_unregister_controller(dspi->ctlr); |
1444 | ||
1445 | /* Disable RX and TX */ | |
1446 | regmap_update_bits(dspi->regmap, SPI_MCR, | |
1447 | SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF, | |
1448 | SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF); | |
1449 | ||
1450 | /* Stop Running */ | |
1451 | regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, SPI_MCR_HALT); | |
1452 | ||
90ba3703 | 1453 | dspi_release_dma(dspi); |
3d87b613 KK |
1454 | if (dspi->irq) |
1455 | free_irq(dspi->irq, dspi); | |
349ad66c CF |
1456 | } |
1457 | ||
dc234825 PM |
1458 | static void dspi_shutdown(struct platform_device *pdev) |
1459 | { | |
3c525b69 | 1460 | dspi_remove(pdev); |
dc234825 PM |
1461 | } |
1462 | ||
349ad66c | 1463 | static struct platform_driver fsl_dspi_driver = { |
50fcd847 VO |
1464 | .driver.name = DRIVER_NAME, |
1465 | .driver.of_match_table = fsl_dspi_dt_ids, | |
1466 | .driver.owner = THIS_MODULE, | |
1467 | .driver.pm = &dspi_pm, | |
1468 | .probe = dspi_probe, | |
1bcab55f | 1469 | .remove_new = dspi_remove, |
dc234825 | 1470 | .shutdown = dspi_shutdown, |
349ad66c CF |
1471 | }; |
1472 | module_platform_driver(fsl_dspi_driver); | |
1473 | ||
1474 | MODULE_DESCRIPTION("Freescale DSPI Controller Driver"); | |
b444d1df | 1475 | MODULE_LICENSE("GPL"); |
349ad66c | 1476 | MODULE_ALIAS("platform:" DRIVER_NAME); |