1 // SPDX-License-Identifier: GPL-2.0
3 // Synquacer HSSPI controller driver
5 // Copyright (c) 2015-2018 Socionext Inc.
6 // Copyright (c) 2018-2019 Linaro Ltd.
9 #include <linux/acpi.h>
10 #include <linux/delay.h>
11 #include <linux/interrupt.h>
13 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/scatterlist.h>
18 #include <linux/slab.h>
19 #include <linux/spi/spi.h>
20 #include <linux/spinlock.h>
21 #include <linux/clk.h>
23 /* HSSPI register address definitions */
24 #define SYNQUACER_HSSPI_REG_MCTRL 0x00
25 #define SYNQUACER_HSSPI_REG_PCC0 0x04
26 #define SYNQUACER_HSSPI_REG_PCC(n) (SYNQUACER_HSSPI_REG_PCC0 + (n) * 4)
27 #define SYNQUACER_HSSPI_REG_TXF 0x14
28 #define SYNQUACER_HSSPI_REG_TXE 0x18
29 #define SYNQUACER_HSSPI_REG_TXC 0x1C
30 #define SYNQUACER_HSSPI_REG_RXF 0x20
31 #define SYNQUACER_HSSPI_REG_RXE 0x24
32 #define SYNQUACER_HSSPI_REG_RXC 0x28
33 #define SYNQUACER_HSSPI_REG_FAULTF 0x2C
34 #define SYNQUACER_HSSPI_REG_FAULTC 0x30
35 #define SYNQUACER_HSSPI_REG_DMCFG 0x34
36 #define SYNQUACER_HSSPI_REG_DMSTART 0x38
37 #define SYNQUACER_HSSPI_REG_DMBCC 0x3C
38 #define SYNQUACER_HSSPI_REG_DMSTATUS 0x40
39 #define SYNQUACER_HSSPI_REG_FIFOCFG 0x4C
40 #define SYNQUACER_HSSPI_REG_TX_FIFO 0x50
41 #define SYNQUACER_HSSPI_REG_RX_FIFO 0x90
42 #define SYNQUACER_HSSPI_REG_MID 0xFC
44 /* HSSPI register bit definitions */
45 #define SYNQUACER_HSSPI_MCTRL_MEN BIT(0)
46 #define SYNQUACER_HSSPI_MCTRL_COMMAND_SEQUENCE_EN BIT(1)
47 #define SYNQUACER_HSSPI_MCTRL_CDSS BIT(3)
48 #define SYNQUACER_HSSPI_MCTRL_MES BIT(4)
49 #define SYNQUACER_HSSPI_MCTRL_SYNCON BIT(5)
51 #define SYNQUACER_HSSPI_PCC_CPHA BIT(0)
52 #define SYNQUACER_HSSPI_PCC_CPOL BIT(1)
53 #define SYNQUACER_HSSPI_PCC_ACES BIT(2)
54 #define SYNQUACER_HSSPI_PCC_RTM BIT(3)
55 #define SYNQUACER_HSSPI_PCC_SSPOL BIT(4)
56 #define SYNQUACER_HSSPI_PCC_SDIR BIT(7)
57 #define SYNQUACER_HSSPI_PCC_SENDIAN BIT(8)
58 #define SYNQUACER_HSSPI_PCC_SAFESYNC BIT(16)
59 #define SYNQUACER_HSSPI_PCC_SS2CD_SHIFT 5U
60 #define SYNQUACER_HSSPI_PCC_CDRS_MASK 0x7f
61 #define SYNQUACER_HSSPI_PCC_CDRS_SHIFT 9U
63 #define SYNQUACER_HSSPI_TXF_FIFO_FULL BIT(0)
64 #define SYNQUACER_HSSPI_TXF_FIFO_EMPTY BIT(1)
65 #define SYNQUACER_HSSPI_TXF_SLAVE_RELEASED BIT(6)
67 #define SYNQUACER_HSSPI_TXE_FIFO_FULL BIT(0)
68 #define SYNQUACER_HSSPI_TXE_FIFO_EMPTY BIT(1)
69 #define SYNQUACER_HSSPI_TXE_SLAVE_RELEASED BIT(6)
71 #define SYNQUACER_HSSPI_RXF_FIFO_MORE_THAN_THRESHOLD BIT(5)
72 #define SYNQUACER_HSSPI_RXF_SLAVE_RELEASED BIT(6)
74 #define SYNQUACER_HSSPI_RXE_FIFO_MORE_THAN_THRESHOLD BIT(5)
75 #define SYNQUACER_HSSPI_RXE_SLAVE_RELEASED BIT(6)
77 #define SYNQUACER_HSSPI_DMCFG_SSDC BIT(1)
78 #define SYNQUACER_HSSPI_DMCFG_MSTARTEN BIT(2)
80 #define SYNQUACER_HSSPI_DMSTART_START BIT(0)
81 #define SYNQUACER_HSSPI_DMSTOP_STOP BIT(8)
82 #define SYNQUACER_HSSPI_DMPSEL_CS_MASK 0x3
83 #define SYNQUACER_HSSPI_DMPSEL_CS_SHIFT 16U
84 #define SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT 24U
85 #define SYNQUACER_HSSPI_DMTRP_DATA_MASK 0x3
86 #define SYNQUACER_HSSPI_DMTRP_DATA_SHIFT 26U
87 #define SYNQUACER_HSSPI_DMTRP_DATA_TXRX 0
88 #define SYNQUACER_HSSPI_DMTRP_DATA_RX 1
89 #define SYNQUACER_HSSPI_DMTRP_DATA_TX 2
91 #define SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK 0x1f
92 #define SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT 8U
93 #define SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK 0x1f
94 #define SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT 16U
96 #define SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_MASK 0xf
97 #define SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT 0U
98 #define SYNQUACER_HSSPI_FIFOCFG_TX_THRESHOLD_MASK 0xf
99 #define SYNQUACER_HSSPI_FIFOCFG_TX_THRESHOLD_SHIFT 4U
100 #define SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_MASK 0x3
101 #define SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT 8U
102 #define SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH BIT(11)
103 #define SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH BIT(12)
105 #define SYNQUACER_HSSPI_FIFO_DEPTH 16U
106 #define SYNQUACER_HSSPI_FIFO_TX_THRESHOLD 4U
107 #define SYNQUACER_HSSPI_FIFO_RX_THRESHOLD \
108 (SYNQUACER_HSSPI_FIFO_DEPTH - SYNQUACER_HSSPI_FIFO_TX_THRESHOLD)
110 #define SYNQUACER_HSSPI_TRANSFER_MODE_TX BIT(1)
111 #define SYNQUACER_HSSPI_TRANSFER_MODE_RX BIT(2)
112 #define SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC 2000U
113 #define SYNQUACER_HSSPI_ENABLE_TMOUT_MSEC 1000U
115 #define SYNQUACER_HSSPI_CLOCK_SRC_IHCLK 0
116 #define SYNQUACER_HSSPI_CLOCK_SRC_IPCLK 1
118 #define SYNQUACER_HSSPI_NUM_CHIP_SELECT 4U
119 #define SYNQUACER_HSSPI_IRQ_NAME_MAX 32U
121 struct synquacer_spi
{
123 struct completion transfer_done
;
134 u32 tx_words
, rx_words
;
135 unsigned int bus_width
;
136 unsigned int transfer_mode
;
137 char rx_irq_name
[SYNQUACER_HSSPI_IRQ_NAME_MAX
];
138 char tx_irq_name
[SYNQUACER_HSSPI_IRQ_NAME_MAX
];
141 static int read_fifo(struct synquacer_spi
*sspi
)
143 u32 len
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTATUS
);
145 len
= (len
>> SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT
) &
146 SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK
;
147 len
= min(len
, sspi
->rx_words
);
151 u8
*buf
= sspi
->rx_buf
;
153 ioread8_rep(sspi
->regs
+ SYNQUACER_HSSPI_REG_RX_FIFO
,
155 sspi
->rx_buf
= buf
+ len
;
159 u16
*buf
= sspi
->rx_buf
;
161 ioread16_rep(sspi
->regs
+ SYNQUACER_HSSPI_REG_RX_FIFO
,
163 sspi
->rx_buf
= buf
+ len
;
167 /* fallthrough, should use 32-bits access */
169 u32
*buf
= sspi
->rx_buf
;
171 ioread32_rep(sspi
->regs
+ SYNQUACER_HSSPI_REG_RX_FIFO
,
173 sspi
->rx_buf
= buf
+ len
;
180 sspi
->rx_words
-= len
;
184 static int write_fifo(struct synquacer_spi
*sspi
)
186 u32 len
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTATUS
);
188 len
= (len
>> SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT
) &
189 SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK
;
190 len
= min(SYNQUACER_HSSPI_FIFO_DEPTH
- len
,
195 const u8
*buf
= sspi
->tx_buf
;
197 iowrite8_rep(sspi
->regs
+ SYNQUACER_HSSPI_REG_TX_FIFO
,
199 sspi
->tx_buf
= buf
+ len
;
203 const u16
*buf
= sspi
->tx_buf
;
205 iowrite16_rep(sspi
->regs
+ SYNQUACER_HSSPI_REG_TX_FIFO
,
207 sspi
->tx_buf
= buf
+ len
;
211 /* fallthrough, should use 32-bits access */
213 const u32
*buf
= sspi
->tx_buf
;
215 iowrite32_rep(sspi
->regs
+ SYNQUACER_HSSPI_REG_TX_FIFO
,
217 sspi
->tx_buf
= buf
+ len
;
224 sspi
->tx_words
-= len
;
228 static int synquacer_spi_config(struct spi_master
*master
,
229 struct spi_device
*spi
,
230 struct spi_transfer
*xfer
)
232 struct synquacer_spi
*sspi
= spi_master_get_devdata(master
);
233 unsigned int speed
, mode
, bpw
, cs
, bus_width
, transfer_mode
;
236 /* Full Duplex only on 1-bit wide bus */
237 if (xfer
->rx_buf
&& xfer
->tx_buf
&&
238 (xfer
->rx_nbits
!= 1 || xfer
->tx_nbits
!= 1)) {
240 "RX and TX bus widths must be 1-bit for Full-Duplex!\n");
245 bus_width
= xfer
->tx_nbits
;
246 transfer_mode
= SYNQUACER_HSSPI_TRANSFER_MODE_TX
;
248 bus_width
= xfer
->rx_nbits
;
249 transfer_mode
= SYNQUACER_HSSPI_TRANSFER_MODE_RX
;
253 cs
= spi
->chip_select
;
254 speed
= xfer
->speed_hz
;
255 bpw
= xfer
->bits_per_word
;
257 /* return if nothing to change */
258 if (speed
== sspi
->speed
&&
259 bus_width
== sspi
->bus_width
&& bpw
== sspi
->bpw
&&
260 mode
== sspi
->mode
&& cs
== sspi
->cs
&&
261 transfer_mode
== sspi
->transfer_mode
) {
265 sspi
->transfer_mode
= transfer_mode
;
266 rate
= master
->max_speed_hz
;
268 div
= DIV_ROUND_UP(rate
, speed
);
270 dev_err(sspi
->dev
, "Requested rate too low (%u)\n",
275 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_PCC(cs
));
276 val
&= ~SYNQUACER_HSSPI_PCC_SAFESYNC
;
277 if (bpw
== 8 && (mode
& (SPI_TX_DUAL
| SPI_RX_DUAL
)) && div
< 3)
278 val
|= SYNQUACER_HSSPI_PCC_SAFESYNC
;
279 if (bpw
== 8 && (mode
& (SPI_TX_QUAD
| SPI_RX_QUAD
)) && div
< 6)
280 val
|= SYNQUACER_HSSPI_PCC_SAFESYNC
;
281 if (bpw
== 16 && (mode
& (SPI_TX_QUAD
| SPI_RX_QUAD
)) && div
< 3)
282 val
|= SYNQUACER_HSSPI_PCC_SAFESYNC
;
285 val
|= SYNQUACER_HSSPI_PCC_CPHA
;
287 val
&= ~SYNQUACER_HSSPI_PCC_CPHA
;
290 val
|= SYNQUACER_HSSPI_PCC_CPOL
;
292 val
&= ~SYNQUACER_HSSPI_PCC_CPOL
;
294 if (mode
& SPI_CS_HIGH
)
295 val
|= SYNQUACER_HSSPI_PCC_SSPOL
;
297 val
&= ~SYNQUACER_HSSPI_PCC_SSPOL
;
299 if (mode
& SPI_LSB_FIRST
)
300 val
|= SYNQUACER_HSSPI_PCC_SDIR
;
302 val
&= ~SYNQUACER_HSSPI_PCC_SDIR
;
305 val
|= SYNQUACER_HSSPI_PCC_ACES
;
307 val
&= ~SYNQUACER_HSSPI_PCC_ACES
;
310 val
|= SYNQUACER_HSSPI_PCC_RTM
;
312 val
&= ~SYNQUACER_HSSPI_PCC_RTM
;
314 val
|= (3 << SYNQUACER_HSSPI_PCC_SS2CD_SHIFT
);
315 val
|= SYNQUACER_HSSPI_PCC_SENDIAN
;
317 val
&= ~(SYNQUACER_HSSPI_PCC_CDRS_MASK
<<
318 SYNQUACER_HSSPI_PCC_CDRS_SHIFT
);
319 val
|= ((div
>> 1) << SYNQUACER_HSSPI_PCC_CDRS_SHIFT
);
321 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_PCC(cs
));
323 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_FIFOCFG
);
324 val
&= ~(SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_MASK
<<
325 SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT
);
326 val
|= ((bpw
/ 8 - 1) << SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT
);
327 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_FIFOCFG
);
329 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
330 val
&= ~(SYNQUACER_HSSPI_DMTRP_DATA_MASK
<<
331 SYNQUACER_HSSPI_DMTRP_DATA_SHIFT
);
334 val
|= (SYNQUACER_HSSPI_DMTRP_DATA_RX
<<
335 SYNQUACER_HSSPI_DMTRP_DATA_SHIFT
);
337 val
|= (SYNQUACER_HSSPI_DMTRP_DATA_TX
<<
338 SYNQUACER_HSSPI_DMTRP_DATA_SHIFT
);
340 val
&= ~(3 << SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT
);
341 val
|= ((bus_width
>> 1) << SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT
);
342 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
347 sspi
->cs
= spi
->chip_select
;
348 sspi
->bus_width
= bus_width
;
353 static int synquacer_spi_transfer_one(struct spi_master
*master
,
354 struct spi_device
*spi
,
355 struct spi_transfer
*xfer
)
357 struct synquacer_spi
*sspi
= spi_master_get_devdata(master
);
364 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
365 val
&= ~SYNQUACER_HSSPI_DMSTOP_STOP
;
366 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
368 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_FIFOCFG
);
369 val
|= SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH
;
370 val
|= SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH
;
371 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_FIFOCFG
);
374 * See if we can transfer 4-bytes as 1 word
375 * to maximize the FIFO buffer efficiency.
377 bpw
= xfer
->bits_per_word
;
378 if (bpw
== 8 && !(xfer
->len
% 4) && !(spi
->mode
& SPI_LSB_FIRST
))
379 xfer
->bits_per_word
= 32;
381 ret
= synquacer_spi_config(master
, spi
, xfer
);
384 xfer
->bits_per_word
= bpw
;
389 reinit_completion(&sspi
->transfer_done
);
391 sspi
->tx_buf
= xfer
->tx_buf
;
392 sspi
->rx_buf
= xfer
->rx_buf
;
399 words
= xfer
->len
/ 2;
402 /* fallthrough, should use 32-bits access */
404 words
= xfer
->len
/ 4;
407 dev_err(sspi
->dev
, "unsupported bpw: %d\n", sspi
->bpw
);
412 sspi
->tx_words
= words
;
417 sspi
->rx_words
= words
;
422 status
= write_fifo(sspi
);
424 dev_err(sspi
->dev
, "failed write_fifo. status: 0x%x\n",
431 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_FIFOCFG
);
432 val
&= ~(SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_MASK
<<
433 SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT
);
434 val
|= ((sspi
->rx_words
> SYNQUACER_HSSPI_FIFO_DEPTH
?
435 SYNQUACER_HSSPI_FIFO_RX_THRESHOLD
: sspi
->rx_words
) <<
436 SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT
);
437 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_FIFOCFG
);
440 writel(~0, sspi
->regs
+ SYNQUACER_HSSPI_REG_TXC
);
441 writel(~0, sspi
->regs
+ SYNQUACER_HSSPI_REG_RXC
);
444 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
445 val
|= SYNQUACER_HSSPI_DMSTART_START
;
446 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
449 val
= SYNQUACER_HSSPI_TXE_FIFO_EMPTY
;
450 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_TXE
);
451 status
= wait_for_completion_timeout(&sspi
->transfer_done
,
452 msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC
));
453 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_TXE
);
457 u32 buf
[SYNQUACER_HSSPI_FIFO_DEPTH
];
459 val
= SYNQUACER_HSSPI_RXE_FIFO_MORE_THAN_THRESHOLD
|
460 SYNQUACER_HSSPI_RXE_SLAVE_RELEASED
;
461 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_RXE
);
462 status
= wait_for_completion_timeout(&sspi
->transfer_done
,
463 msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC
));
464 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_RXE
);
466 /* stop RX and clean RXFIFO */
467 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
468 val
|= SYNQUACER_HSSPI_DMSTOP_STOP
;
469 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
471 sspi
->rx_words
= SYNQUACER_HSSPI_FIFO_DEPTH
;
476 dev_err(sspi
->dev
, "failed to transfer. status: 0x%x\n",
484 static void synquacer_spi_set_cs(struct spi_device
*spi
, bool enable
)
486 struct synquacer_spi
*sspi
= spi_master_get_devdata(spi
->master
);
489 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
490 val
&= ~(SYNQUACER_HSSPI_DMPSEL_CS_MASK
<<
491 SYNQUACER_HSSPI_DMPSEL_CS_SHIFT
);
492 val
|= spi
->chip_select
<< SYNQUACER_HSSPI_DMPSEL_CS_SHIFT
;
493 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_DMSTART
);
496 static int synquacer_spi_wait_status_update(struct synquacer_spi
*sspi
,
500 unsigned long timeout
= jiffies
+
501 msecs_to_jiffies(SYNQUACER_HSSPI_ENABLE_TMOUT_MSEC
);
503 /* wait MES(Module Enable Status) is updated */
505 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_MCTRL
) &
506 SYNQUACER_HSSPI_MCTRL_MES
;
511 } while (time_before(jiffies
, timeout
));
513 dev_err(sspi
->dev
, "timeout occurs in updating Module Enable Status\n");
517 static int synquacer_spi_enable(struct spi_master
*master
)
521 struct synquacer_spi
*sspi
= spi_master_get_devdata(master
);
524 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_MCTRL
);
525 status
= synquacer_spi_wait_status_update(sspi
, false);
529 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_TXE
);
530 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_RXE
);
531 writel(~0, sspi
->regs
+ SYNQUACER_HSSPI_REG_TXC
);
532 writel(~0, sspi
->regs
+ SYNQUACER_HSSPI_REG_RXC
);
533 writel(~0, sspi
->regs
+ SYNQUACER_HSSPI_REG_FAULTC
);
535 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_DMCFG
);
536 val
&= ~SYNQUACER_HSSPI_DMCFG_SSDC
;
537 val
&= ~SYNQUACER_HSSPI_DMCFG_MSTARTEN
;
538 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_DMCFG
);
540 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_MCTRL
);
541 if (sspi
->clk_src_type
== SYNQUACER_HSSPI_CLOCK_SRC_IPCLK
)
542 val
|= SYNQUACER_HSSPI_MCTRL_CDSS
;
544 val
&= ~SYNQUACER_HSSPI_MCTRL_CDSS
;
546 val
&= ~SYNQUACER_HSSPI_MCTRL_COMMAND_SEQUENCE_EN
;
547 val
|= SYNQUACER_HSSPI_MCTRL_MEN
;
548 val
|= SYNQUACER_HSSPI_MCTRL_SYNCON
;
551 writel(val
, sspi
->regs
+ SYNQUACER_HSSPI_REG_MCTRL
);
552 status
= synquacer_spi_wait_status_update(sspi
, true);
559 static irqreturn_t
sq_spi_rx_handler(int irq
, void *priv
)
562 struct synquacer_spi
*sspi
= priv
;
564 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_RXF
);
565 if ((val
& SYNQUACER_HSSPI_RXF_SLAVE_RELEASED
) ||
566 (val
& SYNQUACER_HSSPI_RXF_FIFO_MORE_THAN_THRESHOLD
)) {
569 if (sspi
->rx_words
== 0) {
570 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_RXE
);
571 complete(&sspi
->transfer_done
);
579 static irqreturn_t
sq_spi_tx_handler(int irq
, void *priv
)
582 struct synquacer_spi
*sspi
= priv
;
584 val
= readl(sspi
->regs
+ SYNQUACER_HSSPI_REG_TXF
);
585 if (val
& SYNQUACER_HSSPI_TXF_FIFO_EMPTY
) {
586 if (sspi
->tx_words
== 0) {
587 writel(0, sspi
->regs
+ SYNQUACER_HSSPI_REG_TXE
);
588 complete(&sspi
->transfer_done
);
598 static int synquacer_spi_probe(struct platform_device
*pdev
)
600 struct device_node
*np
= pdev
->dev
.of_node
;
601 struct spi_master
*master
;
602 struct synquacer_spi
*sspi
;
606 master
= spi_alloc_master(&pdev
->dev
, sizeof(*sspi
));
610 platform_set_drvdata(pdev
, master
);
612 sspi
= spi_master_get_devdata(master
);
613 sspi
->dev
= &pdev
->dev
;
615 init_completion(&sspi
->transfer_done
);
617 sspi
->regs
= devm_platform_ioremap_resource(pdev
, 0);
618 if (IS_ERR(sspi
->regs
)) {
619 ret
= PTR_ERR(sspi
->regs
);
623 sspi
->clk_src_type
= SYNQUACER_HSSPI_CLOCK_SRC_IHCLK
; /* Default */
624 device_property_read_u32(&pdev
->dev
, "socionext,ihclk-rate",
625 &master
->max_speed_hz
); /* for ACPI */
627 if (dev_of_node(&pdev
->dev
)) {
628 if (device_property_match_string(&pdev
->dev
,
629 "clock-names", "iHCLK") >= 0) {
630 sspi
->clk_src_type
= SYNQUACER_HSSPI_CLOCK_SRC_IHCLK
;
631 sspi
->clk
= devm_clk_get(sspi
->dev
, "iHCLK");
632 } else if (device_property_match_string(&pdev
->dev
,
633 "clock-names", "iPCLK") >= 0) {
634 sspi
->clk_src_type
= SYNQUACER_HSSPI_CLOCK_SRC_IPCLK
;
635 sspi
->clk
= devm_clk_get(sspi
->dev
, "iPCLK");
637 dev_err(&pdev
->dev
, "specified wrong clock source\n");
642 if (IS_ERR(sspi
->clk
)) {
643 if (!(PTR_ERR(sspi
->clk
) == -EPROBE_DEFER
))
644 dev_err(&pdev
->dev
, "clock not found\n");
645 ret
= PTR_ERR(sspi
->clk
);
649 ret
= clk_prepare_enable(sspi
->clk
);
651 dev_err(&pdev
->dev
, "failed to enable clock (%d)\n",
656 master
->max_speed_hz
= clk_get_rate(sspi
->clk
);
659 if (!master
->max_speed_hz
) {
660 dev_err(&pdev
->dev
, "missing clock source\n");
663 master
->min_speed_hz
= master
->max_speed_hz
/ 254;
665 sspi
->aces
= device_property_read_bool(&pdev
->dev
,
666 "socionext,set-aces");
667 sspi
->rtm
= device_property_read_bool(&pdev
->dev
, "socionext,use-rtm");
669 master
->num_chipselect
= SYNQUACER_HSSPI_NUM_CHIP_SELECT
;
671 rx_irq
= platform_get_irq(pdev
, 0);
676 snprintf(sspi
->rx_irq_name
, SYNQUACER_HSSPI_IRQ_NAME_MAX
, "%s-rx",
677 dev_name(&pdev
->dev
));
678 ret
= devm_request_irq(&pdev
->dev
, rx_irq
, sq_spi_rx_handler
,
679 0, sspi
->rx_irq_name
, sspi
);
681 dev_err(&pdev
->dev
, "request rx_irq failed (%d)\n", ret
);
685 tx_irq
= platform_get_irq(pdev
, 1);
690 snprintf(sspi
->tx_irq_name
, SYNQUACER_HSSPI_IRQ_NAME_MAX
, "%s-tx",
691 dev_name(&pdev
->dev
));
692 ret
= devm_request_irq(&pdev
->dev
, tx_irq
, sq_spi_tx_handler
,
693 0, sspi
->tx_irq_name
, sspi
);
695 dev_err(&pdev
->dev
, "request tx_irq failed (%d)\n", ret
);
699 master
->dev
.of_node
= np
;
700 master
->dev
.fwnode
= pdev
->dev
.fwnode
;
701 master
->auto_runtime_pm
= true;
702 master
->bus_num
= pdev
->id
;
704 master
->mode_bits
= SPI_CPOL
| SPI_CPHA
| SPI_TX_DUAL
| SPI_RX_DUAL
|
705 SPI_TX_QUAD
| SPI_RX_QUAD
;
706 master
->bits_per_word_mask
= SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
707 SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
709 master
->set_cs
= synquacer_spi_set_cs
;
710 master
->transfer_one
= synquacer_spi_transfer_one
;
712 ret
= synquacer_spi_enable(master
);
716 pm_runtime_set_active(sspi
->dev
);
717 pm_runtime_enable(sspi
->dev
);
719 ret
= devm_spi_register_master(sspi
->dev
, master
);
726 pm_runtime_disable(sspi
->dev
);
728 clk_disable_unprepare(sspi
->clk
);
730 spi_master_put(master
);
735 static int synquacer_spi_remove(struct platform_device
*pdev
)
737 struct spi_master
*master
= platform_get_drvdata(pdev
);
738 struct synquacer_spi
*sspi
= spi_master_get_devdata(master
);
740 pm_runtime_disable(sspi
->dev
);
742 clk_disable_unprepare(sspi
->clk
);
747 static int __maybe_unused
synquacer_spi_suspend(struct device
*dev
)
749 struct spi_master
*master
= dev_get_drvdata(dev
);
750 struct synquacer_spi
*sspi
= spi_master_get_devdata(master
);
753 ret
= spi_master_suspend(master
);
757 if (!pm_runtime_suspended(dev
))
758 clk_disable_unprepare(sspi
->clk
);
763 static int __maybe_unused
synquacer_spi_resume(struct device
*dev
)
765 struct spi_master
*master
= dev_get_drvdata(dev
);
766 struct synquacer_spi
*sspi
= spi_master_get_devdata(master
);
769 if (!pm_runtime_suspended(dev
)) {
770 /* Ensure reconfigure during next xfer */
773 ret
= clk_prepare_enable(sspi
->clk
);
775 dev_err(dev
, "failed to enable clk (%d)\n",
780 ret
= synquacer_spi_enable(master
);
782 dev_err(dev
, "failed to enable spi (%d)\n", ret
);
787 ret
= spi_master_resume(master
);
789 clk_disable_unprepare(sspi
->clk
);
794 static SIMPLE_DEV_PM_OPS(synquacer_spi_pm_ops
, synquacer_spi_suspend
,
795 synquacer_spi_resume
);
797 static const struct of_device_id synquacer_spi_of_match
[] = {
798 {.compatible
= "socionext,synquacer-spi"},
801 MODULE_DEVICE_TABLE(of
, synquacer_spi_of_match
);
804 static const struct acpi_device_id synquacer_hsspi_acpi_ids
[] = {
808 MODULE_DEVICE_TABLE(acpi
, synquacer_hsspi_acpi_ids
);
811 static struct platform_driver synquacer_spi_driver
= {
813 .name
= "synquacer-spi",
814 .pm
= &synquacer_spi_pm_ops
,
815 .of_match_table
= synquacer_spi_of_match
,
816 .acpi_match_table
= ACPI_PTR(synquacer_hsspi_acpi_ids
),
818 .probe
= synquacer_spi_probe
,
819 .remove
= synquacer_spi_remove
,
821 module_platform_driver(synquacer_spi_driver
);
823 MODULE_DESCRIPTION("Socionext Synquacer HS-SPI controller driver");
824 MODULE_AUTHOR("Masahisa Kojima <masahisa.kojima@linaro.org>");
825 MODULE_AUTHOR("Jassi Brar <jaswinder.singh@linaro.org>");
826 MODULE_LICENSE("GPL v2");