diff options
author | Ivan T. Ivanov <iivanov@mm-sol.com> | 2014-02-13 11:21:38 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-02-19 10:29:06 -0500 |
commit | 64ff247a978facc437d40f0c9b754675846a98f0 (patch) | |
tree | 36c3432a0a9e745c2fc8fb474ea75fc976da24bd /drivers/spi/spi-qup.c | |
parent | 1074600e79ad63b8986ae9b723b403984cf3408f (diff) |
spi: Add Qualcomm QUP SPI controller support
Qualcomm Universal Peripheral (QUP) core is an AHB slave that
provides a common data path (an output FIFO and an input FIFO)
for serial peripheral interface (SPI) mini-core. SPI in master
mode supports up to 50MHz, up to four chip selects, programmable
data path from 4 bits to 32 bits and numerous protocol variants.
Cc: Alok Chauhan <alokc@codeaurora.org>
Cc: Gilad Avidov <gavidov@codeaurora.org>
Cc: Kiran Gunda <kgunda@codeaurora.org>
Cc: Sagar Dharia <sdharia@codeaurora.org>
Cc: dsneddon@codeaurora.org
Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-qup.c')
-rw-r--r-- | drivers/spi/spi-qup.c | 837 |
1 files changed, 837 insertions, 0 deletions
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c new file mode 100644 index 000000000000..b0bcc09425a7 --- /dev/null +++ b/drivers/spi/spi-qup.c | |||
@@ -0,0 +1,837 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2014, The Linux foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License rev 2 and | ||
6 | * only rev 2 as published by the free Software foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/pm_runtime.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | |||
26 | #define QUP_CONFIG 0x0000 | ||
27 | #define QUP_STATE 0x0004 | ||
28 | #define QUP_IO_M_MODES 0x0008 | ||
29 | #define QUP_SW_RESET 0x000c | ||
30 | #define QUP_OPERATIONAL 0x0018 | ||
31 | #define QUP_ERROR_FLAGS 0x001c | ||
32 | #define QUP_ERROR_FLAGS_EN 0x0020 | ||
33 | #define QUP_OPERATIONAL_MASK 0x0028 | ||
34 | #define QUP_HW_VERSION 0x0030 | ||
35 | #define QUP_MX_OUTPUT_CNT 0x0100 | ||
36 | #define QUP_OUTPUT_FIFO 0x0110 | ||
37 | #define QUP_MX_WRITE_CNT 0x0150 | ||
38 | #define QUP_MX_INPUT_CNT 0x0200 | ||
39 | #define QUP_MX_READ_CNT 0x0208 | ||
40 | #define QUP_INPUT_FIFO 0x0218 | ||
41 | |||
42 | #define SPI_CONFIG 0x0300 | ||
43 | #define SPI_IO_CONTROL 0x0304 | ||
44 | #define SPI_ERROR_FLAGS 0x0308 | ||
45 | #define SPI_ERROR_FLAGS_EN 0x030c | ||
46 | |||
47 | /* QUP_CONFIG fields */ | ||
48 | #define QUP_CONFIG_SPI_MODE (1 << 8) | ||
49 | #define QUP_CONFIG_CLOCK_AUTO_GATE BIT(13) | ||
50 | #define QUP_CONFIG_NO_INPUT BIT(7) | ||
51 | #define QUP_CONFIG_NO_OUTPUT BIT(6) | ||
52 | #define QUP_CONFIG_N 0x001f | ||
53 | |||
54 | /* QUP_STATE fields */ | ||
55 | #define QUP_STATE_VALID BIT(2) | ||
56 | #define QUP_STATE_RESET 0 | ||
57 | #define QUP_STATE_RUN 1 | ||
58 | #define QUP_STATE_PAUSE 3 | ||
59 | #define QUP_STATE_MASK 3 | ||
60 | #define QUP_STATE_CLEAR 2 | ||
61 | |||
62 | #define QUP_HW_VERSION_2_1_1 0x20010001 | ||
63 | |||
64 | /* QUP_IO_M_MODES fields */ | ||
65 | #define QUP_IO_M_PACK_EN BIT(15) | ||
66 | #define QUP_IO_M_UNPACK_EN BIT(14) | ||
67 | #define QUP_IO_M_INPUT_MODE_MASK_SHIFT 12 | ||
68 | #define QUP_IO_M_OUTPUT_MODE_MASK_SHIFT 10 | ||
69 | #define QUP_IO_M_INPUT_MODE_MASK (3 << QUP_IO_M_INPUT_MODE_MASK_SHIFT) | ||
70 | #define QUP_IO_M_OUTPUT_MODE_MASK (3 << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT) | ||
71 | |||
72 | #define QUP_IO_M_OUTPUT_BLOCK_SIZE(x) (((x) & (0x03 << 0)) >> 0) | ||
73 | #define QUP_IO_M_OUTPUT_FIFO_SIZE(x) (((x) & (0x07 << 2)) >> 2) | ||
74 | #define QUP_IO_M_INPUT_BLOCK_SIZE(x) (((x) & (0x03 << 5)) >> 5) | ||
75 | #define QUP_IO_M_INPUT_FIFO_SIZE(x) (((x) & (0x07 << 7)) >> 7) | ||
76 | |||
77 | #define QUP_IO_M_MODE_FIFO 0 | ||
78 | #define QUP_IO_M_MODE_BLOCK 1 | ||
79 | #define QUP_IO_M_MODE_DMOV 2 | ||
80 | #define QUP_IO_M_MODE_BAM 3 | ||
81 | |||
82 | /* QUP_OPERATIONAL fields */ | ||
83 | #define QUP_OP_MAX_INPUT_DONE_FLAG BIT(11) | ||
84 | #define QUP_OP_MAX_OUTPUT_DONE_FLAG BIT(10) | ||
85 | #define QUP_OP_IN_SERVICE_FLAG BIT(9) | ||
86 | #define QUP_OP_OUT_SERVICE_FLAG BIT(8) | ||
87 | #define QUP_OP_IN_FIFO_FULL BIT(7) | ||
88 | #define QUP_OP_OUT_FIFO_FULL BIT(6) | ||
89 | #define QUP_OP_IN_FIFO_NOT_EMPTY BIT(5) | ||
90 | #define QUP_OP_OUT_FIFO_NOT_EMPTY BIT(4) | ||
91 | |||
92 | /* QUP_ERROR_FLAGS and QUP_ERROR_FLAGS_EN fields */ | ||
93 | #define QUP_ERROR_OUTPUT_OVER_RUN BIT(5) | ||
94 | #define QUP_ERROR_INPUT_UNDER_RUN BIT(4) | ||
95 | #define QUP_ERROR_OUTPUT_UNDER_RUN BIT(3) | ||
96 | #define QUP_ERROR_INPUT_OVER_RUN BIT(2) | ||
97 | |||
98 | /* SPI_CONFIG fields */ | ||
99 | #define SPI_CONFIG_HS_MODE BIT(10) | ||
100 | #define SPI_CONFIG_INPUT_FIRST BIT(9) | ||
101 | #define SPI_CONFIG_LOOPBACK BIT(8) | ||
102 | |||
103 | /* SPI_IO_CONTROL fields */ | ||
104 | #define SPI_IO_C_FORCE_CS BIT(11) | ||
105 | #define SPI_IO_C_CLK_IDLE_HIGH BIT(10) | ||
106 | #define SPI_IO_C_MX_CS_MODE BIT(8) | ||
107 | #define SPI_IO_C_CS_N_POLARITY_0 BIT(4) | ||
108 | #define SPI_IO_C_CS_SELECT(x) (((x) & 3) << 2) | ||
109 | #define SPI_IO_C_CS_SELECT_MASK 0x000c | ||
110 | #define SPI_IO_C_TRISTATE_CS BIT(1) | ||
111 | #define SPI_IO_C_NO_TRI_STATE BIT(0) | ||
112 | |||
113 | /* SPI_ERROR_FLAGS and SPI_ERROR_FLAGS_EN fields */ | ||
114 | #define SPI_ERROR_CLK_OVER_RUN BIT(1) | ||
115 | #define SPI_ERROR_CLK_UNDER_RUN BIT(0) | ||
116 | |||
117 | #define SPI_NUM_CHIPSELECTS 4 | ||
118 | |||
119 | /* high speed mode is when bus rate is greater then 26MHz */ | ||
120 | #define SPI_HS_MIN_RATE 26000000 | ||
121 | #define SPI_MAX_RATE 50000000 | ||
122 | |||
123 | #define SPI_DELAY_THRESHOLD 1 | ||
124 | #define SPI_DELAY_RETRY 10 | ||
125 | |||
126 | struct spi_qup_device { | ||
127 | int select; | ||
128 | u16 mode; | ||
129 | }; | ||
130 | |||
131 | struct spi_qup { | ||
132 | void __iomem *base; | ||
133 | struct device *dev; | ||
134 | struct clk *cclk; /* core clock */ | ||
135 | struct clk *iclk; /* interface clock */ | ||
136 | int irq; | ||
137 | u32 max_speed_hz; | ||
138 | spinlock_t lock; | ||
139 | |||
140 | int in_fifo_sz; | ||
141 | int out_fifo_sz; | ||
142 | int in_blk_sz; | ||
143 | int out_blk_sz; | ||
144 | |||
145 | struct spi_transfer *xfer; | ||
146 | struct completion done; | ||
147 | int error; | ||
148 | int w_size; /* bytes per SPI word */ | ||
149 | int tx_bytes; | ||
150 | int rx_bytes; | ||
151 | }; | ||
152 | |||
153 | |||
154 | static inline bool spi_qup_is_valid_state(struct spi_qup *controller) | ||
155 | { | ||
156 | u32 opstate = readl_relaxed(controller->base + QUP_STATE); | ||
157 | |||
158 | return opstate & QUP_STATE_VALID; | ||
159 | } | ||
160 | |||
161 | static int spi_qup_set_state(struct spi_qup *controller, u32 state) | ||
162 | { | ||
163 | unsigned long loop; | ||
164 | u32 cur_state; | ||
165 | |||
166 | loop = 0; | ||
167 | while (!spi_qup_is_valid_state(controller)) { | ||
168 | |||
169 | usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2); | ||
170 | |||
171 | if (++loop > SPI_DELAY_RETRY) | ||
172 | return -EIO; | ||
173 | } | ||
174 | |||
175 | if (loop) | ||
176 | dev_dbg(controller->dev, "invalid state for %ld,us %d\n", | ||
177 | loop, state); | ||
178 | |||
179 | cur_state = readl_relaxed(controller->base + QUP_STATE); | ||
180 | /* | ||
181 | * Per spec: for PAUSE_STATE to RESET_STATE, two writes | ||
182 | * of (b10) are required | ||
183 | */ | ||
184 | if (((cur_state & QUP_STATE_MASK) == QUP_STATE_PAUSE) && | ||
185 | (state == QUP_STATE_RESET)) { | ||
186 | writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE); | ||
187 | writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE); | ||
188 | } else { | ||
189 | cur_state &= ~QUP_STATE_MASK; | ||
190 | cur_state |= state; | ||
191 | writel_relaxed(cur_state, controller->base + QUP_STATE); | ||
192 | } | ||
193 | |||
194 | loop = 0; | ||
195 | while (!spi_qup_is_valid_state(controller)) { | ||
196 | |||
197 | usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2); | ||
198 | |||
199 | if (++loop > SPI_DELAY_RETRY) | ||
200 | return -EIO; | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | |||
207 | static void spi_qup_fifo_read(struct spi_qup *controller, | ||
208 | struct spi_transfer *xfer) | ||
209 | { | ||
210 | u8 *rx_buf = xfer->rx_buf; | ||
211 | u32 word, state; | ||
212 | int idx, shift, w_size; | ||
213 | |||
214 | w_size = controller->w_size; | ||
215 | |||
216 | while (controller->rx_bytes < xfer->len) { | ||
217 | |||
218 | state = readl_relaxed(controller->base + QUP_OPERATIONAL); | ||
219 | if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY)) | ||
220 | break; | ||
221 | |||
222 | word = readl_relaxed(controller->base + QUP_INPUT_FIFO); | ||
223 | |||
224 | if (!rx_buf) { | ||
225 | controller->rx_bytes += w_size; | ||
226 | continue; | ||
227 | } | ||
228 | |||
229 | for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) { | ||
230 | /* | ||
231 | * The data format depends on bytes per SPI word: | ||
232 | * 4 bytes: 0x12345678 | ||
233 | * 2 bytes: 0x00001234 | ||
234 | * 1 byte : 0x00000012 | ||
235 | */ | ||
236 | shift = BITS_PER_BYTE; | ||
237 | shift *= (w_size - idx - 1); | ||
238 | rx_buf[controller->rx_bytes] = word >> shift; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void spi_qup_fifo_write(struct spi_qup *controller, | ||
244 | struct spi_transfer *xfer) | ||
245 | { | ||
246 | const u8 *tx_buf = xfer->tx_buf; | ||
247 | u32 word, state, data; | ||
248 | int idx, w_size; | ||
249 | |||
250 | w_size = controller->w_size; | ||
251 | |||
252 | while (controller->tx_bytes < xfer->len) { | ||
253 | |||
254 | state = readl_relaxed(controller->base + QUP_OPERATIONAL); | ||
255 | if (state & QUP_OP_OUT_FIFO_FULL) | ||
256 | break; | ||
257 | |||
258 | word = 0; | ||
259 | for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) { | ||
260 | |||
261 | if (!tx_buf) { | ||
262 | controller->tx_bytes += w_size; | ||
263 | break; | ||
264 | } | ||
265 | |||
266 | data = tx_buf[controller->tx_bytes]; | ||
267 | word |= data << (BITS_PER_BYTE * (3 - idx)); | ||
268 | } | ||
269 | |||
270 | writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) | ||
275 | { | ||
276 | struct spi_qup *controller = dev_id; | ||
277 | struct spi_transfer *xfer; | ||
278 | u32 opflags, qup_err, spi_err; | ||
279 | unsigned long flags; | ||
280 | int error = 0; | ||
281 | |||
282 | spin_lock_irqsave(&controller->lock, flags); | ||
283 | xfer = controller->xfer; | ||
284 | controller->xfer = NULL; | ||
285 | spin_unlock_irqrestore(&controller->lock, flags); | ||
286 | |||
287 | qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS); | ||
288 | spi_err = readl_relaxed(controller->base + SPI_ERROR_FLAGS); | ||
289 | opflags = readl_relaxed(controller->base + QUP_OPERATIONAL); | ||
290 | |||
291 | writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS); | ||
292 | writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS); | ||
293 | writel_relaxed(opflags, controller->base + QUP_OPERATIONAL); | ||
294 | |||
295 | if (!xfer) { | ||
296 | dev_err_ratelimited(controller->dev, "unexpected irq %x08 %x08 %x08\n", | ||
297 | qup_err, spi_err, opflags); | ||
298 | return IRQ_HANDLED; | ||
299 | } | ||
300 | |||
301 | if (qup_err) { | ||
302 | if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN) | ||
303 | dev_warn(controller->dev, "OUTPUT_OVER_RUN\n"); | ||
304 | if (qup_err & QUP_ERROR_INPUT_UNDER_RUN) | ||
305 | dev_warn(controller->dev, "INPUT_UNDER_RUN\n"); | ||
306 | if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN) | ||
307 | dev_warn(controller->dev, "OUTPUT_UNDER_RUN\n"); | ||
308 | if (qup_err & QUP_ERROR_INPUT_OVER_RUN) | ||
309 | dev_warn(controller->dev, "INPUT_OVER_RUN\n"); | ||
310 | |||
311 | error = -EIO; | ||
312 | } | ||
313 | |||
314 | if (spi_err) { | ||
315 | if (spi_err & SPI_ERROR_CLK_OVER_RUN) | ||
316 | dev_warn(controller->dev, "CLK_OVER_RUN\n"); | ||
317 | if (spi_err & SPI_ERROR_CLK_UNDER_RUN) | ||
318 | dev_warn(controller->dev, "CLK_UNDER_RUN\n"); | ||
319 | |||
320 | error = -EIO; | ||
321 | } | ||
322 | |||
323 | if (opflags & QUP_OP_IN_SERVICE_FLAG) | ||
324 | spi_qup_fifo_read(controller, xfer); | ||
325 | |||
326 | if (opflags & QUP_OP_OUT_SERVICE_FLAG) | ||
327 | spi_qup_fifo_write(controller, xfer); | ||
328 | |||
329 | spin_lock_irqsave(&controller->lock, flags); | ||
330 | controller->error = error; | ||
331 | controller->xfer = xfer; | ||
332 | spin_unlock_irqrestore(&controller->lock, flags); | ||
333 | |||
334 | if (controller->rx_bytes == xfer->len || error) | ||
335 | complete(&controller->done); | ||
336 | |||
337 | return IRQ_HANDLED; | ||
338 | } | ||
339 | |||
340 | |||
341 | /* set clock freq ... bits per word */ | ||
342 | static int spi_qup_io_config(struct spi_qup *controller, | ||
343 | struct spi_qup_device *chip, | ||
344 | struct spi_transfer *xfer) | ||
345 | { | ||
346 | u32 config, iomode, mode; | ||
347 | int ret, n_words, w_size; | ||
348 | |||
349 | if (chip->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) { | ||
350 | dev_err(controller->dev, "too big size for loopback %d > %d\n", | ||
351 | xfer->len, controller->in_fifo_sz); | ||
352 | return -EIO; | ||
353 | } | ||
354 | |||
355 | ret = clk_set_rate(controller->cclk, xfer->speed_hz); | ||
356 | if (ret) { | ||
357 | dev_err(controller->dev, "fail to set frequency %d", | ||
358 | xfer->speed_hz); | ||
359 | return -EIO; | ||
360 | } | ||
361 | |||
362 | if (spi_qup_set_state(controller, QUP_STATE_RESET)) { | ||
363 | dev_err(controller->dev, "cannot set RESET state\n"); | ||
364 | return -EIO; | ||
365 | } | ||
366 | |||
367 | w_size = 4; | ||
368 | if (xfer->bits_per_word <= 8) | ||
369 | w_size = 1; | ||
370 | else if (xfer->bits_per_word <= 16) | ||
371 | w_size = 2; | ||
372 | |||
373 | n_words = xfer->len / w_size; | ||
374 | controller->w_size = w_size; | ||
375 | |||
376 | if (n_words <= controller->in_fifo_sz) { | ||
377 | mode = QUP_IO_M_MODE_FIFO; | ||
378 | writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT); | ||
379 | writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT); | ||
380 | /* must be zero for FIFO */ | ||
381 | writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT); | ||
382 | writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); | ||
383 | } else { | ||
384 | mode = QUP_IO_M_MODE_BLOCK; | ||
385 | writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); | ||
386 | writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); | ||
387 | /* must be zero for BLOCK and BAM */ | ||
388 | writel_relaxed(0, controller->base + QUP_MX_READ_CNT); | ||
389 | writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); | ||
390 | } | ||
391 | |||
392 | iomode = readl_relaxed(controller->base + QUP_IO_M_MODES); | ||
393 | /* Set input and output transfer mode */ | ||
394 | iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK); | ||
395 | iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN); | ||
396 | iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT); | ||
397 | iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT); | ||
398 | |||
399 | writel_relaxed(iomode, controller->base + QUP_IO_M_MODES); | ||
400 | |||
401 | config = readl_relaxed(controller->base + SPI_CONFIG); | ||
402 | |||
403 | if (chip->mode & SPI_LOOP) | ||
404 | config |= SPI_CONFIG_LOOPBACK; | ||
405 | else | ||
406 | config &= ~SPI_CONFIG_LOOPBACK; | ||
407 | |||
408 | if (chip->mode & SPI_CPHA) | ||
409 | config &= ~SPI_CONFIG_INPUT_FIRST; | ||
410 | else | ||
411 | config |= SPI_CONFIG_INPUT_FIRST; | ||
412 | |||
413 | /* | ||
414 | * HS_MODE improves signal stability for spi-clk high rates, | ||
415 | * but is invalid in loop back mode. | ||
416 | */ | ||
417 | if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(chip->mode & SPI_LOOP)) | ||
418 | config |= SPI_CONFIG_HS_MODE; | ||
419 | else | ||
420 | config &= ~SPI_CONFIG_HS_MODE; | ||
421 | |||
422 | writel_relaxed(config, controller->base + SPI_CONFIG); | ||
423 | |||
424 | config = readl_relaxed(controller->base + QUP_CONFIG); | ||
425 | config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N); | ||
426 | config |= xfer->bits_per_word - 1; | ||
427 | config |= QUP_CONFIG_SPI_MODE; | ||
428 | writel_relaxed(config, controller->base + QUP_CONFIG); | ||
429 | |||
430 | writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | static void spi_qup_set_cs(struct spi_device *spi, bool enable) | ||
435 | { | ||
436 | struct spi_qup *controller = spi_master_get_devdata(spi->master); | ||
437 | struct spi_qup_device *chip = spi_get_ctldata(spi); | ||
438 | |||
439 | u32 iocontol, mask; | ||
440 | |||
441 | iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL); | ||
442 | |||
443 | /* Disable auto CS toggle and use manual */ | ||
444 | iocontol &= ~SPI_IO_C_MX_CS_MODE; | ||
445 | iocontol |= SPI_IO_C_FORCE_CS; | ||
446 | |||
447 | iocontol &= ~SPI_IO_C_CS_SELECT_MASK; | ||
448 | iocontol |= SPI_IO_C_CS_SELECT(chip->select); | ||
449 | |||
450 | mask = SPI_IO_C_CS_N_POLARITY_0 << chip->select; | ||
451 | |||
452 | if (enable) | ||
453 | iocontol |= mask; | ||
454 | else | ||
455 | iocontol &= ~mask; | ||
456 | |||
457 | writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL); | ||
458 | } | ||
459 | |||
460 | static int spi_qup_transfer_one(struct spi_master *master, | ||
461 | struct spi_device *spi, | ||
462 | struct spi_transfer *xfer) | ||
463 | { | ||
464 | struct spi_qup *controller = spi_master_get_devdata(master); | ||
465 | struct spi_qup_device *chip = spi_get_ctldata(spi); | ||
466 | unsigned long timeout, flags; | ||
467 | int ret = -EIO; | ||
468 | |||
469 | ret = spi_qup_io_config(controller, chip, xfer); | ||
470 | if (ret) | ||
471 | return ret; | ||
472 | |||
473 | timeout = DIV_ROUND_UP(xfer->speed_hz, MSEC_PER_SEC); | ||
474 | timeout = DIV_ROUND_UP(xfer->len * 8, timeout); | ||
475 | timeout = 100 * msecs_to_jiffies(timeout); | ||
476 | |||
477 | reinit_completion(&controller->done); | ||
478 | |||
479 | spin_lock_irqsave(&controller->lock, flags); | ||
480 | controller->xfer = xfer; | ||
481 | controller->error = 0; | ||
482 | controller->rx_bytes = 0; | ||
483 | controller->tx_bytes = 0; | ||
484 | spin_unlock_irqrestore(&controller->lock, flags); | ||
485 | |||
486 | if (spi_qup_set_state(controller, QUP_STATE_RUN)) { | ||
487 | dev_warn(controller->dev, "cannot set RUN state\n"); | ||
488 | goto exit; | ||
489 | } | ||
490 | |||
491 | if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) { | ||
492 | dev_warn(controller->dev, "cannot set PAUSE state\n"); | ||
493 | goto exit; | ||
494 | } | ||
495 | |||
496 | spi_qup_fifo_write(controller, xfer); | ||
497 | |||
498 | if (spi_qup_set_state(controller, QUP_STATE_RUN)) { | ||
499 | dev_warn(controller->dev, "cannot set EXECUTE state\n"); | ||
500 | goto exit; | ||
501 | } | ||
502 | |||
503 | if (!wait_for_completion_timeout(&controller->done, timeout)) | ||
504 | ret = -ETIMEDOUT; | ||
505 | exit: | ||
506 | spi_qup_set_state(controller, QUP_STATE_RESET); | ||
507 | spin_lock_irqsave(&controller->lock, flags); | ||
508 | controller->xfer = NULL; | ||
509 | if (!ret) | ||
510 | ret = controller->error; | ||
511 | spin_unlock_irqrestore(&controller->lock, flags); | ||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | static int spi_qup_setup(struct spi_device *spi) | ||
516 | { | ||
517 | struct spi_qup *controller = spi_master_get_devdata(spi->master); | ||
518 | struct spi_qup_device *chip = spi_get_ctldata(spi); | ||
519 | |||
520 | if (spi->chip_select >= spi->master->num_chipselect) { | ||
521 | dev_err(controller->dev, "invalid chip_select %d\n", | ||
522 | spi->chip_select); | ||
523 | return -EINVAL; | ||
524 | } | ||
525 | |||
526 | if (spi->max_speed_hz > controller->max_speed_hz) { | ||
527 | dev_err(controller->dev, "invalid max_speed_hz %d\n", | ||
528 | spi->max_speed_hz); | ||
529 | return -EINVAL; | ||
530 | } | ||
531 | |||
532 | if (!chip) { | ||
533 | /* First setup */ | ||
534 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
535 | if (!chip) { | ||
536 | dev_err(controller->dev, "no memory for chip data\n"); | ||
537 | return -ENOMEM; | ||
538 | } | ||
539 | |||
540 | chip->mode = spi->mode; | ||
541 | chip->select = spi->chip_select; | ||
542 | spi_set_ctldata(spi, chip); | ||
543 | } | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static void spi_qup_cleanup(struct spi_device *spi) | ||
549 | { | ||
550 | struct spi_qup_device *chip = spi_get_ctldata(spi); | ||
551 | |||
552 | if (!chip) | ||
553 | return; | ||
554 | |||
555 | spi_set_ctldata(spi, NULL); | ||
556 | kfree(chip); | ||
557 | } | ||
558 | |||
559 | static int spi_qup_probe(struct platform_device *pdev) | ||
560 | { | ||
561 | struct spi_master *master; | ||
562 | struct clk *iclk, *cclk; | ||
563 | struct spi_qup *controller; | ||
564 | struct resource *res; | ||
565 | struct device *dev; | ||
566 | void __iomem *base; | ||
567 | u32 data, max_freq, iomode; | ||
568 | int ret, irq, size; | ||
569 | |||
570 | dev = &pdev->dev; | ||
571 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
572 | base = devm_ioremap_resource(dev, res); | ||
573 | if (IS_ERR(base)) | ||
574 | return PTR_ERR(base); | ||
575 | |||
576 | irq = platform_get_irq(pdev, 0); | ||
577 | |||
578 | if (irq < 0) | ||
579 | return irq; | ||
580 | |||
581 | cclk = devm_clk_get(dev, "core"); | ||
582 | if (IS_ERR(cclk)) | ||
583 | return PTR_ERR(cclk); | ||
584 | |||
585 | iclk = devm_clk_get(dev, "iface"); | ||
586 | if (IS_ERR(iclk)) | ||
587 | return PTR_ERR(iclk); | ||
588 | |||
589 | /* This is optional parameter */ | ||
590 | if (of_property_read_u32(dev->of_node, "spi-max-frequency", &max_freq)) | ||
591 | max_freq = SPI_MAX_RATE; | ||
592 | |||
593 | if (!max_freq || max_freq > SPI_MAX_RATE) { | ||
594 | dev_err(dev, "invalid clock frequency %d\n", max_freq); | ||
595 | return -ENXIO; | ||
596 | } | ||
597 | |||
598 | ret = clk_prepare_enable(cclk); | ||
599 | if (ret) { | ||
600 | dev_err(dev, "cannot enable core clock\n"); | ||
601 | return ret; | ||
602 | } | ||
603 | |||
604 | ret = clk_prepare_enable(iclk); | ||
605 | if (ret) { | ||
606 | clk_disable_unprepare(cclk); | ||
607 | dev_err(dev, "cannot enable iface clock\n"); | ||
608 | return ret; | ||
609 | } | ||
610 | |||
611 | data = readl_relaxed(base + QUP_HW_VERSION); | ||
612 | |||
613 | if (data < QUP_HW_VERSION_2_1_1) { | ||
614 | clk_disable_unprepare(cclk); | ||
615 | clk_disable_unprepare(iclk); | ||
616 | dev_err(dev, "v.%08x is not supported\n", data); | ||
617 | return -ENXIO; | ||
618 | } | ||
619 | |||
620 | master = spi_alloc_master(dev, sizeof(struct spi_qup)); | ||
621 | if (!master) { | ||
622 | clk_disable_unprepare(cclk); | ||
623 | clk_disable_unprepare(iclk); | ||
624 | dev_err(dev, "cannot allocate master\n"); | ||
625 | return -ENOMEM; | ||
626 | } | ||
627 | |||
628 | master->bus_num = pdev->id; | ||
629 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; | ||
630 | master->num_chipselect = SPI_NUM_CHIPSELECTS; | ||
631 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); | ||
632 | master->setup = spi_qup_setup; | ||
633 | master->cleanup = spi_qup_cleanup; | ||
634 | master->set_cs = spi_qup_set_cs; | ||
635 | master->transfer_one = spi_qup_transfer_one; | ||
636 | master->dev.of_node = pdev->dev.of_node; | ||
637 | master->auto_runtime_pm = true; | ||
638 | |||
639 | platform_set_drvdata(pdev, master); | ||
640 | |||
641 | controller = spi_master_get_devdata(master); | ||
642 | |||
643 | controller->dev = dev; | ||
644 | controller->base = base; | ||
645 | controller->iclk = iclk; | ||
646 | controller->cclk = cclk; | ||
647 | controller->irq = irq; | ||
648 | controller->max_speed_hz = max_freq; | ||
649 | |||
650 | spin_lock_init(&controller->lock); | ||
651 | init_completion(&controller->done); | ||
652 | |||
653 | iomode = readl_relaxed(base + QUP_IO_M_MODES); | ||
654 | |||
655 | size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode); | ||
656 | if (size) | ||
657 | controller->out_blk_sz = size * 16; | ||
658 | else | ||
659 | controller->out_blk_sz = 4; | ||
660 | |||
661 | size = QUP_IO_M_INPUT_BLOCK_SIZE(iomode); | ||
662 | if (size) | ||
663 | controller->in_blk_sz = size * 16; | ||
664 | else | ||
665 | controller->in_blk_sz = 4; | ||
666 | |||
667 | size = QUP_IO_M_OUTPUT_FIFO_SIZE(iomode); | ||
668 | controller->out_fifo_sz = controller->out_blk_sz * (2 << size); | ||
669 | |||
670 | size = QUP_IO_M_INPUT_FIFO_SIZE(iomode); | ||
671 | controller->in_fifo_sz = controller->in_blk_sz * (2 << size); | ||
672 | |||
673 | dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", | ||
674 | data, controller->in_blk_sz, controller->in_fifo_sz, | ||
675 | controller->out_blk_sz, controller->out_fifo_sz); | ||
676 | |||
677 | writel_relaxed(1, base + QUP_SW_RESET); | ||
678 | |||
679 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); | ||
680 | if (ret) { | ||
681 | dev_err(dev, "cannot set RESET state\n"); | ||
682 | goto error; | ||
683 | } | ||
684 | |||
685 | writel_relaxed(0, base + QUP_OPERATIONAL); | ||
686 | writel_relaxed(0, base + QUP_IO_M_MODES); | ||
687 | writel_relaxed(0, base + QUP_OPERATIONAL_MASK); | ||
688 | writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN, | ||
689 | base + SPI_ERROR_FLAGS_EN); | ||
690 | |||
691 | writel_relaxed(0, base + SPI_CONFIG); | ||
692 | writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL); | ||
693 | |||
694 | ret = devm_request_irq(dev, irq, spi_qup_qup_irq, | ||
695 | IRQF_TRIGGER_HIGH, pdev->name, controller); | ||
696 | if (ret) | ||
697 | goto error; | ||
698 | |||
699 | ret = devm_spi_register_master(dev, master); | ||
700 | if (ret) | ||
701 | goto error; | ||
702 | |||
703 | pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); | ||
704 | pm_runtime_use_autosuspend(dev); | ||
705 | pm_runtime_set_active(dev); | ||
706 | pm_runtime_enable(dev); | ||
707 | return 0; | ||
708 | |||
709 | error: | ||
710 | clk_disable_unprepare(cclk); | ||
711 | clk_disable_unprepare(iclk); | ||
712 | spi_master_put(master); | ||
713 | return ret; | ||
714 | } | ||
715 | |||
716 | #ifdef CONFIG_PM_RUNTIME | ||
717 | static int spi_qup_pm_suspend_runtime(struct device *device) | ||
718 | { | ||
719 | struct spi_master *master = dev_get_drvdata(device); | ||
720 | struct spi_qup *controller = spi_master_get_devdata(master); | ||
721 | u32 config; | ||
722 | |||
723 | /* Enable clocks auto gaiting */ | ||
724 | config = readl(controller->base + QUP_CONFIG); | ||
725 | config |= QUP_CLOCK_AUTO_GATE; | ||
726 | writel_relaxed(config, controller->base + QUP_CONFIG); | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static int spi_qup_pm_resume_runtime(struct device *device) | ||
731 | { | ||
732 | struct spi_master *master = dev_get_drvdata(device); | ||
733 | struct spi_qup *controller = spi_master_get_devdata(master); | ||
734 | u32 config; | ||
735 | |||
736 | /* Disable clocks auto gaiting */ | ||
737 | config = readl_relaxed(controller->base + QUP_CONFIG); | ||
738 | config &= ~QUP_CLOCK_AUTO_GATE; | ||
739 | writel_relaxed(config, controller->base + QUP_CONFIG); | ||
740 | return 0; | ||
741 | } | ||
742 | #endif /* CONFIG_PM_RUNTIME */ | ||
743 | |||
744 | #ifdef CONFIG_PM_SLEEP | ||
745 | static int spi_qup_suspend(struct device *device) | ||
746 | { | ||
747 | struct spi_master *master = dev_get_drvdata(device); | ||
748 | struct spi_qup *controller = spi_master_get_devdata(master); | ||
749 | int ret; | ||
750 | |||
751 | ret = spi_master_suspend(master); | ||
752 | if (ret) | ||
753 | return ret; | ||
754 | |||
755 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); | ||
756 | if (ret) | ||
757 | return ret; | ||
758 | |||
759 | clk_disable_unprepare(controller->cclk); | ||
760 | clk_disable_unprepare(controller->iclk); | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int spi_qup_resume(struct device *device) | ||
765 | { | ||
766 | struct spi_master *master = dev_get_drvdata(device); | ||
767 | struct spi_qup *controller = spi_master_get_devdata(master); | ||
768 | int ret; | ||
769 | |||
770 | ret = clk_prepare_enable(controller->iclk); | ||
771 | if (ret) | ||
772 | return ret; | ||
773 | |||
774 | ret = clk_prepare_enable(controller->cclk); | ||
775 | if (ret) | ||
776 | return ret; | ||
777 | |||
778 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); | ||
779 | if (ret) | ||
780 | return ret; | ||
781 | |||
782 | return spi_master_resume(master); | ||
783 | } | ||
784 | #endif /* CONFIG_PM_SLEEP */ | ||
785 | |||
786 | static int spi_qup_remove(struct platform_device *pdev) | ||
787 | { | ||
788 | struct spi_master *master = dev_get_drvdata(&pdev->dev); | ||
789 | struct spi_qup *controller = spi_master_get_devdata(master); | ||
790 | int ret; | ||
791 | |||
792 | ret = pm_runtime_get_sync(&pdev->dev); | ||
793 | if (ret) | ||
794 | return ret; | ||
795 | |||
796 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); | ||
797 | if (ret) | ||
798 | return ret; | ||
799 | |||
800 | clk_disable_unprepare(controller->cclk); | ||
801 | clk_disable_unprepare(controller->iclk); | ||
802 | |||
803 | pm_runtime_put_noidle(&pdev->dev); | ||
804 | pm_runtime_disable(&pdev->dev); | ||
805 | spi_master_put(master); | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static struct of_device_id spi_qup_dt_match[] = { | ||
810 | { .compatible = "qcom,spi-qup-v2.1.1", }, | ||
811 | { .compatible = "qcom,spi-qup-v2.2.1", }, | ||
812 | { } | ||
813 | }; | ||
814 | MODULE_DEVICE_TABLE(of, spi_qup_dt_match); | ||
815 | |||
816 | static const struct dev_pm_ops spi_qup_dev_pm_ops = { | ||
817 | SET_SYSTEM_SLEEP_PM_OPS(spi_qup_suspend, spi_qup_resume) | ||
818 | SET_RUNTIME_PM_OPS(spi_qup_pm_suspend_runtime, | ||
819 | spi_qup_pm_resume_runtime, | ||
820 | NULL) | ||
821 | }; | ||
822 | |||
823 | static struct platform_driver spi_qup_driver = { | ||
824 | .driver = { | ||
825 | .name = "spi_qup", | ||
826 | .owner = THIS_MODULE, | ||
827 | .pm = &spi_qup_dev_pm_ops, | ||
828 | .of_match_table = spi_qup_dt_match, | ||
829 | }, | ||
830 | .probe = spi_qup_probe, | ||
831 | .remove = spi_qup_remove, | ||
832 | }; | ||
833 | module_platform_driver(spi_qup_driver); | ||
834 | |||
835 | MODULE_LICENSE("GPL v2"); | ||
836 | MODULE_VERSION("0.4"); | ||
837 | MODULE_ALIAS("platform:spi_qup"); | ||