xref: /OK3568_Linux_fs/kernel/drivers/spi/spi-sun4i.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2012 - 2014 Allwinner Tech
4*4882a593Smuzhiyun  * Pan Nan <pannan@allwinnertech.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2014 Maxime Ripard
7*4882a593Smuzhiyun  * Maxime Ripard <maxime.ripard@free-electrons.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/device.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/io.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/platform_device.h>
17*4882a593Smuzhiyun #include <linux/pm_runtime.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <linux/spi/spi.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #define SUN4I_FIFO_DEPTH		64
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define SUN4I_RXDATA_REG		0x00
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define SUN4I_TXDATA_REG		0x04
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define SUN4I_CTL_REG			0x08
28*4882a593Smuzhiyun #define SUN4I_CTL_ENABLE			BIT(0)
29*4882a593Smuzhiyun #define SUN4I_CTL_MASTER			BIT(1)
30*4882a593Smuzhiyun #define SUN4I_CTL_CPHA				BIT(2)
31*4882a593Smuzhiyun #define SUN4I_CTL_CPOL				BIT(3)
32*4882a593Smuzhiyun #define SUN4I_CTL_CS_ACTIVE_LOW			BIT(4)
33*4882a593Smuzhiyun #define SUN4I_CTL_LMTF				BIT(6)
34*4882a593Smuzhiyun #define SUN4I_CTL_TF_RST			BIT(8)
35*4882a593Smuzhiyun #define SUN4I_CTL_RF_RST			BIT(9)
36*4882a593Smuzhiyun #define SUN4I_CTL_XCH				BIT(10)
37*4882a593Smuzhiyun #define SUN4I_CTL_CS_MASK			0x3000
38*4882a593Smuzhiyun #define SUN4I_CTL_CS(cs)			(((cs) << 12) & SUN4I_CTL_CS_MASK)
39*4882a593Smuzhiyun #define SUN4I_CTL_DHB				BIT(15)
40*4882a593Smuzhiyun #define SUN4I_CTL_CS_MANUAL			BIT(16)
41*4882a593Smuzhiyun #define SUN4I_CTL_CS_LEVEL			BIT(17)
42*4882a593Smuzhiyun #define SUN4I_CTL_TP				BIT(18)
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define SUN4I_INT_CTL_REG		0x0c
45*4882a593Smuzhiyun #define SUN4I_INT_CTL_RF_F34			BIT(4)
46*4882a593Smuzhiyun #define SUN4I_INT_CTL_TF_E34			BIT(12)
47*4882a593Smuzhiyun #define SUN4I_INT_CTL_TC			BIT(16)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define SUN4I_INT_STA_REG		0x10
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define SUN4I_DMA_CTL_REG		0x14
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define SUN4I_WAIT_REG			0x18
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define SUN4I_CLK_CTL_REG		0x1c
56*4882a593Smuzhiyun #define SUN4I_CLK_CTL_CDR2_MASK			0xff
57*4882a593Smuzhiyun #define SUN4I_CLK_CTL_CDR2(div)			((div) & SUN4I_CLK_CTL_CDR2_MASK)
58*4882a593Smuzhiyun #define SUN4I_CLK_CTL_CDR1_MASK			0xf
59*4882a593Smuzhiyun #define SUN4I_CLK_CTL_CDR1(div)			(((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
60*4882a593Smuzhiyun #define SUN4I_CLK_CTL_DRS			BIT(12)
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define SUN4I_MAX_XFER_SIZE			0xffffff
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define SUN4I_BURST_CNT_REG		0x20
65*4882a593Smuzhiyun #define SUN4I_BURST_CNT(cnt)			((cnt) & SUN4I_MAX_XFER_SIZE)
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define SUN4I_XMIT_CNT_REG		0x24
68*4882a593Smuzhiyun #define SUN4I_XMIT_CNT(cnt)			((cnt) & SUN4I_MAX_XFER_SIZE)
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #define SUN4I_FIFO_STA_REG		0x28
72*4882a593Smuzhiyun #define SUN4I_FIFO_STA_RF_CNT_MASK		0x7f
73*4882a593Smuzhiyun #define SUN4I_FIFO_STA_RF_CNT_BITS		0
74*4882a593Smuzhiyun #define SUN4I_FIFO_STA_TF_CNT_MASK		0x7f
75*4882a593Smuzhiyun #define SUN4I_FIFO_STA_TF_CNT_BITS		16
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun struct sun4i_spi {
78*4882a593Smuzhiyun 	struct spi_master	*master;
79*4882a593Smuzhiyun 	void __iomem		*base_addr;
80*4882a593Smuzhiyun 	struct clk		*hclk;
81*4882a593Smuzhiyun 	struct clk		*mclk;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	struct completion	done;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	const u8		*tx_buf;
86*4882a593Smuzhiyun 	u8			*rx_buf;
87*4882a593Smuzhiyun 	int			len;
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun 
sun4i_spi_read(struct sun4i_spi * sspi,u32 reg)90*4882a593Smuzhiyun static inline u32 sun4i_spi_read(struct sun4i_spi *sspi, u32 reg)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun 	return readl(sspi->base_addr + reg);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
sun4i_spi_write(struct sun4i_spi * sspi,u32 reg,u32 value)95*4882a593Smuzhiyun static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	writel(value, sspi->base_addr + reg);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
sun4i_spi_get_tx_fifo_count(struct sun4i_spi * sspi)100*4882a593Smuzhiyun static inline u32 sun4i_spi_get_tx_fifo_count(struct sun4i_spi *sspi)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	u32 reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	reg >>= SUN4I_FIFO_STA_TF_CNT_BITS;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	return reg & SUN4I_FIFO_STA_TF_CNT_MASK;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
sun4i_spi_enable_interrupt(struct sun4i_spi * sspi,u32 mask)109*4882a593Smuzhiyun static inline void sun4i_spi_enable_interrupt(struct sun4i_spi *sspi, u32 mask)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	reg |= mask;
114*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
sun4i_spi_disable_interrupt(struct sun4i_spi * sspi,u32 mask)117*4882a593Smuzhiyun static inline void sun4i_spi_disable_interrupt(struct sun4i_spi *sspi, u32 mask)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	reg &= ~mask;
122*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
sun4i_spi_drain_fifo(struct sun4i_spi * sspi,int len)125*4882a593Smuzhiyun static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	u32 reg, cnt;
128*4882a593Smuzhiyun 	u8 byte;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	/* See how much data is available */
131*4882a593Smuzhiyun 	reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG);
132*4882a593Smuzhiyun 	reg &= SUN4I_FIFO_STA_RF_CNT_MASK;
133*4882a593Smuzhiyun 	cnt = reg >> SUN4I_FIFO_STA_RF_CNT_BITS;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	if (len > cnt)
136*4882a593Smuzhiyun 		len = cnt;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	while (len--) {
139*4882a593Smuzhiyun 		byte = readb(sspi->base_addr + SUN4I_RXDATA_REG);
140*4882a593Smuzhiyun 		if (sspi->rx_buf)
141*4882a593Smuzhiyun 			*sspi->rx_buf++ = byte;
142*4882a593Smuzhiyun 	}
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
sun4i_spi_fill_fifo(struct sun4i_spi * sspi,int len)145*4882a593Smuzhiyun static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	u32 cnt;
148*4882a593Smuzhiyun 	u8 byte;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	/* See how much data we can fit */
151*4882a593Smuzhiyun 	cnt = SUN4I_FIFO_DEPTH - sun4i_spi_get_tx_fifo_count(sspi);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	len = min3(len, (int)cnt, sspi->len);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	while (len--) {
156*4882a593Smuzhiyun 		byte = sspi->tx_buf ? *sspi->tx_buf++ : 0;
157*4882a593Smuzhiyun 		writeb(byte, sspi->base_addr + SUN4I_TXDATA_REG);
158*4882a593Smuzhiyun 		sspi->len--;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
sun4i_spi_set_cs(struct spi_device * spi,bool enable)162*4882a593Smuzhiyun static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
165*4882a593Smuzhiyun 	u32 reg;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	reg &= ~SUN4I_CTL_CS_MASK;
170*4882a593Smuzhiyun 	reg |= SUN4I_CTL_CS(spi->chip_select);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* We want to control the chip select manually */
173*4882a593Smuzhiyun 	reg |= SUN4I_CTL_CS_MANUAL;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	if (enable)
176*4882a593Smuzhiyun 		reg |= SUN4I_CTL_CS_LEVEL;
177*4882a593Smuzhiyun 	else
178*4882a593Smuzhiyun 		reg &= ~SUN4I_CTL_CS_LEVEL;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	/*
181*4882a593Smuzhiyun 	 * Even though this looks irrelevant since we are supposed to
182*4882a593Smuzhiyun 	 * be controlling the chip select manually, this bit also
183*4882a593Smuzhiyun 	 * controls the levels of the chip select for inactive
184*4882a593Smuzhiyun 	 * devices.
185*4882a593Smuzhiyun 	 *
186*4882a593Smuzhiyun 	 * If we don't set it, the chip select level will go low by
187*4882a593Smuzhiyun 	 * default when the device is idle, which is not really
188*4882a593Smuzhiyun 	 * expected in the common case where the chip select is active
189*4882a593Smuzhiyun 	 * low.
190*4882a593Smuzhiyun 	 */
191*4882a593Smuzhiyun 	if (spi->mode & SPI_CS_HIGH)
192*4882a593Smuzhiyun 		reg &= ~SUN4I_CTL_CS_ACTIVE_LOW;
193*4882a593Smuzhiyun 	else
194*4882a593Smuzhiyun 		reg |= SUN4I_CTL_CS_ACTIVE_LOW;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
sun4i_spi_max_transfer_size(struct spi_device * spi)199*4882a593Smuzhiyun static size_t sun4i_spi_max_transfer_size(struct spi_device *spi)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	return SUN4I_MAX_XFER_SIZE - 1;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
sun4i_spi_transfer_one(struct spi_master * master,struct spi_device * spi,struct spi_transfer * tfr)204*4882a593Smuzhiyun static int sun4i_spi_transfer_one(struct spi_master *master,
205*4882a593Smuzhiyun 				  struct spi_device *spi,
206*4882a593Smuzhiyun 				  struct spi_transfer *tfr)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
209*4882a593Smuzhiyun 	unsigned int mclk_rate, div, timeout;
210*4882a593Smuzhiyun 	unsigned int start, end, tx_time;
211*4882a593Smuzhiyun 	unsigned int tx_len = 0;
212*4882a593Smuzhiyun 	int ret = 0;
213*4882a593Smuzhiyun 	u32 reg;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	/* We don't support transfer larger than the FIFO */
216*4882a593Smuzhiyun 	if (tfr->len > SUN4I_MAX_XFER_SIZE)
217*4882a593Smuzhiyun 		return -EMSGSIZE;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (tfr->tx_buf && tfr->len >= SUN4I_MAX_XFER_SIZE)
220*4882a593Smuzhiyun 		return -EMSGSIZE;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	reinit_completion(&sspi->done);
223*4882a593Smuzhiyun 	sspi->tx_buf = tfr->tx_buf;
224*4882a593Smuzhiyun 	sspi->rx_buf = tfr->rx_buf;
225*4882a593Smuzhiyun 	sspi->len = tfr->len;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/* Clear pending interrupts */
228*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_INT_STA_REG, ~0);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	/* Reset FIFOs */
234*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_CTL_REG,
235*4882a593Smuzhiyun 			reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	/*
238*4882a593Smuzhiyun 	 * Setup the transfer control register: Chip Select,
239*4882a593Smuzhiyun 	 * polarities, etc.
240*4882a593Smuzhiyun 	 */
241*4882a593Smuzhiyun 	if (spi->mode & SPI_CPOL)
242*4882a593Smuzhiyun 		reg |= SUN4I_CTL_CPOL;
243*4882a593Smuzhiyun 	else
244*4882a593Smuzhiyun 		reg &= ~SUN4I_CTL_CPOL;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	if (spi->mode & SPI_CPHA)
247*4882a593Smuzhiyun 		reg |= SUN4I_CTL_CPHA;
248*4882a593Smuzhiyun 	else
249*4882a593Smuzhiyun 		reg &= ~SUN4I_CTL_CPHA;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	if (spi->mode & SPI_LSB_FIRST)
252*4882a593Smuzhiyun 		reg |= SUN4I_CTL_LMTF;
253*4882a593Smuzhiyun 	else
254*4882a593Smuzhiyun 		reg &= ~SUN4I_CTL_LMTF;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	/*
258*4882a593Smuzhiyun 	 * If it's a TX only transfer, we don't want to fill the RX
259*4882a593Smuzhiyun 	 * FIFO with bogus data
260*4882a593Smuzhiyun 	 */
261*4882a593Smuzhiyun 	if (sspi->rx_buf)
262*4882a593Smuzhiyun 		reg &= ~SUN4I_CTL_DHB;
263*4882a593Smuzhiyun 	else
264*4882a593Smuzhiyun 		reg |= SUN4I_CTL_DHB;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	/* Ensure that we have a parent clock fast enough */
269*4882a593Smuzhiyun 	mclk_rate = clk_get_rate(sspi->mclk);
270*4882a593Smuzhiyun 	if (mclk_rate < (2 * tfr->speed_hz)) {
271*4882a593Smuzhiyun 		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
272*4882a593Smuzhiyun 		mclk_rate = clk_get_rate(sspi->mclk);
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	/*
276*4882a593Smuzhiyun 	 * Setup clock divider.
277*4882a593Smuzhiyun 	 *
278*4882a593Smuzhiyun 	 * We have two choices there. Either we can use the clock
279*4882a593Smuzhiyun 	 * divide rate 1, which is calculated thanks to this formula:
280*4882a593Smuzhiyun 	 * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1))
281*4882a593Smuzhiyun 	 * Or we can use CDR2, which is calculated with the formula:
282*4882a593Smuzhiyun 	 * SPI_CLK = MOD_CLK / (2 * (cdr + 1))
283*4882a593Smuzhiyun 	 * Wether we use the former or the latter is set through the
284*4882a593Smuzhiyun 	 * DRS bit.
285*4882a593Smuzhiyun 	 *
286*4882a593Smuzhiyun 	 * First try CDR2, and if we can't reach the expected
287*4882a593Smuzhiyun 	 * frequency, fall back to CDR1.
288*4882a593Smuzhiyun 	 */
289*4882a593Smuzhiyun 	div = mclk_rate / (2 * tfr->speed_hz);
290*4882a593Smuzhiyun 	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
291*4882a593Smuzhiyun 		if (div > 0)
292*4882a593Smuzhiyun 			div--;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
295*4882a593Smuzhiyun 	} else {
296*4882a593Smuzhiyun 		div = ilog2(mclk_rate) - ilog2(tfr->speed_hz);
297*4882a593Smuzhiyun 		reg = SUN4I_CLK_CTL_CDR1(div);
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	/* Setup the transfer now... */
303*4882a593Smuzhiyun 	if (sspi->tx_buf)
304*4882a593Smuzhiyun 		tx_len = tfr->len;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	/* Setup the counters */
307*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
308*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	/*
311*4882a593Smuzhiyun 	 * Fill the TX FIFO
312*4882a593Smuzhiyun 	 * Filling the FIFO fully causes timeout for some reason
313*4882a593Smuzhiyun 	 * at least on spi2 on A10s
314*4882a593Smuzhiyun 	 */
315*4882a593Smuzhiyun 	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	/* Enable the interrupts */
318*4882a593Smuzhiyun 	sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TC |
319*4882a593Smuzhiyun 					 SUN4I_INT_CTL_RF_F34);
320*4882a593Smuzhiyun 	/* Only enable Tx FIFO interrupt if we really need it */
321*4882a593Smuzhiyun 	if (tx_len > SUN4I_FIFO_DEPTH)
322*4882a593Smuzhiyun 		sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TF_E34);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	/* Start the transfer */
325*4882a593Smuzhiyun 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
326*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
329*4882a593Smuzhiyun 	start = jiffies;
330*4882a593Smuzhiyun 	timeout = wait_for_completion_timeout(&sspi->done,
331*4882a593Smuzhiyun 					      msecs_to_jiffies(tx_time));
332*4882a593Smuzhiyun 	end = jiffies;
333*4882a593Smuzhiyun 	if (!timeout) {
334*4882a593Smuzhiyun 		dev_warn(&master->dev,
335*4882a593Smuzhiyun 			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
336*4882a593Smuzhiyun 			 dev_name(&spi->dev), tfr->len, tfr->speed_hz,
337*4882a593Smuzhiyun 			 jiffies_to_msecs(end - start), tx_time);
338*4882a593Smuzhiyun 		ret = -ETIMEDOUT;
339*4882a593Smuzhiyun 		goto out;
340*4882a593Smuzhiyun 	}
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun out:
344*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	return ret;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun 
sun4i_spi_handler(int irq,void * dev_id)349*4882a593Smuzhiyun static irqreturn_t sun4i_spi_handler(int irq, void *dev_id)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	struct sun4i_spi *sspi = dev_id;
352*4882a593Smuzhiyun 	u32 status = sun4i_spi_read(sspi, SUN4I_INT_STA_REG);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	/* Transfer complete */
355*4882a593Smuzhiyun 	if (status & SUN4I_INT_CTL_TC) {
356*4882a593Smuzhiyun 		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC);
357*4882a593Smuzhiyun 		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
358*4882a593Smuzhiyun 		complete(&sspi->done);
359*4882a593Smuzhiyun 		return IRQ_HANDLED;
360*4882a593Smuzhiyun 	}
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	/* Receive FIFO 3/4 full */
363*4882a593Smuzhiyun 	if (status & SUN4I_INT_CTL_RF_F34) {
364*4882a593Smuzhiyun 		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
365*4882a593Smuzhiyun 		/* Only clear the interrupt _after_ draining the FIFO */
366*4882a593Smuzhiyun 		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_RF_F34);
367*4882a593Smuzhiyun 		return IRQ_HANDLED;
368*4882a593Smuzhiyun 	}
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	/* Transmit FIFO 3/4 empty */
371*4882a593Smuzhiyun 	if (status & SUN4I_INT_CTL_TF_E34) {
372*4882a593Smuzhiyun 		sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 		if (!sspi->len)
375*4882a593Smuzhiyun 			/* nothing left to transmit */
376*4882a593Smuzhiyun 			sun4i_spi_disable_interrupt(sspi, SUN4I_INT_CTL_TF_E34);
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 		/* Only clear the interrupt _after_ re-seeding the FIFO */
379*4882a593Smuzhiyun 		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TF_E34);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 		return IRQ_HANDLED;
382*4882a593Smuzhiyun 	}
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	return IRQ_NONE;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun 
sun4i_spi_runtime_resume(struct device * dev)387*4882a593Smuzhiyun static int sun4i_spi_runtime_resume(struct device *dev)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun 	struct spi_master *master = dev_get_drvdata(dev);
390*4882a593Smuzhiyun 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
391*4882a593Smuzhiyun 	int ret;
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	ret = clk_prepare_enable(sspi->hclk);
394*4882a593Smuzhiyun 	if (ret) {
395*4882a593Smuzhiyun 		dev_err(dev, "Couldn't enable AHB clock\n");
396*4882a593Smuzhiyun 		goto out;
397*4882a593Smuzhiyun 	}
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	ret = clk_prepare_enable(sspi->mclk);
400*4882a593Smuzhiyun 	if (ret) {
401*4882a593Smuzhiyun 		dev_err(dev, "Couldn't enable module clock\n");
402*4882a593Smuzhiyun 		goto err;
403*4882a593Smuzhiyun 	}
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 	sun4i_spi_write(sspi, SUN4I_CTL_REG,
406*4882a593Smuzhiyun 			SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP);
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 	return 0;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun err:
411*4882a593Smuzhiyun 	clk_disable_unprepare(sspi->hclk);
412*4882a593Smuzhiyun out:
413*4882a593Smuzhiyun 	return ret;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
sun4i_spi_runtime_suspend(struct device * dev)416*4882a593Smuzhiyun static int sun4i_spi_runtime_suspend(struct device *dev)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun 	struct spi_master *master = dev_get_drvdata(dev);
419*4882a593Smuzhiyun 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	clk_disable_unprepare(sspi->mclk);
422*4882a593Smuzhiyun 	clk_disable_unprepare(sspi->hclk);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	return 0;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
sun4i_spi_probe(struct platform_device * pdev)427*4882a593Smuzhiyun static int sun4i_spi_probe(struct platform_device *pdev)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun 	struct spi_master *master;
430*4882a593Smuzhiyun 	struct sun4i_spi *sspi;
431*4882a593Smuzhiyun 	int ret = 0, irq;
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi));
434*4882a593Smuzhiyun 	if (!master) {
435*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
436*4882a593Smuzhiyun 		return -ENOMEM;
437*4882a593Smuzhiyun 	}
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	platform_set_drvdata(pdev, master);
440*4882a593Smuzhiyun 	sspi = spi_master_get_devdata(master);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	sspi->base_addr = devm_platform_ioremap_resource(pdev, 0);
443*4882a593Smuzhiyun 	if (IS_ERR(sspi->base_addr)) {
444*4882a593Smuzhiyun 		ret = PTR_ERR(sspi->base_addr);
445*4882a593Smuzhiyun 		goto err_free_master;
446*4882a593Smuzhiyun 	}
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	irq = platform_get_irq(pdev, 0);
449*4882a593Smuzhiyun 	if (irq < 0) {
450*4882a593Smuzhiyun 		ret = -ENXIO;
451*4882a593Smuzhiyun 		goto err_free_master;
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler,
455*4882a593Smuzhiyun 			       0, "sun4i-spi", sspi);
456*4882a593Smuzhiyun 	if (ret) {
457*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Cannot request IRQ\n");
458*4882a593Smuzhiyun 		goto err_free_master;
459*4882a593Smuzhiyun 	}
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	sspi->master = master;
462*4882a593Smuzhiyun 	master->max_speed_hz = 100 * 1000 * 1000;
463*4882a593Smuzhiyun 	master->min_speed_hz = 3 * 1000;
464*4882a593Smuzhiyun 	master->set_cs = sun4i_spi_set_cs;
465*4882a593Smuzhiyun 	master->transfer_one = sun4i_spi_transfer_one;
466*4882a593Smuzhiyun 	master->num_chipselect = 4;
467*4882a593Smuzhiyun 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
468*4882a593Smuzhiyun 	master->bits_per_word_mask = SPI_BPW_MASK(8);
469*4882a593Smuzhiyun 	master->dev.of_node = pdev->dev.of_node;
470*4882a593Smuzhiyun 	master->auto_runtime_pm = true;
471*4882a593Smuzhiyun 	master->max_transfer_size = sun4i_spi_max_transfer_size;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
474*4882a593Smuzhiyun 	if (IS_ERR(sspi->hclk)) {
475*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
476*4882a593Smuzhiyun 		ret = PTR_ERR(sspi->hclk);
477*4882a593Smuzhiyun 		goto err_free_master;
478*4882a593Smuzhiyun 	}
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	sspi->mclk = devm_clk_get(&pdev->dev, "mod");
481*4882a593Smuzhiyun 	if (IS_ERR(sspi->mclk)) {
482*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Unable to acquire module clock\n");
483*4882a593Smuzhiyun 		ret = PTR_ERR(sspi->mclk);
484*4882a593Smuzhiyun 		goto err_free_master;
485*4882a593Smuzhiyun 	}
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	init_completion(&sspi->done);
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	/*
490*4882a593Smuzhiyun 	 * This wake-up/shutdown pattern is to be able to have the
491*4882a593Smuzhiyun 	 * device woken up, even if runtime_pm is disabled
492*4882a593Smuzhiyun 	 */
493*4882a593Smuzhiyun 	ret = sun4i_spi_runtime_resume(&pdev->dev);
494*4882a593Smuzhiyun 	if (ret) {
495*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Couldn't resume the device\n");
496*4882a593Smuzhiyun 		goto err_free_master;
497*4882a593Smuzhiyun 	}
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	pm_runtime_set_active(&pdev->dev);
500*4882a593Smuzhiyun 	pm_runtime_enable(&pdev->dev);
501*4882a593Smuzhiyun 	pm_runtime_idle(&pdev->dev);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	ret = devm_spi_register_master(&pdev->dev, master);
504*4882a593Smuzhiyun 	if (ret) {
505*4882a593Smuzhiyun 		dev_err(&pdev->dev, "cannot register SPI master\n");
506*4882a593Smuzhiyun 		goto err_pm_disable;
507*4882a593Smuzhiyun 	}
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	return 0;
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun err_pm_disable:
512*4882a593Smuzhiyun 	pm_runtime_disable(&pdev->dev);
513*4882a593Smuzhiyun 	sun4i_spi_runtime_suspend(&pdev->dev);
514*4882a593Smuzhiyun err_free_master:
515*4882a593Smuzhiyun 	spi_master_put(master);
516*4882a593Smuzhiyun 	return ret;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun 
sun4i_spi_remove(struct platform_device * pdev)519*4882a593Smuzhiyun static int sun4i_spi_remove(struct platform_device *pdev)
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun 	pm_runtime_force_suspend(&pdev->dev);
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	return 0;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun static const struct of_device_id sun4i_spi_match[] = {
527*4882a593Smuzhiyun 	{ .compatible = "allwinner,sun4i-a10-spi", },
528*4882a593Smuzhiyun 	{}
529*4882a593Smuzhiyun };
530*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sun4i_spi_match);
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun static const struct dev_pm_ops sun4i_spi_pm_ops = {
533*4882a593Smuzhiyun 	.runtime_resume		= sun4i_spi_runtime_resume,
534*4882a593Smuzhiyun 	.runtime_suspend	= sun4i_spi_runtime_suspend,
535*4882a593Smuzhiyun };
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun static struct platform_driver sun4i_spi_driver = {
538*4882a593Smuzhiyun 	.probe	= sun4i_spi_probe,
539*4882a593Smuzhiyun 	.remove	= sun4i_spi_remove,
540*4882a593Smuzhiyun 	.driver	= {
541*4882a593Smuzhiyun 		.name		= "sun4i-spi",
542*4882a593Smuzhiyun 		.of_match_table	= sun4i_spi_match,
543*4882a593Smuzhiyun 		.pm		= &sun4i_spi_pm_ops,
544*4882a593Smuzhiyun 	},
545*4882a593Smuzhiyun };
546*4882a593Smuzhiyun module_platform_driver(sun4i_spi_driver);
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>");
549*4882a593Smuzhiyun MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
550*4882a593Smuzhiyun MODULE_DESCRIPTION("Allwinner A1X/A20 SPI controller driver");
551*4882a593Smuzhiyun MODULE_LICENSE("GPL");
552