1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Marvell Armada-3700 SPI controller driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2016 Marvell Ltd.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Author: Wilson Ding <dingwei@marvell.com>
8*4882a593Smuzhiyun * Author: Romain Perier <romain.perier@free-electrons.com>
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/clk.h>
12*4882a593Smuzhiyun #include <linux/completion.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun #include <linux/err.h>
15*4882a593Smuzhiyun #include <linux/interrupt.h>
16*4882a593Smuzhiyun #include <linux/io.h>
17*4882a593Smuzhiyun #include <linux/kernel.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/of.h>
20*4882a593Smuzhiyun #include <linux/of_irq.h>
21*4882a593Smuzhiyun #include <linux/of_device.h>
22*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
23*4882a593Smuzhiyun #include <linux/spi/spi.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #define DRIVER_NAME "armada_3700_spi"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define A3700_SPI_MAX_SPEED_HZ 100000000
28*4882a593Smuzhiyun #define A3700_SPI_MAX_PRESCALE 30
29*4882a593Smuzhiyun #define A3700_SPI_TIMEOUT 10
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun /* SPI Register Offest */
32*4882a593Smuzhiyun #define A3700_SPI_IF_CTRL_REG 0x00
33*4882a593Smuzhiyun #define A3700_SPI_IF_CFG_REG 0x04
34*4882a593Smuzhiyun #define A3700_SPI_DATA_OUT_REG 0x08
35*4882a593Smuzhiyun #define A3700_SPI_DATA_IN_REG 0x0C
36*4882a593Smuzhiyun #define A3700_SPI_IF_INST_REG 0x10
37*4882a593Smuzhiyun #define A3700_SPI_IF_ADDR_REG 0x14
38*4882a593Smuzhiyun #define A3700_SPI_IF_RMODE_REG 0x18
39*4882a593Smuzhiyun #define A3700_SPI_IF_HDR_CNT_REG 0x1C
40*4882a593Smuzhiyun #define A3700_SPI_IF_DIN_CNT_REG 0x20
41*4882a593Smuzhiyun #define A3700_SPI_IF_TIME_REG 0x24
42*4882a593Smuzhiyun #define A3700_SPI_INT_STAT_REG 0x28
43*4882a593Smuzhiyun #define A3700_SPI_INT_MASK_REG 0x2C
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun /* A3700_SPI_IF_CTRL_REG */
46*4882a593Smuzhiyun #define A3700_SPI_EN BIT(16)
47*4882a593Smuzhiyun #define A3700_SPI_ADDR_NOT_CONFIG BIT(12)
48*4882a593Smuzhiyun #define A3700_SPI_WFIFO_OVERFLOW BIT(11)
49*4882a593Smuzhiyun #define A3700_SPI_WFIFO_UNDERFLOW BIT(10)
50*4882a593Smuzhiyun #define A3700_SPI_RFIFO_OVERFLOW BIT(9)
51*4882a593Smuzhiyun #define A3700_SPI_RFIFO_UNDERFLOW BIT(8)
52*4882a593Smuzhiyun #define A3700_SPI_WFIFO_FULL BIT(7)
53*4882a593Smuzhiyun #define A3700_SPI_WFIFO_EMPTY BIT(6)
54*4882a593Smuzhiyun #define A3700_SPI_RFIFO_FULL BIT(5)
55*4882a593Smuzhiyun #define A3700_SPI_RFIFO_EMPTY BIT(4)
56*4882a593Smuzhiyun #define A3700_SPI_WFIFO_RDY BIT(3)
57*4882a593Smuzhiyun #define A3700_SPI_RFIFO_RDY BIT(2)
58*4882a593Smuzhiyun #define A3700_SPI_XFER_RDY BIT(1)
59*4882a593Smuzhiyun #define A3700_SPI_XFER_DONE BIT(0)
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* A3700_SPI_IF_CFG_REG */
62*4882a593Smuzhiyun #define A3700_SPI_WFIFO_THRS BIT(28)
63*4882a593Smuzhiyun #define A3700_SPI_RFIFO_THRS BIT(24)
64*4882a593Smuzhiyun #define A3700_SPI_AUTO_CS BIT(20)
65*4882a593Smuzhiyun #define A3700_SPI_DMA_RD_EN BIT(18)
66*4882a593Smuzhiyun #define A3700_SPI_FIFO_MODE BIT(17)
67*4882a593Smuzhiyun #define A3700_SPI_SRST BIT(16)
68*4882a593Smuzhiyun #define A3700_SPI_XFER_START BIT(15)
69*4882a593Smuzhiyun #define A3700_SPI_XFER_STOP BIT(14)
70*4882a593Smuzhiyun #define A3700_SPI_INST_PIN BIT(13)
71*4882a593Smuzhiyun #define A3700_SPI_ADDR_PIN BIT(12)
72*4882a593Smuzhiyun #define A3700_SPI_DATA_PIN1 BIT(11)
73*4882a593Smuzhiyun #define A3700_SPI_DATA_PIN0 BIT(10)
74*4882a593Smuzhiyun #define A3700_SPI_FIFO_FLUSH BIT(9)
75*4882a593Smuzhiyun #define A3700_SPI_RW_EN BIT(8)
76*4882a593Smuzhiyun #define A3700_SPI_CLK_POL BIT(7)
77*4882a593Smuzhiyun #define A3700_SPI_CLK_PHA BIT(6)
78*4882a593Smuzhiyun #define A3700_SPI_BYTE_LEN BIT(5)
79*4882a593Smuzhiyun #define A3700_SPI_CLK_PRESCALE BIT(0)
80*4882a593Smuzhiyun #define A3700_SPI_CLK_PRESCALE_MASK (0x1f)
81*4882a593Smuzhiyun #define A3700_SPI_CLK_EVEN_OFFS (0x10)
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #define A3700_SPI_WFIFO_THRS_BIT 28
84*4882a593Smuzhiyun #define A3700_SPI_RFIFO_THRS_BIT 24
85*4882a593Smuzhiyun #define A3700_SPI_FIFO_THRS_MASK 0x7
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #define A3700_SPI_DATA_PIN_MASK 0x3
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /* A3700_SPI_IF_HDR_CNT_REG */
90*4882a593Smuzhiyun #define A3700_SPI_DUMMY_CNT_BIT 12
91*4882a593Smuzhiyun #define A3700_SPI_DUMMY_CNT_MASK 0x7
92*4882a593Smuzhiyun #define A3700_SPI_RMODE_CNT_BIT 8
93*4882a593Smuzhiyun #define A3700_SPI_RMODE_CNT_MASK 0x3
94*4882a593Smuzhiyun #define A3700_SPI_ADDR_CNT_BIT 4
95*4882a593Smuzhiyun #define A3700_SPI_ADDR_CNT_MASK 0x7
96*4882a593Smuzhiyun #define A3700_SPI_INSTR_CNT_BIT 0
97*4882a593Smuzhiyun #define A3700_SPI_INSTR_CNT_MASK 0x3
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun /* A3700_SPI_IF_TIME_REG */
100*4882a593Smuzhiyun #define A3700_SPI_CLK_CAPT_EDGE BIT(7)
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun struct a3700_spi {
103*4882a593Smuzhiyun struct spi_master *master;
104*4882a593Smuzhiyun void __iomem *base;
105*4882a593Smuzhiyun struct clk *clk;
106*4882a593Smuzhiyun unsigned int irq;
107*4882a593Smuzhiyun unsigned int flags;
108*4882a593Smuzhiyun bool xmit_data;
109*4882a593Smuzhiyun const u8 *tx_buf;
110*4882a593Smuzhiyun u8 *rx_buf;
111*4882a593Smuzhiyun size_t buf_len;
112*4882a593Smuzhiyun u8 byte_len;
113*4882a593Smuzhiyun u32 wait_mask;
114*4882a593Smuzhiyun struct completion done;
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun
spireg_read(struct a3700_spi * a3700_spi,u32 offset)117*4882a593Smuzhiyun static u32 spireg_read(struct a3700_spi *a3700_spi, u32 offset)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun return readl(a3700_spi->base + offset);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
spireg_write(struct a3700_spi * a3700_spi,u32 offset,u32 data)122*4882a593Smuzhiyun static void spireg_write(struct a3700_spi *a3700_spi, u32 offset, u32 data)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun writel(data, a3700_spi->base + offset);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
a3700_spi_auto_cs_unset(struct a3700_spi * a3700_spi)127*4882a593Smuzhiyun static void a3700_spi_auto_cs_unset(struct a3700_spi *a3700_spi)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun u32 val;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
132*4882a593Smuzhiyun val &= ~A3700_SPI_AUTO_CS;
133*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
a3700_spi_activate_cs(struct a3700_spi * a3700_spi,unsigned int cs)136*4882a593Smuzhiyun static void a3700_spi_activate_cs(struct a3700_spi *a3700_spi, unsigned int cs)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun u32 val;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
141*4882a593Smuzhiyun val |= (A3700_SPI_EN << cs);
142*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CTRL_REG, val);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
a3700_spi_deactivate_cs(struct a3700_spi * a3700_spi,unsigned int cs)145*4882a593Smuzhiyun static void a3700_spi_deactivate_cs(struct a3700_spi *a3700_spi,
146*4882a593Smuzhiyun unsigned int cs)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun u32 val;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
151*4882a593Smuzhiyun val &= ~(A3700_SPI_EN << cs);
152*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CTRL_REG, val);
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
a3700_spi_pin_mode_set(struct a3700_spi * a3700_spi,unsigned int pin_mode,bool receiving)155*4882a593Smuzhiyun static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
156*4882a593Smuzhiyun unsigned int pin_mode, bool receiving)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun u32 val;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
161*4882a593Smuzhiyun val &= ~(A3700_SPI_INST_PIN | A3700_SPI_ADDR_PIN);
162*4882a593Smuzhiyun val &= ~(A3700_SPI_DATA_PIN0 | A3700_SPI_DATA_PIN1);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun switch (pin_mode) {
165*4882a593Smuzhiyun case SPI_NBITS_SINGLE:
166*4882a593Smuzhiyun break;
167*4882a593Smuzhiyun case SPI_NBITS_DUAL:
168*4882a593Smuzhiyun val |= A3700_SPI_DATA_PIN0;
169*4882a593Smuzhiyun break;
170*4882a593Smuzhiyun case SPI_NBITS_QUAD:
171*4882a593Smuzhiyun val |= A3700_SPI_DATA_PIN1;
172*4882a593Smuzhiyun /* RX during address reception uses 4-pin */
173*4882a593Smuzhiyun if (receiving)
174*4882a593Smuzhiyun val |= A3700_SPI_ADDR_PIN;
175*4882a593Smuzhiyun break;
176*4882a593Smuzhiyun default:
177*4882a593Smuzhiyun dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode);
178*4882a593Smuzhiyun return -EINVAL;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun return 0;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
a3700_spi_fifo_mode_set(struct a3700_spi * a3700_spi,bool enable)186*4882a593Smuzhiyun static void a3700_spi_fifo_mode_set(struct a3700_spi *a3700_spi, bool enable)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun u32 val;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
191*4882a593Smuzhiyun if (enable)
192*4882a593Smuzhiyun val |= A3700_SPI_FIFO_MODE;
193*4882a593Smuzhiyun else
194*4882a593Smuzhiyun val &= ~A3700_SPI_FIFO_MODE;
195*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
a3700_spi_mode_set(struct a3700_spi * a3700_spi,unsigned int mode_bits)198*4882a593Smuzhiyun static void a3700_spi_mode_set(struct a3700_spi *a3700_spi,
199*4882a593Smuzhiyun unsigned int mode_bits)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun u32 val;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun if (mode_bits & SPI_CPOL)
206*4882a593Smuzhiyun val |= A3700_SPI_CLK_POL;
207*4882a593Smuzhiyun else
208*4882a593Smuzhiyun val &= ~A3700_SPI_CLK_POL;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun if (mode_bits & SPI_CPHA)
211*4882a593Smuzhiyun val |= A3700_SPI_CLK_PHA;
212*4882a593Smuzhiyun else
213*4882a593Smuzhiyun val &= ~A3700_SPI_CLK_PHA;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
a3700_spi_clock_set(struct a3700_spi * a3700_spi,unsigned int speed_hz)218*4882a593Smuzhiyun static void a3700_spi_clock_set(struct a3700_spi *a3700_spi,
219*4882a593Smuzhiyun unsigned int speed_hz)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun u32 val;
222*4882a593Smuzhiyun u32 prescale;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /* For prescaler values over 15, we can only set it by steps of 2.
227*4882a593Smuzhiyun * Starting from A3700_SPI_CLK_EVEN_OFFS, we set values from 0 up to
228*4882a593Smuzhiyun * 30. We only use this range from 16 to 30.
229*4882a593Smuzhiyun */
230*4882a593Smuzhiyun if (prescale > 15)
231*4882a593Smuzhiyun prescale = A3700_SPI_CLK_EVEN_OFFS + DIV_ROUND_UP(prescale, 2);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
234*4882a593Smuzhiyun val = val & ~A3700_SPI_CLK_PRESCALE_MASK;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun val = val | (prescale & A3700_SPI_CLK_PRESCALE_MASK);
237*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (prescale <= 2) {
240*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_TIME_REG);
241*4882a593Smuzhiyun val |= A3700_SPI_CLK_CAPT_EDGE;
242*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_TIME_REG, val);
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
a3700_spi_bytelen_set(struct a3700_spi * a3700_spi,unsigned int len)246*4882a593Smuzhiyun static void a3700_spi_bytelen_set(struct a3700_spi *a3700_spi, unsigned int len)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun u32 val;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
251*4882a593Smuzhiyun if (len == 4)
252*4882a593Smuzhiyun val |= A3700_SPI_BYTE_LEN;
253*4882a593Smuzhiyun else
254*4882a593Smuzhiyun val &= ~A3700_SPI_BYTE_LEN;
255*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun a3700_spi->byte_len = len;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
a3700_spi_fifo_flush(struct a3700_spi * a3700_spi)260*4882a593Smuzhiyun static int a3700_spi_fifo_flush(struct a3700_spi *a3700_spi)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun int timeout = A3700_SPI_TIMEOUT;
263*4882a593Smuzhiyun u32 val;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
266*4882a593Smuzhiyun val |= A3700_SPI_FIFO_FLUSH;
267*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun while (--timeout) {
270*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
271*4882a593Smuzhiyun if (!(val & A3700_SPI_FIFO_FLUSH))
272*4882a593Smuzhiyun return 0;
273*4882a593Smuzhiyun udelay(1);
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun return -ETIMEDOUT;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
a3700_spi_init(struct a3700_spi * a3700_spi)279*4882a593Smuzhiyun static void a3700_spi_init(struct a3700_spi *a3700_spi)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun struct spi_master *master = a3700_spi->master;
282*4882a593Smuzhiyun u32 val;
283*4882a593Smuzhiyun int i;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /* Reset SPI unit */
286*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
287*4882a593Smuzhiyun val |= A3700_SPI_SRST;
288*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun udelay(A3700_SPI_TIMEOUT);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
293*4882a593Smuzhiyun val &= ~A3700_SPI_SRST;
294*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun /* Disable AUTO_CS and deactivate all chip-selects */
297*4882a593Smuzhiyun a3700_spi_auto_cs_unset(a3700_spi);
298*4882a593Smuzhiyun for (i = 0; i < master->num_chipselect; i++)
299*4882a593Smuzhiyun a3700_spi_deactivate_cs(a3700_spi, i);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /* Enable FIFO mode */
302*4882a593Smuzhiyun a3700_spi_fifo_mode_set(a3700_spi, true);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /* Set SPI mode */
305*4882a593Smuzhiyun a3700_spi_mode_set(a3700_spi, master->mode_bits);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun /* Reset counters */
308*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0);
309*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG, 0);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun /* Mask the interrupts and clear cause bits */
312*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
313*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, ~0U);
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
a3700_spi_interrupt(int irq,void * dev_id)316*4882a593Smuzhiyun static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun struct spi_master *master = dev_id;
319*4882a593Smuzhiyun struct a3700_spi *a3700_spi;
320*4882a593Smuzhiyun u32 cause;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun a3700_spi = spi_master_get_devdata(master);
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun /* Get interrupt causes */
325*4882a593Smuzhiyun cause = spireg_read(a3700_spi, A3700_SPI_INT_STAT_REG);
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun if (!cause || !(a3700_spi->wait_mask & cause))
328*4882a593Smuzhiyun return IRQ_NONE;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /* mask and acknowledge the SPI interrupts */
331*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
332*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, cause);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* Wake up the transfer */
335*4882a593Smuzhiyun complete(&a3700_spi->done);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun return IRQ_HANDLED;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
a3700_spi_wait_completion(struct spi_device * spi)340*4882a593Smuzhiyun static bool a3700_spi_wait_completion(struct spi_device *spi)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun struct a3700_spi *a3700_spi;
343*4882a593Smuzhiyun unsigned int timeout;
344*4882a593Smuzhiyun unsigned int ctrl_reg;
345*4882a593Smuzhiyun unsigned long timeout_jiffies;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun a3700_spi = spi_master_get_devdata(spi->master);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun /* SPI interrupt is edge-triggered, which means an interrupt will
350*4882a593Smuzhiyun * be generated only when detecting a specific status bit changed
351*4882a593Smuzhiyun * from '0' to '1'. So when we start waiting for a interrupt, we
352*4882a593Smuzhiyun * need to check status bit in control reg first, if it is already 1,
353*4882a593Smuzhiyun * then we do not need to wait for interrupt
354*4882a593Smuzhiyun */
355*4882a593Smuzhiyun ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
356*4882a593Smuzhiyun if (a3700_spi->wait_mask & ctrl_reg)
357*4882a593Smuzhiyun return true;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun reinit_completion(&a3700_spi->done);
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG,
362*4882a593Smuzhiyun a3700_spi->wait_mask);
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun timeout_jiffies = msecs_to_jiffies(A3700_SPI_TIMEOUT);
365*4882a593Smuzhiyun timeout = wait_for_completion_timeout(&a3700_spi->done,
366*4882a593Smuzhiyun timeout_jiffies);
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun a3700_spi->wait_mask = 0;
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun if (timeout)
371*4882a593Smuzhiyun return true;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun /* there might be the case that right after we checked the
374*4882a593Smuzhiyun * status bits in this routine and before start to wait for
375*4882a593Smuzhiyun * interrupt by wait_for_completion_timeout, the interrupt
376*4882a593Smuzhiyun * happens, to avoid missing it we need to double check
377*4882a593Smuzhiyun * status bits in control reg, if it is already 1, then
378*4882a593Smuzhiyun * consider that we have the interrupt successfully and
379*4882a593Smuzhiyun * return true.
380*4882a593Smuzhiyun */
381*4882a593Smuzhiyun ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
382*4882a593Smuzhiyun if (a3700_spi->wait_mask & ctrl_reg)
383*4882a593Smuzhiyun return true;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* Timeout was reached */
388*4882a593Smuzhiyun return false;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
a3700_spi_transfer_wait(struct spi_device * spi,unsigned int bit_mask)391*4882a593Smuzhiyun static bool a3700_spi_transfer_wait(struct spi_device *spi,
392*4882a593Smuzhiyun unsigned int bit_mask)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun struct a3700_spi *a3700_spi;
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun a3700_spi = spi_master_get_devdata(spi->master);
397*4882a593Smuzhiyun a3700_spi->wait_mask = bit_mask;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun return a3700_spi_wait_completion(spi);
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun
a3700_spi_fifo_thres_set(struct a3700_spi * a3700_spi,unsigned int bytes)402*4882a593Smuzhiyun static void a3700_spi_fifo_thres_set(struct a3700_spi *a3700_spi,
403*4882a593Smuzhiyun unsigned int bytes)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun u32 val;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
408*4882a593Smuzhiyun val &= ~(A3700_SPI_FIFO_THRS_MASK << A3700_SPI_RFIFO_THRS_BIT);
409*4882a593Smuzhiyun val |= (bytes - 1) << A3700_SPI_RFIFO_THRS_BIT;
410*4882a593Smuzhiyun val &= ~(A3700_SPI_FIFO_THRS_MASK << A3700_SPI_WFIFO_THRS_BIT);
411*4882a593Smuzhiyun val |= (7 - bytes) << A3700_SPI_WFIFO_THRS_BIT;
412*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun
a3700_spi_transfer_setup(struct spi_device * spi,struct spi_transfer * xfer)415*4882a593Smuzhiyun static void a3700_spi_transfer_setup(struct spi_device *spi,
416*4882a593Smuzhiyun struct spi_transfer *xfer)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun struct a3700_spi *a3700_spi;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun a3700_spi = spi_master_get_devdata(spi->master);
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun a3700_spi_clock_set(a3700_spi, xfer->speed_hz);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /* Use 4 bytes long transfers. Each transfer method has its way to deal
425*4882a593Smuzhiyun * with the remaining bytes for non 4-bytes aligned transfers.
426*4882a593Smuzhiyun */
427*4882a593Smuzhiyun a3700_spi_bytelen_set(a3700_spi, 4);
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /* Initialize the working buffers */
430*4882a593Smuzhiyun a3700_spi->tx_buf = xfer->tx_buf;
431*4882a593Smuzhiyun a3700_spi->rx_buf = xfer->rx_buf;
432*4882a593Smuzhiyun a3700_spi->buf_len = xfer->len;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun
a3700_spi_set_cs(struct spi_device * spi,bool enable)435*4882a593Smuzhiyun static void a3700_spi_set_cs(struct spi_device *spi, bool enable)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun struct a3700_spi *a3700_spi = spi_master_get_devdata(spi->master);
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun if (!enable)
440*4882a593Smuzhiyun a3700_spi_activate_cs(a3700_spi, spi->chip_select);
441*4882a593Smuzhiyun else
442*4882a593Smuzhiyun a3700_spi_deactivate_cs(a3700_spi, spi->chip_select);
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun
a3700_spi_header_set(struct a3700_spi * a3700_spi)445*4882a593Smuzhiyun static void a3700_spi_header_set(struct a3700_spi *a3700_spi)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun unsigned int addr_cnt;
448*4882a593Smuzhiyun u32 val = 0;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun /* Clear the header registers */
451*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, 0);
452*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, 0);
453*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_RMODE_REG, 0);
454*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0);
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun /* Set header counters */
457*4882a593Smuzhiyun if (a3700_spi->tx_buf) {
458*4882a593Smuzhiyun /*
459*4882a593Smuzhiyun * when tx data is not 4 bytes aligned, there will be unexpected
460*4882a593Smuzhiyun * bytes out of SPI output register, since it always shifts out
461*4882a593Smuzhiyun * as whole 4 bytes. This might cause incorrect transaction with
462*4882a593Smuzhiyun * some devices. To avoid that, use SPI header count feature to
463*4882a593Smuzhiyun * transfer up to 3 bytes of data first, and then make the rest
464*4882a593Smuzhiyun * of data 4-byte aligned.
465*4882a593Smuzhiyun */
466*4882a593Smuzhiyun addr_cnt = a3700_spi->buf_len % 4;
467*4882a593Smuzhiyun if (addr_cnt) {
468*4882a593Smuzhiyun val = (addr_cnt & A3700_SPI_ADDR_CNT_MASK)
469*4882a593Smuzhiyun << A3700_SPI_ADDR_CNT_BIT;
470*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, val);
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun /* Update the buffer length to be transferred */
473*4882a593Smuzhiyun a3700_spi->buf_len -= addr_cnt;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* transfer 1~3 bytes through address count */
476*4882a593Smuzhiyun val = 0;
477*4882a593Smuzhiyun while (addr_cnt--) {
478*4882a593Smuzhiyun val = (val << 8) | a3700_spi->tx_buf[0];
479*4882a593Smuzhiyun a3700_spi->tx_buf++;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, val);
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun
a3700_is_wfifo_full(struct a3700_spi * a3700_spi)486*4882a593Smuzhiyun static int a3700_is_wfifo_full(struct a3700_spi *a3700_spi)
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun u32 val;
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
491*4882a593Smuzhiyun return (val & A3700_SPI_WFIFO_FULL);
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
a3700_spi_fifo_write(struct a3700_spi * a3700_spi)494*4882a593Smuzhiyun static int a3700_spi_fifo_write(struct a3700_spi *a3700_spi)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun u32 val;
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun while (!a3700_is_wfifo_full(a3700_spi) && a3700_spi->buf_len) {
499*4882a593Smuzhiyun val = *(u32 *)a3700_spi->tx_buf;
500*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val);
501*4882a593Smuzhiyun a3700_spi->buf_len -= 4;
502*4882a593Smuzhiyun a3700_spi->tx_buf += 4;
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun return 0;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
a3700_is_rfifo_empty(struct a3700_spi * a3700_spi)508*4882a593Smuzhiyun static int a3700_is_rfifo_empty(struct a3700_spi *a3700_spi)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun u32 val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun return (val & A3700_SPI_RFIFO_EMPTY);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
a3700_spi_fifo_read(struct a3700_spi * a3700_spi)515*4882a593Smuzhiyun static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi)
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun u32 val;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun while (!a3700_is_rfifo_empty(a3700_spi) && a3700_spi->buf_len) {
520*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG);
521*4882a593Smuzhiyun if (a3700_spi->buf_len >= 4) {
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun memcpy(a3700_spi->rx_buf, &val, 4);
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun a3700_spi->buf_len -= 4;
526*4882a593Smuzhiyun a3700_spi->rx_buf += 4;
527*4882a593Smuzhiyun } else {
528*4882a593Smuzhiyun /*
529*4882a593Smuzhiyun * When remain bytes is not larger than 4, we should
530*4882a593Smuzhiyun * avoid memory overwriting and just write the left rx
531*4882a593Smuzhiyun * buffer bytes.
532*4882a593Smuzhiyun */
533*4882a593Smuzhiyun while (a3700_spi->buf_len) {
534*4882a593Smuzhiyun *a3700_spi->rx_buf = val & 0xff;
535*4882a593Smuzhiyun val >>= 8;
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun a3700_spi->buf_len--;
538*4882a593Smuzhiyun a3700_spi->rx_buf++;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun return 0;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun
a3700_spi_transfer_abort_fifo(struct a3700_spi * a3700_spi)546*4882a593Smuzhiyun static void a3700_spi_transfer_abort_fifo(struct a3700_spi *a3700_spi)
547*4882a593Smuzhiyun {
548*4882a593Smuzhiyun int timeout = A3700_SPI_TIMEOUT;
549*4882a593Smuzhiyun u32 val;
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
552*4882a593Smuzhiyun val |= A3700_SPI_XFER_STOP;
553*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun while (--timeout) {
556*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
557*4882a593Smuzhiyun if (!(val & A3700_SPI_XFER_START))
558*4882a593Smuzhiyun break;
559*4882a593Smuzhiyun udelay(1);
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun a3700_spi_fifo_flush(a3700_spi);
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun val &= ~A3700_SPI_XFER_STOP;
565*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun
a3700_spi_prepare_message(struct spi_master * master,struct spi_message * message)568*4882a593Smuzhiyun static int a3700_spi_prepare_message(struct spi_master *master,
569*4882a593Smuzhiyun struct spi_message *message)
570*4882a593Smuzhiyun {
571*4882a593Smuzhiyun struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
572*4882a593Smuzhiyun struct spi_device *spi = message->spi;
573*4882a593Smuzhiyun int ret;
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun ret = clk_enable(a3700_spi->clk);
576*4882a593Smuzhiyun if (ret) {
577*4882a593Smuzhiyun dev_err(&spi->dev, "failed to enable clk with error %d\n", ret);
578*4882a593Smuzhiyun return ret;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun /* Flush the FIFOs */
582*4882a593Smuzhiyun ret = a3700_spi_fifo_flush(a3700_spi);
583*4882a593Smuzhiyun if (ret)
584*4882a593Smuzhiyun return ret;
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun a3700_spi_mode_set(a3700_spi, spi->mode);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun return 0;
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun
a3700_spi_transfer_one_fifo(struct spi_master * master,struct spi_device * spi,struct spi_transfer * xfer)591*4882a593Smuzhiyun static int a3700_spi_transfer_one_fifo(struct spi_master *master,
592*4882a593Smuzhiyun struct spi_device *spi,
593*4882a593Smuzhiyun struct spi_transfer *xfer)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
596*4882a593Smuzhiyun int ret = 0, timeout = A3700_SPI_TIMEOUT;
597*4882a593Smuzhiyun unsigned int nbits = 0, byte_len;
598*4882a593Smuzhiyun u32 val;
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun /* Make sure we use FIFO mode */
601*4882a593Smuzhiyun a3700_spi_fifo_mode_set(a3700_spi, true);
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun /* Configure FIFO thresholds */
604*4882a593Smuzhiyun byte_len = xfer->bits_per_word >> 3;
605*4882a593Smuzhiyun a3700_spi_fifo_thres_set(a3700_spi, byte_len);
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun if (xfer->tx_buf)
608*4882a593Smuzhiyun nbits = xfer->tx_nbits;
609*4882a593Smuzhiyun else if (xfer->rx_buf)
610*4882a593Smuzhiyun nbits = xfer->rx_nbits;
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun a3700_spi_pin_mode_set(a3700_spi, nbits, xfer->rx_buf ? true : false);
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun /* Flush the FIFOs */
615*4882a593Smuzhiyun a3700_spi_fifo_flush(a3700_spi);
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun /* Transfer first bytes of data when buffer is not 4-byte aligned */
618*4882a593Smuzhiyun a3700_spi_header_set(a3700_spi);
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun if (xfer->rx_buf) {
621*4882a593Smuzhiyun /* Clear WFIFO, since it's last 2 bytes are shifted out during
622*4882a593Smuzhiyun * a read operation
623*4882a593Smuzhiyun */
624*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, 0);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun /* Set read data length */
627*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG,
628*4882a593Smuzhiyun a3700_spi->buf_len);
629*4882a593Smuzhiyun /* Start READ transfer */
630*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
631*4882a593Smuzhiyun val &= ~A3700_SPI_RW_EN;
632*4882a593Smuzhiyun val |= A3700_SPI_XFER_START;
633*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
634*4882a593Smuzhiyun } else if (xfer->tx_buf) {
635*4882a593Smuzhiyun /* Start Write transfer */
636*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
637*4882a593Smuzhiyun val |= (A3700_SPI_XFER_START | A3700_SPI_RW_EN);
638*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /*
641*4882a593Smuzhiyun * If there are data to be written to the SPI device, xmit_data
642*4882a593Smuzhiyun * flag is set true; otherwise the instruction in SPI_INSTR does
643*4882a593Smuzhiyun * not require data to be written to the SPI device, then
644*4882a593Smuzhiyun * xmit_data flag is set false.
645*4882a593Smuzhiyun */
646*4882a593Smuzhiyun a3700_spi->xmit_data = (a3700_spi->buf_len != 0);
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun while (a3700_spi->buf_len) {
650*4882a593Smuzhiyun if (a3700_spi->tx_buf) {
651*4882a593Smuzhiyun /* Wait wfifo ready */
652*4882a593Smuzhiyun if (!a3700_spi_transfer_wait(spi,
653*4882a593Smuzhiyun A3700_SPI_WFIFO_RDY)) {
654*4882a593Smuzhiyun dev_err(&spi->dev,
655*4882a593Smuzhiyun "wait wfifo ready timed out\n");
656*4882a593Smuzhiyun ret = -ETIMEDOUT;
657*4882a593Smuzhiyun goto error;
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun /* Fill up the wfifo */
660*4882a593Smuzhiyun ret = a3700_spi_fifo_write(a3700_spi);
661*4882a593Smuzhiyun if (ret)
662*4882a593Smuzhiyun goto error;
663*4882a593Smuzhiyun } else if (a3700_spi->rx_buf) {
664*4882a593Smuzhiyun /* Wait rfifo ready */
665*4882a593Smuzhiyun if (!a3700_spi_transfer_wait(spi,
666*4882a593Smuzhiyun A3700_SPI_RFIFO_RDY)) {
667*4882a593Smuzhiyun dev_err(&spi->dev,
668*4882a593Smuzhiyun "wait rfifo ready timed out\n");
669*4882a593Smuzhiyun ret = -ETIMEDOUT;
670*4882a593Smuzhiyun goto error;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun /* Drain out the rfifo */
673*4882a593Smuzhiyun ret = a3700_spi_fifo_read(a3700_spi);
674*4882a593Smuzhiyun if (ret)
675*4882a593Smuzhiyun goto error;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /*
680*4882a593Smuzhiyun * Stop a write transfer in fifo mode:
681*4882a593Smuzhiyun * - wait all the bytes in wfifo to be shifted out
682*4882a593Smuzhiyun * - set XFER_STOP bit
683*4882a593Smuzhiyun * - wait XFER_START bit clear
684*4882a593Smuzhiyun * - clear XFER_STOP bit
685*4882a593Smuzhiyun * Stop a read transfer in fifo mode:
686*4882a593Smuzhiyun * - the hardware is to reset the XFER_START bit
687*4882a593Smuzhiyun * after the number of bytes indicated in DIN_CNT
688*4882a593Smuzhiyun * register
689*4882a593Smuzhiyun * - just wait XFER_START bit clear
690*4882a593Smuzhiyun */
691*4882a593Smuzhiyun if (a3700_spi->tx_buf) {
692*4882a593Smuzhiyun if (a3700_spi->xmit_data) {
693*4882a593Smuzhiyun /*
694*4882a593Smuzhiyun * If there are data written to the SPI device, wait
695*4882a593Smuzhiyun * until SPI_WFIFO_EMPTY is 1 to wait for all data to
696*4882a593Smuzhiyun * transfer out of write FIFO.
697*4882a593Smuzhiyun */
698*4882a593Smuzhiyun if (!a3700_spi_transfer_wait(spi,
699*4882a593Smuzhiyun A3700_SPI_WFIFO_EMPTY)) {
700*4882a593Smuzhiyun dev_err(&spi->dev, "wait wfifo empty timed out\n");
701*4882a593Smuzhiyun return -ETIMEDOUT;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun if (!a3700_spi_transfer_wait(spi, A3700_SPI_XFER_RDY)) {
706*4882a593Smuzhiyun dev_err(&spi->dev, "wait xfer ready timed out\n");
707*4882a593Smuzhiyun return -ETIMEDOUT;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
711*4882a593Smuzhiyun val |= A3700_SPI_XFER_STOP;
712*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun while (--timeout) {
716*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
717*4882a593Smuzhiyun if (!(val & A3700_SPI_XFER_START))
718*4882a593Smuzhiyun break;
719*4882a593Smuzhiyun udelay(1);
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun if (timeout == 0) {
723*4882a593Smuzhiyun dev_err(&spi->dev, "wait transfer start clear timed out\n");
724*4882a593Smuzhiyun ret = -ETIMEDOUT;
725*4882a593Smuzhiyun goto error;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun val &= ~A3700_SPI_XFER_STOP;
729*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
730*4882a593Smuzhiyun goto out;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun error:
733*4882a593Smuzhiyun a3700_spi_transfer_abort_fifo(a3700_spi);
734*4882a593Smuzhiyun out:
735*4882a593Smuzhiyun spi_finalize_current_transfer(master);
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun return ret;
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun
a3700_spi_transfer_one_full_duplex(struct spi_master * master,struct spi_device * spi,struct spi_transfer * xfer)740*4882a593Smuzhiyun static int a3700_spi_transfer_one_full_duplex(struct spi_master *master,
741*4882a593Smuzhiyun struct spi_device *spi,
742*4882a593Smuzhiyun struct spi_transfer *xfer)
743*4882a593Smuzhiyun {
744*4882a593Smuzhiyun struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
745*4882a593Smuzhiyun u32 val;
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun /* Disable FIFO mode */
748*4882a593Smuzhiyun a3700_spi_fifo_mode_set(a3700_spi, false);
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun while (a3700_spi->buf_len) {
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun /* When we have less than 4 bytes to transfer, switch to 1 byte
753*4882a593Smuzhiyun * mode. This is reset after each transfer
754*4882a593Smuzhiyun */
755*4882a593Smuzhiyun if (a3700_spi->buf_len < 4)
756*4882a593Smuzhiyun a3700_spi_bytelen_set(a3700_spi, 1);
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun if (a3700_spi->byte_len == 1)
759*4882a593Smuzhiyun val = *a3700_spi->tx_buf;
760*4882a593Smuzhiyun else
761*4882a593Smuzhiyun val = *(u32 *)a3700_spi->tx_buf;
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val);
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun /* Wait for all the data to be shifted in / out */
766*4882a593Smuzhiyun while (!(spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG) &
767*4882a593Smuzhiyun A3700_SPI_XFER_DONE))
768*4882a593Smuzhiyun cpu_relax();
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG);
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun memcpy(a3700_spi->rx_buf, &val, a3700_spi->byte_len);
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun a3700_spi->buf_len -= a3700_spi->byte_len;
775*4882a593Smuzhiyun a3700_spi->tx_buf += a3700_spi->byte_len;
776*4882a593Smuzhiyun a3700_spi->rx_buf += a3700_spi->byte_len;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun }
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun spi_finalize_current_transfer(master);
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun return 0;
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
a3700_spi_transfer_one(struct spi_master * master,struct spi_device * spi,struct spi_transfer * xfer)785*4882a593Smuzhiyun static int a3700_spi_transfer_one(struct spi_master *master,
786*4882a593Smuzhiyun struct spi_device *spi,
787*4882a593Smuzhiyun struct spi_transfer *xfer)
788*4882a593Smuzhiyun {
789*4882a593Smuzhiyun a3700_spi_transfer_setup(spi, xfer);
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun if (xfer->tx_buf && xfer->rx_buf)
792*4882a593Smuzhiyun return a3700_spi_transfer_one_full_duplex(master, spi, xfer);
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun return a3700_spi_transfer_one_fifo(master, spi, xfer);
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun
a3700_spi_unprepare_message(struct spi_master * master,struct spi_message * message)797*4882a593Smuzhiyun static int a3700_spi_unprepare_message(struct spi_master *master,
798*4882a593Smuzhiyun struct spi_message *message)
799*4882a593Smuzhiyun {
800*4882a593Smuzhiyun struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun clk_disable(a3700_spi->clk);
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun return 0;
805*4882a593Smuzhiyun }
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun static const struct of_device_id a3700_spi_dt_ids[] = {
808*4882a593Smuzhiyun { .compatible = "marvell,armada-3700-spi", .data = NULL },
809*4882a593Smuzhiyun {},
810*4882a593Smuzhiyun };
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, a3700_spi_dt_ids);
813*4882a593Smuzhiyun
a3700_spi_probe(struct platform_device * pdev)814*4882a593Smuzhiyun static int a3700_spi_probe(struct platform_device *pdev)
815*4882a593Smuzhiyun {
816*4882a593Smuzhiyun struct device *dev = &pdev->dev;
817*4882a593Smuzhiyun struct device_node *of_node = dev->of_node;
818*4882a593Smuzhiyun struct spi_master *master;
819*4882a593Smuzhiyun struct a3700_spi *spi;
820*4882a593Smuzhiyun u32 num_cs = 0;
821*4882a593Smuzhiyun int irq, ret = 0;
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun master = spi_alloc_master(dev, sizeof(*spi));
824*4882a593Smuzhiyun if (!master) {
825*4882a593Smuzhiyun dev_err(dev, "master allocation failed\n");
826*4882a593Smuzhiyun ret = -ENOMEM;
827*4882a593Smuzhiyun goto out;
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun if (of_property_read_u32(of_node, "num-cs", &num_cs)) {
831*4882a593Smuzhiyun dev_err(dev, "could not find num-cs\n");
832*4882a593Smuzhiyun ret = -ENXIO;
833*4882a593Smuzhiyun goto error;
834*4882a593Smuzhiyun }
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun master->bus_num = pdev->id;
837*4882a593Smuzhiyun master->dev.of_node = of_node;
838*4882a593Smuzhiyun master->mode_bits = SPI_MODE_3;
839*4882a593Smuzhiyun master->num_chipselect = num_cs;
840*4882a593Smuzhiyun master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32);
841*4882a593Smuzhiyun master->prepare_message = a3700_spi_prepare_message;
842*4882a593Smuzhiyun master->transfer_one = a3700_spi_transfer_one;
843*4882a593Smuzhiyun master->unprepare_message = a3700_spi_unprepare_message;
844*4882a593Smuzhiyun master->set_cs = a3700_spi_set_cs;
845*4882a593Smuzhiyun master->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL |
846*4882a593Smuzhiyun SPI_RX_QUAD | SPI_TX_QUAD);
847*4882a593Smuzhiyun
848*4882a593Smuzhiyun platform_set_drvdata(pdev, master);
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun spi = spi_master_get_devdata(master);
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun spi->master = master;
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun spi->base = devm_platform_ioremap_resource(pdev, 0);
855*4882a593Smuzhiyun if (IS_ERR(spi->base)) {
856*4882a593Smuzhiyun ret = PTR_ERR(spi->base);
857*4882a593Smuzhiyun goto error;
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
861*4882a593Smuzhiyun if (irq < 0) {
862*4882a593Smuzhiyun ret = -ENXIO;
863*4882a593Smuzhiyun goto error;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun spi->irq = irq;
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun init_completion(&spi->done);
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun spi->clk = devm_clk_get(dev, NULL);
870*4882a593Smuzhiyun if (IS_ERR(spi->clk)) {
871*4882a593Smuzhiyun dev_err(dev, "could not find clk: %ld\n", PTR_ERR(spi->clk));
872*4882a593Smuzhiyun goto error;
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun ret = clk_prepare(spi->clk);
876*4882a593Smuzhiyun if (ret) {
877*4882a593Smuzhiyun dev_err(dev, "could not prepare clk: %d\n", ret);
878*4882a593Smuzhiyun goto error;
879*4882a593Smuzhiyun }
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun master->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ,
882*4882a593Smuzhiyun clk_get_rate(spi->clk));
883*4882a593Smuzhiyun master->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk),
884*4882a593Smuzhiyun A3700_SPI_MAX_PRESCALE);
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun a3700_spi_init(spi);
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0,
889*4882a593Smuzhiyun dev_name(dev), master);
890*4882a593Smuzhiyun if (ret) {
891*4882a593Smuzhiyun dev_err(dev, "could not request IRQ: %d\n", ret);
892*4882a593Smuzhiyun goto error_clk;
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun ret = devm_spi_register_master(dev, master);
896*4882a593Smuzhiyun if (ret) {
897*4882a593Smuzhiyun dev_err(dev, "Failed to register master\n");
898*4882a593Smuzhiyun goto error_clk;
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun return 0;
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun error_clk:
904*4882a593Smuzhiyun clk_unprepare(spi->clk);
905*4882a593Smuzhiyun error:
906*4882a593Smuzhiyun spi_master_put(master);
907*4882a593Smuzhiyun out:
908*4882a593Smuzhiyun return ret;
909*4882a593Smuzhiyun }
910*4882a593Smuzhiyun
a3700_spi_remove(struct platform_device * pdev)911*4882a593Smuzhiyun static int a3700_spi_remove(struct platform_device *pdev)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun struct spi_master *master = platform_get_drvdata(pdev);
914*4882a593Smuzhiyun struct a3700_spi *spi = spi_master_get_devdata(master);
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun clk_unprepare(spi->clk);
917*4882a593Smuzhiyun
918*4882a593Smuzhiyun return 0;
919*4882a593Smuzhiyun }
920*4882a593Smuzhiyun
921*4882a593Smuzhiyun static struct platform_driver a3700_spi_driver = {
922*4882a593Smuzhiyun .driver = {
923*4882a593Smuzhiyun .name = DRIVER_NAME,
924*4882a593Smuzhiyun .of_match_table = of_match_ptr(a3700_spi_dt_ids),
925*4882a593Smuzhiyun },
926*4882a593Smuzhiyun .probe = a3700_spi_probe,
927*4882a593Smuzhiyun .remove = a3700_spi_remove,
928*4882a593Smuzhiyun };
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun module_platform_driver(a3700_spi_driver);
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun MODULE_DESCRIPTION("Armada-3700 SPI driver");
933*4882a593Smuzhiyun MODULE_AUTHOR("Wilson Ding <dingwei@marvell.com>");
934*4882a593Smuzhiyun MODULE_LICENSE("GPL");
935*4882a593Smuzhiyun MODULE_ALIAS("platform:" DRIVER_NAME);
936