1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // Freescale i.MX7ULP LPSPI driver
4*4882a593Smuzhiyun //
5*4882a593Smuzhiyun // Copyright 2016 Freescale Semiconductor, Inc.
6*4882a593Smuzhiyun // Copyright 2018 NXP Semiconductors
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/clk.h>
9*4882a593Smuzhiyun #include <linux/completion.h>
10*4882a593Smuzhiyun #include <linux/delay.h>
11*4882a593Smuzhiyun #include <linux/dmaengine.h>
12*4882a593Smuzhiyun #include <linux/dma-mapping.h>
13*4882a593Smuzhiyun #include <linux/err.h>
14*4882a593Smuzhiyun #include <linux/interrupt.h>
15*4882a593Smuzhiyun #include <linux/io.h>
16*4882a593Smuzhiyun #include <linux/irq.h>
17*4882a593Smuzhiyun #include <linux/kernel.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/of.h>
20*4882a593Smuzhiyun #include <linux/of_device.h>
21*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
22*4882a593Smuzhiyun #include <linux/platform_device.h>
23*4882a593Smuzhiyun #include <linux/platform_data/dma-imx.h>
24*4882a593Smuzhiyun #include <linux/pm_runtime.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/spi/spi.h>
27*4882a593Smuzhiyun #include <linux/spi/spi_bitbang.h>
28*4882a593Smuzhiyun #include <linux/types.h>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define DRIVER_NAME "fsl_lpspi"
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #define FSL_LPSPI_RPM_TIMEOUT 50 /* 50ms */
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /* The maximum bytes that edma can transfer once.*/
35*4882a593Smuzhiyun #define FSL_LPSPI_MAX_EDMA_BYTES ((1 << 15) - 1)
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* i.MX7ULP LPSPI registers */
38*4882a593Smuzhiyun #define IMX7ULP_VERID 0x0
39*4882a593Smuzhiyun #define IMX7ULP_PARAM 0x4
40*4882a593Smuzhiyun #define IMX7ULP_CR 0x10
41*4882a593Smuzhiyun #define IMX7ULP_SR 0x14
42*4882a593Smuzhiyun #define IMX7ULP_IER 0x18
43*4882a593Smuzhiyun #define IMX7ULP_DER 0x1c
44*4882a593Smuzhiyun #define IMX7ULP_CFGR0 0x20
45*4882a593Smuzhiyun #define IMX7ULP_CFGR1 0x24
46*4882a593Smuzhiyun #define IMX7ULP_DMR0 0x30
47*4882a593Smuzhiyun #define IMX7ULP_DMR1 0x34
48*4882a593Smuzhiyun #define IMX7ULP_CCR 0x40
49*4882a593Smuzhiyun #define IMX7ULP_FCR 0x58
50*4882a593Smuzhiyun #define IMX7ULP_FSR 0x5c
51*4882a593Smuzhiyun #define IMX7ULP_TCR 0x60
52*4882a593Smuzhiyun #define IMX7ULP_TDR 0x64
53*4882a593Smuzhiyun #define IMX7ULP_RSR 0x70
54*4882a593Smuzhiyun #define IMX7ULP_RDR 0x74
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /* General control register field define */
57*4882a593Smuzhiyun #define CR_RRF BIT(9)
58*4882a593Smuzhiyun #define CR_RTF BIT(8)
59*4882a593Smuzhiyun #define CR_RST BIT(1)
60*4882a593Smuzhiyun #define CR_MEN BIT(0)
61*4882a593Smuzhiyun #define SR_MBF BIT(24)
62*4882a593Smuzhiyun #define SR_TCF BIT(10)
63*4882a593Smuzhiyun #define SR_FCF BIT(9)
64*4882a593Smuzhiyun #define SR_RDF BIT(1)
65*4882a593Smuzhiyun #define SR_TDF BIT(0)
66*4882a593Smuzhiyun #define IER_TCIE BIT(10)
67*4882a593Smuzhiyun #define IER_FCIE BIT(9)
68*4882a593Smuzhiyun #define IER_RDIE BIT(1)
69*4882a593Smuzhiyun #define IER_TDIE BIT(0)
70*4882a593Smuzhiyun #define DER_RDDE BIT(1)
71*4882a593Smuzhiyun #define DER_TDDE BIT(0)
72*4882a593Smuzhiyun #define CFGR1_PCSCFG BIT(27)
73*4882a593Smuzhiyun #define CFGR1_PINCFG (BIT(24)|BIT(25))
74*4882a593Smuzhiyun #define CFGR1_PCSPOL BIT(8)
75*4882a593Smuzhiyun #define CFGR1_NOSTALL BIT(3)
76*4882a593Smuzhiyun #define CFGR1_MASTER BIT(0)
77*4882a593Smuzhiyun #define FSR_TXCOUNT (0xFF)
78*4882a593Smuzhiyun #define RSR_RXEMPTY BIT(1)
79*4882a593Smuzhiyun #define TCR_CPOL BIT(31)
80*4882a593Smuzhiyun #define TCR_CPHA BIT(30)
81*4882a593Smuzhiyun #define TCR_CONT BIT(21)
82*4882a593Smuzhiyun #define TCR_CONTC BIT(20)
83*4882a593Smuzhiyun #define TCR_RXMSK BIT(19)
84*4882a593Smuzhiyun #define TCR_TXMSK BIT(18)
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun struct lpspi_config {
87*4882a593Smuzhiyun u8 bpw;
88*4882a593Smuzhiyun u8 chip_select;
89*4882a593Smuzhiyun u8 prescale;
90*4882a593Smuzhiyun u16 mode;
91*4882a593Smuzhiyun u32 speed_hz;
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun struct fsl_lpspi_data {
95*4882a593Smuzhiyun struct device *dev;
96*4882a593Smuzhiyun void __iomem *base;
97*4882a593Smuzhiyun unsigned long base_phys;
98*4882a593Smuzhiyun struct clk *clk_ipg;
99*4882a593Smuzhiyun struct clk *clk_per;
100*4882a593Smuzhiyun bool is_slave;
101*4882a593Smuzhiyun bool is_only_cs1;
102*4882a593Smuzhiyun bool is_first_byte;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun void *rx_buf;
105*4882a593Smuzhiyun const void *tx_buf;
106*4882a593Smuzhiyun void (*tx)(struct fsl_lpspi_data *);
107*4882a593Smuzhiyun void (*rx)(struct fsl_lpspi_data *);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun u32 remain;
110*4882a593Smuzhiyun u8 watermark;
111*4882a593Smuzhiyun u8 txfifosize;
112*4882a593Smuzhiyun u8 rxfifosize;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun struct lpspi_config config;
115*4882a593Smuzhiyun struct completion xfer_done;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun bool slave_aborted;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* DMA */
120*4882a593Smuzhiyun bool usedma;
121*4882a593Smuzhiyun struct completion dma_rx_completion;
122*4882a593Smuzhiyun struct completion dma_tx_completion;
123*4882a593Smuzhiyun };
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun static const struct of_device_id fsl_lpspi_dt_ids[] = {
126*4882a593Smuzhiyun { .compatible = "fsl,imx7ulp-spi", },
127*4882a593Smuzhiyun { /* sentinel */ }
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun #define LPSPI_BUF_RX(type) \
132*4882a593Smuzhiyun static void fsl_lpspi_buf_rx_##type(struct fsl_lpspi_data *fsl_lpspi) \
133*4882a593Smuzhiyun { \
134*4882a593Smuzhiyun unsigned int val = readl(fsl_lpspi->base + IMX7ULP_RDR); \
135*4882a593Smuzhiyun \
136*4882a593Smuzhiyun if (fsl_lpspi->rx_buf) { \
137*4882a593Smuzhiyun *(type *)fsl_lpspi->rx_buf = val; \
138*4882a593Smuzhiyun fsl_lpspi->rx_buf += sizeof(type); \
139*4882a593Smuzhiyun } \
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun #define LPSPI_BUF_TX(type) \
143*4882a593Smuzhiyun static void fsl_lpspi_buf_tx_##type(struct fsl_lpspi_data *fsl_lpspi) \
144*4882a593Smuzhiyun { \
145*4882a593Smuzhiyun type val = 0; \
146*4882a593Smuzhiyun \
147*4882a593Smuzhiyun if (fsl_lpspi->tx_buf) { \
148*4882a593Smuzhiyun val = *(type *)fsl_lpspi->tx_buf; \
149*4882a593Smuzhiyun fsl_lpspi->tx_buf += sizeof(type); \
150*4882a593Smuzhiyun } \
151*4882a593Smuzhiyun \
152*4882a593Smuzhiyun fsl_lpspi->remain -= sizeof(type); \
153*4882a593Smuzhiyun writel(val, fsl_lpspi->base + IMX7ULP_TDR); \
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun LPSPI_BUF_RX(u8)
LPSPI_BUF_TX(u8)157*4882a593Smuzhiyun LPSPI_BUF_TX(u8)
158*4882a593Smuzhiyun LPSPI_BUF_RX(u16)
159*4882a593Smuzhiyun LPSPI_BUF_TX(u16)
160*4882a593Smuzhiyun LPSPI_BUF_RX(u32)
161*4882a593Smuzhiyun LPSPI_BUF_TX(u32)
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun static void fsl_lpspi_intctrl(struct fsl_lpspi_data *fsl_lpspi,
164*4882a593Smuzhiyun unsigned int enable)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun writel(enable, fsl_lpspi->base + IMX7ULP_IER);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
fsl_lpspi_bytes_per_word(const int bpw)169*4882a593Smuzhiyun static int fsl_lpspi_bytes_per_word(const int bpw)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun return DIV_ROUND_UP(bpw, BITS_PER_BYTE);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
fsl_lpspi_can_dma(struct spi_controller * controller,struct spi_device * spi,struct spi_transfer * transfer)174*4882a593Smuzhiyun static bool fsl_lpspi_can_dma(struct spi_controller *controller,
175*4882a593Smuzhiyun struct spi_device *spi,
176*4882a593Smuzhiyun struct spi_transfer *transfer)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun unsigned int bytes_per_word;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun if (!controller->dma_rx)
181*4882a593Smuzhiyun return false;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun bytes_per_word = fsl_lpspi_bytes_per_word(transfer->bits_per_word);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun switch (bytes_per_word) {
186*4882a593Smuzhiyun case 1:
187*4882a593Smuzhiyun case 2:
188*4882a593Smuzhiyun case 4:
189*4882a593Smuzhiyun break;
190*4882a593Smuzhiyun default:
191*4882a593Smuzhiyun return false;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun return true;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
lpspi_prepare_xfer_hardware(struct spi_controller * controller)197*4882a593Smuzhiyun static int lpspi_prepare_xfer_hardware(struct spi_controller *controller)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
200*4882a593Smuzhiyun spi_controller_get_devdata(controller);
201*4882a593Smuzhiyun int ret;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun ret = pm_runtime_resume_and_get(fsl_lpspi->dev);
204*4882a593Smuzhiyun if (ret < 0) {
205*4882a593Smuzhiyun dev_err(fsl_lpspi->dev, "failed to enable clock\n");
206*4882a593Smuzhiyun return ret;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun return 0;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
lpspi_unprepare_xfer_hardware(struct spi_controller * controller)212*4882a593Smuzhiyun static int lpspi_unprepare_xfer_hardware(struct spi_controller *controller)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
215*4882a593Smuzhiyun spi_controller_get_devdata(controller);
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun pm_runtime_mark_last_busy(fsl_lpspi->dev);
218*4882a593Smuzhiyun pm_runtime_put_autosuspend(fsl_lpspi->dev);
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun return 0;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun
fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data * fsl_lpspi)223*4882a593Smuzhiyun static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun u8 txfifo_cnt;
226*4882a593Smuzhiyun u32 temp;
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun while (txfifo_cnt < fsl_lpspi->txfifosize) {
231*4882a593Smuzhiyun if (!fsl_lpspi->remain)
232*4882a593Smuzhiyun break;
233*4882a593Smuzhiyun fsl_lpspi->tx(fsl_lpspi);
234*4882a593Smuzhiyun txfifo_cnt++;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun if (txfifo_cnt < fsl_lpspi->txfifosize) {
238*4882a593Smuzhiyun if (!fsl_lpspi->is_slave) {
239*4882a593Smuzhiyun temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
240*4882a593Smuzhiyun temp &= ~TCR_CONTC;
241*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
245*4882a593Smuzhiyun } else
246*4882a593Smuzhiyun fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE);
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data * fsl_lpspi)249*4882a593Smuzhiyun static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun while (!(readl(fsl_lpspi->base + IMX7ULP_RSR) & RSR_RXEMPTY))
252*4882a593Smuzhiyun fsl_lpspi->rx(fsl_lpspi);
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun
fsl_lpspi_set_cmd(struct fsl_lpspi_data * fsl_lpspi)255*4882a593Smuzhiyun static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun u32 temp = 0;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun temp |= fsl_lpspi->config.bpw - 1;
260*4882a593Smuzhiyun temp |= (fsl_lpspi->config.mode & 0x3) << 30;
261*4882a593Smuzhiyun temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
262*4882a593Smuzhiyun if (!fsl_lpspi->is_slave) {
263*4882a593Smuzhiyun temp |= fsl_lpspi->config.prescale << 27;
264*4882a593Smuzhiyun /*
265*4882a593Smuzhiyun * Set TCR_CONT will keep SS asserted after current transfer.
266*4882a593Smuzhiyun * For the first transfer, clear TCR_CONTC to assert SS.
267*4882a593Smuzhiyun * For subsequent transfer, set TCR_CONTC to keep SS asserted.
268*4882a593Smuzhiyun */
269*4882a593Smuzhiyun if (!fsl_lpspi->usedma) {
270*4882a593Smuzhiyun temp |= TCR_CONT;
271*4882a593Smuzhiyun if (fsl_lpspi->is_first_byte)
272*4882a593Smuzhiyun temp &= ~TCR_CONTC;
273*4882a593Smuzhiyun else
274*4882a593Smuzhiyun temp |= TCR_CONTC;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
fsl_lpspi_set_watermark(struct fsl_lpspi_data * fsl_lpspi)282*4882a593Smuzhiyun static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun u32 temp;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun if (!fsl_lpspi->usedma)
287*4882a593Smuzhiyun temp = fsl_lpspi->watermark >> 1 |
288*4882a593Smuzhiyun (fsl_lpspi->watermark >> 1) << 16;
289*4882a593Smuzhiyun else
290*4882a593Smuzhiyun temp = fsl_lpspi->watermark >> 1;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_FCR);
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev, "FCR=0x%x\n", temp);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
fsl_lpspi_set_bitrate(struct fsl_lpspi_data * fsl_lpspi)297*4882a593Smuzhiyun static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun struct lpspi_config config = fsl_lpspi->config;
300*4882a593Smuzhiyun unsigned int perclk_rate, scldiv;
301*4882a593Smuzhiyun u8 prescale;
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun perclk_rate = clk_get_rate(fsl_lpspi->clk_per);
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun if (config.speed_hz > perclk_rate / 2) {
306*4882a593Smuzhiyun dev_err(fsl_lpspi->dev,
307*4882a593Smuzhiyun "per-clk should be at least two times of transfer speed");
308*4882a593Smuzhiyun return -EINVAL;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun for (prescale = 0; prescale < 8; prescale++) {
312*4882a593Smuzhiyun scldiv = perclk_rate / config.speed_hz / (1 << prescale) - 2;
313*4882a593Smuzhiyun if (scldiv < 256) {
314*4882a593Smuzhiyun fsl_lpspi->config.prescale = prescale;
315*4882a593Smuzhiyun break;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (scldiv >= 256)
320*4882a593Smuzhiyun return -EINVAL;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16),
323*4882a593Smuzhiyun fsl_lpspi->base + IMX7ULP_CCR);
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale=%d, scldiv=%d\n",
326*4882a593Smuzhiyun perclk_rate, config.speed_hz, prescale, scldiv);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun return 0;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
fsl_lpspi_dma_configure(struct spi_controller * controller)331*4882a593Smuzhiyun static int fsl_lpspi_dma_configure(struct spi_controller *controller)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun int ret;
334*4882a593Smuzhiyun enum dma_slave_buswidth buswidth;
335*4882a593Smuzhiyun struct dma_slave_config rx = {}, tx = {};
336*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
337*4882a593Smuzhiyun spi_controller_get_devdata(controller);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun switch (fsl_lpspi_bytes_per_word(fsl_lpspi->config.bpw)) {
340*4882a593Smuzhiyun case 4:
341*4882a593Smuzhiyun buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
342*4882a593Smuzhiyun break;
343*4882a593Smuzhiyun case 2:
344*4882a593Smuzhiyun buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
345*4882a593Smuzhiyun break;
346*4882a593Smuzhiyun case 1:
347*4882a593Smuzhiyun buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
348*4882a593Smuzhiyun break;
349*4882a593Smuzhiyun default:
350*4882a593Smuzhiyun return -EINVAL;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun tx.direction = DMA_MEM_TO_DEV;
354*4882a593Smuzhiyun tx.dst_addr = fsl_lpspi->base_phys + IMX7ULP_TDR;
355*4882a593Smuzhiyun tx.dst_addr_width = buswidth;
356*4882a593Smuzhiyun tx.dst_maxburst = 1;
357*4882a593Smuzhiyun ret = dmaengine_slave_config(controller->dma_tx, &tx);
358*4882a593Smuzhiyun if (ret) {
359*4882a593Smuzhiyun dev_err(fsl_lpspi->dev, "TX dma configuration failed with %d\n",
360*4882a593Smuzhiyun ret);
361*4882a593Smuzhiyun return ret;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun rx.direction = DMA_DEV_TO_MEM;
365*4882a593Smuzhiyun rx.src_addr = fsl_lpspi->base_phys + IMX7ULP_RDR;
366*4882a593Smuzhiyun rx.src_addr_width = buswidth;
367*4882a593Smuzhiyun rx.src_maxburst = 1;
368*4882a593Smuzhiyun ret = dmaengine_slave_config(controller->dma_rx, &rx);
369*4882a593Smuzhiyun if (ret) {
370*4882a593Smuzhiyun dev_err(fsl_lpspi->dev, "RX dma configuration failed with %d\n",
371*4882a593Smuzhiyun ret);
372*4882a593Smuzhiyun return ret;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun return 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun
fsl_lpspi_config(struct fsl_lpspi_data * fsl_lpspi)378*4882a593Smuzhiyun static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun u32 temp;
381*4882a593Smuzhiyun int ret;
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun if (!fsl_lpspi->is_slave) {
384*4882a593Smuzhiyun ret = fsl_lpspi_set_bitrate(fsl_lpspi);
385*4882a593Smuzhiyun if (ret)
386*4882a593Smuzhiyun return ret;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun fsl_lpspi_set_watermark(fsl_lpspi);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun if (!fsl_lpspi->is_slave)
392*4882a593Smuzhiyun temp = CFGR1_MASTER;
393*4882a593Smuzhiyun else
394*4882a593Smuzhiyun temp = CFGR1_PINCFG;
395*4882a593Smuzhiyun if (fsl_lpspi->config.mode & SPI_CS_HIGH)
396*4882a593Smuzhiyun temp |= CFGR1_PCSPOL;
397*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1);
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun temp = readl(fsl_lpspi->base + IMX7ULP_CR);
400*4882a593Smuzhiyun temp |= CR_RRF | CR_RTF | CR_MEN;
401*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_CR);
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun temp = 0;
404*4882a593Smuzhiyun if (fsl_lpspi->usedma)
405*4882a593Smuzhiyun temp = DER_TDDE | DER_RDDE;
406*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_DER);
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun return 0;
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
fsl_lpspi_setup_transfer(struct spi_controller * controller,struct spi_device * spi,struct spi_transfer * t)411*4882a593Smuzhiyun static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
412*4882a593Smuzhiyun struct spi_device *spi,
413*4882a593Smuzhiyun struct spi_transfer *t)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
416*4882a593Smuzhiyun spi_controller_get_devdata(spi->controller);
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun if (t == NULL)
419*4882a593Smuzhiyun return -EINVAL;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun fsl_lpspi->config.mode = spi->mode;
422*4882a593Smuzhiyun fsl_lpspi->config.bpw = t->bits_per_word;
423*4882a593Smuzhiyun fsl_lpspi->config.speed_hz = t->speed_hz;
424*4882a593Smuzhiyun if (fsl_lpspi->is_only_cs1)
425*4882a593Smuzhiyun fsl_lpspi->config.chip_select = 1;
426*4882a593Smuzhiyun else
427*4882a593Smuzhiyun fsl_lpspi->config.chip_select = spi->chip_select;
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun if (!fsl_lpspi->config.speed_hz)
430*4882a593Smuzhiyun fsl_lpspi->config.speed_hz = spi->max_speed_hz;
431*4882a593Smuzhiyun if (!fsl_lpspi->config.bpw)
432*4882a593Smuzhiyun fsl_lpspi->config.bpw = spi->bits_per_word;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun /* Initialize the functions for transfer */
435*4882a593Smuzhiyun if (fsl_lpspi->config.bpw <= 8) {
436*4882a593Smuzhiyun fsl_lpspi->rx = fsl_lpspi_buf_rx_u8;
437*4882a593Smuzhiyun fsl_lpspi->tx = fsl_lpspi_buf_tx_u8;
438*4882a593Smuzhiyun } else if (fsl_lpspi->config.bpw <= 16) {
439*4882a593Smuzhiyun fsl_lpspi->rx = fsl_lpspi_buf_rx_u16;
440*4882a593Smuzhiyun fsl_lpspi->tx = fsl_lpspi_buf_tx_u16;
441*4882a593Smuzhiyun } else {
442*4882a593Smuzhiyun fsl_lpspi->rx = fsl_lpspi_buf_rx_u32;
443*4882a593Smuzhiyun fsl_lpspi->tx = fsl_lpspi_buf_tx_u32;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun if (t->len <= fsl_lpspi->txfifosize)
447*4882a593Smuzhiyun fsl_lpspi->watermark = t->len;
448*4882a593Smuzhiyun else
449*4882a593Smuzhiyun fsl_lpspi->watermark = fsl_lpspi->txfifosize;
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (fsl_lpspi_can_dma(controller, spi, t))
452*4882a593Smuzhiyun fsl_lpspi->usedma = true;
453*4882a593Smuzhiyun else
454*4882a593Smuzhiyun fsl_lpspi->usedma = false;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun return fsl_lpspi_config(fsl_lpspi);
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun
fsl_lpspi_slave_abort(struct spi_controller * controller)459*4882a593Smuzhiyun static int fsl_lpspi_slave_abort(struct spi_controller *controller)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
462*4882a593Smuzhiyun spi_controller_get_devdata(controller);
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun fsl_lpspi->slave_aborted = true;
465*4882a593Smuzhiyun if (!fsl_lpspi->usedma)
466*4882a593Smuzhiyun complete(&fsl_lpspi->xfer_done);
467*4882a593Smuzhiyun else {
468*4882a593Smuzhiyun complete(&fsl_lpspi->dma_tx_completion);
469*4882a593Smuzhiyun complete(&fsl_lpspi->dma_rx_completion);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun return 0;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
fsl_lpspi_wait_for_completion(struct spi_controller * controller)475*4882a593Smuzhiyun static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
478*4882a593Smuzhiyun spi_controller_get_devdata(controller);
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun if (fsl_lpspi->is_slave) {
481*4882a593Smuzhiyun if (wait_for_completion_interruptible(&fsl_lpspi->xfer_done) ||
482*4882a593Smuzhiyun fsl_lpspi->slave_aborted) {
483*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev, "interrupted\n");
484*4882a593Smuzhiyun return -EINTR;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun } else {
487*4882a593Smuzhiyun if (!wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ)) {
488*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n");
489*4882a593Smuzhiyun return -ETIMEDOUT;
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun return 0;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun
fsl_lpspi_reset(struct fsl_lpspi_data * fsl_lpspi)496*4882a593Smuzhiyun static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun u32 temp;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun if (!fsl_lpspi->usedma) {
501*4882a593Smuzhiyun /* Disable all interrupt */
502*4882a593Smuzhiyun fsl_lpspi_intctrl(fsl_lpspi, 0);
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun /* W1C for all flags in SR */
506*4882a593Smuzhiyun temp = 0x3F << 8;
507*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_SR);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun /* Clear FIFO and disable module */
510*4882a593Smuzhiyun temp = CR_RRF | CR_RTF;
511*4882a593Smuzhiyun writel(temp, fsl_lpspi->base + IMX7ULP_CR);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun return 0;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun
fsl_lpspi_dma_rx_callback(void * cookie)516*4882a593Smuzhiyun static void fsl_lpspi_dma_rx_callback(void *cookie)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi = (struct fsl_lpspi_data *)cookie;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun complete(&fsl_lpspi->dma_rx_completion);
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun
fsl_lpspi_dma_tx_callback(void * cookie)523*4882a593Smuzhiyun static void fsl_lpspi_dma_tx_callback(void *cookie)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi = (struct fsl_lpspi_data *)cookie;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun complete(&fsl_lpspi->dma_tx_completion);
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun
fsl_lpspi_calculate_timeout(struct fsl_lpspi_data * fsl_lpspi,int size)530*4882a593Smuzhiyun static int fsl_lpspi_calculate_timeout(struct fsl_lpspi_data *fsl_lpspi,
531*4882a593Smuzhiyun int size)
532*4882a593Smuzhiyun {
533*4882a593Smuzhiyun unsigned long timeout = 0;
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun /* Time with actual data transfer and CS change delay related to HW */
536*4882a593Smuzhiyun timeout = (8 + 4) * size / fsl_lpspi->config.speed_hz;
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun /* Add extra second for scheduler related activities */
539*4882a593Smuzhiyun timeout += 1;
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun /* Double calculated timeout */
542*4882a593Smuzhiyun return msecs_to_jiffies(2 * timeout * MSEC_PER_SEC);
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun
fsl_lpspi_dma_transfer(struct spi_controller * controller,struct fsl_lpspi_data * fsl_lpspi,struct spi_transfer * transfer)545*4882a593Smuzhiyun static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
546*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi,
547*4882a593Smuzhiyun struct spi_transfer *transfer)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun struct dma_async_tx_descriptor *desc_tx, *desc_rx;
550*4882a593Smuzhiyun unsigned long transfer_timeout;
551*4882a593Smuzhiyun unsigned long timeout;
552*4882a593Smuzhiyun struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
553*4882a593Smuzhiyun int ret;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun ret = fsl_lpspi_dma_configure(controller);
556*4882a593Smuzhiyun if (ret)
557*4882a593Smuzhiyun return ret;
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun desc_rx = dmaengine_prep_slave_sg(controller->dma_rx,
560*4882a593Smuzhiyun rx->sgl, rx->nents, DMA_DEV_TO_MEM,
561*4882a593Smuzhiyun DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
562*4882a593Smuzhiyun if (!desc_rx)
563*4882a593Smuzhiyun return -EINVAL;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun desc_rx->callback = fsl_lpspi_dma_rx_callback;
566*4882a593Smuzhiyun desc_rx->callback_param = (void *)fsl_lpspi;
567*4882a593Smuzhiyun dmaengine_submit(desc_rx);
568*4882a593Smuzhiyun reinit_completion(&fsl_lpspi->dma_rx_completion);
569*4882a593Smuzhiyun dma_async_issue_pending(controller->dma_rx);
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun desc_tx = dmaengine_prep_slave_sg(controller->dma_tx,
572*4882a593Smuzhiyun tx->sgl, tx->nents, DMA_MEM_TO_DEV,
573*4882a593Smuzhiyun DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
574*4882a593Smuzhiyun if (!desc_tx) {
575*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_tx);
576*4882a593Smuzhiyun return -EINVAL;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun desc_tx->callback = fsl_lpspi_dma_tx_callback;
580*4882a593Smuzhiyun desc_tx->callback_param = (void *)fsl_lpspi;
581*4882a593Smuzhiyun dmaengine_submit(desc_tx);
582*4882a593Smuzhiyun reinit_completion(&fsl_lpspi->dma_tx_completion);
583*4882a593Smuzhiyun dma_async_issue_pending(controller->dma_tx);
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun fsl_lpspi->slave_aborted = false;
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun if (!fsl_lpspi->is_slave) {
588*4882a593Smuzhiyun transfer_timeout = fsl_lpspi_calculate_timeout(fsl_lpspi,
589*4882a593Smuzhiyun transfer->len);
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun /* Wait eDMA to finish the data transfer.*/
592*4882a593Smuzhiyun timeout = wait_for_completion_timeout(&fsl_lpspi->dma_tx_completion,
593*4882a593Smuzhiyun transfer_timeout);
594*4882a593Smuzhiyun if (!timeout) {
595*4882a593Smuzhiyun dev_err(fsl_lpspi->dev, "I/O Error in DMA TX\n");
596*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_tx);
597*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_rx);
598*4882a593Smuzhiyun fsl_lpspi_reset(fsl_lpspi);
599*4882a593Smuzhiyun return -ETIMEDOUT;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun timeout = wait_for_completion_timeout(&fsl_lpspi->dma_rx_completion,
603*4882a593Smuzhiyun transfer_timeout);
604*4882a593Smuzhiyun if (!timeout) {
605*4882a593Smuzhiyun dev_err(fsl_lpspi->dev, "I/O Error in DMA RX\n");
606*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_tx);
607*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_rx);
608*4882a593Smuzhiyun fsl_lpspi_reset(fsl_lpspi);
609*4882a593Smuzhiyun return -ETIMEDOUT;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun } else {
612*4882a593Smuzhiyun if (wait_for_completion_interruptible(&fsl_lpspi->dma_tx_completion) ||
613*4882a593Smuzhiyun fsl_lpspi->slave_aborted) {
614*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev,
615*4882a593Smuzhiyun "I/O Error in DMA TX interrupted\n");
616*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_tx);
617*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_rx);
618*4882a593Smuzhiyun fsl_lpspi_reset(fsl_lpspi);
619*4882a593Smuzhiyun return -EINTR;
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun if (wait_for_completion_interruptible(&fsl_lpspi->dma_rx_completion) ||
623*4882a593Smuzhiyun fsl_lpspi->slave_aborted) {
624*4882a593Smuzhiyun dev_dbg(fsl_lpspi->dev,
625*4882a593Smuzhiyun "I/O Error in DMA RX interrupted\n");
626*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_tx);
627*4882a593Smuzhiyun dmaengine_terminate_all(controller->dma_rx);
628*4882a593Smuzhiyun fsl_lpspi_reset(fsl_lpspi);
629*4882a593Smuzhiyun return -EINTR;
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun fsl_lpspi_reset(fsl_lpspi);
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun return 0;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
fsl_lpspi_dma_exit(struct spi_controller * controller)638*4882a593Smuzhiyun static void fsl_lpspi_dma_exit(struct spi_controller *controller)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun if (controller->dma_rx) {
641*4882a593Smuzhiyun dma_release_channel(controller->dma_rx);
642*4882a593Smuzhiyun controller->dma_rx = NULL;
643*4882a593Smuzhiyun }
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun if (controller->dma_tx) {
646*4882a593Smuzhiyun dma_release_channel(controller->dma_tx);
647*4882a593Smuzhiyun controller->dma_tx = NULL;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun
fsl_lpspi_dma_init(struct device * dev,struct fsl_lpspi_data * fsl_lpspi,struct spi_controller * controller)651*4882a593Smuzhiyun static int fsl_lpspi_dma_init(struct device *dev,
652*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi,
653*4882a593Smuzhiyun struct spi_controller *controller)
654*4882a593Smuzhiyun {
655*4882a593Smuzhiyun int ret;
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /* Prepare for TX DMA: */
658*4882a593Smuzhiyun controller->dma_tx = dma_request_chan(dev, "tx");
659*4882a593Smuzhiyun if (IS_ERR(controller->dma_tx)) {
660*4882a593Smuzhiyun ret = PTR_ERR(controller->dma_tx);
661*4882a593Smuzhiyun dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret);
662*4882a593Smuzhiyun controller->dma_tx = NULL;
663*4882a593Smuzhiyun goto err;
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun /* Prepare for RX DMA: */
667*4882a593Smuzhiyun controller->dma_rx = dma_request_chan(dev, "rx");
668*4882a593Smuzhiyun if (IS_ERR(controller->dma_rx)) {
669*4882a593Smuzhiyun ret = PTR_ERR(controller->dma_rx);
670*4882a593Smuzhiyun dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret);
671*4882a593Smuzhiyun controller->dma_rx = NULL;
672*4882a593Smuzhiyun goto err;
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun init_completion(&fsl_lpspi->dma_rx_completion);
676*4882a593Smuzhiyun init_completion(&fsl_lpspi->dma_tx_completion);
677*4882a593Smuzhiyun controller->can_dma = fsl_lpspi_can_dma;
678*4882a593Smuzhiyun controller->max_dma_len = FSL_LPSPI_MAX_EDMA_BYTES;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun return 0;
681*4882a593Smuzhiyun err:
682*4882a593Smuzhiyun fsl_lpspi_dma_exit(controller);
683*4882a593Smuzhiyun return ret;
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun
fsl_lpspi_pio_transfer(struct spi_controller * controller,struct spi_transfer * t)686*4882a593Smuzhiyun static int fsl_lpspi_pio_transfer(struct spi_controller *controller,
687*4882a593Smuzhiyun struct spi_transfer *t)
688*4882a593Smuzhiyun {
689*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
690*4882a593Smuzhiyun spi_controller_get_devdata(controller);
691*4882a593Smuzhiyun int ret;
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun fsl_lpspi->tx_buf = t->tx_buf;
694*4882a593Smuzhiyun fsl_lpspi->rx_buf = t->rx_buf;
695*4882a593Smuzhiyun fsl_lpspi->remain = t->len;
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun reinit_completion(&fsl_lpspi->xfer_done);
698*4882a593Smuzhiyun fsl_lpspi->slave_aborted = false;
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun fsl_lpspi_write_tx_fifo(fsl_lpspi);
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun ret = fsl_lpspi_wait_for_completion(controller);
703*4882a593Smuzhiyun if (ret)
704*4882a593Smuzhiyun return ret;
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun fsl_lpspi_reset(fsl_lpspi);
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun return 0;
709*4882a593Smuzhiyun }
710*4882a593Smuzhiyun
fsl_lpspi_transfer_one(struct spi_controller * controller,struct spi_device * spi,struct spi_transfer * t)711*4882a593Smuzhiyun static int fsl_lpspi_transfer_one(struct spi_controller *controller,
712*4882a593Smuzhiyun struct spi_device *spi,
713*4882a593Smuzhiyun struct spi_transfer *t)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
716*4882a593Smuzhiyun spi_controller_get_devdata(controller);
717*4882a593Smuzhiyun int ret;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun fsl_lpspi->is_first_byte = true;
720*4882a593Smuzhiyun ret = fsl_lpspi_setup_transfer(controller, spi, t);
721*4882a593Smuzhiyun if (ret < 0)
722*4882a593Smuzhiyun return ret;
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun fsl_lpspi_set_cmd(fsl_lpspi);
725*4882a593Smuzhiyun fsl_lpspi->is_first_byte = false;
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun if (fsl_lpspi->usedma)
728*4882a593Smuzhiyun ret = fsl_lpspi_dma_transfer(controller, fsl_lpspi, t);
729*4882a593Smuzhiyun else
730*4882a593Smuzhiyun ret = fsl_lpspi_pio_transfer(controller, t);
731*4882a593Smuzhiyun if (ret < 0)
732*4882a593Smuzhiyun return ret;
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun return 0;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun
fsl_lpspi_isr(int irq,void * dev_id)737*4882a593Smuzhiyun static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
738*4882a593Smuzhiyun {
739*4882a593Smuzhiyun u32 temp_SR, temp_IER;
740*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi = dev_id;
741*4882a593Smuzhiyun
742*4882a593Smuzhiyun temp_IER = readl(fsl_lpspi->base + IMX7ULP_IER);
743*4882a593Smuzhiyun fsl_lpspi_intctrl(fsl_lpspi, 0);
744*4882a593Smuzhiyun temp_SR = readl(fsl_lpspi->base + IMX7ULP_SR);
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun fsl_lpspi_read_rx_fifo(fsl_lpspi);
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun if ((temp_SR & SR_TDF) && (temp_IER & IER_TDIE)) {
749*4882a593Smuzhiyun fsl_lpspi_write_tx_fifo(fsl_lpspi);
750*4882a593Smuzhiyun return IRQ_HANDLED;
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun if (temp_SR & SR_MBF ||
754*4882a593Smuzhiyun readl(fsl_lpspi->base + IMX7ULP_FSR) & FSR_TXCOUNT) {
755*4882a593Smuzhiyun writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
756*4882a593Smuzhiyun fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
757*4882a593Smuzhiyun return IRQ_HANDLED;
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun if (temp_SR & SR_FCF && (temp_IER & IER_FCIE)) {
761*4882a593Smuzhiyun writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
762*4882a593Smuzhiyun complete(&fsl_lpspi->xfer_done);
763*4882a593Smuzhiyun return IRQ_HANDLED;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun return IRQ_NONE;
767*4882a593Smuzhiyun }
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun #ifdef CONFIG_PM
fsl_lpspi_runtime_resume(struct device * dev)770*4882a593Smuzhiyun static int fsl_lpspi_runtime_resume(struct device *dev)
771*4882a593Smuzhiyun {
772*4882a593Smuzhiyun struct spi_controller *controller = dev_get_drvdata(dev);
773*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi;
774*4882a593Smuzhiyun int ret;
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun fsl_lpspi = spi_controller_get_devdata(controller);
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun ret = clk_prepare_enable(fsl_lpspi->clk_per);
779*4882a593Smuzhiyun if (ret)
780*4882a593Smuzhiyun return ret;
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun ret = clk_prepare_enable(fsl_lpspi->clk_ipg);
783*4882a593Smuzhiyun if (ret) {
784*4882a593Smuzhiyun clk_disable_unprepare(fsl_lpspi->clk_per);
785*4882a593Smuzhiyun return ret;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun return 0;
789*4882a593Smuzhiyun }
790*4882a593Smuzhiyun
fsl_lpspi_runtime_suspend(struct device * dev)791*4882a593Smuzhiyun static int fsl_lpspi_runtime_suspend(struct device *dev)
792*4882a593Smuzhiyun {
793*4882a593Smuzhiyun struct spi_controller *controller = dev_get_drvdata(dev);
794*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi;
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun fsl_lpspi = spi_controller_get_devdata(controller);
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun clk_disable_unprepare(fsl_lpspi->clk_per);
799*4882a593Smuzhiyun clk_disable_unprepare(fsl_lpspi->clk_ipg);
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun return 0;
802*4882a593Smuzhiyun }
803*4882a593Smuzhiyun #endif
804*4882a593Smuzhiyun
fsl_lpspi_init_rpm(struct fsl_lpspi_data * fsl_lpspi)805*4882a593Smuzhiyun static int fsl_lpspi_init_rpm(struct fsl_lpspi_data *fsl_lpspi)
806*4882a593Smuzhiyun {
807*4882a593Smuzhiyun struct device *dev = fsl_lpspi->dev;
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun pm_runtime_enable(dev);
810*4882a593Smuzhiyun pm_runtime_set_autosuspend_delay(dev, FSL_LPSPI_RPM_TIMEOUT);
811*4882a593Smuzhiyun pm_runtime_use_autosuspend(dev);
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun return 0;
814*4882a593Smuzhiyun }
815*4882a593Smuzhiyun
fsl_lpspi_probe(struct platform_device * pdev)816*4882a593Smuzhiyun static int fsl_lpspi_probe(struct platform_device *pdev)
817*4882a593Smuzhiyun {
818*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi;
819*4882a593Smuzhiyun struct spi_controller *controller;
820*4882a593Smuzhiyun struct resource *res;
821*4882a593Smuzhiyun int ret, irq;
822*4882a593Smuzhiyun u32 temp;
823*4882a593Smuzhiyun bool is_slave;
824*4882a593Smuzhiyun
825*4882a593Smuzhiyun is_slave = of_property_read_bool((&pdev->dev)->of_node, "spi-slave");
826*4882a593Smuzhiyun if (is_slave)
827*4882a593Smuzhiyun controller = spi_alloc_slave(&pdev->dev,
828*4882a593Smuzhiyun sizeof(struct fsl_lpspi_data));
829*4882a593Smuzhiyun else
830*4882a593Smuzhiyun controller = spi_alloc_master(&pdev->dev,
831*4882a593Smuzhiyun sizeof(struct fsl_lpspi_data));
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun if (!controller)
834*4882a593Smuzhiyun return -ENOMEM;
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun platform_set_drvdata(pdev, controller);
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun fsl_lpspi = spi_controller_get_devdata(controller);
839*4882a593Smuzhiyun fsl_lpspi->dev = &pdev->dev;
840*4882a593Smuzhiyun fsl_lpspi->is_slave = is_slave;
841*4882a593Smuzhiyun fsl_lpspi->is_only_cs1 = of_property_read_bool((&pdev->dev)->of_node,
842*4882a593Smuzhiyun "fsl,spi-only-use-cs1-sel");
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
845*4882a593Smuzhiyun controller->transfer_one = fsl_lpspi_transfer_one;
846*4882a593Smuzhiyun controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
847*4882a593Smuzhiyun controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
848*4882a593Smuzhiyun controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
849*4882a593Smuzhiyun controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
850*4882a593Smuzhiyun controller->dev.of_node = pdev->dev.of_node;
851*4882a593Smuzhiyun controller->bus_num = pdev->id;
852*4882a593Smuzhiyun controller->slave_abort = fsl_lpspi_slave_abort;
853*4882a593Smuzhiyun if (!fsl_lpspi->is_slave)
854*4882a593Smuzhiyun controller->use_gpio_descriptors = true;
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun init_completion(&fsl_lpspi->xfer_done);
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
859*4882a593Smuzhiyun fsl_lpspi->base = devm_ioremap_resource(&pdev->dev, res);
860*4882a593Smuzhiyun if (IS_ERR(fsl_lpspi->base)) {
861*4882a593Smuzhiyun ret = PTR_ERR(fsl_lpspi->base);
862*4882a593Smuzhiyun goto out_controller_put;
863*4882a593Smuzhiyun }
864*4882a593Smuzhiyun fsl_lpspi->base_phys = res->start;
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
867*4882a593Smuzhiyun if (irq < 0) {
868*4882a593Smuzhiyun ret = irq;
869*4882a593Smuzhiyun goto out_controller_put;
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0,
873*4882a593Smuzhiyun dev_name(&pdev->dev), fsl_lpspi);
874*4882a593Smuzhiyun if (ret) {
875*4882a593Smuzhiyun dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
876*4882a593Smuzhiyun goto out_controller_put;
877*4882a593Smuzhiyun }
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun fsl_lpspi->clk_per = devm_clk_get(&pdev->dev, "per");
880*4882a593Smuzhiyun if (IS_ERR(fsl_lpspi->clk_per)) {
881*4882a593Smuzhiyun ret = PTR_ERR(fsl_lpspi->clk_per);
882*4882a593Smuzhiyun goto out_controller_put;
883*4882a593Smuzhiyun }
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun fsl_lpspi->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
886*4882a593Smuzhiyun if (IS_ERR(fsl_lpspi->clk_ipg)) {
887*4882a593Smuzhiyun ret = PTR_ERR(fsl_lpspi->clk_ipg);
888*4882a593Smuzhiyun goto out_controller_put;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun /* enable the clock */
892*4882a593Smuzhiyun ret = fsl_lpspi_init_rpm(fsl_lpspi);
893*4882a593Smuzhiyun if (ret)
894*4882a593Smuzhiyun goto out_controller_put;
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun ret = pm_runtime_get_sync(fsl_lpspi->dev);
897*4882a593Smuzhiyun if (ret < 0) {
898*4882a593Smuzhiyun dev_err(fsl_lpspi->dev, "failed to enable clock\n");
899*4882a593Smuzhiyun goto out_pm_get;
900*4882a593Smuzhiyun }
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun temp = readl(fsl_lpspi->base + IMX7ULP_PARAM);
903*4882a593Smuzhiyun fsl_lpspi->txfifosize = 1 << (temp & 0x0f);
904*4882a593Smuzhiyun fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f);
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
907*4882a593Smuzhiyun if (ret == -EPROBE_DEFER)
908*4882a593Smuzhiyun goto out_pm_get;
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun if (ret < 0)
911*4882a593Smuzhiyun dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
912*4882a593Smuzhiyun
913*4882a593Smuzhiyun ret = devm_spi_register_controller(&pdev->dev, controller);
914*4882a593Smuzhiyun if (ret < 0) {
915*4882a593Smuzhiyun dev_err(&pdev->dev, "spi_register_controller error.\n");
916*4882a593Smuzhiyun goto out_pm_get;
917*4882a593Smuzhiyun }
918*4882a593Smuzhiyun
919*4882a593Smuzhiyun pm_runtime_mark_last_busy(fsl_lpspi->dev);
920*4882a593Smuzhiyun pm_runtime_put_autosuspend(fsl_lpspi->dev);
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun return 0;
923*4882a593Smuzhiyun
924*4882a593Smuzhiyun out_pm_get:
925*4882a593Smuzhiyun pm_runtime_dont_use_autosuspend(fsl_lpspi->dev);
926*4882a593Smuzhiyun pm_runtime_put_sync(fsl_lpspi->dev);
927*4882a593Smuzhiyun pm_runtime_disable(fsl_lpspi->dev);
928*4882a593Smuzhiyun out_controller_put:
929*4882a593Smuzhiyun spi_controller_put(controller);
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun return ret;
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
fsl_lpspi_remove(struct platform_device * pdev)934*4882a593Smuzhiyun static int fsl_lpspi_remove(struct platform_device *pdev)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun struct spi_controller *controller = platform_get_drvdata(pdev);
937*4882a593Smuzhiyun struct fsl_lpspi_data *fsl_lpspi =
938*4882a593Smuzhiyun spi_controller_get_devdata(controller);
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun pm_runtime_disable(fsl_lpspi->dev);
941*4882a593Smuzhiyun return 0;
942*4882a593Smuzhiyun }
943*4882a593Smuzhiyun
fsl_lpspi_suspend(struct device * dev)944*4882a593Smuzhiyun static int __maybe_unused fsl_lpspi_suspend(struct device *dev)
945*4882a593Smuzhiyun {
946*4882a593Smuzhiyun int ret;
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun pinctrl_pm_select_sleep_state(dev);
949*4882a593Smuzhiyun ret = pm_runtime_force_suspend(dev);
950*4882a593Smuzhiyun return ret;
951*4882a593Smuzhiyun }
952*4882a593Smuzhiyun
fsl_lpspi_resume(struct device * dev)953*4882a593Smuzhiyun static int __maybe_unused fsl_lpspi_resume(struct device *dev)
954*4882a593Smuzhiyun {
955*4882a593Smuzhiyun int ret;
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun ret = pm_runtime_force_resume(dev);
958*4882a593Smuzhiyun if (ret) {
959*4882a593Smuzhiyun dev_err(dev, "Error in resume: %d\n", ret);
960*4882a593Smuzhiyun return ret;
961*4882a593Smuzhiyun }
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun pinctrl_pm_select_default_state(dev);
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun return 0;
966*4882a593Smuzhiyun }
967*4882a593Smuzhiyun
968*4882a593Smuzhiyun static const struct dev_pm_ops fsl_lpspi_pm_ops = {
969*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(fsl_lpspi_runtime_suspend,
970*4882a593Smuzhiyun fsl_lpspi_runtime_resume, NULL)
971*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(fsl_lpspi_suspend, fsl_lpspi_resume)
972*4882a593Smuzhiyun };
973*4882a593Smuzhiyun
974*4882a593Smuzhiyun static struct platform_driver fsl_lpspi_driver = {
975*4882a593Smuzhiyun .driver = {
976*4882a593Smuzhiyun .name = DRIVER_NAME,
977*4882a593Smuzhiyun .of_match_table = fsl_lpspi_dt_ids,
978*4882a593Smuzhiyun .pm = &fsl_lpspi_pm_ops,
979*4882a593Smuzhiyun },
980*4882a593Smuzhiyun .probe = fsl_lpspi_probe,
981*4882a593Smuzhiyun .remove = fsl_lpspi_remove,
982*4882a593Smuzhiyun };
983*4882a593Smuzhiyun module_platform_driver(fsl_lpspi_driver);
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun MODULE_DESCRIPTION("LPSPI Controller driver");
986*4882a593Smuzhiyun MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
987*4882a593Smuzhiyun MODULE_LICENSE("GPL");
988