1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * SuperH MSIOF SPI Controller Interface
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2009 Magnus Damm
6*4882a593Smuzhiyun * Copyright (C) 2014 Renesas Electronics Corporation
7*4882a593Smuzhiyun * Copyright (C) 2014-2017 Glider bvba
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/bitmap.h>
11*4882a593Smuzhiyun #include <linux/clk.h>
12*4882a593Smuzhiyun #include <linux/completion.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun #include <linux/dma-mapping.h>
15*4882a593Smuzhiyun #include <linux/dmaengine.h>
16*4882a593Smuzhiyun #include <linux/err.h>
17*4882a593Smuzhiyun #include <linux/interrupt.h>
18*4882a593Smuzhiyun #include <linux/io.h>
19*4882a593Smuzhiyun #include <linux/iopoll.h>
20*4882a593Smuzhiyun #include <linux/kernel.h>
21*4882a593Smuzhiyun #include <linux/module.h>
22*4882a593Smuzhiyun #include <linux/of.h>
23*4882a593Smuzhiyun #include <linux/of_device.h>
24*4882a593Smuzhiyun #include <linux/platform_device.h>
25*4882a593Smuzhiyun #include <linux/pm_runtime.h>
26*4882a593Smuzhiyun #include <linux/sh_dma.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include <linux/spi/sh_msiof.h>
29*4882a593Smuzhiyun #include <linux/spi/spi.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include <asm/unaligned.h>
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun struct sh_msiof_chipdata {
34*4882a593Smuzhiyun u32 bits_per_word_mask;
35*4882a593Smuzhiyun u16 tx_fifo_size;
36*4882a593Smuzhiyun u16 rx_fifo_size;
37*4882a593Smuzhiyun u16 ctlr_flags;
38*4882a593Smuzhiyun u16 min_div_pow;
39*4882a593Smuzhiyun };
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun struct sh_msiof_spi_priv {
42*4882a593Smuzhiyun struct spi_controller *ctlr;
43*4882a593Smuzhiyun void __iomem *mapbase;
44*4882a593Smuzhiyun struct clk *clk;
45*4882a593Smuzhiyun struct platform_device *pdev;
46*4882a593Smuzhiyun struct sh_msiof_spi_info *info;
47*4882a593Smuzhiyun struct completion done;
48*4882a593Smuzhiyun struct completion done_txdma;
49*4882a593Smuzhiyun unsigned int tx_fifo_size;
50*4882a593Smuzhiyun unsigned int rx_fifo_size;
51*4882a593Smuzhiyun unsigned int min_div_pow;
52*4882a593Smuzhiyun void *tx_dma_page;
53*4882a593Smuzhiyun void *rx_dma_page;
54*4882a593Smuzhiyun dma_addr_t tx_dma_addr;
55*4882a593Smuzhiyun dma_addr_t rx_dma_addr;
56*4882a593Smuzhiyun bool native_cs_inited;
57*4882a593Smuzhiyun bool native_cs_high;
58*4882a593Smuzhiyun bool slave_aborted;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #define MAX_SS 3 /* Maximum number of native chip selects */
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define SITMDR1 0x00 /* Transmit Mode Register 1 */
64*4882a593Smuzhiyun #define SITMDR2 0x04 /* Transmit Mode Register 2 */
65*4882a593Smuzhiyun #define SITMDR3 0x08 /* Transmit Mode Register 3 */
66*4882a593Smuzhiyun #define SIRMDR1 0x10 /* Receive Mode Register 1 */
67*4882a593Smuzhiyun #define SIRMDR2 0x14 /* Receive Mode Register 2 */
68*4882a593Smuzhiyun #define SIRMDR3 0x18 /* Receive Mode Register 3 */
69*4882a593Smuzhiyun #define SITSCR 0x20 /* Transmit Clock Select Register */
70*4882a593Smuzhiyun #define SIRSCR 0x22 /* Receive Clock Select Register (SH, A1, APE6) */
71*4882a593Smuzhiyun #define SICTR 0x28 /* Control Register */
72*4882a593Smuzhiyun #define SIFCTR 0x30 /* FIFO Control Register */
73*4882a593Smuzhiyun #define SISTR 0x40 /* Status Register */
74*4882a593Smuzhiyun #define SIIER 0x44 /* Interrupt Enable Register */
75*4882a593Smuzhiyun #define SITDR1 0x48 /* Transmit Control Data Register 1 (SH, A1) */
76*4882a593Smuzhiyun #define SITDR2 0x4c /* Transmit Control Data Register 2 (SH, A1) */
77*4882a593Smuzhiyun #define SITFDR 0x50 /* Transmit FIFO Data Register */
78*4882a593Smuzhiyun #define SIRDR1 0x58 /* Receive Control Data Register 1 (SH, A1) */
79*4882a593Smuzhiyun #define SIRDR2 0x5c /* Receive Control Data Register 2 (SH, A1) */
80*4882a593Smuzhiyun #define SIRFDR 0x60 /* Receive FIFO Data Register */
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* SITMDR1 and SIRMDR1 */
83*4882a593Smuzhiyun #define SIMDR1_TRMD BIT(31) /* Transfer Mode (1 = Master mode) */
84*4882a593Smuzhiyun #define SIMDR1_SYNCMD_MASK GENMASK(29, 28) /* SYNC Mode */
85*4882a593Smuzhiyun #define SIMDR1_SYNCMD_SPI (2 << 28) /* Level mode/SPI */
86*4882a593Smuzhiyun #define SIMDR1_SYNCMD_LR (3 << 28) /* L/R mode */
87*4882a593Smuzhiyun #define SIMDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */
88*4882a593Smuzhiyun #define SIMDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */
89*4882a593Smuzhiyun #define SIMDR1_DTDL_SHIFT 20 /* Data Pin Bit Delay for MSIOF_SYNC */
90*4882a593Smuzhiyun #define SIMDR1_SYNCDL_SHIFT 16 /* Frame Sync Signal Timing Delay */
91*4882a593Smuzhiyun #define SIMDR1_FLD_MASK GENMASK(3, 2) /* Frame Sync Signal Interval (0-3) */
92*4882a593Smuzhiyun #define SIMDR1_FLD_SHIFT 2
93*4882a593Smuzhiyun #define SIMDR1_XXSTP BIT(0) /* Transmission/Reception Stop on FIFO */
94*4882a593Smuzhiyun /* SITMDR1 */
95*4882a593Smuzhiyun #define SITMDR1_PCON BIT(30) /* Transfer Signal Connection */
96*4882a593Smuzhiyun #define SITMDR1_SYNCCH_MASK GENMASK(27, 26) /* Sync Signal Channel Select */
97*4882a593Smuzhiyun #define SITMDR1_SYNCCH_SHIFT 26 /* 0=MSIOF_SYNC, 1=MSIOF_SS1, 2=MSIOF_SS2 */
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun /* SITMDR2 and SIRMDR2 */
100*4882a593Smuzhiyun #define SIMDR2_BITLEN1(i) (((i) - 1) << 24) /* Data Size (8-32 bits) */
101*4882a593Smuzhiyun #define SIMDR2_WDLEN1(i) (((i) - 1) << 16) /* Word Count (1-64/256 (SH, A1))) */
102*4882a593Smuzhiyun #define SIMDR2_GRPMASK1 BIT(0) /* Group Output Mask 1 (SH, A1) */
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /* SITSCR and SIRSCR */
105*4882a593Smuzhiyun #define SISCR_BRPS_MASK GENMASK(12, 8) /* Prescaler Setting (1-32) */
106*4882a593Smuzhiyun #define SISCR_BRPS(i) (((i) - 1) << 8)
107*4882a593Smuzhiyun #define SISCR_BRDV_MASK GENMASK(2, 0) /* Baud Rate Generator's Division Ratio */
108*4882a593Smuzhiyun #define SISCR_BRDV_DIV_2 0
109*4882a593Smuzhiyun #define SISCR_BRDV_DIV_4 1
110*4882a593Smuzhiyun #define SISCR_BRDV_DIV_8 2
111*4882a593Smuzhiyun #define SISCR_BRDV_DIV_16 3
112*4882a593Smuzhiyun #define SISCR_BRDV_DIV_32 4
113*4882a593Smuzhiyun #define SISCR_BRDV_DIV_1 7
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* SICTR */
116*4882a593Smuzhiyun #define SICTR_TSCKIZ_MASK GENMASK(31, 30) /* Transmit Clock I/O Polarity Select */
117*4882a593Smuzhiyun #define SICTR_TSCKIZ_SCK BIT(31) /* Disable SCK when TX disabled */
118*4882a593Smuzhiyun #define SICTR_TSCKIZ_POL_SHIFT 30 /* Transmit Clock Polarity */
119*4882a593Smuzhiyun #define SICTR_RSCKIZ_MASK GENMASK(29, 28) /* Receive Clock Polarity Select */
120*4882a593Smuzhiyun #define SICTR_RSCKIZ_SCK BIT(29) /* Must match CTR_TSCKIZ_SCK */
121*4882a593Smuzhiyun #define SICTR_RSCKIZ_POL_SHIFT 28 /* Receive Clock Polarity */
122*4882a593Smuzhiyun #define SICTR_TEDG_SHIFT 27 /* Transmit Timing (1 = falling edge) */
123*4882a593Smuzhiyun #define SICTR_REDG_SHIFT 26 /* Receive Timing (1 = falling edge) */
124*4882a593Smuzhiyun #define SICTR_TXDIZ_MASK GENMASK(23, 22) /* Pin Output When TX is Disabled */
125*4882a593Smuzhiyun #define SICTR_TXDIZ_LOW (0 << 22) /* 0 */
126*4882a593Smuzhiyun #define SICTR_TXDIZ_HIGH (1 << 22) /* 1 */
127*4882a593Smuzhiyun #define SICTR_TXDIZ_HIZ (2 << 22) /* High-impedance */
128*4882a593Smuzhiyun #define SICTR_TSCKE BIT(15) /* Transmit Serial Clock Output Enable */
129*4882a593Smuzhiyun #define SICTR_TFSE BIT(14) /* Transmit Frame Sync Signal Output Enable */
130*4882a593Smuzhiyun #define SICTR_TXE BIT(9) /* Transmit Enable */
131*4882a593Smuzhiyun #define SICTR_RXE BIT(8) /* Receive Enable */
132*4882a593Smuzhiyun #define SICTR_TXRST BIT(1) /* Transmit Reset */
133*4882a593Smuzhiyun #define SICTR_RXRST BIT(0) /* Receive Reset */
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /* SIFCTR */
136*4882a593Smuzhiyun #define SIFCTR_TFWM_MASK GENMASK(31, 29) /* Transmit FIFO Watermark */
137*4882a593Smuzhiyun #define SIFCTR_TFWM_64 (0 << 29) /* Transfer Request when 64 empty stages */
138*4882a593Smuzhiyun #define SIFCTR_TFWM_32 (1 << 29) /* Transfer Request when 32 empty stages */
139*4882a593Smuzhiyun #define SIFCTR_TFWM_24 (2 << 29) /* Transfer Request when 24 empty stages */
140*4882a593Smuzhiyun #define SIFCTR_TFWM_16 (3 << 29) /* Transfer Request when 16 empty stages */
141*4882a593Smuzhiyun #define SIFCTR_TFWM_12 (4 << 29) /* Transfer Request when 12 empty stages */
142*4882a593Smuzhiyun #define SIFCTR_TFWM_8 (5 << 29) /* Transfer Request when 8 empty stages */
143*4882a593Smuzhiyun #define SIFCTR_TFWM_4 (6 << 29) /* Transfer Request when 4 empty stages */
144*4882a593Smuzhiyun #define SIFCTR_TFWM_1 (7 << 29) /* Transfer Request when 1 empty stage */
145*4882a593Smuzhiyun #define SIFCTR_TFUA_MASK GENMASK(26, 20) /* Transmit FIFO Usable Area */
146*4882a593Smuzhiyun #define SIFCTR_TFUA_SHIFT 20
147*4882a593Smuzhiyun #define SIFCTR_TFUA(i) ((i) << SIFCTR_TFUA_SHIFT)
148*4882a593Smuzhiyun #define SIFCTR_RFWM_MASK GENMASK(15, 13) /* Receive FIFO Watermark */
149*4882a593Smuzhiyun #define SIFCTR_RFWM_1 (0 << 13) /* Transfer Request when 1 valid stages */
150*4882a593Smuzhiyun #define SIFCTR_RFWM_4 (1 << 13) /* Transfer Request when 4 valid stages */
151*4882a593Smuzhiyun #define SIFCTR_RFWM_8 (2 << 13) /* Transfer Request when 8 valid stages */
152*4882a593Smuzhiyun #define SIFCTR_RFWM_16 (3 << 13) /* Transfer Request when 16 valid stages */
153*4882a593Smuzhiyun #define SIFCTR_RFWM_32 (4 << 13) /* Transfer Request when 32 valid stages */
154*4882a593Smuzhiyun #define SIFCTR_RFWM_64 (5 << 13) /* Transfer Request when 64 valid stages */
155*4882a593Smuzhiyun #define SIFCTR_RFWM_128 (6 << 13) /* Transfer Request when 128 valid stages */
156*4882a593Smuzhiyun #define SIFCTR_RFWM_256 (7 << 13) /* Transfer Request when 256 valid stages */
157*4882a593Smuzhiyun #define SIFCTR_RFUA_MASK GENMASK(12, 4) /* Receive FIFO Usable Area (0x40 = full) */
158*4882a593Smuzhiyun #define SIFCTR_RFUA_SHIFT 4
159*4882a593Smuzhiyun #define SIFCTR_RFUA(i) ((i) << SIFCTR_RFUA_SHIFT)
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* SISTR */
162*4882a593Smuzhiyun #define SISTR_TFEMP BIT(29) /* Transmit FIFO Empty */
163*4882a593Smuzhiyun #define SISTR_TDREQ BIT(28) /* Transmit Data Transfer Request */
164*4882a593Smuzhiyun #define SISTR_TEOF BIT(23) /* Frame Transmission End */
165*4882a593Smuzhiyun #define SISTR_TFSERR BIT(21) /* Transmit Frame Synchronization Error */
166*4882a593Smuzhiyun #define SISTR_TFOVF BIT(20) /* Transmit FIFO Overflow */
167*4882a593Smuzhiyun #define SISTR_TFUDF BIT(19) /* Transmit FIFO Underflow */
168*4882a593Smuzhiyun #define SISTR_RFFUL BIT(13) /* Receive FIFO Full */
169*4882a593Smuzhiyun #define SISTR_RDREQ BIT(12) /* Receive Data Transfer Request */
170*4882a593Smuzhiyun #define SISTR_REOF BIT(7) /* Frame Reception End */
171*4882a593Smuzhiyun #define SISTR_RFSERR BIT(5) /* Receive Frame Synchronization Error */
172*4882a593Smuzhiyun #define SISTR_RFUDF BIT(4) /* Receive FIFO Underflow */
173*4882a593Smuzhiyun #define SISTR_RFOVF BIT(3) /* Receive FIFO Overflow */
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun /* SIIER */
176*4882a593Smuzhiyun #define SIIER_TDMAE BIT(31) /* Transmit Data DMA Transfer Req. Enable */
177*4882a593Smuzhiyun #define SIIER_TFEMPE BIT(29) /* Transmit FIFO Empty Enable */
178*4882a593Smuzhiyun #define SIIER_TDREQE BIT(28) /* Transmit Data Transfer Request Enable */
179*4882a593Smuzhiyun #define SIIER_TEOFE BIT(23) /* Frame Transmission End Enable */
180*4882a593Smuzhiyun #define SIIER_TFSERRE BIT(21) /* Transmit Frame Sync Error Enable */
181*4882a593Smuzhiyun #define SIIER_TFOVFE BIT(20) /* Transmit FIFO Overflow Enable */
182*4882a593Smuzhiyun #define SIIER_TFUDFE BIT(19) /* Transmit FIFO Underflow Enable */
183*4882a593Smuzhiyun #define SIIER_RDMAE BIT(15) /* Receive Data DMA Transfer Req. Enable */
184*4882a593Smuzhiyun #define SIIER_RFFULE BIT(13) /* Receive FIFO Full Enable */
185*4882a593Smuzhiyun #define SIIER_RDREQE BIT(12) /* Receive Data Transfer Request Enable */
186*4882a593Smuzhiyun #define SIIER_REOFE BIT(7) /* Frame Reception End Enable */
187*4882a593Smuzhiyun #define SIIER_RFSERRE BIT(5) /* Receive Frame Sync Error Enable */
188*4882a593Smuzhiyun #define SIIER_RFUDFE BIT(4) /* Receive FIFO Underflow Enable */
189*4882a593Smuzhiyun #define SIIER_RFOVFE BIT(3) /* Receive FIFO Overflow Enable */
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun
sh_msiof_read(struct sh_msiof_spi_priv * p,int reg_offs)192*4882a593Smuzhiyun static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun switch (reg_offs) {
195*4882a593Smuzhiyun case SITSCR:
196*4882a593Smuzhiyun case SIRSCR:
197*4882a593Smuzhiyun return ioread16(p->mapbase + reg_offs);
198*4882a593Smuzhiyun default:
199*4882a593Smuzhiyun return ioread32(p->mapbase + reg_offs);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
sh_msiof_write(struct sh_msiof_spi_priv * p,int reg_offs,u32 value)203*4882a593Smuzhiyun static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs,
204*4882a593Smuzhiyun u32 value)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun switch (reg_offs) {
207*4882a593Smuzhiyun case SITSCR:
208*4882a593Smuzhiyun case SIRSCR:
209*4882a593Smuzhiyun iowrite16(value, p->mapbase + reg_offs);
210*4882a593Smuzhiyun break;
211*4882a593Smuzhiyun default:
212*4882a593Smuzhiyun iowrite32(value, p->mapbase + reg_offs);
213*4882a593Smuzhiyun break;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun
sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv * p,u32 clr,u32 set)217*4882a593Smuzhiyun static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
218*4882a593Smuzhiyun u32 clr, u32 set)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun u32 mask = clr | set;
221*4882a593Smuzhiyun u32 data;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun data = sh_msiof_read(p, SICTR);
224*4882a593Smuzhiyun data &= ~clr;
225*4882a593Smuzhiyun data |= set;
226*4882a593Smuzhiyun sh_msiof_write(p, SICTR, data);
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun return readl_poll_timeout_atomic(p->mapbase + SICTR, data,
229*4882a593Smuzhiyun (data & mask) == set, 1, 100);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
sh_msiof_spi_irq(int irq,void * data)232*4882a593Smuzhiyun static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = data;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /* just disable the interrupt and wake up */
237*4882a593Smuzhiyun sh_msiof_write(p, SIIER, 0);
238*4882a593Smuzhiyun complete(&p->done);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun return IRQ_HANDLED;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv * p)243*4882a593Smuzhiyun static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun u32 mask = SICTR_TXRST | SICTR_RXRST;
246*4882a593Smuzhiyun u32 data;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun data = sh_msiof_read(p, SICTR);
249*4882a593Smuzhiyun data |= mask;
250*4882a593Smuzhiyun sh_msiof_write(p, SICTR, data);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun readl_poll_timeout_atomic(p->mapbase + SICTR, data, !(data & mask), 1,
253*4882a593Smuzhiyun 100);
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun static const u32 sh_msiof_spi_div_array[] = {
257*4882a593Smuzhiyun SISCR_BRDV_DIV_1, SISCR_BRDV_DIV_2, SISCR_BRDV_DIV_4,
258*4882a593Smuzhiyun SISCR_BRDV_DIV_8, SISCR_BRDV_DIV_16, SISCR_BRDV_DIV_32,
259*4882a593Smuzhiyun };
260*4882a593Smuzhiyun
sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv * p,unsigned long parent_rate,u32 spi_hz)261*4882a593Smuzhiyun static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
262*4882a593Smuzhiyun unsigned long parent_rate, u32 spi_hz)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun unsigned long div;
265*4882a593Smuzhiyun u32 brps, scr;
266*4882a593Smuzhiyun unsigned int div_pow = p->min_div_pow;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun if (!spi_hz || !parent_rate) {
269*4882a593Smuzhiyun WARN(1, "Invalid clock rate parameters %lu and %u\n",
270*4882a593Smuzhiyun parent_rate, spi_hz);
271*4882a593Smuzhiyun return;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun div = DIV_ROUND_UP(parent_rate, spi_hz);
275*4882a593Smuzhiyun if (div <= 1024) {
276*4882a593Smuzhiyun /* SISCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */
277*4882a593Smuzhiyun if (!div_pow && div <= 32 && div > 2)
278*4882a593Smuzhiyun div_pow = 1;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun if (div_pow)
281*4882a593Smuzhiyun brps = (div + 1) >> div_pow;
282*4882a593Smuzhiyun else
283*4882a593Smuzhiyun brps = div;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun for (; brps > 32; div_pow++)
286*4882a593Smuzhiyun brps = (brps + 1) >> 1;
287*4882a593Smuzhiyun } else {
288*4882a593Smuzhiyun /* Set transfer rate composite divisor to 2^5 * 32 = 1024 */
289*4882a593Smuzhiyun dev_err(&p->pdev->dev,
290*4882a593Smuzhiyun "Requested SPI transfer rate %d is too low\n", spi_hz);
291*4882a593Smuzhiyun div_pow = 5;
292*4882a593Smuzhiyun brps = 32;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun scr = sh_msiof_spi_div_array[div_pow] | SISCR_BRPS(brps);
296*4882a593Smuzhiyun sh_msiof_write(p, SITSCR, scr);
297*4882a593Smuzhiyun if (!(p->ctlr->flags & SPI_CONTROLLER_MUST_TX))
298*4882a593Smuzhiyun sh_msiof_write(p, SIRSCR, scr);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
sh_msiof_get_delay_bit(u32 dtdl_or_syncdl)301*4882a593Smuzhiyun static u32 sh_msiof_get_delay_bit(u32 dtdl_or_syncdl)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun /*
304*4882a593Smuzhiyun * DTDL/SYNCDL bit : p->info->dtdl or p->info->syncdl
305*4882a593Smuzhiyun * b'000 : 0
306*4882a593Smuzhiyun * b'001 : 100
307*4882a593Smuzhiyun * b'010 : 200
308*4882a593Smuzhiyun * b'011 (SYNCDL only) : 300
309*4882a593Smuzhiyun * b'101 : 50
310*4882a593Smuzhiyun * b'110 : 150
311*4882a593Smuzhiyun */
312*4882a593Smuzhiyun if (dtdl_or_syncdl % 100)
313*4882a593Smuzhiyun return dtdl_or_syncdl / 100 + 5;
314*4882a593Smuzhiyun else
315*4882a593Smuzhiyun return dtdl_or_syncdl / 100;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
sh_msiof_spi_get_dtdl_and_syncdl(struct sh_msiof_spi_priv * p)318*4882a593Smuzhiyun static u32 sh_msiof_spi_get_dtdl_and_syncdl(struct sh_msiof_spi_priv *p)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun u32 val;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun if (!p->info)
323*4882a593Smuzhiyun return 0;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /* check if DTDL and SYNCDL is allowed value */
326*4882a593Smuzhiyun if (p->info->dtdl > 200 || p->info->syncdl > 300) {
327*4882a593Smuzhiyun dev_warn(&p->pdev->dev, "DTDL or SYNCDL is too large\n");
328*4882a593Smuzhiyun return 0;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /* check if the sum of DTDL and SYNCDL becomes an integer value */
332*4882a593Smuzhiyun if ((p->info->dtdl + p->info->syncdl) % 100) {
333*4882a593Smuzhiyun dev_warn(&p->pdev->dev, "the sum of DTDL/SYNCDL is not good\n");
334*4882a593Smuzhiyun return 0;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun val = sh_msiof_get_delay_bit(p->info->dtdl) << SIMDR1_DTDL_SHIFT;
338*4882a593Smuzhiyun val |= sh_msiof_get_delay_bit(p->info->syncdl) << SIMDR1_SYNCDL_SHIFT;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun return val;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv * p,u32 ss,u32 cpol,u32 cpha,u32 tx_hi_z,u32 lsb_first,u32 cs_high)343*4882a593Smuzhiyun static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, u32 ss,
344*4882a593Smuzhiyun u32 cpol, u32 cpha,
345*4882a593Smuzhiyun u32 tx_hi_z, u32 lsb_first, u32 cs_high)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun u32 tmp;
348*4882a593Smuzhiyun int edge;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun /*
351*4882a593Smuzhiyun * CPOL CPHA TSCKIZ RSCKIZ TEDG REDG
352*4882a593Smuzhiyun * 0 0 10 10 1 1
353*4882a593Smuzhiyun * 0 1 10 10 0 0
354*4882a593Smuzhiyun * 1 0 11 11 0 0
355*4882a593Smuzhiyun * 1 1 11 11 1 1
356*4882a593Smuzhiyun */
357*4882a593Smuzhiyun tmp = SIMDR1_SYNCMD_SPI | 1 << SIMDR1_FLD_SHIFT | SIMDR1_XXSTP;
358*4882a593Smuzhiyun tmp |= !cs_high << SIMDR1_SYNCAC_SHIFT;
359*4882a593Smuzhiyun tmp |= lsb_first << SIMDR1_BITLSB_SHIFT;
360*4882a593Smuzhiyun tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p);
361*4882a593Smuzhiyun if (spi_controller_is_slave(p->ctlr)) {
362*4882a593Smuzhiyun sh_msiof_write(p, SITMDR1, tmp | SITMDR1_PCON);
363*4882a593Smuzhiyun } else {
364*4882a593Smuzhiyun sh_msiof_write(p, SITMDR1,
365*4882a593Smuzhiyun tmp | SIMDR1_TRMD | SITMDR1_PCON |
366*4882a593Smuzhiyun (ss < MAX_SS ? ss : 0) << SITMDR1_SYNCCH_SHIFT);
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun if (p->ctlr->flags & SPI_CONTROLLER_MUST_TX) {
369*4882a593Smuzhiyun /* These bits are reserved if RX needs TX */
370*4882a593Smuzhiyun tmp &= ~0x0000ffff;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun sh_msiof_write(p, SIRMDR1, tmp);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun tmp = 0;
375*4882a593Smuzhiyun tmp |= SICTR_TSCKIZ_SCK | cpol << SICTR_TSCKIZ_POL_SHIFT;
376*4882a593Smuzhiyun tmp |= SICTR_RSCKIZ_SCK | cpol << SICTR_RSCKIZ_POL_SHIFT;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun edge = cpol ^ !cpha;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun tmp |= edge << SICTR_TEDG_SHIFT;
381*4882a593Smuzhiyun tmp |= edge << SICTR_REDG_SHIFT;
382*4882a593Smuzhiyun tmp |= tx_hi_z ? SICTR_TXDIZ_HIZ : SICTR_TXDIZ_LOW;
383*4882a593Smuzhiyun sh_msiof_write(p, SICTR, tmp);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun
sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv * p,const void * tx_buf,void * rx_buf,u32 bits,u32 words)386*4882a593Smuzhiyun static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,
387*4882a593Smuzhiyun const void *tx_buf, void *rx_buf,
388*4882a593Smuzhiyun u32 bits, u32 words)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun u32 dr2 = SIMDR2_BITLEN1(bits) | SIMDR2_WDLEN1(words);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun if (tx_buf || (p->ctlr->flags & SPI_CONTROLLER_MUST_TX))
393*4882a593Smuzhiyun sh_msiof_write(p, SITMDR2, dr2);
394*4882a593Smuzhiyun else
395*4882a593Smuzhiyun sh_msiof_write(p, SITMDR2, dr2 | SIMDR2_GRPMASK1);
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun if (rx_buf)
398*4882a593Smuzhiyun sh_msiof_write(p, SIRMDR2, dr2);
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
sh_msiof_reset_str(struct sh_msiof_spi_priv * p)401*4882a593Smuzhiyun static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun sh_msiof_write(p, SISTR,
404*4882a593Smuzhiyun sh_msiof_read(p, SISTR) & ~(SISTR_TDREQ | SISTR_RDREQ));
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)407*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p,
408*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun const u8 *buf_8 = tx_buf;
411*4882a593Smuzhiyun int k;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun for (k = 0; k < words; k++)
414*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, buf_8[k] << fs);
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)417*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p,
418*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun const u16 *buf_16 = tx_buf;
421*4882a593Smuzhiyun int k;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun for (k = 0; k < words; k++)
424*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, buf_16[k] << fs);
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)427*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p,
428*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun const u16 *buf_16 = tx_buf;
431*4882a593Smuzhiyun int k;
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun for (k = 0; k < words; k++)
434*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, get_unaligned(&buf_16[k]) << fs);
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)437*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p,
438*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
439*4882a593Smuzhiyun {
440*4882a593Smuzhiyun const u32 *buf_32 = tx_buf;
441*4882a593Smuzhiyun int k;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun for (k = 0; k < words; k++)
444*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, buf_32[k] << fs);
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)447*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p,
448*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
449*4882a593Smuzhiyun {
450*4882a593Smuzhiyun const u32 *buf_32 = tx_buf;
451*4882a593Smuzhiyun int k;
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun for (k = 0; k < words; k++)
454*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, get_unaligned(&buf_32[k]) << fs);
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)457*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv *p,
458*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun const u32 *buf_32 = tx_buf;
461*4882a593Smuzhiyun int k;
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun for (k = 0; k < words; k++)
464*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, swab32(buf_32[k] << fs));
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun
sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv * p,const void * tx_buf,int words,int fs)467*4882a593Smuzhiyun static void sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv *p,
468*4882a593Smuzhiyun const void *tx_buf, int words, int fs)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun const u32 *buf_32 = tx_buf;
471*4882a593Smuzhiyun int k;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun for (k = 0; k < words; k++)
474*4882a593Smuzhiyun sh_msiof_write(p, SITFDR, swab32(get_unaligned(&buf_32[k]) << fs));
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)477*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p,
478*4882a593Smuzhiyun void *rx_buf, int words, int fs)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun u8 *buf_8 = rx_buf;
481*4882a593Smuzhiyun int k;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun for (k = 0; k < words; k++)
484*4882a593Smuzhiyun buf_8[k] = sh_msiof_read(p, SIRFDR) >> fs;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)487*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p,
488*4882a593Smuzhiyun void *rx_buf, int words, int fs)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun u16 *buf_16 = rx_buf;
491*4882a593Smuzhiyun int k;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun for (k = 0; k < words; k++)
494*4882a593Smuzhiyun buf_16[k] = sh_msiof_read(p, SIRFDR) >> fs;
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)497*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p,
498*4882a593Smuzhiyun void *rx_buf, int words, int fs)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun u16 *buf_16 = rx_buf;
501*4882a593Smuzhiyun int k;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun for (k = 0; k < words; k++)
504*4882a593Smuzhiyun put_unaligned(sh_msiof_read(p, SIRFDR) >> fs, &buf_16[k]);
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)507*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p,
508*4882a593Smuzhiyun void *rx_buf, int words, int fs)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun u32 *buf_32 = rx_buf;
511*4882a593Smuzhiyun int k;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun for (k = 0; k < words; k++)
514*4882a593Smuzhiyun buf_32[k] = sh_msiof_read(p, SIRFDR) >> fs;
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)517*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p,
518*4882a593Smuzhiyun void *rx_buf, int words, int fs)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun u32 *buf_32 = rx_buf;
521*4882a593Smuzhiyun int k;
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun for (k = 0; k < words; k++)
524*4882a593Smuzhiyun put_unaligned(sh_msiof_read(p, SIRFDR) >> fs, &buf_32[k]);
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)527*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv *p,
528*4882a593Smuzhiyun void *rx_buf, int words, int fs)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun u32 *buf_32 = rx_buf;
531*4882a593Smuzhiyun int k;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun for (k = 0; k < words; k++)
534*4882a593Smuzhiyun buf_32[k] = swab32(sh_msiof_read(p, SIRFDR) >> fs);
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv * p,void * rx_buf,int words,int fs)537*4882a593Smuzhiyun static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p,
538*4882a593Smuzhiyun void *rx_buf, int words, int fs)
539*4882a593Smuzhiyun {
540*4882a593Smuzhiyun u32 *buf_32 = rx_buf;
541*4882a593Smuzhiyun int k;
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun for (k = 0; k < words; k++)
544*4882a593Smuzhiyun put_unaligned(swab32(sh_msiof_read(p, SIRFDR) >> fs), &buf_32[k]);
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
sh_msiof_spi_setup(struct spi_device * spi)547*4882a593Smuzhiyun static int sh_msiof_spi_setup(struct spi_device *spi)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun struct sh_msiof_spi_priv *p =
550*4882a593Smuzhiyun spi_controller_get_devdata(spi->controller);
551*4882a593Smuzhiyun u32 clr, set, tmp;
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun if (spi->cs_gpiod || spi_controller_is_slave(p->ctlr))
554*4882a593Smuzhiyun return 0;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun if (p->native_cs_inited &&
557*4882a593Smuzhiyun (p->native_cs_high == !!(spi->mode & SPI_CS_HIGH)))
558*4882a593Smuzhiyun return 0;
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun /* Configure native chip select mode/polarity early */
561*4882a593Smuzhiyun clr = SIMDR1_SYNCMD_MASK;
562*4882a593Smuzhiyun set = SIMDR1_SYNCMD_SPI;
563*4882a593Smuzhiyun if (spi->mode & SPI_CS_HIGH)
564*4882a593Smuzhiyun clr |= BIT(SIMDR1_SYNCAC_SHIFT);
565*4882a593Smuzhiyun else
566*4882a593Smuzhiyun set |= BIT(SIMDR1_SYNCAC_SHIFT);
567*4882a593Smuzhiyun pm_runtime_get_sync(&p->pdev->dev);
568*4882a593Smuzhiyun tmp = sh_msiof_read(p, SITMDR1) & ~clr;
569*4882a593Smuzhiyun sh_msiof_write(p, SITMDR1, tmp | set | SIMDR1_TRMD | SITMDR1_PCON);
570*4882a593Smuzhiyun tmp = sh_msiof_read(p, SIRMDR1) & ~clr;
571*4882a593Smuzhiyun sh_msiof_write(p, SIRMDR1, tmp | set);
572*4882a593Smuzhiyun pm_runtime_put(&p->pdev->dev);
573*4882a593Smuzhiyun p->native_cs_high = spi->mode & SPI_CS_HIGH;
574*4882a593Smuzhiyun p->native_cs_inited = true;
575*4882a593Smuzhiyun return 0;
576*4882a593Smuzhiyun }
577*4882a593Smuzhiyun
sh_msiof_prepare_message(struct spi_controller * ctlr,struct spi_message * msg)578*4882a593Smuzhiyun static int sh_msiof_prepare_message(struct spi_controller *ctlr,
579*4882a593Smuzhiyun struct spi_message *msg)
580*4882a593Smuzhiyun {
581*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = spi_controller_get_devdata(ctlr);
582*4882a593Smuzhiyun const struct spi_device *spi = msg->spi;
583*4882a593Smuzhiyun u32 ss, cs_high;
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun /* Configure pins before asserting CS */
586*4882a593Smuzhiyun if (spi->cs_gpiod) {
587*4882a593Smuzhiyun ss = ctlr->unused_native_cs;
588*4882a593Smuzhiyun cs_high = p->native_cs_high;
589*4882a593Smuzhiyun } else {
590*4882a593Smuzhiyun ss = spi->chip_select;
591*4882a593Smuzhiyun cs_high = !!(spi->mode & SPI_CS_HIGH);
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun sh_msiof_spi_set_pin_regs(p, ss, !!(spi->mode & SPI_CPOL),
594*4882a593Smuzhiyun !!(spi->mode & SPI_CPHA),
595*4882a593Smuzhiyun !!(spi->mode & SPI_3WIRE),
596*4882a593Smuzhiyun !!(spi->mode & SPI_LSB_FIRST), cs_high);
597*4882a593Smuzhiyun return 0;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun
sh_msiof_spi_start(struct sh_msiof_spi_priv * p,void * rx_buf)600*4882a593Smuzhiyun static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
601*4882a593Smuzhiyun {
602*4882a593Smuzhiyun bool slave = spi_controller_is_slave(p->ctlr);
603*4882a593Smuzhiyun int ret = 0;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun /* setup clock and rx/tx signals */
606*4882a593Smuzhiyun if (!slave)
607*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, 0, SICTR_TSCKE);
608*4882a593Smuzhiyun if (rx_buf && !ret)
609*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, 0, SICTR_RXE);
610*4882a593Smuzhiyun if (!ret)
611*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, 0, SICTR_TXE);
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun /* start by setting frame bit */
614*4882a593Smuzhiyun if (!ret && !slave)
615*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, 0, SICTR_TFSE);
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun return ret;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun
sh_msiof_spi_stop(struct sh_msiof_spi_priv * p,void * rx_buf)620*4882a593Smuzhiyun static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun bool slave = spi_controller_is_slave(p->ctlr);
623*4882a593Smuzhiyun int ret = 0;
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun /* shut down frame, rx/tx and clock signals */
626*4882a593Smuzhiyun if (!slave)
627*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, SICTR_TFSE, 0);
628*4882a593Smuzhiyun if (!ret)
629*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, SICTR_TXE, 0);
630*4882a593Smuzhiyun if (rx_buf && !ret)
631*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, SICTR_RXE, 0);
632*4882a593Smuzhiyun if (!ret && !slave)
633*4882a593Smuzhiyun ret = sh_msiof_modify_ctr_wait(p, SICTR_TSCKE, 0);
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun return ret;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
sh_msiof_slave_abort(struct spi_controller * ctlr)638*4882a593Smuzhiyun static int sh_msiof_slave_abort(struct spi_controller *ctlr)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = spi_controller_get_devdata(ctlr);
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun p->slave_aborted = true;
643*4882a593Smuzhiyun complete(&p->done);
644*4882a593Smuzhiyun complete(&p->done_txdma);
645*4882a593Smuzhiyun return 0;
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
sh_msiof_wait_for_completion(struct sh_msiof_spi_priv * p,struct completion * x)648*4882a593Smuzhiyun static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p,
649*4882a593Smuzhiyun struct completion *x)
650*4882a593Smuzhiyun {
651*4882a593Smuzhiyun if (spi_controller_is_slave(p->ctlr)) {
652*4882a593Smuzhiyun if (wait_for_completion_interruptible(x) ||
653*4882a593Smuzhiyun p->slave_aborted) {
654*4882a593Smuzhiyun dev_dbg(&p->pdev->dev, "interrupted\n");
655*4882a593Smuzhiyun return -EINTR;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun } else {
658*4882a593Smuzhiyun if (!wait_for_completion_timeout(x, HZ)) {
659*4882a593Smuzhiyun dev_err(&p->pdev->dev, "timeout\n");
660*4882a593Smuzhiyun return -ETIMEDOUT;
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun return 0;
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun
sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv * p,void (* tx_fifo)(struct sh_msiof_spi_priv *,const void *,int,int),void (* rx_fifo)(struct sh_msiof_spi_priv *,void *,int,int),const void * tx_buf,void * rx_buf,int words,int bits)667*4882a593Smuzhiyun static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
668*4882a593Smuzhiyun void (*tx_fifo)(struct sh_msiof_spi_priv *,
669*4882a593Smuzhiyun const void *, int, int),
670*4882a593Smuzhiyun void (*rx_fifo)(struct sh_msiof_spi_priv *,
671*4882a593Smuzhiyun void *, int, int),
672*4882a593Smuzhiyun const void *tx_buf, void *rx_buf,
673*4882a593Smuzhiyun int words, int bits)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun int fifo_shift;
676*4882a593Smuzhiyun int ret;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun /* limit maximum word transfer to rx/tx fifo size */
679*4882a593Smuzhiyun if (tx_buf)
680*4882a593Smuzhiyun words = min_t(int, words, p->tx_fifo_size);
681*4882a593Smuzhiyun if (rx_buf)
682*4882a593Smuzhiyun words = min_t(int, words, p->rx_fifo_size);
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun /* the fifo contents need shifting */
685*4882a593Smuzhiyun fifo_shift = 32 - bits;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun /* default FIFO watermarks for PIO */
688*4882a593Smuzhiyun sh_msiof_write(p, SIFCTR, 0);
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun /* setup msiof transfer mode registers */
691*4882a593Smuzhiyun sh_msiof_spi_set_mode_regs(p, tx_buf, rx_buf, bits, words);
692*4882a593Smuzhiyun sh_msiof_write(p, SIIER, SIIER_TEOFE | SIIER_REOFE);
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun /* write tx fifo */
695*4882a593Smuzhiyun if (tx_buf)
696*4882a593Smuzhiyun tx_fifo(p, tx_buf, words, fifo_shift);
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun reinit_completion(&p->done);
699*4882a593Smuzhiyun p->slave_aborted = false;
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun ret = sh_msiof_spi_start(p, rx_buf);
702*4882a593Smuzhiyun if (ret) {
703*4882a593Smuzhiyun dev_err(&p->pdev->dev, "failed to start hardware\n");
704*4882a593Smuzhiyun goto stop_ier;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun /* wait for tx fifo to be emptied / rx fifo to be filled */
708*4882a593Smuzhiyun ret = sh_msiof_wait_for_completion(p, &p->done);
709*4882a593Smuzhiyun if (ret)
710*4882a593Smuzhiyun goto stop_reset;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun /* read rx fifo */
713*4882a593Smuzhiyun if (rx_buf)
714*4882a593Smuzhiyun rx_fifo(p, rx_buf, words, fifo_shift);
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun /* clear status bits */
717*4882a593Smuzhiyun sh_msiof_reset_str(p);
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun ret = sh_msiof_spi_stop(p, rx_buf);
720*4882a593Smuzhiyun if (ret) {
721*4882a593Smuzhiyun dev_err(&p->pdev->dev, "failed to shut down hardware\n");
722*4882a593Smuzhiyun return ret;
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun return words;
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun stop_reset:
728*4882a593Smuzhiyun sh_msiof_reset_str(p);
729*4882a593Smuzhiyun sh_msiof_spi_stop(p, rx_buf);
730*4882a593Smuzhiyun stop_ier:
731*4882a593Smuzhiyun sh_msiof_write(p, SIIER, 0);
732*4882a593Smuzhiyun return ret;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun
sh_msiof_dma_complete(void * arg)735*4882a593Smuzhiyun static void sh_msiof_dma_complete(void *arg)
736*4882a593Smuzhiyun {
737*4882a593Smuzhiyun complete(arg);
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun
sh_msiof_dma_once(struct sh_msiof_spi_priv * p,const void * tx,void * rx,unsigned int len)740*4882a593Smuzhiyun static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
741*4882a593Smuzhiyun void *rx, unsigned int len)
742*4882a593Smuzhiyun {
743*4882a593Smuzhiyun u32 ier_bits = 0;
744*4882a593Smuzhiyun struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
745*4882a593Smuzhiyun dma_cookie_t cookie;
746*4882a593Smuzhiyun int ret;
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun /* First prepare and submit the DMA request(s), as this may fail */
749*4882a593Smuzhiyun if (rx) {
750*4882a593Smuzhiyun ier_bits |= SIIER_RDREQE | SIIER_RDMAE;
751*4882a593Smuzhiyun desc_rx = dmaengine_prep_slave_single(p->ctlr->dma_rx,
752*4882a593Smuzhiyun p->rx_dma_addr, len, DMA_DEV_TO_MEM,
753*4882a593Smuzhiyun DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
754*4882a593Smuzhiyun if (!desc_rx)
755*4882a593Smuzhiyun return -EAGAIN;
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun desc_rx->callback = sh_msiof_dma_complete;
758*4882a593Smuzhiyun desc_rx->callback_param = &p->done;
759*4882a593Smuzhiyun cookie = dmaengine_submit(desc_rx);
760*4882a593Smuzhiyun if (dma_submit_error(cookie))
761*4882a593Smuzhiyun return cookie;
762*4882a593Smuzhiyun }
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun if (tx) {
765*4882a593Smuzhiyun ier_bits |= SIIER_TDREQE | SIIER_TDMAE;
766*4882a593Smuzhiyun dma_sync_single_for_device(p->ctlr->dma_tx->device->dev,
767*4882a593Smuzhiyun p->tx_dma_addr, len, DMA_TO_DEVICE);
768*4882a593Smuzhiyun desc_tx = dmaengine_prep_slave_single(p->ctlr->dma_tx,
769*4882a593Smuzhiyun p->tx_dma_addr, len, DMA_MEM_TO_DEV,
770*4882a593Smuzhiyun DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
771*4882a593Smuzhiyun if (!desc_tx) {
772*4882a593Smuzhiyun ret = -EAGAIN;
773*4882a593Smuzhiyun goto no_dma_tx;
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun desc_tx->callback = sh_msiof_dma_complete;
777*4882a593Smuzhiyun desc_tx->callback_param = &p->done_txdma;
778*4882a593Smuzhiyun cookie = dmaengine_submit(desc_tx);
779*4882a593Smuzhiyun if (dma_submit_error(cookie)) {
780*4882a593Smuzhiyun ret = cookie;
781*4882a593Smuzhiyun goto no_dma_tx;
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun /* 1 stage FIFO watermarks for DMA */
786*4882a593Smuzhiyun sh_msiof_write(p, SIFCTR, SIFCTR_TFWM_1 | SIFCTR_RFWM_1);
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun /* setup msiof transfer mode registers (32-bit words) */
789*4882a593Smuzhiyun sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun sh_msiof_write(p, SIIER, ier_bits);
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun reinit_completion(&p->done);
794*4882a593Smuzhiyun if (tx)
795*4882a593Smuzhiyun reinit_completion(&p->done_txdma);
796*4882a593Smuzhiyun p->slave_aborted = false;
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun /* Now start DMA */
799*4882a593Smuzhiyun if (rx)
800*4882a593Smuzhiyun dma_async_issue_pending(p->ctlr->dma_rx);
801*4882a593Smuzhiyun if (tx)
802*4882a593Smuzhiyun dma_async_issue_pending(p->ctlr->dma_tx);
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun ret = sh_msiof_spi_start(p, rx);
805*4882a593Smuzhiyun if (ret) {
806*4882a593Smuzhiyun dev_err(&p->pdev->dev, "failed to start hardware\n");
807*4882a593Smuzhiyun goto stop_dma;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun if (tx) {
811*4882a593Smuzhiyun /* wait for tx DMA completion */
812*4882a593Smuzhiyun ret = sh_msiof_wait_for_completion(p, &p->done_txdma);
813*4882a593Smuzhiyun if (ret)
814*4882a593Smuzhiyun goto stop_reset;
815*4882a593Smuzhiyun }
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun if (rx) {
818*4882a593Smuzhiyun /* wait for rx DMA completion */
819*4882a593Smuzhiyun ret = sh_msiof_wait_for_completion(p, &p->done);
820*4882a593Smuzhiyun if (ret)
821*4882a593Smuzhiyun goto stop_reset;
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun sh_msiof_write(p, SIIER, 0);
824*4882a593Smuzhiyun } else {
825*4882a593Smuzhiyun /* wait for tx fifo to be emptied */
826*4882a593Smuzhiyun sh_msiof_write(p, SIIER, SIIER_TEOFE);
827*4882a593Smuzhiyun ret = sh_msiof_wait_for_completion(p, &p->done);
828*4882a593Smuzhiyun if (ret)
829*4882a593Smuzhiyun goto stop_reset;
830*4882a593Smuzhiyun }
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun /* clear status bits */
833*4882a593Smuzhiyun sh_msiof_reset_str(p);
834*4882a593Smuzhiyun
835*4882a593Smuzhiyun ret = sh_msiof_spi_stop(p, rx);
836*4882a593Smuzhiyun if (ret) {
837*4882a593Smuzhiyun dev_err(&p->pdev->dev, "failed to shut down hardware\n");
838*4882a593Smuzhiyun return ret;
839*4882a593Smuzhiyun }
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun if (rx)
842*4882a593Smuzhiyun dma_sync_single_for_cpu(p->ctlr->dma_rx->device->dev,
843*4882a593Smuzhiyun p->rx_dma_addr, len, DMA_FROM_DEVICE);
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun return 0;
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun stop_reset:
848*4882a593Smuzhiyun sh_msiof_reset_str(p);
849*4882a593Smuzhiyun sh_msiof_spi_stop(p, rx);
850*4882a593Smuzhiyun stop_dma:
851*4882a593Smuzhiyun if (tx)
852*4882a593Smuzhiyun dmaengine_terminate_all(p->ctlr->dma_tx);
853*4882a593Smuzhiyun no_dma_tx:
854*4882a593Smuzhiyun if (rx)
855*4882a593Smuzhiyun dmaengine_terminate_all(p->ctlr->dma_rx);
856*4882a593Smuzhiyun sh_msiof_write(p, SIIER, 0);
857*4882a593Smuzhiyun return ret;
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun
copy_bswap32(u32 * dst,const u32 * src,unsigned int words)860*4882a593Smuzhiyun static void copy_bswap32(u32 *dst, const u32 *src, unsigned int words)
861*4882a593Smuzhiyun {
862*4882a593Smuzhiyun /* src or dst can be unaligned, but not both */
863*4882a593Smuzhiyun if ((unsigned long)src & 3) {
864*4882a593Smuzhiyun while (words--) {
865*4882a593Smuzhiyun *dst++ = swab32(get_unaligned(src));
866*4882a593Smuzhiyun src++;
867*4882a593Smuzhiyun }
868*4882a593Smuzhiyun } else if ((unsigned long)dst & 3) {
869*4882a593Smuzhiyun while (words--) {
870*4882a593Smuzhiyun put_unaligned(swab32(*src++), dst);
871*4882a593Smuzhiyun dst++;
872*4882a593Smuzhiyun }
873*4882a593Smuzhiyun } else {
874*4882a593Smuzhiyun while (words--)
875*4882a593Smuzhiyun *dst++ = swab32(*src++);
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun }
878*4882a593Smuzhiyun
copy_wswap32(u32 * dst,const u32 * src,unsigned int words)879*4882a593Smuzhiyun static void copy_wswap32(u32 *dst, const u32 *src, unsigned int words)
880*4882a593Smuzhiyun {
881*4882a593Smuzhiyun /* src or dst can be unaligned, but not both */
882*4882a593Smuzhiyun if ((unsigned long)src & 3) {
883*4882a593Smuzhiyun while (words--) {
884*4882a593Smuzhiyun *dst++ = swahw32(get_unaligned(src));
885*4882a593Smuzhiyun src++;
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun } else if ((unsigned long)dst & 3) {
888*4882a593Smuzhiyun while (words--) {
889*4882a593Smuzhiyun put_unaligned(swahw32(*src++), dst);
890*4882a593Smuzhiyun dst++;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun } else {
893*4882a593Smuzhiyun while (words--)
894*4882a593Smuzhiyun *dst++ = swahw32(*src++);
895*4882a593Smuzhiyun }
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun
copy_plain32(u32 * dst,const u32 * src,unsigned int words)898*4882a593Smuzhiyun static void copy_plain32(u32 *dst, const u32 *src, unsigned int words)
899*4882a593Smuzhiyun {
900*4882a593Smuzhiyun memcpy(dst, src, words * 4);
901*4882a593Smuzhiyun }
902*4882a593Smuzhiyun
sh_msiof_transfer_one(struct spi_controller * ctlr,struct spi_device * spi,struct spi_transfer * t)903*4882a593Smuzhiyun static int sh_msiof_transfer_one(struct spi_controller *ctlr,
904*4882a593Smuzhiyun struct spi_device *spi,
905*4882a593Smuzhiyun struct spi_transfer *t)
906*4882a593Smuzhiyun {
907*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = spi_controller_get_devdata(ctlr);
908*4882a593Smuzhiyun void (*copy32)(u32 *, const u32 *, unsigned int);
909*4882a593Smuzhiyun void (*tx_fifo)(struct sh_msiof_spi_priv *, const void *, int, int);
910*4882a593Smuzhiyun void (*rx_fifo)(struct sh_msiof_spi_priv *, void *, int, int);
911*4882a593Smuzhiyun const void *tx_buf = t->tx_buf;
912*4882a593Smuzhiyun void *rx_buf = t->rx_buf;
913*4882a593Smuzhiyun unsigned int len = t->len;
914*4882a593Smuzhiyun unsigned int bits = t->bits_per_word;
915*4882a593Smuzhiyun unsigned int bytes_per_word;
916*4882a593Smuzhiyun unsigned int words;
917*4882a593Smuzhiyun int n;
918*4882a593Smuzhiyun bool swab;
919*4882a593Smuzhiyun int ret;
920*4882a593Smuzhiyun
921*4882a593Smuzhiyun /* reset registers */
922*4882a593Smuzhiyun sh_msiof_spi_reset_regs(p);
923*4882a593Smuzhiyun
924*4882a593Smuzhiyun /* setup clocks (clock already enabled in chipselect()) */
925*4882a593Smuzhiyun if (!spi_controller_is_slave(p->ctlr))
926*4882a593Smuzhiyun sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz);
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun while (ctlr->dma_tx && len > 15) {
929*4882a593Smuzhiyun /*
930*4882a593Smuzhiyun * DMA supports 32-bit words only, hence pack 8-bit and 16-bit
931*4882a593Smuzhiyun * words, with byte resp. word swapping.
932*4882a593Smuzhiyun */
933*4882a593Smuzhiyun unsigned int l = 0;
934*4882a593Smuzhiyun
935*4882a593Smuzhiyun if (tx_buf)
936*4882a593Smuzhiyun l = min(round_down(len, 4), p->tx_fifo_size * 4);
937*4882a593Smuzhiyun if (rx_buf)
938*4882a593Smuzhiyun l = min(round_down(len, 4), p->rx_fifo_size * 4);
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun if (bits <= 8) {
941*4882a593Smuzhiyun copy32 = copy_bswap32;
942*4882a593Smuzhiyun } else if (bits <= 16) {
943*4882a593Smuzhiyun copy32 = copy_wswap32;
944*4882a593Smuzhiyun } else {
945*4882a593Smuzhiyun copy32 = copy_plain32;
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun if (tx_buf)
949*4882a593Smuzhiyun copy32(p->tx_dma_page, tx_buf, l / 4);
950*4882a593Smuzhiyun
951*4882a593Smuzhiyun ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l);
952*4882a593Smuzhiyun if (ret == -EAGAIN) {
953*4882a593Smuzhiyun dev_warn_once(&p->pdev->dev,
954*4882a593Smuzhiyun "DMA not available, falling back to PIO\n");
955*4882a593Smuzhiyun break;
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun if (ret)
958*4882a593Smuzhiyun return ret;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun if (rx_buf) {
961*4882a593Smuzhiyun copy32(rx_buf, p->rx_dma_page, l / 4);
962*4882a593Smuzhiyun rx_buf += l;
963*4882a593Smuzhiyun }
964*4882a593Smuzhiyun if (tx_buf)
965*4882a593Smuzhiyun tx_buf += l;
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun len -= l;
968*4882a593Smuzhiyun if (!len)
969*4882a593Smuzhiyun return 0;
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun if (bits <= 8 && len > 15) {
973*4882a593Smuzhiyun bits = 32;
974*4882a593Smuzhiyun swab = true;
975*4882a593Smuzhiyun } else {
976*4882a593Smuzhiyun swab = false;
977*4882a593Smuzhiyun }
978*4882a593Smuzhiyun
979*4882a593Smuzhiyun /* setup bytes per word and fifo read/write functions */
980*4882a593Smuzhiyun if (bits <= 8) {
981*4882a593Smuzhiyun bytes_per_word = 1;
982*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_8;
983*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_8;
984*4882a593Smuzhiyun } else if (bits <= 16) {
985*4882a593Smuzhiyun bytes_per_word = 2;
986*4882a593Smuzhiyun if ((unsigned long)tx_buf & 0x01)
987*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_16u;
988*4882a593Smuzhiyun else
989*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_16;
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun if ((unsigned long)rx_buf & 0x01)
992*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_16u;
993*4882a593Smuzhiyun else
994*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_16;
995*4882a593Smuzhiyun } else if (swab) {
996*4882a593Smuzhiyun bytes_per_word = 4;
997*4882a593Smuzhiyun if ((unsigned long)tx_buf & 0x03)
998*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_s32u;
999*4882a593Smuzhiyun else
1000*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_s32;
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun if ((unsigned long)rx_buf & 0x03)
1003*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_s32u;
1004*4882a593Smuzhiyun else
1005*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_s32;
1006*4882a593Smuzhiyun } else {
1007*4882a593Smuzhiyun bytes_per_word = 4;
1008*4882a593Smuzhiyun if ((unsigned long)tx_buf & 0x03)
1009*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_32u;
1010*4882a593Smuzhiyun else
1011*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_32;
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun if ((unsigned long)rx_buf & 0x03)
1014*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_32u;
1015*4882a593Smuzhiyun else
1016*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_32;
1017*4882a593Smuzhiyun }
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun /* transfer in fifo sized chunks */
1020*4882a593Smuzhiyun words = len / bytes_per_word;
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun while (words > 0) {
1023*4882a593Smuzhiyun n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo, tx_buf, rx_buf,
1024*4882a593Smuzhiyun words, bits);
1025*4882a593Smuzhiyun if (n < 0)
1026*4882a593Smuzhiyun return n;
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun if (tx_buf)
1029*4882a593Smuzhiyun tx_buf += n * bytes_per_word;
1030*4882a593Smuzhiyun if (rx_buf)
1031*4882a593Smuzhiyun rx_buf += n * bytes_per_word;
1032*4882a593Smuzhiyun words -= n;
1033*4882a593Smuzhiyun
1034*4882a593Smuzhiyun if (words == 0 && (len % bytes_per_word)) {
1035*4882a593Smuzhiyun words = len % bytes_per_word;
1036*4882a593Smuzhiyun bits = t->bits_per_word;
1037*4882a593Smuzhiyun bytes_per_word = 1;
1038*4882a593Smuzhiyun tx_fifo = sh_msiof_spi_write_fifo_8;
1039*4882a593Smuzhiyun rx_fifo = sh_msiof_spi_read_fifo_8;
1040*4882a593Smuzhiyun }
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun return 0;
1044*4882a593Smuzhiyun }
1045*4882a593Smuzhiyun
1046*4882a593Smuzhiyun static const struct sh_msiof_chipdata sh_data = {
1047*4882a593Smuzhiyun .bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32),
1048*4882a593Smuzhiyun .tx_fifo_size = 64,
1049*4882a593Smuzhiyun .rx_fifo_size = 64,
1050*4882a593Smuzhiyun .ctlr_flags = 0,
1051*4882a593Smuzhiyun .min_div_pow = 0,
1052*4882a593Smuzhiyun };
1053*4882a593Smuzhiyun
1054*4882a593Smuzhiyun static const struct sh_msiof_chipdata rcar_gen2_data = {
1055*4882a593Smuzhiyun .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) |
1056*4882a593Smuzhiyun SPI_BPW_MASK(24) | SPI_BPW_MASK(32),
1057*4882a593Smuzhiyun .tx_fifo_size = 64,
1058*4882a593Smuzhiyun .rx_fifo_size = 64,
1059*4882a593Smuzhiyun .ctlr_flags = SPI_CONTROLLER_MUST_TX,
1060*4882a593Smuzhiyun .min_div_pow = 0,
1061*4882a593Smuzhiyun };
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun static const struct sh_msiof_chipdata rcar_gen3_data = {
1064*4882a593Smuzhiyun .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) |
1065*4882a593Smuzhiyun SPI_BPW_MASK(24) | SPI_BPW_MASK(32),
1066*4882a593Smuzhiyun .tx_fifo_size = 64,
1067*4882a593Smuzhiyun .rx_fifo_size = 64,
1068*4882a593Smuzhiyun .ctlr_flags = SPI_CONTROLLER_MUST_TX,
1069*4882a593Smuzhiyun .min_div_pow = 1,
1070*4882a593Smuzhiyun };
1071*4882a593Smuzhiyun
1072*4882a593Smuzhiyun static const struct of_device_id sh_msiof_match[] = {
1073*4882a593Smuzhiyun { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data },
1074*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data },
1075*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7745", .data = &rcar_gen2_data },
1076*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7790", .data = &rcar_gen2_data },
1077*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7791", .data = &rcar_gen2_data },
1078*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7792", .data = &rcar_gen2_data },
1079*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data },
1080*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data },
1081*4882a593Smuzhiyun { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data },
1082*4882a593Smuzhiyun { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data },
1083*4882a593Smuzhiyun { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data },
1084*4882a593Smuzhiyun { .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */
1085*4882a593Smuzhiyun {},
1086*4882a593Smuzhiyun };
1087*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sh_msiof_match);
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun #ifdef CONFIG_OF
sh_msiof_spi_parse_dt(struct device * dev)1090*4882a593Smuzhiyun static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
1091*4882a593Smuzhiyun {
1092*4882a593Smuzhiyun struct sh_msiof_spi_info *info;
1093*4882a593Smuzhiyun struct device_node *np = dev->of_node;
1094*4882a593Smuzhiyun u32 num_cs = 1;
1095*4882a593Smuzhiyun
1096*4882a593Smuzhiyun info = devm_kzalloc(dev, sizeof(struct sh_msiof_spi_info), GFP_KERNEL);
1097*4882a593Smuzhiyun if (!info)
1098*4882a593Smuzhiyun return NULL;
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun info->mode = of_property_read_bool(np, "spi-slave") ? MSIOF_SPI_SLAVE
1101*4882a593Smuzhiyun : MSIOF_SPI_MASTER;
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun /* Parse the MSIOF properties */
1104*4882a593Smuzhiyun if (info->mode == MSIOF_SPI_MASTER)
1105*4882a593Smuzhiyun of_property_read_u32(np, "num-cs", &num_cs);
1106*4882a593Smuzhiyun of_property_read_u32(np, "renesas,tx-fifo-size",
1107*4882a593Smuzhiyun &info->tx_fifo_override);
1108*4882a593Smuzhiyun of_property_read_u32(np, "renesas,rx-fifo-size",
1109*4882a593Smuzhiyun &info->rx_fifo_override);
1110*4882a593Smuzhiyun of_property_read_u32(np, "renesas,dtdl", &info->dtdl);
1111*4882a593Smuzhiyun of_property_read_u32(np, "renesas,syncdl", &info->syncdl);
1112*4882a593Smuzhiyun
1113*4882a593Smuzhiyun info->num_chipselect = num_cs;
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun return info;
1116*4882a593Smuzhiyun }
1117*4882a593Smuzhiyun #else
sh_msiof_spi_parse_dt(struct device * dev)1118*4882a593Smuzhiyun static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
1119*4882a593Smuzhiyun {
1120*4882a593Smuzhiyun return NULL;
1121*4882a593Smuzhiyun }
1122*4882a593Smuzhiyun #endif
1123*4882a593Smuzhiyun
sh_msiof_request_dma_chan(struct device * dev,enum dma_transfer_direction dir,unsigned int id,dma_addr_t port_addr)1124*4882a593Smuzhiyun static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev,
1125*4882a593Smuzhiyun enum dma_transfer_direction dir, unsigned int id, dma_addr_t port_addr)
1126*4882a593Smuzhiyun {
1127*4882a593Smuzhiyun dma_cap_mask_t mask;
1128*4882a593Smuzhiyun struct dma_chan *chan;
1129*4882a593Smuzhiyun struct dma_slave_config cfg;
1130*4882a593Smuzhiyun int ret;
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun dma_cap_zero(mask);
1133*4882a593Smuzhiyun dma_cap_set(DMA_SLAVE, mask);
1134*4882a593Smuzhiyun
1135*4882a593Smuzhiyun chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
1136*4882a593Smuzhiyun (void *)(unsigned long)id, dev,
1137*4882a593Smuzhiyun dir == DMA_MEM_TO_DEV ? "tx" : "rx");
1138*4882a593Smuzhiyun if (!chan) {
1139*4882a593Smuzhiyun dev_warn(dev, "dma_request_slave_channel_compat failed\n");
1140*4882a593Smuzhiyun return NULL;
1141*4882a593Smuzhiyun }
1142*4882a593Smuzhiyun
1143*4882a593Smuzhiyun memset(&cfg, 0, sizeof(cfg));
1144*4882a593Smuzhiyun cfg.direction = dir;
1145*4882a593Smuzhiyun if (dir == DMA_MEM_TO_DEV) {
1146*4882a593Smuzhiyun cfg.dst_addr = port_addr;
1147*4882a593Smuzhiyun cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1148*4882a593Smuzhiyun } else {
1149*4882a593Smuzhiyun cfg.src_addr = port_addr;
1150*4882a593Smuzhiyun cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1151*4882a593Smuzhiyun }
1152*4882a593Smuzhiyun
1153*4882a593Smuzhiyun ret = dmaengine_slave_config(chan, &cfg);
1154*4882a593Smuzhiyun if (ret) {
1155*4882a593Smuzhiyun dev_warn(dev, "dmaengine_slave_config failed %d\n", ret);
1156*4882a593Smuzhiyun dma_release_channel(chan);
1157*4882a593Smuzhiyun return NULL;
1158*4882a593Smuzhiyun }
1159*4882a593Smuzhiyun
1160*4882a593Smuzhiyun return chan;
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun
sh_msiof_request_dma(struct sh_msiof_spi_priv * p)1163*4882a593Smuzhiyun static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
1164*4882a593Smuzhiyun {
1165*4882a593Smuzhiyun struct platform_device *pdev = p->pdev;
1166*4882a593Smuzhiyun struct device *dev = &pdev->dev;
1167*4882a593Smuzhiyun const struct sh_msiof_spi_info *info = p->info;
1168*4882a593Smuzhiyun unsigned int dma_tx_id, dma_rx_id;
1169*4882a593Smuzhiyun const struct resource *res;
1170*4882a593Smuzhiyun struct spi_controller *ctlr;
1171*4882a593Smuzhiyun struct device *tx_dev, *rx_dev;
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun if (dev->of_node) {
1174*4882a593Smuzhiyun /* In the OF case we will get the slave IDs from the DT */
1175*4882a593Smuzhiyun dma_tx_id = 0;
1176*4882a593Smuzhiyun dma_rx_id = 0;
1177*4882a593Smuzhiyun } else if (info && info->dma_tx_id && info->dma_rx_id) {
1178*4882a593Smuzhiyun dma_tx_id = info->dma_tx_id;
1179*4882a593Smuzhiyun dma_rx_id = info->dma_rx_id;
1180*4882a593Smuzhiyun } else {
1181*4882a593Smuzhiyun /* The driver assumes no error */
1182*4882a593Smuzhiyun return 0;
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun
1185*4882a593Smuzhiyun /* The DMA engine uses the second register set, if present */
1186*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1187*4882a593Smuzhiyun if (!res)
1188*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1189*4882a593Smuzhiyun
1190*4882a593Smuzhiyun ctlr = p->ctlr;
1191*4882a593Smuzhiyun ctlr->dma_tx = sh_msiof_request_dma_chan(dev, DMA_MEM_TO_DEV,
1192*4882a593Smuzhiyun dma_tx_id, res->start + SITFDR);
1193*4882a593Smuzhiyun if (!ctlr->dma_tx)
1194*4882a593Smuzhiyun return -ENODEV;
1195*4882a593Smuzhiyun
1196*4882a593Smuzhiyun ctlr->dma_rx = sh_msiof_request_dma_chan(dev, DMA_DEV_TO_MEM,
1197*4882a593Smuzhiyun dma_rx_id, res->start + SIRFDR);
1198*4882a593Smuzhiyun if (!ctlr->dma_rx)
1199*4882a593Smuzhiyun goto free_tx_chan;
1200*4882a593Smuzhiyun
1201*4882a593Smuzhiyun p->tx_dma_page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
1202*4882a593Smuzhiyun if (!p->tx_dma_page)
1203*4882a593Smuzhiyun goto free_rx_chan;
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun p->rx_dma_page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
1206*4882a593Smuzhiyun if (!p->rx_dma_page)
1207*4882a593Smuzhiyun goto free_tx_page;
1208*4882a593Smuzhiyun
1209*4882a593Smuzhiyun tx_dev = ctlr->dma_tx->device->dev;
1210*4882a593Smuzhiyun p->tx_dma_addr = dma_map_single(tx_dev, p->tx_dma_page, PAGE_SIZE,
1211*4882a593Smuzhiyun DMA_TO_DEVICE);
1212*4882a593Smuzhiyun if (dma_mapping_error(tx_dev, p->tx_dma_addr))
1213*4882a593Smuzhiyun goto free_rx_page;
1214*4882a593Smuzhiyun
1215*4882a593Smuzhiyun rx_dev = ctlr->dma_rx->device->dev;
1216*4882a593Smuzhiyun p->rx_dma_addr = dma_map_single(rx_dev, p->rx_dma_page, PAGE_SIZE,
1217*4882a593Smuzhiyun DMA_FROM_DEVICE);
1218*4882a593Smuzhiyun if (dma_mapping_error(rx_dev, p->rx_dma_addr))
1219*4882a593Smuzhiyun goto unmap_tx_page;
1220*4882a593Smuzhiyun
1221*4882a593Smuzhiyun dev_info(dev, "DMA available");
1222*4882a593Smuzhiyun return 0;
1223*4882a593Smuzhiyun
1224*4882a593Smuzhiyun unmap_tx_page:
1225*4882a593Smuzhiyun dma_unmap_single(tx_dev, p->tx_dma_addr, PAGE_SIZE, DMA_TO_DEVICE);
1226*4882a593Smuzhiyun free_rx_page:
1227*4882a593Smuzhiyun free_page((unsigned long)p->rx_dma_page);
1228*4882a593Smuzhiyun free_tx_page:
1229*4882a593Smuzhiyun free_page((unsigned long)p->tx_dma_page);
1230*4882a593Smuzhiyun free_rx_chan:
1231*4882a593Smuzhiyun dma_release_channel(ctlr->dma_rx);
1232*4882a593Smuzhiyun free_tx_chan:
1233*4882a593Smuzhiyun dma_release_channel(ctlr->dma_tx);
1234*4882a593Smuzhiyun ctlr->dma_tx = NULL;
1235*4882a593Smuzhiyun return -ENODEV;
1236*4882a593Smuzhiyun }
1237*4882a593Smuzhiyun
sh_msiof_release_dma(struct sh_msiof_spi_priv * p)1238*4882a593Smuzhiyun static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p)
1239*4882a593Smuzhiyun {
1240*4882a593Smuzhiyun struct spi_controller *ctlr = p->ctlr;
1241*4882a593Smuzhiyun
1242*4882a593Smuzhiyun if (!ctlr->dma_tx)
1243*4882a593Smuzhiyun return;
1244*4882a593Smuzhiyun
1245*4882a593Smuzhiyun dma_unmap_single(ctlr->dma_rx->device->dev, p->rx_dma_addr, PAGE_SIZE,
1246*4882a593Smuzhiyun DMA_FROM_DEVICE);
1247*4882a593Smuzhiyun dma_unmap_single(ctlr->dma_tx->device->dev, p->tx_dma_addr, PAGE_SIZE,
1248*4882a593Smuzhiyun DMA_TO_DEVICE);
1249*4882a593Smuzhiyun free_page((unsigned long)p->rx_dma_page);
1250*4882a593Smuzhiyun free_page((unsigned long)p->tx_dma_page);
1251*4882a593Smuzhiyun dma_release_channel(ctlr->dma_rx);
1252*4882a593Smuzhiyun dma_release_channel(ctlr->dma_tx);
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun
sh_msiof_spi_probe(struct platform_device * pdev)1255*4882a593Smuzhiyun static int sh_msiof_spi_probe(struct platform_device *pdev)
1256*4882a593Smuzhiyun {
1257*4882a593Smuzhiyun struct spi_controller *ctlr;
1258*4882a593Smuzhiyun const struct sh_msiof_chipdata *chipdata;
1259*4882a593Smuzhiyun struct sh_msiof_spi_info *info;
1260*4882a593Smuzhiyun struct sh_msiof_spi_priv *p;
1261*4882a593Smuzhiyun int i;
1262*4882a593Smuzhiyun int ret;
1263*4882a593Smuzhiyun
1264*4882a593Smuzhiyun chipdata = of_device_get_match_data(&pdev->dev);
1265*4882a593Smuzhiyun if (chipdata) {
1266*4882a593Smuzhiyun info = sh_msiof_spi_parse_dt(&pdev->dev);
1267*4882a593Smuzhiyun } else {
1268*4882a593Smuzhiyun chipdata = (const void *)pdev->id_entry->driver_data;
1269*4882a593Smuzhiyun info = dev_get_platdata(&pdev->dev);
1270*4882a593Smuzhiyun }
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun if (!info) {
1273*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to obtain device info\n");
1274*4882a593Smuzhiyun return -ENXIO;
1275*4882a593Smuzhiyun }
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun if (info->mode == MSIOF_SPI_SLAVE)
1278*4882a593Smuzhiyun ctlr = spi_alloc_slave(&pdev->dev,
1279*4882a593Smuzhiyun sizeof(struct sh_msiof_spi_priv));
1280*4882a593Smuzhiyun else
1281*4882a593Smuzhiyun ctlr = spi_alloc_master(&pdev->dev,
1282*4882a593Smuzhiyun sizeof(struct sh_msiof_spi_priv));
1283*4882a593Smuzhiyun if (ctlr == NULL)
1284*4882a593Smuzhiyun return -ENOMEM;
1285*4882a593Smuzhiyun
1286*4882a593Smuzhiyun p = spi_controller_get_devdata(ctlr);
1287*4882a593Smuzhiyun
1288*4882a593Smuzhiyun platform_set_drvdata(pdev, p);
1289*4882a593Smuzhiyun p->ctlr = ctlr;
1290*4882a593Smuzhiyun p->info = info;
1291*4882a593Smuzhiyun p->min_div_pow = chipdata->min_div_pow;
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun init_completion(&p->done);
1294*4882a593Smuzhiyun init_completion(&p->done_txdma);
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun p->clk = devm_clk_get(&pdev->dev, NULL);
1297*4882a593Smuzhiyun if (IS_ERR(p->clk)) {
1298*4882a593Smuzhiyun dev_err(&pdev->dev, "cannot get clock\n");
1299*4882a593Smuzhiyun ret = PTR_ERR(p->clk);
1300*4882a593Smuzhiyun goto err1;
1301*4882a593Smuzhiyun }
1302*4882a593Smuzhiyun
1303*4882a593Smuzhiyun i = platform_get_irq(pdev, 0);
1304*4882a593Smuzhiyun if (i < 0) {
1305*4882a593Smuzhiyun ret = i;
1306*4882a593Smuzhiyun goto err1;
1307*4882a593Smuzhiyun }
1308*4882a593Smuzhiyun
1309*4882a593Smuzhiyun p->mapbase = devm_platform_ioremap_resource(pdev, 0);
1310*4882a593Smuzhiyun if (IS_ERR(p->mapbase)) {
1311*4882a593Smuzhiyun ret = PTR_ERR(p->mapbase);
1312*4882a593Smuzhiyun goto err1;
1313*4882a593Smuzhiyun }
1314*4882a593Smuzhiyun
1315*4882a593Smuzhiyun ret = devm_request_irq(&pdev->dev, i, sh_msiof_spi_irq, 0,
1316*4882a593Smuzhiyun dev_name(&pdev->dev), p);
1317*4882a593Smuzhiyun if (ret) {
1318*4882a593Smuzhiyun dev_err(&pdev->dev, "unable to request irq\n");
1319*4882a593Smuzhiyun goto err1;
1320*4882a593Smuzhiyun }
1321*4882a593Smuzhiyun
1322*4882a593Smuzhiyun p->pdev = pdev;
1323*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun /* Platform data may override FIFO sizes */
1326*4882a593Smuzhiyun p->tx_fifo_size = chipdata->tx_fifo_size;
1327*4882a593Smuzhiyun p->rx_fifo_size = chipdata->rx_fifo_size;
1328*4882a593Smuzhiyun if (p->info->tx_fifo_override)
1329*4882a593Smuzhiyun p->tx_fifo_size = p->info->tx_fifo_override;
1330*4882a593Smuzhiyun if (p->info->rx_fifo_override)
1331*4882a593Smuzhiyun p->rx_fifo_size = p->info->rx_fifo_override;
1332*4882a593Smuzhiyun
1333*4882a593Smuzhiyun /* init controller code */
1334*4882a593Smuzhiyun ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
1335*4882a593Smuzhiyun ctlr->mode_bits |= SPI_LSB_FIRST | SPI_3WIRE;
1336*4882a593Smuzhiyun ctlr->flags = chipdata->ctlr_flags;
1337*4882a593Smuzhiyun ctlr->bus_num = pdev->id;
1338*4882a593Smuzhiyun ctlr->num_chipselect = p->info->num_chipselect;
1339*4882a593Smuzhiyun ctlr->dev.of_node = pdev->dev.of_node;
1340*4882a593Smuzhiyun ctlr->setup = sh_msiof_spi_setup;
1341*4882a593Smuzhiyun ctlr->prepare_message = sh_msiof_prepare_message;
1342*4882a593Smuzhiyun ctlr->slave_abort = sh_msiof_slave_abort;
1343*4882a593Smuzhiyun ctlr->bits_per_word_mask = chipdata->bits_per_word_mask;
1344*4882a593Smuzhiyun ctlr->auto_runtime_pm = true;
1345*4882a593Smuzhiyun ctlr->transfer_one = sh_msiof_transfer_one;
1346*4882a593Smuzhiyun ctlr->use_gpio_descriptors = true;
1347*4882a593Smuzhiyun ctlr->max_native_cs = MAX_SS;
1348*4882a593Smuzhiyun
1349*4882a593Smuzhiyun ret = sh_msiof_request_dma(p);
1350*4882a593Smuzhiyun if (ret < 0)
1351*4882a593Smuzhiyun dev_warn(&pdev->dev, "DMA not available, using PIO\n");
1352*4882a593Smuzhiyun
1353*4882a593Smuzhiyun ret = devm_spi_register_controller(&pdev->dev, ctlr);
1354*4882a593Smuzhiyun if (ret < 0) {
1355*4882a593Smuzhiyun dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
1356*4882a593Smuzhiyun goto err2;
1357*4882a593Smuzhiyun }
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun return 0;
1360*4882a593Smuzhiyun
1361*4882a593Smuzhiyun err2:
1362*4882a593Smuzhiyun sh_msiof_release_dma(p);
1363*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
1364*4882a593Smuzhiyun err1:
1365*4882a593Smuzhiyun spi_controller_put(ctlr);
1366*4882a593Smuzhiyun return ret;
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun
sh_msiof_spi_remove(struct platform_device * pdev)1369*4882a593Smuzhiyun static int sh_msiof_spi_remove(struct platform_device *pdev)
1370*4882a593Smuzhiyun {
1371*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
1372*4882a593Smuzhiyun
1373*4882a593Smuzhiyun sh_msiof_release_dma(p);
1374*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
1375*4882a593Smuzhiyun return 0;
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun
1378*4882a593Smuzhiyun static const struct platform_device_id spi_driver_ids[] = {
1379*4882a593Smuzhiyun { "spi_sh_msiof", (kernel_ulong_t)&sh_data },
1380*4882a593Smuzhiyun {},
1381*4882a593Smuzhiyun };
1382*4882a593Smuzhiyun MODULE_DEVICE_TABLE(platform, spi_driver_ids);
1383*4882a593Smuzhiyun
1384*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
sh_msiof_spi_suspend(struct device * dev)1385*4882a593Smuzhiyun static int sh_msiof_spi_suspend(struct device *dev)
1386*4882a593Smuzhiyun {
1387*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = dev_get_drvdata(dev);
1388*4882a593Smuzhiyun
1389*4882a593Smuzhiyun return spi_controller_suspend(p->ctlr);
1390*4882a593Smuzhiyun }
1391*4882a593Smuzhiyun
sh_msiof_spi_resume(struct device * dev)1392*4882a593Smuzhiyun static int sh_msiof_spi_resume(struct device *dev)
1393*4882a593Smuzhiyun {
1394*4882a593Smuzhiyun struct sh_msiof_spi_priv *p = dev_get_drvdata(dev);
1395*4882a593Smuzhiyun
1396*4882a593Smuzhiyun return spi_controller_resume(p->ctlr);
1397*4882a593Smuzhiyun }
1398*4882a593Smuzhiyun
1399*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(sh_msiof_spi_pm_ops, sh_msiof_spi_suspend,
1400*4882a593Smuzhiyun sh_msiof_spi_resume);
1401*4882a593Smuzhiyun #define DEV_PM_OPS (&sh_msiof_spi_pm_ops)
1402*4882a593Smuzhiyun #else
1403*4882a593Smuzhiyun #define DEV_PM_OPS NULL
1404*4882a593Smuzhiyun #endif /* CONFIG_PM_SLEEP */
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun static struct platform_driver sh_msiof_spi_drv = {
1407*4882a593Smuzhiyun .probe = sh_msiof_spi_probe,
1408*4882a593Smuzhiyun .remove = sh_msiof_spi_remove,
1409*4882a593Smuzhiyun .id_table = spi_driver_ids,
1410*4882a593Smuzhiyun .driver = {
1411*4882a593Smuzhiyun .name = "spi_sh_msiof",
1412*4882a593Smuzhiyun .pm = DEV_PM_OPS,
1413*4882a593Smuzhiyun .of_match_table = of_match_ptr(sh_msiof_match),
1414*4882a593Smuzhiyun },
1415*4882a593Smuzhiyun };
1416*4882a593Smuzhiyun module_platform_driver(sh_msiof_spi_drv);
1417*4882a593Smuzhiyun
1418*4882a593Smuzhiyun MODULE_DESCRIPTION("SuperH MSIOF SPI Controller Interface Driver");
1419*4882a593Smuzhiyun MODULE_AUTHOR("Magnus Damm");
1420*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1421*4882a593Smuzhiyun MODULE_ALIAS("platform:spi_sh_msiof");
1422