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