1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * MPC52xx PSC in SPI mode driver. |
4 | * |
5 | * Maintainer: Dragos Carp |
6 | * |
7 | * Copyright (C) 2006 TOPTICA Photonics AG. |
8 | */ |
9 | |
10 | #include <linux/module.h> |
11 | #include <linux/types.h> |
12 | #include <linux/errno.h> |
13 | #include <linux/interrupt.h> |
14 | #include <linux/platform_device.h> |
15 | #include <linux/property.h> |
16 | #include <linux/workqueue.h> |
17 | #include <linux/completion.h> |
18 | #include <linux/io.h> |
19 | #include <linux/delay.h> |
20 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> |
22 | |
23 | #include <asm/mpc52xx.h> |
24 | #include <asm/mpc52xx_psc.h> |
25 | |
26 | #define MCLK 20000000 /* PSC port MClk in hz */ |
27 | |
28 | struct mpc52xx_psc_spi { |
29 | /* driver internal data */ |
30 | struct mpc52xx_psc __iomem *psc; |
31 | struct mpc52xx_psc_fifo __iomem *fifo; |
32 | int irq; |
33 | u8 bits_per_word; |
34 | |
35 | struct completion done; |
36 | }; |
37 | |
38 | /* controller state */ |
39 | struct mpc52xx_psc_spi_cs { |
40 | int bits_per_word; |
41 | int speed_hz; |
42 | }; |
43 | |
44 | /* set clock freq, clock ramp, bits per work |
45 | * if t is NULL then reset the values to the default values |
46 | */ |
47 | static int mpc52xx_psc_spi_transfer_setup(struct spi_device *spi, |
48 | struct spi_transfer *t) |
49 | { |
50 | struct mpc52xx_psc_spi_cs *cs = spi->controller_state; |
51 | |
52 | cs->speed_hz = (t && t->speed_hz) |
53 | ? t->speed_hz : spi->max_speed_hz; |
54 | cs->bits_per_word = (t && t->bits_per_word) |
55 | ? t->bits_per_word : spi->bits_per_word; |
56 | cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8; |
57 | return 0; |
58 | } |
59 | |
60 | static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi) |
61 | { |
62 | struct mpc52xx_psc_spi_cs *cs = spi->controller_state; |
63 | struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(ctlr: spi->controller); |
64 | struct mpc52xx_psc __iomem *psc = mps->psc; |
65 | u32 sicr; |
66 | u16 ccr; |
67 | |
68 | sicr = in_be32(&psc->sicr); |
69 | |
70 | /* Set clock phase and polarity */ |
71 | if (spi->mode & SPI_CPHA) |
72 | sicr |= 0x00001000; |
73 | else |
74 | sicr &= ~0x00001000; |
75 | if (spi->mode & SPI_CPOL) |
76 | sicr |= 0x00002000; |
77 | else |
78 | sicr &= ~0x00002000; |
79 | |
80 | if (spi->mode & SPI_LSB_FIRST) |
81 | sicr |= 0x10000000; |
82 | else |
83 | sicr &= ~0x10000000; |
84 | out_be32(&psc->sicr, sicr); |
85 | |
86 | /* Set clock frequency and bits per word |
87 | * Because psc->ccr is defined as 16bit register instead of 32bit |
88 | * just set the lower byte of BitClkDiv |
89 | */ |
90 | ccr = in_be16((u16 __iomem *)&psc->ccr); |
91 | ccr &= 0xFF00; |
92 | if (cs->speed_hz) |
93 | ccr |= (MCLK / cs->speed_hz - 1) & 0xFF; |
94 | else /* by default SPI Clk 1MHz */ |
95 | ccr |= (MCLK / 1000000 - 1) & 0xFF; |
96 | out_be16((u16 __iomem *)&psc->ccr, ccr); |
97 | mps->bits_per_word = cs->bits_per_word; |
98 | } |
99 | |
100 | #define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1) |
101 | /* wake up when 80% fifo full */ |
102 | #define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100) |
103 | |
104 | static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, |
105 | struct spi_transfer *t) |
106 | { |
107 | struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(ctlr: spi->controller); |
108 | struct mpc52xx_psc __iomem *psc = mps->psc; |
109 | struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; |
110 | unsigned rb = 0; /* number of bytes receieved */ |
111 | unsigned sb = 0; /* number of bytes sent */ |
112 | unsigned char *rx_buf = (unsigned char *)t->rx_buf; |
113 | unsigned char *tx_buf = (unsigned char *)t->tx_buf; |
114 | unsigned rfalarm; |
115 | unsigned send_at_once = MPC52xx_PSC_BUFSIZE; |
116 | unsigned recv_at_once; |
117 | int last_block = 0; |
118 | |
119 | if (!t->tx_buf && !t->rx_buf && t->len) |
120 | return -EINVAL; |
121 | |
122 | /* enable transmiter/receiver */ |
123 | out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); |
124 | while (rb < t->len) { |
125 | if (t->len - rb > MPC52xx_PSC_BUFSIZE) { |
126 | rfalarm = MPC52xx_PSC_RFALARM; |
127 | last_block = 0; |
128 | } else { |
129 | send_at_once = t->len - sb; |
130 | rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb); |
131 | last_block = 1; |
132 | } |
133 | |
134 | dev_dbg(&spi->dev, "send %d bytes...\n" , send_at_once); |
135 | for (; send_at_once; sb++, send_at_once--) { |
136 | /* set EOF flag before the last word is sent */ |
137 | if (send_at_once == 1 && last_block) |
138 | out_8(&psc->ircr2, 0x01); |
139 | |
140 | if (tx_buf) |
141 | out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]); |
142 | else |
143 | out_8(&psc->mpc52xx_psc_buffer_8, 0); |
144 | } |
145 | |
146 | |
147 | /* enable interrupts and wait for wake up |
148 | * if just one byte is expected the Rx FIFO genererates no |
149 | * FFULL interrupt, so activate the RxRDY interrupt |
150 | */ |
151 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
152 | if (t->len - rb == 1) { |
153 | out_8(&psc->mode, 0); |
154 | } else { |
155 | out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); |
156 | out_be16(&fifo->rfalarm, rfalarm); |
157 | } |
158 | out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY); |
159 | wait_for_completion(&mps->done); |
160 | recv_at_once = in_be16(&fifo->rfnum); |
161 | dev_dbg(&spi->dev, "%d bytes received\n" , recv_at_once); |
162 | |
163 | send_at_once = recv_at_once; |
164 | if (rx_buf) { |
165 | for (; recv_at_once; rb++, recv_at_once--) |
166 | rx_buf[rb] = in_8(&psc->mpc52xx_psc_buffer_8); |
167 | } else { |
168 | for (; recv_at_once; rb++, recv_at_once--) |
169 | in_8(&psc->mpc52xx_psc_buffer_8); |
170 | } |
171 | } |
172 | /* disable transmiter/receiver */ |
173 | out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); |
174 | |
175 | return 0; |
176 | } |
177 | |
178 | static int mpc52xx_psc_spi_transfer_one_message(struct spi_controller *ctlr, |
179 | struct spi_message *m) |
180 | { |
181 | struct spi_device *spi; |
182 | struct spi_transfer *t = NULL; |
183 | unsigned cs_change; |
184 | int status; |
185 | |
186 | spi = m->spi; |
187 | cs_change = 1; |
188 | status = 0; |
189 | list_for_each_entry (t, &m->transfers, transfer_list) { |
190 | if (t->bits_per_word || t->speed_hz) { |
191 | status = mpc52xx_psc_spi_transfer_setup(spi, t); |
192 | if (status < 0) |
193 | break; |
194 | } |
195 | |
196 | if (cs_change) |
197 | mpc52xx_psc_spi_activate_cs(spi); |
198 | cs_change = t->cs_change; |
199 | |
200 | status = mpc52xx_psc_spi_transfer_rxtx(spi, t); |
201 | if (status) |
202 | break; |
203 | m->actual_length += t->len; |
204 | |
205 | spi_transfer_delay_exec(t); |
206 | } |
207 | |
208 | m->status = status; |
209 | |
210 | mpc52xx_psc_spi_transfer_setup(spi, NULL); |
211 | |
212 | spi_finalize_current_message(ctlr); |
213 | |
214 | return 0; |
215 | } |
216 | |
217 | static int mpc52xx_psc_spi_setup(struct spi_device *spi) |
218 | { |
219 | struct mpc52xx_psc_spi_cs *cs = spi->controller_state; |
220 | |
221 | if (spi->bits_per_word%8) |
222 | return -EINVAL; |
223 | |
224 | if (!cs) { |
225 | cs = kzalloc(size: sizeof(*cs), GFP_KERNEL); |
226 | if (!cs) |
227 | return -ENOMEM; |
228 | spi->controller_state = cs; |
229 | } |
230 | |
231 | cs->bits_per_word = spi->bits_per_word; |
232 | cs->speed_hz = spi->max_speed_hz; |
233 | |
234 | return 0; |
235 | } |
236 | |
237 | static void mpc52xx_psc_spi_cleanup(struct spi_device *spi) |
238 | { |
239 | kfree(objp: spi->controller_state); |
240 | } |
241 | |
242 | static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) |
243 | { |
244 | struct mpc52xx_psc __iomem *psc = mps->psc; |
245 | struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; |
246 | u32 mclken_div; |
247 | int ret; |
248 | |
249 | /* default sysclk is 512MHz */ |
250 | mclken_div = 512000000 / MCLK; |
251 | ret = mpc52xx_set_psc_clkdiv(psc_id, mclken_div); |
252 | if (ret) |
253 | return ret; |
254 | |
255 | /* Reset the PSC into a known state */ |
256 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
257 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
258 | out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); |
259 | |
260 | /* Disable interrupts, interrupts are based on alarm level */ |
261 | out_be16(&psc->mpc52xx_psc_imr, 0); |
262 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
263 | out_8(&fifo->rfcntl, 0); |
264 | out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); |
265 | |
266 | /* Configure 8bit codec mode as a SPI host and use EOF flags */ |
267 | /* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */ |
268 | out_be32(&psc->sicr, 0x0180C800); |
269 | out_be16((u16 __iomem *)&psc->ccr, 0x070F); /* default SPI Clk 1MHz */ |
270 | |
271 | /* Set 2ms DTL delay */ |
272 | out_8(&psc->ctur, 0x00); |
273 | out_8(&psc->ctlr, 0x84); |
274 | |
275 | mps->bits_per_word = 8; |
276 | |
277 | return 0; |
278 | } |
279 | |
280 | static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id) |
281 | { |
282 | struct mpc52xx_psc_spi *mps = (struct mpc52xx_psc_spi *)dev_id; |
283 | struct mpc52xx_psc __iomem *psc = mps->psc; |
284 | |
285 | /* disable interrupt and wake up the work queue */ |
286 | if (in_be16(&psc->mpc52xx_psc_isr) & MPC52xx_PSC_IMR_RXRDY) { |
287 | out_be16(&psc->mpc52xx_psc_imr, 0); |
288 | complete(&mps->done); |
289 | return IRQ_HANDLED; |
290 | } |
291 | return IRQ_NONE; |
292 | } |
293 | |
294 | static int mpc52xx_psc_spi_of_probe(struct platform_device *pdev) |
295 | { |
296 | struct device *dev = &pdev->dev; |
297 | struct mpc52xx_psc_spi *mps; |
298 | struct spi_controller *host; |
299 | u32 bus_num; |
300 | int ret; |
301 | |
302 | host = devm_spi_alloc_host(dev, size: sizeof(*mps)); |
303 | if (host == NULL) |
304 | return -ENOMEM; |
305 | |
306 | dev_set_drvdata(dev, data: host); |
307 | mps = spi_controller_get_devdata(ctlr: host); |
308 | |
309 | /* the spi->mode bits understood by this driver: */ |
310 | host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; |
311 | |
312 | ret = device_property_read_u32(dev, propname: "cell-index" , val: &bus_num); |
313 | if (ret || bus_num > 5) |
314 | return dev_err_probe(dev, err: ret ? : -EINVAL, fmt: "Invalid cell-index property\n" ); |
315 | host->bus_num = bus_num + 1; |
316 | |
317 | host->num_chipselect = 255; |
318 | host->setup = mpc52xx_psc_spi_setup; |
319 | host->transfer_one_message = mpc52xx_psc_spi_transfer_one_message; |
320 | host->cleanup = mpc52xx_psc_spi_cleanup; |
321 | |
322 | device_set_node(dev: &host->dev, dev_fwnode(dev)); |
323 | |
324 | mps->psc = devm_platform_get_and_ioremap_resource(pdev, index: 0, NULL); |
325 | if (IS_ERR(ptr: mps->psc)) |
326 | return dev_err_probe(dev, err: PTR_ERR(ptr: mps->psc), fmt: "could not ioremap I/O port range\n" ); |
327 | |
328 | /* On the 5200, fifo regs are immediately ajacent to the psc regs */ |
329 | mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc); |
330 | |
331 | mps->irq = platform_get_irq(pdev, 0); |
332 | if (mps->irq < 0) |
333 | return mps->irq; |
334 | |
335 | ret = devm_request_irq(dev, irq: mps->irq, handler: mpc52xx_psc_spi_isr, irqflags: 0, |
336 | devname: "mpc52xx-psc-spi" , dev_id: mps); |
337 | if (ret) |
338 | return ret; |
339 | |
340 | ret = mpc52xx_psc_spi_port_config(psc_id: host->bus_num, mps); |
341 | if (ret < 0) |
342 | return dev_err_probe(dev, err: ret, fmt: "can't configure PSC! Is it capable of SPI?\n" ); |
343 | |
344 | init_completion(x: &mps->done); |
345 | |
346 | return devm_spi_register_controller(dev, ctlr: host); |
347 | } |
348 | |
349 | static const struct of_device_id mpc52xx_psc_spi_of_match[] = { |
350 | { .compatible = "fsl,mpc5200-psc-spi" , }, |
351 | { .compatible = "mpc5200-psc-spi" , }, /* old */ |
352 | {} |
353 | }; |
354 | |
355 | MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); |
356 | |
357 | static struct platform_driver mpc52xx_psc_spi_of_driver = { |
358 | .probe = mpc52xx_psc_spi_of_probe, |
359 | .driver = { |
360 | .name = "mpc52xx-psc-spi" , |
361 | .of_match_table = mpc52xx_psc_spi_of_match, |
362 | }, |
363 | }; |
364 | module_platform_driver(mpc52xx_psc_spi_of_driver); |
365 | |
366 | MODULE_AUTHOR("Dragos Carp" ); |
367 | MODULE_DESCRIPTION("MPC52xx PSC SPI Driver" ); |
368 | MODULE_LICENSE("GPL" ); |
369 | |