]>
Commit | Line | Data |
---|---|---|
79650597 FE |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | |
3 | // Copyright (C) 2008 Juergen Beisert | |
b5f3294f SH |
4 | |
5 | #include <linux/clk.h> | |
6 | #include <linux/completion.h> | |
7 | #include <linux/delay.h> | |
f62caccd RG |
8 | #include <linux/dmaengine.h> |
9 | #include <linux/dma-mapping.h> | |
b5f3294f SH |
10 | #include <linux/err.h> |
11 | #include <linux/gpio.h> | |
b5f3294f SH |
12 | #include <linux/interrupt.h> |
13 | #include <linux/io.h> | |
14 | #include <linux/irq.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/module.h> | |
17 | #include <linux/platform_device.h> | |
5a0e3ad6 | 18 | #include <linux/slab.h> |
b5f3294f SH |
19 | #include <linux/spi/spi.h> |
20 | #include <linux/spi/spi_bitbang.h> | |
21 | #include <linux/types.h> | |
22a85e4c SG |
22 | #include <linux/of.h> |
23 | #include <linux/of_device.h> | |
24 | #include <linux/of_gpio.h> | |
b5f3294f | 25 | |
f62caccd | 26 | #include <linux/platform_data/dma-imx.h> |
82906b13 | 27 | #include <linux/platform_data/spi-imx.h> |
b5f3294f SH |
28 | |
29 | #define DRIVER_NAME "spi_imx" | |
30 | ||
31 | #define MXC_CSPIRXDATA 0x00 | |
32 | #define MXC_CSPITXDATA 0x04 | |
33 | #define MXC_CSPICTRL 0x08 | |
34 | #define MXC_CSPIINT 0x0c | |
35 | #define MXC_RESET 0x1c | |
36 | ||
37 | /* generic defines to abstract from the different register layouts */ | |
38 | #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ | |
39 | #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ | |
71abd290 | 40 | #define MXC_INT_RDR BIT(4) /* Receive date threshold interrupt */ |
b5f3294f | 41 | |
f62caccd RG |
42 | /* The maximum bytes that a sdma BD can transfer.*/ |
43 | #define MAX_SDMA_BD_BYTES (1 << 15) | |
1673c81d | 44 | #define MX51_ECSPI_CTRL_MAX_BURST 512 |
71abd290 | 45 | /* The maximum bytes that IMX53_ECSPI can transfer in slave mode.*/ |
46 | #define MX53_MAX_TRANSFER_BYTES 512 | |
b5f3294f | 47 | |
f4ba6315 | 48 | enum spi_imx_devtype { |
04ee5854 SG |
49 | IMX1_CSPI, |
50 | IMX21_CSPI, | |
51 | IMX27_CSPI, | |
52 | IMX31_CSPI, | |
53 | IMX35_CSPI, /* CSPI on all i.mx except above */ | |
26e4bb86 | 54 | IMX51_ECSPI, /* ECSPI on i.mx51 */ |
55 | IMX53_ECSPI, /* ECSPI on i.mx53 and later */ | |
f4ba6315 UKK |
56 | }; |
57 | ||
58 | struct spi_imx_data; | |
59 | ||
60 | struct spi_imx_devtype_data { | |
61 | void (*intctrl)(struct spi_imx_data *, int); | |
d52345b6 | 62 | int (*config)(struct spi_device *); |
f4ba6315 UKK |
63 | void (*trigger)(struct spi_imx_data *); |
64 | int (*rx_available)(struct spi_imx_data *); | |
1723e66b | 65 | void (*reset)(struct spi_imx_data *); |
987a2dfe | 66 | void (*setup_wml)(struct spi_imx_data *); |
71abd290 | 67 | void (*disable)(struct spi_imx_data *); |
fd8d4e2d | 68 | bool has_dmamode; |
71abd290 | 69 | bool has_slavemode; |
fd8d4e2d | 70 | unsigned int fifo_size; |
1673c81d | 71 | bool dynamic_burst; |
04ee5854 | 72 | enum spi_imx_devtype devtype; |
f4ba6315 UKK |
73 | }; |
74 | ||
6cdeb002 | 75 | struct spi_imx_data { |
b5f3294f | 76 | struct spi_bitbang bitbang; |
6aa800ca | 77 | struct device *dev; |
b5f3294f SH |
78 | |
79 | struct completion xfer_done; | |
cc4d22ae | 80 | void __iomem *base; |
f12ae171 AB |
81 | unsigned long base_phys; |
82 | ||
aa29d840 SH |
83 | struct clk *clk_per; |
84 | struct clk *clk_ipg; | |
b5f3294f | 85 | unsigned long spi_clk; |
4bfe927a | 86 | unsigned int spi_bus_clk; |
b5f3294f | 87 | |
d52345b6 SH |
88 | unsigned int speed_hz; |
89 | unsigned int bits_per_word; | |
f72efa7e | 90 | unsigned int spi_drctl; |
f12ae171 | 91 | |
1673c81d | 92 | unsigned int count, remainder; |
6cdeb002 UKK |
93 | void (*tx)(struct spi_imx_data *); |
94 | void (*rx)(struct spi_imx_data *); | |
b5f3294f SH |
95 | void *rx_buf; |
96 | const void *tx_buf; | |
97 | unsigned int txfifo; /* number of words pushed in tx FIFO */ | |
2ca300ac | 98 | unsigned int dynamic_burst; |
b5f3294f | 99 | |
71abd290 | 100 | /* Slave mode */ |
101 | bool slave_mode; | |
102 | bool slave_aborted; | |
103 | unsigned int slave_burst; | |
104 | ||
f62caccd | 105 | /* DMA */ |
f62caccd | 106 | bool usedma; |
0dfbaa89 | 107 | u32 wml; |
f62caccd RG |
108 | struct completion dma_rx_completion; |
109 | struct completion dma_tx_completion; | |
110 | ||
80023cb3 | 111 | const struct spi_imx_devtype_data *devtype_data; |
b5f3294f SH |
112 | }; |
113 | ||
04ee5854 SG |
114 | static inline int is_imx27_cspi(struct spi_imx_data *d) |
115 | { | |
116 | return d->devtype_data->devtype == IMX27_CSPI; | |
117 | } | |
118 | ||
119 | static inline int is_imx35_cspi(struct spi_imx_data *d) | |
120 | { | |
121 | return d->devtype_data->devtype == IMX35_CSPI; | |
122 | } | |
123 | ||
f8a87617 AB |
124 | static inline int is_imx51_ecspi(struct spi_imx_data *d) |
125 | { | |
126 | return d->devtype_data->devtype == IMX51_ECSPI; | |
127 | } | |
128 | ||
26e4bb86 | 129 | static inline int is_imx53_ecspi(struct spi_imx_data *d) |
130 | { | |
131 | return d->devtype_data->devtype == IMX53_ECSPI; | |
132 | } | |
133 | ||
b5f3294f | 134 | #define MXC_SPI_BUF_RX(type) \ |
6cdeb002 | 135 | static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \ |
b5f3294f | 136 | { \ |
6cdeb002 | 137 | unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); \ |
b5f3294f | 138 | \ |
6cdeb002 UKK |
139 | if (spi_imx->rx_buf) { \ |
140 | *(type *)spi_imx->rx_buf = val; \ | |
141 | spi_imx->rx_buf += sizeof(type); \ | |
b5f3294f | 142 | } \ |
2ca300ac MC |
143 | \ |
144 | spi_imx->remainder -= sizeof(type); \ | |
b5f3294f SH |
145 | } |
146 | ||
147 | #define MXC_SPI_BUF_TX(type) \ | |
6cdeb002 | 148 | static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx) \ |
b5f3294f SH |
149 | { \ |
150 | type val = 0; \ | |
151 | \ | |
6cdeb002 UKK |
152 | if (spi_imx->tx_buf) { \ |
153 | val = *(type *)spi_imx->tx_buf; \ | |
154 | spi_imx->tx_buf += sizeof(type); \ | |
b5f3294f SH |
155 | } \ |
156 | \ | |
6cdeb002 | 157 | spi_imx->count -= sizeof(type); \ |
b5f3294f | 158 | \ |
6cdeb002 | 159 | writel(val, spi_imx->base + MXC_CSPITXDATA); \ |
b5f3294f SH |
160 | } |
161 | ||
162 | MXC_SPI_BUF_RX(u8) | |
163 | MXC_SPI_BUF_TX(u8) | |
164 | MXC_SPI_BUF_RX(u16) | |
165 | MXC_SPI_BUF_TX(u16) | |
166 | MXC_SPI_BUF_RX(u32) | |
167 | MXC_SPI_BUF_TX(u32) | |
168 | ||
169 | /* First entry is reserved, second entry is valid only if SDHC_SPIEN is set | |
170 | * (which is currently not the case in this driver) | |
171 | */ | |
172 | static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, | |
173 | 256, 384, 512, 768, 1024}; | |
174 | ||
175 | /* MX21, MX27 */ | |
6cdeb002 | 176 | static unsigned int spi_imx_clkdiv_1(unsigned int fin, |
32df9ff2 | 177 | unsigned int fspi, unsigned int max, unsigned int *fres) |
b5f3294f | 178 | { |
04ee5854 | 179 | int i; |
b5f3294f SH |
180 | |
181 | for (i = 2; i < max; i++) | |
182 | if (fspi * mxc_clkdivs[i] >= fin) | |
32df9ff2 | 183 | break; |
b5f3294f | 184 | |
32df9ff2 RB |
185 | *fres = fin / mxc_clkdivs[i]; |
186 | return i; | |
b5f3294f SH |
187 | } |
188 | ||
0b599603 | 189 | /* MX1, MX31, MX35, MX51 CSPI */ |
6cdeb002 | 190 | static unsigned int spi_imx_clkdiv_2(unsigned int fin, |
2636ba8f | 191 | unsigned int fspi, unsigned int *fres) |
b5f3294f SH |
192 | { |
193 | int i, div = 4; | |
194 | ||
195 | for (i = 0; i < 7; i++) { | |
196 | if (fspi * div >= fin) | |
2636ba8f | 197 | goto out; |
b5f3294f SH |
198 | div <<= 1; |
199 | } | |
200 | ||
2636ba8f MK |
201 | out: |
202 | *fres = fin / div; | |
203 | return i; | |
b5f3294f SH |
204 | } |
205 | ||
2e312f6c | 206 | static int spi_imx_bytes_per_word(const int bits_per_word) |
f12ae171 | 207 | { |
afb27208 MC |
208 | if (bits_per_word <= 8) |
209 | return 1; | |
210 | else if (bits_per_word <= 16) | |
211 | return 2; | |
212 | else | |
213 | return 4; | |
f12ae171 AB |
214 | } |
215 | ||
f62caccd RG |
216 | static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, |
217 | struct spi_transfer *transfer) | |
218 | { | |
219 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | |
f12ae171 AB |
220 | |
221 | if (!master->dma_rx) | |
222 | return false; | |
223 | ||
71abd290 | 224 | if (spi_imx->slave_mode) |
225 | return false; | |
226 | ||
133eb8e3 RG |
227 | if (transfer->len < spi_imx->devtype_data->fifo_size) |
228 | return false; | |
229 | ||
1673c81d | 230 | spi_imx->dynamic_burst = 0; |
66459c5a | 231 | |
f12ae171 | 232 | return true; |
f62caccd RG |
233 | } |
234 | ||
66de757c SG |
235 | #define MX51_ECSPI_CTRL 0x08 |
236 | #define MX51_ECSPI_CTRL_ENABLE (1 << 0) | |
237 | #define MX51_ECSPI_CTRL_XCH (1 << 2) | |
f62caccd | 238 | #define MX51_ECSPI_CTRL_SMC (1 << 3) |
66de757c | 239 | #define MX51_ECSPI_CTRL_MODE_MASK (0xf << 4) |
f72efa7e | 240 | #define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16) |
66de757c SG |
241 | #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 |
242 | #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 | |
243 | #define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) | |
244 | #define MX51_ECSPI_CTRL_BL_OFFSET 20 | |
1673c81d | 245 | #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) |
66de757c SG |
246 | |
247 | #define MX51_ECSPI_CONFIG 0x0c | |
248 | #define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) | |
249 | #define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) | |
250 | #define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) | |
251 | #define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) | |
c09b890b | 252 | #define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20)) |
66de757c SG |
253 | |
254 | #define MX51_ECSPI_INT 0x10 | |
255 | #define MX51_ECSPI_INT_TEEN (1 << 0) | |
256 | #define MX51_ECSPI_INT_RREN (1 << 3) | |
71abd290 | 257 | #define MX51_ECSPI_INT_RDREN (1 << 4) |
66de757c | 258 | |
f62caccd | 259 | #define MX51_ECSPI_DMA 0x14 |
d629c2a0 SH |
260 | #define MX51_ECSPI_DMA_TX_WML(wml) ((wml) & 0x3f) |
261 | #define MX51_ECSPI_DMA_RX_WML(wml) (((wml) & 0x3f) << 16) | |
262 | #define MX51_ECSPI_DMA_RXT_WML(wml) (((wml) & 0x3f) << 24) | |
f62caccd | 263 | |
2b0fd069 SH |
264 | #define MX51_ECSPI_DMA_TEDEN (1 << 7) |
265 | #define MX51_ECSPI_DMA_RXDEN (1 << 23) | |
266 | #define MX51_ECSPI_DMA_RXTDEN (1 << 31) | |
f62caccd | 267 | |
66de757c SG |
268 | #define MX51_ECSPI_STAT 0x18 |
269 | #define MX51_ECSPI_STAT_RR (1 << 3) | |
0b599603 | 270 | |
9f6aa42b FE |
271 | #define MX51_ECSPI_TESTREG 0x20 |
272 | #define MX51_ECSPI_TESTREG_LBC BIT(31) | |
273 | ||
1673c81d | 274 | static void spi_imx_buf_rx_swap_u32(struct spi_imx_data *spi_imx) |
275 | { | |
276 | unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); | |
5904c9d3 | 277 | #ifdef __LITTLE_ENDIAN |
1673c81d | 278 | unsigned int bytes_per_word; |
5904c9d3 | 279 | #endif |
1673c81d | 280 | |
281 | if (spi_imx->rx_buf) { | |
282 | #ifdef __LITTLE_ENDIAN | |
283 | bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); | |
284 | if (bytes_per_word == 1) | |
285 | val = cpu_to_be32(val); | |
286 | else if (bytes_per_word == 2) | |
287 | val = (val << 16) | (val >> 16); | |
288 | #endif | |
1673c81d | 289 | *(u32 *)spi_imx->rx_buf = val; |
290 | spi_imx->rx_buf += sizeof(u32); | |
291 | } | |
2ca300ac MC |
292 | |
293 | spi_imx->remainder -= sizeof(u32); | |
1673c81d | 294 | } |
295 | ||
296 | static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) | |
297 | { | |
2ca300ac MC |
298 | int unaligned; |
299 | u32 val; | |
1673c81d | 300 | |
2ca300ac MC |
301 | unaligned = spi_imx->remainder % 4; |
302 | ||
303 | if (!unaligned) { | |
1673c81d | 304 | spi_imx_buf_rx_swap_u32(spi_imx); |
305 | return; | |
306 | } | |
307 | ||
2ca300ac | 308 | if (spi_imx_bytes_per_word(spi_imx->bits_per_word) == 2) { |
1673c81d | 309 | spi_imx_buf_rx_u16(spi_imx); |
2ca300ac MC |
310 | return; |
311 | } | |
312 | ||
313 | val = readl(spi_imx->base + MXC_CSPIRXDATA); | |
314 | ||
315 | while (unaligned--) { | |
316 | if (spi_imx->rx_buf) { | |
317 | *(u8 *)spi_imx->rx_buf = (val >> (8 * unaligned)) & 0xff; | |
318 | spi_imx->rx_buf++; | |
319 | } | |
320 | spi_imx->remainder--; | |
321 | } | |
1673c81d | 322 | } |
323 | ||
324 | static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) | |
325 | { | |
326 | u32 val = 0; | |
5904c9d3 | 327 | #ifdef __LITTLE_ENDIAN |
1673c81d | 328 | unsigned int bytes_per_word; |
5904c9d3 | 329 | #endif |
1673c81d | 330 | |
331 | if (spi_imx->tx_buf) { | |
332 | val = *(u32 *)spi_imx->tx_buf; | |
1673c81d | 333 | spi_imx->tx_buf += sizeof(u32); |
334 | } | |
335 | ||
336 | spi_imx->count -= sizeof(u32); | |
337 | #ifdef __LITTLE_ENDIAN | |
338 | bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); | |
339 | ||
340 | if (bytes_per_word == 1) | |
341 | val = cpu_to_be32(val); | |
342 | else if (bytes_per_word == 2) | |
343 | val = (val << 16) | (val >> 16); | |
344 | #endif | |
345 | writel(val, spi_imx->base + MXC_CSPITXDATA); | |
346 | } | |
347 | ||
348 | static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) | |
349 | { | |
2ca300ac MC |
350 | int unaligned; |
351 | u32 val = 0; | |
1673c81d | 352 | |
2ca300ac | 353 | unaligned = spi_imx->count % 4; |
1673c81d | 354 | |
2ca300ac MC |
355 | if (!unaligned) { |
356 | spi_imx_buf_tx_swap_u32(spi_imx); | |
357 | return; | |
1673c81d | 358 | } |
359 | ||
2ca300ac MC |
360 | if (spi_imx_bytes_per_word(spi_imx->bits_per_word) == 2) { |
361 | spi_imx_buf_tx_u16(spi_imx); | |
1673c81d | 362 | return; |
363 | } | |
364 | ||
2ca300ac MC |
365 | while (unaligned--) { |
366 | if (spi_imx->tx_buf) { | |
367 | val |= *(u8 *)spi_imx->tx_buf << (8 * unaligned); | |
368 | spi_imx->tx_buf++; | |
369 | } | |
370 | spi_imx->count--; | |
371 | } | |
1673c81d | 372 | |
2ca300ac | 373 | writel(val, spi_imx->base + MXC_CSPITXDATA); |
1673c81d | 374 | } |
375 | ||
71abd290 | 376 | static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx) |
377 | { | |
378 | u32 val = be32_to_cpu(readl(spi_imx->base + MXC_CSPIRXDATA)); | |
379 | ||
380 | if (spi_imx->rx_buf) { | |
381 | int n_bytes = spi_imx->slave_burst % sizeof(val); | |
382 | ||
383 | if (!n_bytes) | |
384 | n_bytes = sizeof(val); | |
385 | ||
386 | memcpy(spi_imx->rx_buf, | |
387 | ((u8 *)&val) + sizeof(val) - n_bytes, n_bytes); | |
388 | ||
389 | spi_imx->rx_buf += n_bytes; | |
390 | spi_imx->slave_burst -= n_bytes; | |
391 | } | |
2ca300ac MC |
392 | |
393 | spi_imx->remainder -= sizeof(u32); | |
71abd290 | 394 | } |
395 | ||
396 | static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx) | |
397 | { | |
398 | u32 val = 0; | |
399 | int n_bytes = spi_imx->count % sizeof(val); | |
400 | ||
401 | if (!n_bytes) | |
402 | n_bytes = sizeof(val); | |
403 | ||
404 | if (spi_imx->tx_buf) { | |
405 | memcpy(((u8 *)&val) + sizeof(val) - n_bytes, | |
406 | spi_imx->tx_buf, n_bytes); | |
407 | val = cpu_to_be32(val); | |
408 | spi_imx->tx_buf += n_bytes; | |
409 | } | |
410 | ||
411 | spi_imx->count -= n_bytes; | |
412 | ||
413 | writel(val, spi_imx->base + MXC_CSPITXDATA); | |
414 | } | |
415 | ||
0b599603 | 416 | /* MX51 eCSPI */ |
6aa800ca SH |
417 | static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx, |
418 | unsigned int fspi, unsigned int *fres) | |
0b599603 UKK |
419 | { |
420 | /* | |
421 | * there are two 4-bit dividers, the pre-divider divides by | |
422 | * $pre, the post-divider by 2^$post | |
423 | */ | |
424 | unsigned int pre, post; | |
6aa800ca | 425 | unsigned int fin = spi_imx->spi_clk; |
0b599603 UKK |
426 | |
427 | if (unlikely(fspi > fin)) | |
428 | return 0; | |
429 | ||
430 | post = fls(fin) - fls(fspi); | |
431 | if (fin > fspi << post) | |
432 | post++; | |
433 | ||
434 | /* now we have: (fin <= fspi << post) with post being minimal */ | |
435 | ||
436 | post = max(4U, post) - 4; | |
437 | if (unlikely(post > 0xf)) { | |
6aa800ca SH |
438 | dev_err(spi_imx->dev, "cannot set clock freq: %u (base freq: %u)\n", |
439 | fspi, fin); | |
0b599603 UKK |
440 | return 0xff; |
441 | } | |
442 | ||
443 | pre = DIV_ROUND_UP(fin, fspi << post) - 1; | |
444 | ||
6aa800ca | 445 | dev_dbg(spi_imx->dev, "%s: fin: %u, fspi: %u, post: %u, pre: %u\n", |
0b599603 | 446 | __func__, fin, fspi, post, pre); |
6fd8b850 MV |
447 | |
448 | /* Resulting frequency for the SCLK line. */ | |
449 | *fres = (fin / (pre + 1)) >> post; | |
450 | ||
66de757c SG |
451 | return (pre << MX51_ECSPI_CTRL_PREDIV_OFFSET) | |
452 | (post << MX51_ECSPI_CTRL_POSTDIV_OFFSET); | |
0b599603 UKK |
453 | } |
454 | ||
f989bc69 | 455 | static void mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int enable) |
0b599603 UKK |
456 | { |
457 | unsigned val = 0; | |
458 | ||
459 | if (enable & MXC_INT_TE) | |
66de757c | 460 | val |= MX51_ECSPI_INT_TEEN; |
0b599603 UKK |
461 | |
462 | if (enable & MXC_INT_RR) | |
66de757c | 463 | val |= MX51_ECSPI_INT_RREN; |
0b599603 | 464 | |
71abd290 | 465 | if (enable & MXC_INT_RDR) |
466 | val |= MX51_ECSPI_INT_RDREN; | |
467 | ||
66de757c | 468 | writel(val, spi_imx->base + MX51_ECSPI_INT); |
0b599603 UKK |
469 | } |
470 | ||
f989bc69 | 471 | static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx) |
0b599603 | 472 | { |
b03c3884 | 473 | u32 reg; |
f62caccd | 474 | |
b03c3884 SH |
475 | reg = readl(spi_imx->base + MX51_ECSPI_CTRL); |
476 | reg |= MX51_ECSPI_CTRL_XCH; | |
66de757c | 477 | writel(reg, spi_imx->base + MX51_ECSPI_CTRL); |
0b599603 UKK |
478 | } |
479 | ||
71abd290 | 480 | static void mx51_ecspi_disable(struct spi_imx_data *spi_imx) |
481 | { | |
482 | u32 ctrl; | |
483 | ||
484 | ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); | |
485 | ctrl &= ~MX51_ECSPI_CTRL_ENABLE; | |
486 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); | |
487 | } | |
488 | ||
d52345b6 | 489 | static int mx51_ecspi_config(struct spi_device *spi) |
0b599603 | 490 | { |
b36581df | 491 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
793c7f92 | 492 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; |
d52345b6 | 493 | u32 clk = spi_imx->speed_hz, delay, reg; |
793c7f92 | 494 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); |
0b599603 | 495 | |
71abd290 | 496 | /* set Master or Slave mode */ |
497 | if (spi_imx->slave_mode) | |
498 | ctrl &= ~MX51_ECSPI_CTRL_MODE_MASK; | |
499 | else | |
500 | ctrl |= MX51_ECSPI_CTRL_MODE_MASK; | |
0b599603 | 501 | |
f72efa7e LM |
502 | /* |
503 | * Enable SPI_RDY handling (falling edge/level triggered). | |
504 | */ | |
505 | if (spi->mode & SPI_READY) | |
506 | ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl); | |
507 | ||
0b599603 | 508 | /* set clock speed */ |
d52345b6 | 509 | ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk); |
4bfe927a | 510 | spi_imx->spi_bus_clk = clk; |
0b599603 UKK |
511 | |
512 | /* set chip select to use */ | |
b36581df | 513 | ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select); |
0b599603 | 514 | |
71abd290 | 515 | if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx)) |
516 | ctrl |= (spi_imx->slave_burst * 8 - 1) | |
517 | << MX51_ECSPI_CTRL_BL_OFFSET; | |
518 | else | |
519 | ctrl |= (spi_imx->bits_per_word - 1) | |
520 | << MX51_ECSPI_CTRL_BL_OFFSET; | |
0b599603 | 521 | |
71abd290 | 522 | /* |
523 | * eCSPI burst completion by Chip Select signal in Slave mode | |
524 | * is not functional for imx53 Soc, config SPI burst completed when | |
525 | * BURST_LENGTH + 1 bits are received | |
526 | */ | |
527 | if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx)) | |
528 | cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); | |
529 | else | |
530 | cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); | |
0b599603 | 531 | |
c0c7a5d7 | 532 | if (spi->mode & SPI_CPHA) |
b36581df | 533 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select); |
793c7f92 | 534 | else |
b36581df | 535 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select); |
0b599603 | 536 | |
c0c7a5d7 | 537 | if (spi->mode & SPI_CPOL) { |
b36581df AS |
538 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select); |
539 | cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select); | |
793c7f92 | 540 | } else { |
b36581df AS |
541 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select); |
542 | cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select); | |
c09b890b | 543 | } |
c0c7a5d7 | 544 | if (spi->mode & SPI_CS_HIGH) |
b36581df | 545 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select); |
793c7f92 | 546 | else |
b36581df | 547 | cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select); |
0b599603 | 548 | |
b03c3884 SH |
549 | if (spi_imx->usedma) |
550 | ctrl |= MX51_ECSPI_CTRL_SMC; | |
551 | ||
f677f17c AB |
552 | /* CTRL register always go first to bring out controller from reset */ |
553 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); | |
554 | ||
9f6aa42b | 555 | reg = readl(spi_imx->base + MX51_ECSPI_TESTREG); |
c0c7a5d7 | 556 | if (spi->mode & SPI_LOOP) |
9f6aa42b FE |
557 | reg |= MX51_ECSPI_TESTREG_LBC; |
558 | else | |
559 | reg &= ~MX51_ECSPI_TESTREG_LBC; | |
560 | writel(reg, spi_imx->base + MX51_ECSPI_TESTREG); | |
561 | ||
66de757c | 562 | writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); |
0b599603 | 563 | |
6fd8b850 MV |
564 | /* |
565 | * Wait until the changes in the configuration register CONFIGREG | |
566 | * propagate into the hardware. It takes exactly one tick of the | |
567 | * SCLK clock, but we will wait two SCLK clock just to be sure. The | |
568 | * effect of the delay it takes for the hardware to apply changes | |
569 | * is noticable if the SCLK clock run very slow. In such a case, if | |
570 | * the polarity of SCLK should be inverted, the GPIO ChipSelect might | |
571 | * be asserted before the SCLK polarity changes, which would disrupt | |
572 | * the SPI communication as the device on the other end would consider | |
573 | * the change of SCLK polarity as a clock tick already. | |
574 | */ | |
575 | delay = (2 * 1000000) / clk; | |
576 | if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ | |
577 | udelay(delay); | |
578 | else /* SCLK is _very_ slow */ | |
579 | usleep_range(delay, delay + 10); | |
580 | ||
987a2dfe RG |
581 | return 0; |
582 | } | |
583 | ||
584 | static void mx51_setup_wml(struct spi_imx_data *spi_imx) | |
585 | { | |
f62caccd RG |
586 | /* |
587 | * Configure the DMA register: setup the watermark | |
588 | * and enable DMA request. | |
589 | */ | |
2b0fd069 | 590 | |
5ba5a373 | 591 | writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) | |
d629c2a0 SH |
592 | MX51_ECSPI_DMA_TX_WML(spi_imx->wml) | |
593 | MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) | | |
2b0fd069 SH |
594 | MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN | |
595 | MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA); | |
0b599603 UKK |
596 | } |
597 | ||
f989bc69 | 598 | static int mx51_ecspi_rx_available(struct spi_imx_data *spi_imx) |
0b599603 | 599 | { |
66de757c | 600 | return readl(spi_imx->base + MX51_ECSPI_STAT) & MX51_ECSPI_STAT_RR; |
0b599603 UKK |
601 | } |
602 | ||
f989bc69 | 603 | static void mx51_ecspi_reset(struct spi_imx_data *spi_imx) |
0b599603 UKK |
604 | { |
605 | /* drain receive buffer */ | |
66de757c | 606 | while (mx51_ecspi_rx_available(spi_imx)) |
0b599603 UKK |
607 | readl(spi_imx->base + MXC_CSPIRXDATA); |
608 | } | |
609 | ||
b5f3294f SH |
610 | #define MX31_INTREG_TEEN (1 << 0) |
611 | #define MX31_INTREG_RREN (1 << 3) | |
612 | ||
613 | #define MX31_CSPICTRL_ENABLE (1 << 0) | |
614 | #define MX31_CSPICTRL_MASTER (1 << 1) | |
615 | #define MX31_CSPICTRL_XCH (1 << 2) | |
2dd33f9c | 616 | #define MX31_CSPICTRL_SMC (1 << 3) |
b5f3294f SH |
617 | #define MX31_CSPICTRL_POL (1 << 4) |
618 | #define MX31_CSPICTRL_PHA (1 << 5) | |
619 | #define MX31_CSPICTRL_SSCTL (1 << 6) | |
620 | #define MX31_CSPICTRL_SSPOL (1 << 7) | |
621 | #define MX31_CSPICTRL_BC_SHIFT 8 | |
622 | #define MX35_CSPICTRL_BL_SHIFT 20 | |
623 | #define MX31_CSPICTRL_CS_SHIFT 24 | |
624 | #define MX35_CSPICTRL_CS_SHIFT 12 | |
625 | #define MX31_CSPICTRL_DR_SHIFT 16 | |
626 | ||
2dd33f9c MK |
627 | #define MX31_CSPI_DMAREG 0x10 |
628 | #define MX31_DMAREG_RH_DEN (1<<4) | |
629 | #define MX31_DMAREG_TH_DEN (1<<1) | |
630 | ||
b5f3294f SH |
631 | #define MX31_CSPISTATUS 0x14 |
632 | #define MX31_STATUS_RR (1 << 3) | |
633 | ||
15ca9215 MK |
634 | #define MX31_CSPI_TESTREG 0x1C |
635 | #define MX31_TEST_LBC (1 << 14) | |
636 | ||
b5f3294f SH |
637 | /* These functions also work for the i.MX35, but be aware that |
638 | * the i.MX35 has a slightly different register layout for bits | |
639 | * we do not use here. | |
640 | */ | |
f989bc69 | 641 | static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable) |
b5f3294f SH |
642 | { |
643 | unsigned int val = 0; | |
644 | ||
645 | if (enable & MXC_INT_TE) | |
646 | val |= MX31_INTREG_TEEN; | |
647 | if (enable & MXC_INT_RR) | |
648 | val |= MX31_INTREG_RREN; | |
649 | ||
6cdeb002 | 650 | writel(val, spi_imx->base + MXC_CSPIINT); |
b5f3294f SH |
651 | } |
652 | ||
f989bc69 | 653 | static void mx31_trigger(struct spi_imx_data *spi_imx) |
b5f3294f SH |
654 | { |
655 | unsigned int reg; | |
656 | ||
6cdeb002 | 657 | reg = readl(spi_imx->base + MXC_CSPICTRL); |
b5f3294f | 658 | reg |= MX31_CSPICTRL_XCH; |
6cdeb002 | 659 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
b5f3294f SH |
660 | } |
661 | ||
d52345b6 | 662 | static int mx31_config(struct spi_device *spi) |
1723e66b | 663 | { |
b36581df | 664 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
1723e66b | 665 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; |
2636ba8f | 666 | unsigned int clk; |
1723e66b | 667 | |
d52345b6 | 668 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->speed_hz, &clk) << |
1723e66b | 669 | MX31_CSPICTRL_DR_SHIFT; |
2636ba8f | 670 | spi_imx->spi_bus_clk = clk; |
1723e66b | 671 | |
04ee5854 | 672 | if (is_imx35_cspi(spi_imx)) { |
d52345b6 | 673 | reg |= (spi_imx->bits_per_word - 1) << MX35_CSPICTRL_BL_SHIFT; |
2a64a90a SG |
674 | reg |= MX31_CSPICTRL_SSCTL; |
675 | } else { | |
d52345b6 | 676 | reg |= (spi_imx->bits_per_word - 1) << MX31_CSPICTRL_BC_SHIFT; |
2a64a90a | 677 | } |
1723e66b | 678 | |
c0c7a5d7 | 679 | if (spi->mode & SPI_CPHA) |
1723e66b | 680 | reg |= MX31_CSPICTRL_PHA; |
c0c7a5d7 | 681 | if (spi->mode & SPI_CPOL) |
1723e66b | 682 | reg |= MX31_CSPICTRL_POL; |
c0c7a5d7 | 683 | if (spi->mode & SPI_CS_HIGH) |
1723e66b | 684 | reg |= MX31_CSPICTRL_SSPOL; |
602c8f44 GU |
685 | if (!gpio_is_valid(spi->cs_gpio)) |
686 | reg |= (spi->chip_select) << | |
04ee5854 SG |
687 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : |
688 | MX31_CSPICTRL_CS_SHIFT); | |
1723e66b | 689 | |
2dd33f9c MK |
690 | if (spi_imx->usedma) |
691 | reg |= MX31_CSPICTRL_SMC; | |
692 | ||
1723e66b UKK |
693 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
694 | ||
15ca9215 MK |
695 | reg = readl(spi_imx->base + MX31_CSPI_TESTREG); |
696 | if (spi->mode & SPI_LOOP) | |
697 | reg |= MX31_TEST_LBC; | |
698 | else | |
699 | reg &= ~MX31_TEST_LBC; | |
700 | writel(reg, spi_imx->base + MX31_CSPI_TESTREG); | |
701 | ||
2dd33f9c MK |
702 | if (spi_imx->usedma) { |
703 | /* configure DMA requests when RXFIFO is half full and | |
704 | when TXFIFO is half empty */ | |
705 | writel(MX31_DMAREG_RH_DEN | MX31_DMAREG_TH_DEN, | |
706 | spi_imx->base + MX31_CSPI_DMAREG); | |
707 | } | |
708 | ||
1723e66b UKK |
709 | return 0; |
710 | } | |
711 | ||
f989bc69 | 712 | static int mx31_rx_available(struct spi_imx_data *spi_imx) |
b5f3294f | 713 | { |
6cdeb002 | 714 | return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR; |
b5f3294f SH |
715 | } |
716 | ||
f989bc69 | 717 | static void mx31_reset(struct spi_imx_data *spi_imx) |
1723e66b UKK |
718 | { |
719 | /* drain receive buffer */ | |
2a64a90a | 720 | while (readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR) |
1723e66b UKK |
721 | readl(spi_imx->base + MXC_CSPIRXDATA); |
722 | } | |
723 | ||
3451fb15 SG |
724 | #define MX21_INTREG_RR (1 << 4) |
725 | #define MX21_INTREG_TEEN (1 << 9) | |
726 | #define MX21_INTREG_RREN (1 << 13) | |
727 | ||
728 | #define MX21_CSPICTRL_POL (1 << 5) | |
729 | #define MX21_CSPICTRL_PHA (1 << 6) | |
730 | #define MX21_CSPICTRL_SSPOL (1 << 8) | |
731 | #define MX21_CSPICTRL_XCH (1 << 9) | |
732 | #define MX21_CSPICTRL_ENABLE (1 << 10) | |
733 | #define MX21_CSPICTRL_MASTER (1 << 11) | |
734 | #define MX21_CSPICTRL_DR_SHIFT 14 | |
735 | #define MX21_CSPICTRL_CS_SHIFT 19 | |
736 | ||
f989bc69 | 737 | static void mx21_intctrl(struct spi_imx_data *spi_imx, int enable) |
b5f3294f SH |
738 | { |
739 | unsigned int val = 0; | |
740 | ||
741 | if (enable & MXC_INT_TE) | |
3451fb15 | 742 | val |= MX21_INTREG_TEEN; |
b5f3294f | 743 | if (enable & MXC_INT_RR) |
3451fb15 | 744 | val |= MX21_INTREG_RREN; |
b5f3294f | 745 | |
6cdeb002 | 746 | writel(val, spi_imx->base + MXC_CSPIINT); |
b5f3294f SH |
747 | } |
748 | ||
f989bc69 | 749 | static void mx21_trigger(struct spi_imx_data *spi_imx) |
b5f3294f SH |
750 | { |
751 | unsigned int reg; | |
752 | ||
6cdeb002 | 753 | reg = readl(spi_imx->base + MXC_CSPICTRL); |
3451fb15 | 754 | reg |= MX21_CSPICTRL_XCH; |
6cdeb002 | 755 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
b5f3294f SH |
756 | } |
757 | ||
d52345b6 | 758 | static int mx21_config(struct spi_device *spi) |
b5f3294f | 759 | { |
b36581df | 760 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
3451fb15 | 761 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; |
04ee5854 | 762 | unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; |
32df9ff2 RB |
763 | unsigned int clk; |
764 | ||
d52345b6 | 765 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, spi_imx->speed_hz, max, &clk) |
32df9ff2 RB |
766 | << MX21_CSPICTRL_DR_SHIFT; |
767 | spi_imx->spi_bus_clk = clk; | |
b5f3294f | 768 | |
d52345b6 | 769 | reg |= spi_imx->bits_per_word - 1; |
b5f3294f | 770 | |
c0c7a5d7 | 771 | if (spi->mode & SPI_CPHA) |
3451fb15 | 772 | reg |= MX21_CSPICTRL_PHA; |
c0c7a5d7 | 773 | if (spi->mode & SPI_CPOL) |
3451fb15 | 774 | reg |= MX21_CSPICTRL_POL; |
c0c7a5d7 | 775 | if (spi->mode & SPI_CS_HIGH) |
3451fb15 | 776 | reg |= MX21_CSPICTRL_SSPOL; |
602c8f44 GU |
777 | if (!gpio_is_valid(spi->cs_gpio)) |
778 | reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; | |
b5f3294f | 779 | |
6cdeb002 | 780 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
b5f3294f SH |
781 | |
782 | return 0; | |
783 | } | |
784 | ||
f989bc69 | 785 | static int mx21_rx_available(struct spi_imx_data *spi_imx) |
b5f3294f | 786 | { |
3451fb15 | 787 | return readl(spi_imx->base + MXC_CSPIINT) & MX21_INTREG_RR; |
b5f3294f SH |
788 | } |
789 | ||
f989bc69 | 790 | static void mx21_reset(struct spi_imx_data *spi_imx) |
1723e66b UKK |
791 | { |
792 | writel(1, spi_imx->base + MXC_RESET); | |
793 | } | |
794 | ||
b5f3294f SH |
795 | #define MX1_INTREG_RR (1 << 3) |
796 | #define MX1_INTREG_TEEN (1 << 8) | |
797 | #define MX1_INTREG_RREN (1 << 11) | |
798 | ||
799 | #define MX1_CSPICTRL_POL (1 << 4) | |
800 | #define MX1_CSPICTRL_PHA (1 << 5) | |
801 | #define MX1_CSPICTRL_XCH (1 << 8) | |
802 | #define MX1_CSPICTRL_ENABLE (1 << 9) | |
803 | #define MX1_CSPICTRL_MASTER (1 << 10) | |
804 | #define MX1_CSPICTRL_DR_SHIFT 13 | |
805 | ||
f989bc69 | 806 | static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable) |
b5f3294f SH |
807 | { |
808 | unsigned int val = 0; | |
809 | ||
810 | if (enable & MXC_INT_TE) | |
811 | val |= MX1_INTREG_TEEN; | |
812 | if (enable & MXC_INT_RR) | |
813 | val |= MX1_INTREG_RREN; | |
814 | ||
6cdeb002 | 815 | writel(val, spi_imx->base + MXC_CSPIINT); |
b5f3294f SH |
816 | } |
817 | ||
f989bc69 | 818 | static void mx1_trigger(struct spi_imx_data *spi_imx) |
b5f3294f SH |
819 | { |
820 | unsigned int reg; | |
821 | ||
6cdeb002 | 822 | reg = readl(spi_imx->base + MXC_CSPICTRL); |
b5f3294f | 823 | reg |= MX1_CSPICTRL_XCH; |
6cdeb002 | 824 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
b5f3294f SH |
825 | } |
826 | ||
d52345b6 | 827 | static int mx1_config(struct spi_device *spi) |
b5f3294f | 828 | { |
b36581df | 829 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
b5f3294f | 830 | unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; |
2636ba8f | 831 | unsigned int clk; |
b5f3294f | 832 | |
d52345b6 | 833 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->speed_hz, &clk) << |
b5f3294f | 834 | MX1_CSPICTRL_DR_SHIFT; |
2636ba8f MK |
835 | spi_imx->spi_bus_clk = clk; |
836 | ||
d52345b6 | 837 | reg |= spi_imx->bits_per_word - 1; |
b5f3294f | 838 | |
c0c7a5d7 | 839 | if (spi->mode & SPI_CPHA) |
b5f3294f | 840 | reg |= MX1_CSPICTRL_PHA; |
c0c7a5d7 | 841 | if (spi->mode & SPI_CPOL) |
b5f3294f SH |
842 | reg |= MX1_CSPICTRL_POL; |
843 | ||
6cdeb002 | 844 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
b5f3294f SH |
845 | |
846 | return 0; | |
847 | } | |
848 | ||
f989bc69 | 849 | static int mx1_rx_available(struct spi_imx_data *spi_imx) |
b5f3294f | 850 | { |
6cdeb002 | 851 | return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR; |
b5f3294f SH |
852 | } |
853 | ||
f989bc69 | 854 | static void mx1_reset(struct spi_imx_data *spi_imx) |
1723e66b UKK |
855 | { |
856 | writel(1, spi_imx->base + MXC_RESET); | |
857 | } | |
858 | ||
04ee5854 SG |
859 | static struct spi_imx_devtype_data imx1_cspi_devtype_data = { |
860 | .intctrl = mx1_intctrl, | |
861 | .config = mx1_config, | |
862 | .trigger = mx1_trigger, | |
863 | .rx_available = mx1_rx_available, | |
864 | .reset = mx1_reset, | |
fd8d4e2d | 865 | .fifo_size = 8, |
866 | .has_dmamode = false, | |
1673c81d | 867 | .dynamic_burst = false, |
71abd290 | 868 | .has_slavemode = false, |
04ee5854 SG |
869 | .devtype = IMX1_CSPI, |
870 | }; | |
871 | ||
872 | static struct spi_imx_devtype_data imx21_cspi_devtype_data = { | |
873 | .intctrl = mx21_intctrl, | |
874 | .config = mx21_config, | |
875 | .trigger = mx21_trigger, | |
876 | .rx_available = mx21_rx_available, | |
877 | .reset = mx21_reset, | |
fd8d4e2d | 878 | .fifo_size = 8, |
879 | .has_dmamode = false, | |
1673c81d | 880 | .dynamic_burst = false, |
71abd290 | 881 | .has_slavemode = false, |
04ee5854 SG |
882 | .devtype = IMX21_CSPI, |
883 | }; | |
884 | ||
885 | static struct spi_imx_devtype_data imx27_cspi_devtype_data = { | |
886 | /* i.mx27 cspi shares the functions with i.mx21 one */ | |
887 | .intctrl = mx21_intctrl, | |
888 | .config = mx21_config, | |
889 | .trigger = mx21_trigger, | |
890 | .rx_available = mx21_rx_available, | |
891 | .reset = mx21_reset, | |
fd8d4e2d | 892 | .fifo_size = 8, |
893 | .has_dmamode = false, | |
1673c81d | 894 | .dynamic_burst = false, |
71abd290 | 895 | .has_slavemode = false, |
04ee5854 SG |
896 | .devtype = IMX27_CSPI, |
897 | }; | |
898 | ||
899 | static struct spi_imx_devtype_data imx31_cspi_devtype_data = { | |
900 | .intctrl = mx31_intctrl, | |
901 | .config = mx31_config, | |
902 | .trigger = mx31_trigger, | |
903 | .rx_available = mx31_rx_available, | |
904 | .reset = mx31_reset, | |
fd8d4e2d | 905 | .fifo_size = 8, |
906 | .has_dmamode = false, | |
1673c81d | 907 | .dynamic_burst = false, |
71abd290 | 908 | .has_slavemode = false, |
04ee5854 SG |
909 | .devtype = IMX31_CSPI, |
910 | }; | |
911 | ||
912 | static struct spi_imx_devtype_data imx35_cspi_devtype_data = { | |
913 | /* i.mx35 and later cspi shares the functions with i.mx31 one */ | |
914 | .intctrl = mx31_intctrl, | |
915 | .config = mx31_config, | |
916 | .trigger = mx31_trigger, | |
917 | .rx_available = mx31_rx_available, | |
918 | .reset = mx31_reset, | |
fd8d4e2d | 919 | .fifo_size = 8, |
920 | .has_dmamode = true, | |
1673c81d | 921 | .dynamic_burst = false, |
71abd290 | 922 | .has_slavemode = false, |
04ee5854 SG |
923 | .devtype = IMX35_CSPI, |
924 | }; | |
925 | ||
926 | static struct spi_imx_devtype_data imx51_ecspi_devtype_data = { | |
927 | .intctrl = mx51_ecspi_intctrl, | |
928 | .config = mx51_ecspi_config, | |
929 | .trigger = mx51_ecspi_trigger, | |
930 | .rx_available = mx51_ecspi_rx_available, | |
931 | .reset = mx51_ecspi_reset, | |
987a2dfe | 932 | .setup_wml = mx51_setup_wml, |
fd8d4e2d | 933 | .fifo_size = 64, |
934 | .has_dmamode = true, | |
1673c81d | 935 | .dynamic_burst = true, |
71abd290 | 936 | .has_slavemode = true, |
937 | .disable = mx51_ecspi_disable, | |
04ee5854 SG |
938 | .devtype = IMX51_ECSPI, |
939 | }; | |
940 | ||
26e4bb86 | 941 | static struct spi_imx_devtype_data imx53_ecspi_devtype_data = { |
942 | .intctrl = mx51_ecspi_intctrl, | |
943 | .config = mx51_ecspi_config, | |
944 | .trigger = mx51_ecspi_trigger, | |
945 | .rx_available = mx51_ecspi_rx_available, | |
946 | .reset = mx51_ecspi_reset, | |
947 | .fifo_size = 64, | |
948 | .has_dmamode = true, | |
71abd290 | 949 | .has_slavemode = true, |
950 | .disable = mx51_ecspi_disable, | |
26e4bb86 | 951 | .devtype = IMX53_ECSPI, |
952 | }; | |
953 | ||
db1b8200 | 954 | static const struct platform_device_id spi_imx_devtype[] = { |
04ee5854 SG |
955 | { |
956 | .name = "imx1-cspi", | |
957 | .driver_data = (kernel_ulong_t) &imx1_cspi_devtype_data, | |
958 | }, { | |
959 | .name = "imx21-cspi", | |
960 | .driver_data = (kernel_ulong_t) &imx21_cspi_devtype_data, | |
961 | }, { | |
962 | .name = "imx27-cspi", | |
963 | .driver_data = (kernel_ulong_t) &imx27_cspi_devtype_data, | |
964 | }, { | |
965 | .name = "imx31-cspi", | |
966 | .driver_data = (kernel_ulong_t) &imx31_cspi_devtype_data, | |
967 | }, { | |
968 | .name = "imx35-cspi", | |
969 | .driver_data = (kernel_ulong_t) &imx35_cspi_devtype_data, | |
970 | }, { | |
971 | .name = "imx51-ecspi", | |
972 | .driver_data = (kernel_ulong_t) &imx51_ecspi_devtype_data, | |
26e4bb86 | 973 | }, { |
974 | .name = "imx53-ecspi", | |
975 | .driver_data = (kernel_ulong_t) &imx53_ecspi_devtype_data, | |
04ee5854 SG |
976 | }, { |
977 | /* sentinel */ | |
978 | } | |
f4ba6315 UKK |
979 | }; |
980 | ||
22a85e4c SG |
981 | static const struct of_device_id spi_imx_dt_ids[] = { |
982 | { .compatible = "fsl,imx1-cspi", .data = &imx1_cspi_devtype_data, }, | |
983 | { .compatible = "fsl,imx21-cspi", .data = &imx21_cspi_devtype_data, }, | |
984 | { .compatible = "fsl,imx27-cspi", .data = &imx27_cspi_devtype_data, }, | |
985 | { .compatible = "fsl,imx31-cspi", .data = &imx31_cspi_devtype_data, }, | |
986 | { .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, }, | |
987 | { .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, }, | |
26e4bb86 | 988 | { .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, }, |
22a85e4c SG |
989 | { /* sentinel */ } |
990 | }; | |
27743e0b | 991 | MODULE_DEVICE_TABLE(of, spi_imx_dt_ids); |
22a85e4c | 992 | |
6cdeb002 | 993 | static void spi_imx_chipselect(struct spi_device *spi, int is_active) |
b5f3294f | 994 | { |
e6a0a8bf UKK |
995 | int active = is_active != BITBANG_CS_INACTIVE; |
996 | int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); | |
b5f3294f | 997 | |
ab2f3572 OR |
998 | if (spi->mode & SPI_NO_CS) |
999 | return; | |
1000 | ||
b36581df | 1001 | if (!gpio_is_valid(spi->cs_gpio)) |
b5f3294f | 1002 | return; |
b5f3294f | 1003 | |
b36581df | 1004 | gpio_set_value(spi->cs_gpio, dev_is_lowactive ^ active); |
b5f3294f SH |
1005 | } |
1006 | ||
2ca300ac MC |
1007 | static void spi_imx_set_burst_len(struct spi_imx_data *spi_imx, int n_bits) |
1008 | { | |
1009 | u32 ctrl; | |
1010 | ||
1011 | ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); | |
1012 | ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; | |
1013 | ctrl |= ((n_bits - 1) << MX51_ECSPI_CTRL_BL_OFFSET); | |
1014 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); | |
1015 | } | |
1016 | ||
6cdeb002 | 1017 | static void spi_imx_push(struct spi_imx_data *spi_imx) |
b5f3294f | 1018 | { |
2ca300ac MC |
1019 | unsigned int burst_len, fifo_words; |
1020 | ||
1021 | if (spi_imx->dynamic_burst) | |
1022 | fifo_words = 4; | |
1023 | else | |
1024 | fifo_words = spi_imx_bytes_per_word(spi_imx->bits_per_word); | |
1025 | /* | |
1026 | * Reload the FIFO when the remaining bytes to be transferred in the | |
1027 | * current burst is 0. This only applies when bits_per_word is a | |
1028 | * multiple of 8. | |
1029 | */ | |
1030 | if (!spi_imx->remainder) { | |
1031 | if (spi_imx->dynamic_burst) { | |
1032 | ||
1033 | /* We need to deal unaligned data first */ | |
1034 | burst_len = spi_imx->count % MX51_ECSPI_CTRL_MAX_BURST; | |
1035 | ||
1036 | if (!burst_len) | |
1037 | burst_len = MX51_ECSPI_CTRL_MAX_BURST; | |
1038 | ||
1039 | spi_imx_set_burst_len(spi_imx, burst_len * 8); | |
1040 | ||
1041 | spi_imx->remainder = burst_len; | |
1042 | } else { | |
1043 | spi_imx->remainder = fifo_words; | |
1044 | } | |
1045 | } | |
1046 | ||
fd8d4e2d | 1047 | while (spi_imx->txfifo < spi_imx->devtype_data->fifo_size) { |
6cdeb002 | 1048 | if (!spi_imx->count) |
b5f3294f | 1049 | break; |
2ca300ac MC |
1050 | if (spi_imx->dynamic_burst && |
1051 | spi_imx->txfifo >= DIV_ROUND_UP(spi_imx->remainder, | |
1052 | fifo_words)) | |
1673c81d | 1053 | break; |
6cdeb002 UKK |
1054 | spi_imx->tx(spi_imx); |
1055 | spi_imx->txfifo++; | |
b5f3294f SH |
1056 | } |
1057 | ||
71abd290 | 1058 | if (!spi_imx->slave_mode) |
1059 | spi_imx->devtype_data->trigger(spi_imx); | |
b5f3294f SH |
1060 | } |
1061 | ||
6cdeb002 | 1062 | static irqreturn_t spi_imx_isr(int irq, void *dev_id) |
b5f3294f | 1063 | { |
6cdeb002 | 1064 | struct spi_imx_data *spi_imx = dev_id; |
b5f3294f | 1065 | |
71abd290 | 1066 | while (spi_imx->txfifo && |
1067 | spi_imx->devtype_data->rx_available(spi_imx)) { | |
6cdeb002 UKK |
1068 | spi_imx->rx(spi_imx); |
1069 | spi_imx->txfifo--; | |
b5f3294f SH |
1070 | } |
1071 | ||
6cdeb002 UKK |
1072 | if (spi_imx->count) { |
1073 | spi_imx_push(spi_imx); | |
b5f3294f SH |
1074 | return IRQ_HANDLED; |
1075 | } | |
1076 | ||
6cdeb002 | 1077 | if (spi_imx->txfifo) { |
b5f3294f SH |
1078 | /* No data left to push, but still waiting for rx data, |
1079 | * enable receive data available interrupt. | |
1080 | */ | |
edd501bb | 1081 | spi_imx->devtype_data->intctrl( |
f4ba6315 | 1082 | spi_imx, MXC_INT_RR); |
b5f3294f SH |
1083 | return IRQ_HANDLED; |
1084 | } | |
1085 | ||
edd501bb | 1086 | spi_imx->devtype_data->intctrl(spi_imx, 0); |
6cdeb002 | 1087 | complete(&spi_imx->xfer_done); |
b5f3294f SH |
1088 | |
1089 | return IRQ_HANDLED; | |
1090 | } | |
1091 | ||
65017ee2 | 1092 | static int spi_imx_dma_configure(struct spi_master *master) |
f12ae171 AB |
1093 | { |
1094 | int ret; | |
1095 | enum dma_slave_buswidth buswidth; | |
1096 | struct dma_slave_config rx = {}, tx = {}; | |
1097 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | |
1098 | ||
65017ee2 | 1099 | switch (spi_imx_bytes_per_word(spi_imx->bits_per_word)) { |
f12ae171 AB |
1100 | case 4: |
1101 | buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; | |
1102 | break; | |
1103 | case 2: | |
1104 | buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; | |
1105 | break; | |
1106 | case 1: | |
1107 | buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; | |
1108 | break; | |
1109 | default: | |
1110 | return -EINVAL; | |
1111 | } | |
1112 | ||
1113 | tx.direction = DMA_MEM_TO_DEV; | |
1114 | tx.dst_addr = spi_imx->base_phys + MXC_CSPITXDATA; | |
1115 | tx.dst_addr_width = buswidth; | |
1116 | tx.dst_maxburst = spi_imx->wml; | |
1117 | ret = dmaengine_slave_config(master->dma_tx, &tx); | |
1118 | if (ret) { | |
1119 | dev_err(spi_imx->dev, "TX dma configuration failed with %d\n", ret); | |
1120 | return ret; | |
1121 | } | |
1122 | ||
1123 | rx.direction = DMA_DEV_TO_MEM; | |
1124 | rx.src_addr = spi_imx->base_phys + MXC_CSPIRXDATA; | |
1125 | rx.src_addr_width = buswidth; | |
1126 | rx.src_maxburst = spi_imx->wml; | |
1127 | ret = dmaengine_slave_config(master->dma_rx, &rx); | |
1128 | if (ret) { | |
1129 | dev_err(spi_imx->dev, "RX dma configuration failed with %d\n", ret); | |
1130 | return ret; | |
1131 | } | |
1132 | ||
f12ae171 AB |
1133 | return 0; |
1134 | } | |
1135 | ||
6cdeb002 | 1136 | static int spi_imx_setupxfer(struct spi_device *spi, |
b5f3294f SH |
1137 | struct spi_transfer *t) |
1138 | { | |
6cdeb002 | 1139 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
b5f3294f | 1140 | |
abb1ff19 SH |
1141 | if (!t) |
1142 | return 0; | |
1143 | ||
d52345b6 SH |
1144 | spi_imx->bits_per_word = t->bits_per_word; |
1145 | spi_imx->speed_hz = t->speed_hz; | |
b5f3294f | 1146 | |
2801b2f5 MC |
1147 | /* |
1148 | * Initialize the functions for transfer. To transfer non byte-aligned | |
1149 | * words, we have to use multiple word-size bursts, we can't use | |
1150 | * dynamic_burst in that case. | |
1151 | */ | |
1152 | if (spi_imx->devtype_data->dynamic_burst && !spi_imx->slave_mode && | |
1153 | (spi_imx->bits_per_word == 8 || | |
1154 | spi_imx->bits_per_word == 16 || | |
1155 | spi_imx->bits_per_word == 32)) { | |
1673c81d | 1156 | |
1673c81d | 1157 | spi_imx->rx = spi_imx_buf_rx_swap; |
1158 | spi_imx->tx = spi_imx_buf_tx_swap; | |
1159 | spi_imx->dynamic_burst = 1; | |
1673c81d | 1160 | |
6051426f | 1161 | } else { |
1673c81d | 1162 | if (spi_imx->bits_per_word <= 8) { |
1163 | spi_imx->rx = spi_imx_buf_rx_u8; | |
1164 | spi_imx->tx = spi_imx_buf_tx_u8; | |
1165 | } else if (spi_imx->bits_per_word <= 16) { | |
1166 | spi_imx->rx = spi_imx_buf_rx_u16; | |
1167 | spi_imx->tx = spi_imx_buf_tx_u16; | |
1168 | } else { | |
1169 | spi_imx->rx = spi_imx_buf_rx_u32; | |
1170 | spi_imx->tx = spi_imx_buf_tx_u32; | |
1171 | } | |
2ca300ac | 1172 | spi_imx->dynamic_burst = 0; |
24778be2 | 1173 | } |
e6a0a8bf | 1174 | |
c008a800 SH |
1175 | if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) |
1176 | spi_imx->usedma = 1; | |
1177 | else | |
1178 | spi_imx->usedma = 0; | |
1179 | ||
71abd290 | 1180 | if (is_imx53_ecspi(spi_imx) && spi_imx->slave_mode) { |
1181 | spi_imx->rx = mx53_ecspi_rx_slave; | |
1182 | spi_imx->tx = mx53_ecspi_tx_slave; | |
1183 | spi_imx->slave_burst = t->len; | |
1184 | } | |
1185 | ||
d52345b6 | 1186 | spi_imx->devtype_data->config(spi); |
b5f3294f SH |
1187 | |
1188 | return 0; | |
1189 | } | |
1190 | ||
f62caccd RG |
1191 | static void spi_imx_sdma_exit(struct spi_imx_data *spi_imx) |
1192 | { | |
1193 | struct spi_master *master = spi_imx->bitbang.master; | |
1194 | ||
1195 | if (master->dma_rx) { | |
1196 | dma_release_channel(master->dma_rx); | |
1197 | master->dma_rx = NULL; | |
1198 | } | |
1199 | ||
1200 | if (master->dma_tx) { | |
1201 | dma_release_channel(master->dma_tx); | |
1202 | master->dma_tx = NULL; | |
1203 | } | |
f62caccd RG |
1204 | } |
1205 | ||
1206 | static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, | |
f12ae171 | 1207 | struct spi_master *master) |
f62caccd | 1208 | { |
f62caccd RG |
1209 | int ret; |
1210 | ||
a02bb401 RG |
1211 | /* use pio mode for i.mx6dl chip TKT238285 */ |
1212 | if (of_machine_is_compatible("fsl,imx6dl")) | |
1213 | return 0; | |
1214 | ||
fd8d4e2d | 1215 | spi_imx->wml = spi_imx->devtype_data->fifo_size / 2; |
0dfbaa89 | 1216 | |
f62caccd | 1217 | /* Prepare for TX DMA: */ |
3760047a AB |
1218 | master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); |
1219 | if (IS_ERR(master->dma_tx)) { | |
1220 | ret = PTR_ERR(master->dma_tx); | |
1221 | dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret); | |
1222 | master->dma_tx = NULL; | |
f62caccd RG |
1223 | goto err; |
1224 | } | |
1225 | ||
f62caccd | 1226 | /* Prepare for RX : */ |
3760047a AB |
1227 | master->dma_rx = dma_request_slave_channel_reason(dev, "rx"); |
1228 | if (IS_ERR(master->dma_rx)) { | |
1229 | ret = PTR_ERR(master->dma_rx); | |
1230 | dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret); | |
1231 | master->dma_rx = NULL; | |
f62caccd RG |
1232 | goto err; |
1233 | } | |
1234 | ||
f62caccd RG |
1235 | init_completion(&spi_imx->dma_rx_completion); |
1236 | init_completion(&spi_imx->dma_tx_completion); | |
1237 | master->can_dma = spi_imx_can_dma; | |
1238 | master->max_dma_len = MAX_SDMA_BD_BYTES; | |
1239 | spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | | |
1240 | SPI_MASTER_MUST_TX; | |
f62caccd RG |
1241 | |
1242 | return 0; | |
1243 | err: | |
1244 | spi_imx_sdma_exit(spi_imx); | |
1245 | return ret; | |
1246 | } | |
1247 | ||
1248 | static void spi_imx_dma_rx_callback(void *cookie) | |
1249 | { | |
1250 | struct spi_imx_data *spi_imx = (struct spi_imx_data *)cookie; | |
1251 | ||
1252 | complete(&spi_imx->dma_rx_completion); | |
1253 | } | |
1254 | ||
1255 | static void spi_imx_dma_tx_callback(void *cookie) | |
1256 | { | |
1257 | struct spi_imx_data *spi_imx = (struct spi_imx_data *)cookie; | |
1258 | ||
1259 | complete(&spi_imx->dma_tx_completion); | |
1260 | } | |
1261 | ||
4bfe927a AB |
1262 | static int spi_imx_calculate_timeout(struct spi_imx_data *spi_imx, int size) |
1263 | { | |
1264 | unsigned long timeout = 0; | |
1265 | ||
1266 | /* Time with actual data transfer and CS change delay related to HW */ | |
1267 | timeout = (8 + 4) * size / spi_imx->spi_bus_clk; | |
1268 | ||
1269 | /* Add extra second for scheduler related activities */ | |
1270 | timeout += 1; | |
1271 | ||
1272 | /* Double calculated timeout */ | |
1273 | return msecs_to_jiffies(2 * timeout * MSEC_PER_SEC); | |
1274 | } | |
1275 | ||
f62caccd RG |
1276 | static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, |
1277 | struct spi_transfer *transfer) | |
1278 | { | |
6b6192c0 | 1279 | struct dma_async_tx_descriptor *desc_tx, *desc_rx; |
4bfe927a | 1280 | unsigned long transfer_timeout; |
56536a7f | 1281 | unsigned long timeout; |
f62caccd RG |
1282 | struct spi_master *master = spi_imx->bitbang.master; |
1283 | struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg; | |
5ba5a373 RG |
1284 | struct scatterlist *last_sg = sg_last(rx->sgl, rx->nents); |
1285 | unsigned int bytes_per_word, i; | |
987a2dfe RG |
1286 | int ret; |
1287 | ||
5ba5a373 RG |
1288 | /* Get the right burst length from the last sg to ensure no tail data */ |
1289 | bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word); | |
1290 | for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) { | |
1291 | if (!(sg_dma_len(last_sg) % (i * bytes_per_word))) | |
1292 | break; | |
1293 | } | |
1294 | /* Use 1 as wml in case no available burst length got */ | |
1295 | if (i == 0) | |
1296 | i = 1; | |
1297 | ||
1298 | spi_imx->wml = i; | |
1299 | ||
987a2dfe RG |
1300 | ret = spi_imx_dma_configure(master); |
1301 | if (ret) | |
1302 | return ret; | |
1303 | ||
5ba5a373 RG |
1304 | if (!spi_imx->devtype_data->setup_wml) { |
1305 | dev_err(spi_imx->dev, "No setup_wml()?\n"); | |
1306 | return -EINVAL; | |
1307 | } | |
987a2dfe | 1308 | spi_imx->devtype_data->setup_wml(spi_imx); |
f62caccd | 1309 | |
6b6192c0 SH |
1310 | /* |
1311 | * The TX DMA setup starts the transfer, so make sure RX is configured | |
1312 | * before TX. | |
1313 | */ | |
1314 | desc_rx = dmaengine_prep_slave_sg(master->dma_rx, | |
1315 | rx->sgl, rx->nents, DMA_DEV_TO_MEM, | |
1316 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | |
1317 | if (!desc_rx) | |
1318 | return -EINVAL; | |
f62caccd | 1319 | |
6b6192c0 SH |
1320 | desc_rx->callback = spi_imx_dma_rx_callback; |
1321 | desc_rx->callback_param = (void *)spi_imx; | |
1322 | dmaengine_submit(desc_rx); | |
1323 | reinit_completion(&spi_imx->dma_rx_completion); | |
1324 | dma_async_issue_pending(master->dma_rx); | |
f62caccd | 1325 | |
6b6192c0 SH |
1326 | desc_tx = dmaengine_prep_slave_sg(master->dma_tx, |
1327 | tx->sgl, tx->nents, DMA_MEM_TO_DEV, | |
1328 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | |
1329 | if (!desc_tx) { | |
1330 | dmaengine_terminate_all(master->dma_tx); | |
1331 | return -EINVAL; | |
f62caccd RG |
1332 | } |
1333 | ||
6b6192c0 SH |
1334 | desc_tx->callback = spi_imx_dma_tx_callback; |
1335 | desc_tx->callback_param = (void *)spi_imx; | |
1336 | dmaengine_submit(desc_tx); | |
f62caccd | 1337 | reinit_completion(&spi_imx->dma_tx_completion); |
fab44ef1 | 1338 | dma_async_issue_pending(master->dma_tx); |
f62caccd | 1339 | |
4bfe927a AB |
1340 | transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len); |
1341 | ||
f62caccd | 1342 | /* Wait SDMA to finish the data transfer.*/ |
56536a7f | 1343 | timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion, |
4bfe927a | 1344 | transfer_timeout); |
56536a7f | 1345 | if (!timeout) { |
6aa800ca | 1346 | dev_err(spi_imx->dev, "I/O Error in DMA TX\n"); |
f62caccd | 1347 | dmaengine_terminate_all(master->dma_tx); |
e47b33c0 | 1348 | dmaengine_terminate_all(master->dma_rx); |
6b6192c0 | 1349 | return -ETIMEDOUT; |
f62caccd RG |
1350 | } |
1351 | ||
6b6192c0 SH |
1352 | timeout = wait_for_completion_timeout(&spi_imx->dma_rx_completion, |
1353 | transfer_timeout); | |
1354 | if (!timeout) { | |
1355 | dev_err(&master->dev, "I/O Error in DMA RX\n"); | |
1356 | spi_imx->devtype_data->reset(spi_imx); | |
1357 | dmaengine_terminate_all(master->dma_rx); | |
1358 | return -ETIMEDOUT; | |
1359 | } | |
f62caccd | 1360 | |
6b6192c0 | 1361 | return transfer->len; |
f62caccd RG |
1362 | } |
1363 | ||
1364 | static int spi_imx_pio_transfer(struct spi_device *spi, | |
b5f3294f SH |
1365 | struct spi_transfer *transfer) |
1366 | { | |
6cdeb002 | 1367 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
ff1ba3da CG |
1368 | unsigned long transfer_timeout; |
1369 | unsigned long timeout; | |
b5f3294f | 1370 | |
6cdeb002 UKK |
1371 | spi_imx->tx_buf = transfer->tx_buf; |
1372 | spi_imx->rx_buf = transfer->rx_buf; | |
1373 | spi_imx->count = transfer->len; | |
1374 | spi_imx->txfifo = 0; | |
2ca300ac | 1375 | spi_imx->remainder = 0; |
b5f3294f | 1376 | |
aa0fe826 | 1377 | reinit_completion(&spi_imx->xfer_done); |
b5f3294f | 1378 | |
6cdeb002 | 1379 | spi_imx_push(spi_imx); |
b5f3294f | 1380 | |
edd501bb | 1381 | spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE); |
b5f3294f | 1382 | |
ff1ba3da CG |
1383 | transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len); |
1384 | ||
1385 | timeout = wait_for_completion_timeout(&spi_imx->xfer_done, | |
1386 | transfer_timeout); | |
1387 | if (!timeout) { | |
1388 | dev_err(&spi->dev, "I/O Error in PIO\n"); | |
1389 | spi_imx->devtype_data->reset(spi_imx); | |
1390 | return -ETIMEDOUT; | |
1391 | } | |
b5f3294f SH |
1392 | |
1393 | return transfer->len; | |
1394 | } | |
1395 | ||
71abd290 | 1396 | static int spi_imx_pio_transfer_slave(struct spi_device *spi, |
1397 | struct spi_transfer *transfer) | |
1398 | { | |
1399 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | |
1400 | int ret = transfer->len; | |
1401 | ||
1402 | if (is_imx53_ecspi(spi_imx) && | |
1403 | transfer->len > MX53_MAX_TRANSFER_BYTES) { | |
1404 | dev_err(&spi->dev, "Transaction too big, max size is %d bytes\n", | |
1405 | MX53_MAX_TRANSFER_BYTES); | |
1406 | return -EMSGSIZE; | |
1407 | } | |
1408 | ||
1409 | spi_imx->tx_buf = transfer->tx_buf; | |
1410 | spi_imx->rx_buf = transfer->rx_buf; | |
1411 | spi_imx->count = transfer->len; | |
1412 | spi_imx->txfifo = 0; | |
2ca300ac | 1413 | spi_imx->remainder = 0; |
71abd290 | 1414 | |
1415 | reinit_completion(&spi_imx->xfer_done); | |
1416 | spi_imx->slave_aborted = false; | |
1417 | ||
1418 | spi_imx_push(spi_imx); | |
1419 | ||
1420 | spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE | MXC_INT_RDR); | |
1421 | ||
1422 | if (wait_for_completion_interruptible(&spi_imx->xfer_done) || | |
1423 | spi_imx->slave_aborted) { | |
1424 | dev_dbg(&spi->dev, "interrupted\n"); | |
1425 | ret = -EINTR; | |
1426 | } | |
1427 | ||
1428 | /* ecspi has a HW issue when works in Slave mode, | |
1429 | * after 64 words writtern to TXFIFO, even TXFIFO becomes empty, | |
1430 | * ECSPI_TXDATA keeps shift out the last word data, | |
1431 | * so we have to disable ECSPI when in slave mode after the | |
1432 | * transfer completes | |
1433 | */ | |
1434 | if (spi_imx->devtype_data->disable) | |
1435 | spi_imx->devtype_data->disable(spi_imx); | |
1436 | ||
1437 | return ret; | |
1438 | } | |
1439 | ||
f62caccd RG |
1440 | static int spi_imx_transfer(struct spi_device *spi, |
1441 | struct spi_transfer *transfer) | |
1442 | { | |
f62caccd RG |
1443 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
1444 | ||
71abd290 | 1445 | /* flush rxfifo before transfer */ |
1446 | while (spi_imx->devtype_data->rx_available(spi_imx)) | |
1447 | spi_imx->rx(spi_imx); | |
1448 | ||
1449 | if (spi_imx->slave_mode) | |
1450 | return spi_imx_pio_transfer_slave(spi, transfer); | |
1451 | ||
c008a800 | 1452 | if (spi_imx->usedma) |
99f1cf1c | 1453 | return spi_imx_dma_transfer(spi_imx, transfer); |
c008a800 SH |
1454 | else |
1455 | return spi_imx_pio_transfer(spi, transfer); | |
f62caccd RG |
1456 | } |
1457 | ||
6cdeb002 | 1458 | static int spi_imx_setup(struct spi_device *spi) |
b5f3294f | 1459 | { |
f4d4ecfe | 1460 | dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, |
b5f3294f SH |
1461 | spi->mode, spi->bits_per_word, spi->max_speed_hz); |
1462 | ||
ab2f3572 OR |
1463 | if (spi->mode & SPI_NO_CS) |
1464 | return 0; | |
1465 | ||
b36581df AS |
1466 | if (gpio_is_valid(spi->cs_gpio)) |
1467 | gpio_direction_output(spi->cs_gpio, | |
1468 | spi->mode & SPI_CS_HIGH ? 0 : 1); | |
6c23e5d4 | 1469 | |
6cdeb002 | 1470 | spi_imx_chipselect(spi, BITBANG_CS_INACTIVE); |
b5f3294f SH |
1471 | |
1472 | return 0; | |
1473 | } | |
1474 | ||
6cdeb002 | 1475 | static void spi_imx_cleanup(struct spi_device *spi) |
b5f3294f SH |
1476 | { |
1477 | } | |
1478 | ||
9e556dcc HS |
1479 | static int |
1480 | spi_imx_prepare_message(struct spi_master *master, struct spi_message *msg) | |
1481 | { | |
1482 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | |
1483 | int ret; | |
1484 | ||
1485 | ret = clk_enable(spi_imx->clk_per); | |
1486 | if (ret) | |
1487 | return ret; | |
1488 | ||
1489 | ret = clk_enable(spi_imx->clk_ipg); | |
1490 | if (ret) { | |
1491 | clk_disable(spi_imx->clk_per); | |
1492 | return ret; | |
1493 | } | |
1494 | ||
1495 | return 0; | |
1496 | } | |
1497 | ||
1498 | static int | |
1499 | spi_imx_unprepare_message(struct spi_master *master, struct spi_message *msg) | |
1500 | { | |
1501 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | |
1502 | ||
1503 | clk_disable(spi_imx->clk_ipg); | |
1504 | clk_disable(spi_imx->clk_per); | |
1505 | return 0; | |
1506 | } | |
1507 | ||
71abd290 | 1508 | static int spi_imx_slave_abort(struct spi_master *master) |
1509 | { | |
1510 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | |
1511 | ||
1512 | spi_imx->slave_aborted = true; | |
1513 | complete(&spi_imx->xfer_done); | |
1514 | ||
1515 | return 0; | |
1516 | } | |
1517 | ||
fd4a319b | 1518 | static int spi_imx_probe(struct platform_device *pdev) |
b5f3294f | 1519 | { |
22a85e4c SG |
1520 | struct device_node *np = pdev->dev.of_node; |
1521 | const struct of_device_id *of_id = | |
1522 | of_match_device(spi_imx_dt_ids, &pdev->dev); | |
1523 | struct spi_imx_master *mxc_platform_info = | |
1524 | dev_get_platdata(&pdev->dev); | |
b5f3294f | 1525 | struct spi_master *master; |
6cdeb002 | 1526 | struct spi_imx_data *spi_imx; |
b5f3294f | 1527 | struct resource *res; |
f72efa7e | 1528 | int i, ret, irq, spi_drctl; |
71abd290 | 1529 | const struct spi_imx_devtype_data *devtype_data = of_id ? of_id->data : |
1530 | (struct spi_imx_devtype_data *)pdev->id_entry->driver_data; | |
1531 | bool slave_mode; | |
b5f3294f | 1532 | |
22a85e4c | 1533 | if (!np && !mxc_platform_info) { |
b5f3294f SH |
1534 | dev_err(&pdev->dev, "can't get the platform data\n"); |
1535 | return -EINVAL; | |
1536 | } | |
1537 | ||
71abd290 | 1538 | slave_mode = devtype_data->has_slavemode && |
1539 | of_property_read_bool(np, "spi-slave"); | |
1540 | if (slave_mode) | |
1541 | master = spi_alloc_slave(&pdev->dev, | |
1542 | sizeof(struct spi_imx_data)); | |
1543 | else | |
1544 | master = spi_alloc_master(&pdev->dev, | |
1545 | sizeof(struct spi_imx_data)); | |
2c147776 FE |
1546 | if (!master) |
1547 | return -ENOMEM; | |
1548 | ||
f72efa7e LM |
1549 | ret = of_property_read_u32(np, "fsl,spi-rdy-drctl", &spi_drctl); |
1550 | if ((ret < 0) || (spi_drctl >= 0x3)) { | |
1551 | /* '11' is reserved */ | |
1552 | spi_drctl = 0; | |
1553 | } | |
1554 | ||
b5f3294f SH |
1555 | platform_set_drvdata(pdev, master); |
1556 | ||
24778be2 | 1557 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); |
b36581df | 1558 | master->bus_num = np ? -1 : pdev->id; |
b5f3294f | 1559 | |
6cdeb002 | 1560 | spi_imx = spi_master_get_devdata(master); |
94c69f76 | 1561 | spi_imx->bitbang.master = master; |
6aa800ca | 1562 | spi_imx->dev = &pdev->dev; |
71abd290 | 1563 | spi_imx->slave_mode = slave_mode; |
b5f3294f | 1564 | |
71abd290 | 1565 | spi_imx->devtype_data = devtype_data; |
4686d1c3 | 1566 | |
881a0b99 | 1567 | /* Get number of chip selects, either platform data or OF */ |
b36581df AS |
1568 | if (mxc_platform_info) { |
1569 | master->num_chipselect = mxc_platform_info->num_chipselect; | |
ffd4db9e | 1570 | if (mxc_platform_info->chipselect) { |
a86854d0 KC |
1571 | master->cs_gpios = devm_kcalloc(&master->dev, |
1572 | master->num_chipselect, sizeof(int), | |
1573 | GFP_KERNEL); | |
ffd4db9e TP |
1574 | if (!master->cs_gpios) |
1575 | return -ENOMEM; | |
1576 | ||
1577 | for (i = 0; i < master->num_chipselect; i++) | |
1578 | master->cs_gpios[i] = mxc_platform_info->chipselect[i]; | |
1579 | } | |
881a0b99 TP |
1580 | } else { |
1581 | u32 num_cs; | |
1582 | ||
1583 | if (!of_property_read_u32(np, "num-cs", &num_cs)) | |
1584 | master->num_chipselect = num_cs; | |
1585 | /* If not preset, default value of 1 is used */ | |
1586 | } | |
b5f3294f | 1587 | |
6cdeb002 UKK |
1588 | spi_imx->bitbang.chipselect = spi_imx_chipselect; |
1589 | spi_imx->bitbang.setup_transfer = spi_imx_setupxfer; | |
1590 | spi_imx->bitbang.txrx_bufs = spi_imx_transfer; | |
1591 | spi_imx->bitbang.master->setup = spi_imx_setup; | |
1592 | spi_imx->bitbang.master->cleanup = spi_imx_cleanup; | |
9e556dcc HS |
1593 | spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; |
1594 | spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; | |
71abd290 | 1595 | spi_imx->bitbang.master->slave_abort = spi_imx_slave_abort; |
ab2f3572 OR |
1596 | spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ |
1597 | | SPI_NO_CS; | |
26e4bb86 | 1598 | if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) || |
1599 | is_imx53_ecspi(spi_imx)) | |
f72efa7e LM |
1600 | spi_imx->bitbang.master->mode_bits |= SPI_LOOP | SPI_READY; |
1601 | ||
1602 | spi_imx->spi_drctl = spi_drctl; | |
b5f3294f | 1603 | |
6cdeb002 | 1604 | init_completion(&spi_imx->xfer_done); |
b5f3294f SH |
1605 | |
1606 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
130b82c0 FE |
1607 | spi_imx->base = devm_ioremap_resource(&pdev->dev, res); |
1608 | if (IS_ERR(spi_imx->base)) { | |
1609 | ret = PTR_ERR(spi_imx->base); | |
1610 | goto out_master_put; | |
b5f3294f | 1611 | } |
f12ae171 | 1612 | spi_imx->base_phys = res->start; |
b5f3294f | 1613 | |
4b5d6aad FE |
1614 | irq = platform_get_irq(pdev, 0); |
1615 | if (irq < 0) { | |
1616 | ret = irq; | |
130b82c0 | 1617 | goto out_master_put; |
b5f3294f SH |
1618 | } |
1619 | ||
4b5d6aad | 1620 | ret = devm_request_irq(&pdev->dev, irq, spi_imx_isr, 0, |
8fc39b51 | 1621 | dev_name(&pdev->dev), spi_imx); |
b5f3294f | 1622 | if (ret) { |
4b5d6aad | 1623 | dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret); |
130b82c0 | 1624 | goto out_master_put; |
b5f3294f SH |
1625 | } |
1626 | ||
aa29d840 SH |
1627 | spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1628 | if (IS_ERR(spi_imx->clk_ipg)) { | |
1629 | ret = PTR_ERR(spi_imx->clk_ipg); | |
130b82c0 | 1630 | goto out_master_put; |
b5f3294f SH |
1631 | } |
1632 | ||
aa29d840 SH |
1633 | spi_imx->clk_per = devm_clk_get(&pdev->dev, "per"); |
1634 | if (IS_ERR(spi_imx->clk_per)) { | |
1635 | ret = PTR_ERR(spi_imx->clk_per); | |
130b82c0 | 1636 | goto out_master_put; |
aa29d840 SH |
1637 | } |
1638 | ||
83174626 FE |
1639 | ret = clk_prepare_enable(spi_imx->clk_per); |
1640 | if (ret) | |
1641 | goto out_master_put; | |
1642 | ||
1643 | ret = clk_prepare_enable(spi_imx->clk_ipg); | |
1644 | if (ret) | |
1645 | goto out_put_per; | |
aa29d840 SH |
1646 | |
1647 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); | |
f62caccd | 1648 | /* |
2dd33f9c MK |
1649 | * Only validated on i.mx35 and i.mx6 now, can remove the constraint |
1650 | * if validated on other chips. | |
f62caccd | 1651 | */ |
fd8d4e2d | 1652 | if (spi_imx->devtype_data->has_dmamode) { |
f12ae171 | 1653 | ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master); |
bf9af08c AB |
1654 | if (ret == -EPROBE_DEFER) |
1655 | goto out_clk_put; | |
1656 | ||
3760047a AB |
1657 | if (ret < 0) |
1658 | dev_err(&pdev->dev, "dma setup error %d, use pio\n", | |
1659 | ret); | |
1660 | } | |
b5f3294f | 1661 | |
edd501bb | 1662 | spi_imx->devtype_data->reset(spi_imx); |
ce1807b2 | 1663 | |
edd501bb | 1664 | spi_imx->devtype_data->intctrl(spi_imx, 0); |
b5f3294f | 1665 | |
22a85e4c | 1666 | master->dev.of_node = pdev->dev.of_node; |
8197f489 TP |
1667 | ret = spi_bitbang_start(&spi_imx->bitbang); |
1668 | if (ret) { | |
1669 | dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); | |
1670 | goto out_clk_put; | |
1671 | } | |
b5f3294f | 1672 | |
881a0b99 TP |
1673 | /* Request GPIO CS lines, if any */ |
1674 | if (!spi_imx->slave_mode && master->cs_gpios) { | |
71abd290 | 1675 | for (i = 0; i < master->num_chipselect; i++) { |
1676 | if (!gpio_is_valid(master->cs_gpios[i])) | |
1677 | continue; | |
1678 | ||
1679 | ret = devm_gpio_request(&pdev->dev, | |
1680 | master->cs_gpios[i], | |
1681 | DRIVER_NAME); | |
1682 | if (ret) { | |
1683 | dev_err(&pdev->dev, "Can't get CS GPIO %i\n", | |
1684 | master->cs_gpios[i]); | |
4e21791e | 1685 | goto out_spi_bitbang; |
71abd290 | 1686 | } |
1687 | } | |
b36581df AS |
1688 | } |
1689 | ||
b5f3294f SH |
1690 | dev_info(&pdev->dev, "probed\n"); |
1691 | ||
9e556dcc HS |
1692 | clk_disable(spi_imx->clk_ipg); |
1693 | clk_disable(spi_imx->clk_per); | |
b5f3294f SH |
1694 | return ret; |
1695 | ||
4e21791e TP |
1696 | out_spi_bitbang: |
1697 | spi_bitbang_stop(&spi_imx->bitbang); | |
b5f3294f | 1698 | out_clk_put: |
aa29d840 | 1699 | clk_disable_unprepare(spi_imx->clk_ipg); |
83174626 FE |
1700 | out_put_per: |
1701 | clk_disable_unprepare(spi_imx->clk_per); | |
130b82c0 | 1702 | out_master_put: |
b5f3294f | 1703 | spi_master_put(master); |
130b82c0 | 1704 | |
b5f3294f SH |
1705 | return ret; |
1706 | } | |
1707 | ||
fd4a319b | 1708 | static int spi_imx_remove(struct platform_device *pdev) |
b5f3294f SH |
1709 | { |
1710 | struct spi_master *master = platform_get_drvdata(pdev); | |
6cdeb002 | 1711 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); |
d593574a | 1712 | int ret; |
b5f3294f | 1713 | |
6cdeb002 | 1714 | spi_bitbang_stop(&spi_imx->bitbang); |
b5f3294f | 1715 | |
d593574a SA |
1716 | ret = clk_enable(spi_imx->clk_per); |
1717 | if (ret) | |
1718 | return ret; | |
1719 | ||
1720 | ret = clk_enable(spi_imx->clk_ipg); | |
1721 | if (ret) { | |
1722 | clk_disable(spi_imx->clk_per); | |
1723 | return ret; | |
1724 | } | |
1725 | ||
6cdeb002 | 1726 | writel(0, spi_imx->base + MXC_CSPICTRL); |
d593574a SA |
1727 | clk_disable_unprepare(spi_imx->clk_ipg); |
1728 | clk_disable_unprepare(spi_imx->clk_per); | |
f62caccd | 1729 | spi_imx_sdma_exit(spi_imx); |
b5f3294f SH |
1730 | spi_master_put(master); |
1731 | ||
b5f3294f SH |
1732 | return 0; |
1733 | } | |
1734 | ||
6cdeb002 | 1735 | static struct platform_driver spi_imx_driver = { |
b5f3294f SH |
1736 | .driver = { |
1737 | .name = DRIVER_NAME, | |
22a85e4c | 1738 | .of_match_table = spi_imx_dt_ids, |
b5f3294f | 1739 | }, |
f4ba6315 | 1740 | .id_table = spi_imx_devtype, |
6cdeb002 | 1741 | .probe = spi_imx_probe, |
fd4a319b | 1742 | .remove = spi_imx_remove, |
b5f3294f | 1743 | }; |
940ab889 | 1744 | module_platform_driver(spi_imx_driver); |
b5f3294f | 1745 | |
af82800c | 1746 | MODULE_DESCRIPTION("SPI Controller driver"); |
b5f3294f SH |
1747 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
1748 | MODULE_LICENSE("GPL"); | |
3133fba3 | 1749 | MODULE_ALIAS("platform:" DRIVER_NAME); |