aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Armstrong <narmstrong@baylibre.com>2017-05-23 09:39:33 -0400
committerMark Brown <broonie@kernel.org>2017-05-24 13:19:25 -0400
commit454fa271bc4e71090ef55087027c3f8701fadc5b (patch)
treecde774dec7343b86a559d03ed0ab03e82a665b28
parent01a330da0c0ea2971be039f74a2288cbd2d17fbf (diff)
spi: Add Meson SPICC driver
The SPICC hardware block on the Amlogic SoCs is Communication oriented and can do Full-Duplex 8- to 32-bit width SPI transfers up to 30MHz. The current driver only supportd the PIO transfer mode since the DMA seems broken on available hardware. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi-meson-spicc.c619
3 files changed, 627 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 1761c9004fc1..1dcb14ce6f38 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -393,6 +393,13 @@ config SPI_FSL_ESPI
393 From MPC8536, 85xx platform uses the controller, and all P10xx, 393 From MPC8536, 85xx platform uses the controller, and all P10xx,
394 P20xx, P30xx,P40xx, P50xx uses this controller. 394 P20xx, P30xx,P40xx, P50xx uses this controller.
395 395
396config SPI_MESON_SPICC
397 tristate "Amlogic Meson SPICC controller"
398 depends on ARCH_MESON || COMPILE_TEST
399 help
400 This enables master mode support for the SPICC (SPI communication
401 controller) available in Amlogic Meson SoCs.
402
396config SPI_MESON_SPIFC 403config SPI_MESON_SPIFC
397 tristate "Amlogic Meson SPIFC controller" 404 tristate "Amlogic Meson SPIFC controller"
398 depends on ARCH_MESON || COMPILE_TEST 405 depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index b375a7a89216..0d8c95e66a9b 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
53obj-$(CONFIG_SPI_JCORE) += spi-jcore.o 53obj-$(CONFIG_SPI_JCORE) += spi-jcore.o
54obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o 54obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
55obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o 55obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
56obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o
56obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o 57obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
57obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o 58obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
58obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o 59obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
new file mode 100644
index 000000000000..7f8429635502
--- /dev/null
+++ b/drivers/spi/spi-meson-spicc.c
@@ -0,0 +1,619 @@
1/*
2 * Driver for Amlogic Meson SPI communication controller (SPICC)
3 *
4 * Copyright (C) BayLibre, SAS
5 * Author: Neil Armstrong <narmstrong@baylibre.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10#include <linux/bitfield.h>
11#include <linux/clk.h>
12#include <linux/device.h>
13#include <linux/io.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/platform_device.h>
18#include <linux/spi/spi.h>
19#include <linux/types.h>
20#include <linux/interrupt.h>
21#include <linux/reset.h>
22#include <linux/gpio.h>
23
24/*
25 * The Meson SPICC controller could support DMA based transfers, but is not
26 * implemented by the vendor code, and while having the registers documentation
27 * it has never worked on the GXL Hardware.
28 * The PIO mode is the only mode implemented, and due to badly designed HW :
29 * - all transfers are cutted in 16 words burst because the FIFO hangs on
30 * TX underflow, and there is no TX "Half-Empty" interrupt, so we go by
31 * FIFO max size chunk only
32 * - CS management is dumb, and goes UP between every burst, so is really a
33 * "Data Valid" signal than a Chip Select, GPIO link should be used instead
34 * to have a CS go down over the full transfer
35 */
36
37#define SPICC_MAX_FREQ 30000000
38#define SPICC_MAX_BURST 128
39
40/* Register Map */
41#define SPICC_RXDATA 0x00
42
43#define SPICC_TXDATA 0x04
44
45#define SPICC_CONREG 0x08
46#define SPICC_ENABLE BIT(0)
47#define SPICC_MODE_MASTER BIT(1)
48#define SPICC_XCH BIT(2)
49#define SPICC_SMC BIT(3)
50#define SPICC_POL BIT(4)
51#define SPICC_PHA BIT(5)
52#define SPICC_SSCTL BIT(6)
53#define SPICC_SSPOL BIT(7)
54#define SPICC_DRCTL_MASK GENMASK(9, 8)
55#define SPICC_DRCTL_IGNORE 0
56#define SPICC_DRCTL_FALLING 1
57#define SPICC_DRCTL_LOWLEVEL 2
58#define SPICC_CS_MASK GENMASK(13, 12)
59#define SPICC_DATARATE_MASK GENMASK(18, 16)
60#define SPICC_DATARATE_DIV4 0
61#define SPICC_DATARATE_DIV8 1
62#define SPICC_DATARATE_DIV16 2
63#define SPICC_DATARATE_DIV32 3
64#define SPICC_BITLENGTH_MASK GENMASK(24, 19)
65#define SPICC_BURSTLENGTH_MASK GENMASK(31, 25)
66
67#define SPICC_INTREG 0x0c
68#define SPICC_TE_EN BIT(0) /* TX FIFO Empty Interrupt */
69#define SPICC_TH_EN BIT(1) /* TX FIFO Half-Full Interrupt */
70#define SPICC_TF_EN BIT(2) /* TX FIFO Full Interrupt */
71#define SPICC_RR_EN BIT(3) /* RX FIFO Ready Interrupt */
72#define SPICC_RH_EN BIT(4) /* RX FIFO Half-Full Interrupt */
73#define SPICC_RF_EN BIT(5) /* RX FIFO Full Interrupt */
74#define SPICC_RO_EN BIT(6) /* RX FIFO Overflow Interrupt */
75#define SPICC_TC_EN BIT(7) /* Transfert Complete Interrupt */
76
77#define SPICC_DMAREG 0x10
78#define SPICC_DMA_ENABLE BIT(0)
79#define SPICC_TXFIFO_THRESHOLD_MASK GENMASK(5, 1)
80#define SPICC_RXFIFO_THRESHOLD_MASK GENMASK(10, 6)
81#define SPICC_READ_BURST_MASK GENMASK(14, 11)
82#define SPICC_WRITE_BURST_MASK GENMASK(18, 15)
83#define SPICC_DMA_URGENT BIT(19)
84#define SPICC_DMA_THREADID_MASK GENMASK(25, 20)
85#define SPICC_DMA_BURSTNUM_MASK GENMASK(31, 26)
86
87#define SPICC_STATREG 0x14
88#define SPICC_TE BIT(0) /* TX FIFO Empty Interrupt */
89#define SPICC_TH BIT(1) /* TX FIFO Half-Full Interrupt */
90#define SPICC_TF BIT(2) /* TX FIFO Full Interrupt */
91#define SPICC_RR BIT(3) /* RX FIFO Ready Interrupt */
92#define SPICC_RH BIT(4) /* RX FIFO Half-Full Interrupt */
93#define SPICC_RF BIT(5) /* RX FIFO Full Interrupt */
94#define SPICC_RO BIT(6) /* RX FIFO Overflow Interrupt */
95#define SPICC_TC BIT(7) /* Transfert Complete Interrupt */
96
97#define SPICC_PERIODREG 0x18
98#define SPICC_PERIOD GENMASK(14, 0) /* Wait cycles */
99
100#define SPICC_TESTREG 0x1c
101#define SPICC_TXCNT_MASK GENMASK(4, 0) /* TX FIFO Counter */
102#define SPICC_RXCNT_MASK GENMASK(9, 5) /* RX FIFO Counter */
103#define SPICC_SMSTATUS_MASK GENMASK(12, 10) /* State Machine Status */
104#define SPICC_LBC_RO BIT(13) /* Loop Back Control Read-Only */
105#define SPICC_LBC_W1 BIT(14) /* Loop Back Control Write-Only */
106#define SPICC_SWAP_RO BIT(14) /* RX FIFO Data Swap Read-Only */
107#define SPICC_SWAP_W1 BIT(15) /* RX FIFO Data Swap Write-Only */
108#define SPICC_DLYCTL_RO_MASK GENMASK(20, 15) /* Delay Control Read-Only */
109#define SPICC_DLYCTL_W1_MASK GENMASK(21, 16) /* Delay Control Write-Only */
110#define SPICC_FIFORST_RO_MASK GENMASK(22, 21) /* FIFO Softreset Read-Only */
111#define SPICC_FIFORST_W1_MASK GENMASK(23, 22) /* FIFO Softreset Write-Only */
112
113#define SPICC_DRADDR 0x20 /* Read Address of DMA */
114
115#define SPICC_DWADDR 0x24 /* Write Address of DMA */
116
117#define writel_bits_relaxed(mask, val, addr) \
118 writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
119
120#define SPICC_BURST_MAX 16
121#define SPICC_FIFO_HALF 10
122
123struct meson_spicc_device {
124 struct spi_master *master;
125 struct platform_device *pdev;
126 void __iomem *base;
127 struct clk *core;
128 struct spi_message *message;
129 struct spi_transfer *xfer;
130 u8 *tx_buf;
131 u8 *rx_buf;
132 unsigned int bytes_per_word;
133 unsigned long tx_remain;
134 unsigned long txb_remain;
135 unsigned long rx_remain;
136 unsigned long rxb_remain;
137 unsigned long xfer_remain;
138 bool is_burst_end;
139 bool is_last_burst;
140};
141
142static inline bool meson_spicc_txfull(struct meson_spicc_device *spicc)
143{
144 return !!FIELD_GET(SPICC_TF,
145 readl_relaxed(spicc->base + SPICC_STATREG));
146}
147
148static inline bool meson_spicc_rxready(struct meson_spicc_device *spicc)
149{
150 return FIELD_GET(SPICC_RH | SPICC_RR | SPICC_RF_EN,
151 readl_relaxed(spicc->base + SPICC_STATREG));
152}
153
154static inline u32 meson_spicc_pull_data(struct meson_spicc_device *spicc)
155{
156 unsigned int bytes = spicc->bytes_per_word;
157 unsigned int byte_shift = 0;
158 u32 data = 0;
159 u8 byte;
160
161 while (bytes--) {
162 byte = *spicc->tx_buf++;
163 data |= (byte & 0xff) << byte_shift;
164 byte_shift += 8;
165 }
166
167 spicc->tx_remain--;
168 return data;
169}
170
171static inline void meson_spicc_push_data(struct meson_spicc_device *spicc,
172 u32 data)
173{
174 unsigned int bytes = spicc->bytes_per_word;
175 unsigned int byte_shift = 0;
176 u8 byte;
177
178 while (bytes--) {
179 byte = (data >> byte_shift) & 0xff;
180 *spicc->rx_buf++ = byte;
181 byte_shift += 8;
182 }
183
184 spicc->rx_remain--;
185}
186
187static inline void meson_spicc_rx(struct meson_spicc_device *spicc)
188{
189 /* Empty RX FIFO */
190 while (spicc->rx_remain &&
191 meson_spicc_rxready(spicc))
192 meson_spicc_push_data(spicc,
193 readl_relaxed(spicc->base + SPICC_RXDATA));
194}
195
196static inline void meson_spicc_tx(struct meson_spicc_device *spicc)
197{
198 /* Fill Up TX FIFO */
199 while (spicc->tx_remain &&
200 !meson_spicc_txfull(spicc))
201 writel_relaxed(meson_spicc_pull_data(spicc),
202 spicc->base + SPICC_TXDATA);
203}
204
205static inline u32 meson_spicc_setup_rx_irq(struct meson_spicc_device *spicc,
206 u32 irq_ctrl)
207{
208 if (spicc->rx_remain > SPICC_FIFO_HALF)
209 irq_ctrl |= SPICC_RH_EN;
210 else
211 irq_ctrl |= SPICC_RR_EN;
212
213 return irq_ctrl;
214}
215
216static inline void meson_spicc_setup_burst(struct meson_spicc_device *spicc,
217 unsigned int burst_len)
218{
219 /* Setup Xfer variables */
220 spicc->tx_remain = burst_len;
221 spicc->rx_remain = burst_len;
222 spicc->xfer_remain -= burst_len * spicc->bytes_per_word;
223 spicc->is_burst_end = false;
224 if (burst_len < SPICC_BURST_MAX || !spicc->xfer_remain)
225 spicc->is_last_burst = true;
226 else
227 spicc->is_last_burst = false;
228
229 /* Setup burst length */
230 writel_bits_relaxed(SPICC_BURSTLENGTH_MASK,
231 FIELD_PREP(SPICC_BURSTLENGTH_MASK,
232 burst_len),
233 spicc->base + SPICC_CONREG);
234
235 /* Fill TX FIFO */
236 meson_spicc_tx(spicc);
237}
238
239static irqreturn_t meson_spicc_irq(int irq, void *data)
240{
241 struct meson_spicc_device *spicc = (void *) data;
242 u32 ctrl = readl_relaxed(spicc->base + SPICC_INTREG);
243 u32 stat = readl_relaxed(spicc->base + SPICC_STATREG) & ctrl;
244
245 ctrl &= ~(SPICC_RH_EN | SPICC_RR_EN);
246
247 /* Empty RX FIFO */
248 meson_spicc_rx(spicc);
249
250 /* Enable TC interrupt since we transferred everything */
251 if (!spicc->tx_remain && !spicc->rx_remain) {
252 spicc->is_burst_end = true;
253
254 /* Enable TC interrupt */
255 ctrl |= SPICC_TC_EN;
256
257 /* Reload IRQ status */
258 stat = readl_relaxed(spicc->base + SPICC_STATREG) & ctrl;
259 }
260
261 /* Check transfer complete */
262 if ((stat & SPICC_TC) && spicc->is_burst_end) {
263 unsigned int burst_len;
264
265 /* Clear TC bit */
266 writel_relaxed(SPICC_TC, spicc->base + SPICC_STATREG);
267
268 /* Disable TC interrupt */
269 ctrl &= ~SPICC_TC_EN;
270
271 if (spicc->is_last_burst) {
272 /* Disable all IRQs */
273 writel(0, spicc->base + SPICC_INTREG);
274
275 spi_finalize_current_transfer(spicc->master);
276
277 return IRQ_HANDLED;
278 }
279
280 burst_len = min_t(unsigned int,
281 spicc->xfer_remain / spicc->bytes_per_word,
282 SPICC_BURST_MAX);
283
284 /* Setup burst */
285 meson_spicc_setup_burst(spicc, burst_len);
286
287 /* Restart burst */
288 writel_bits_relaxed(SPICC_XCH, SPICC_XCH,
289 spicc->base + SPICC_CONREG);
290 }
291
292 /* Setup RX interrupt trigger */
293 ctrl = meson_spicc_setup_rx_irq(spicc, ctrl);
294
295 /* Reconfigure interrupts */
296 writel(ctrl, spicc->base + SPICC_INTREG);
297
298 return IRQ_HANDLED;
299}
300
301static u32 meson_spicc_setup_speed(struct meson_spicc_device *spicc, u32 conf,
302 u32 speed)
303{
304 unsigned long parent, value;
305 unsigned int i, div;
306
307 parent = clk_get_rate(spicc->core);
308
309 /* Find closest inferior/equal possible speed */
310 for (i = 0 ; i < 7 ; ++i) {
311 /* 2^(data_rate+2) */
312 value = parent >> (i + 2);
313
314 if (value <= speed)
315 break;
316 }
317
318 /* If provided speed it lower than max divider, use max divider */
319 if (i > 7) {
320 div = 7;
321 dev_warn_once(&spicc->pdev->dev, "unable to get close to speed %u\n",
322 speed);
323 } else
324 div = i;
325
326 dev_dbg(&spicc->pdev->dev, "parent %lu, speed %u -> %lu (%u)\n",
327 parent, speed, value, div);
328
329 conf &= ~SPICC_DATARATE_MASK;
330 conf |= FIELD_PREP(SPICC_DATARATE_MASK, div);
331
332 return conf;
333}
334
335static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc,
336 struct spi_transfer *xfer)
337{
338 u32 conf, conf_orig;
339
340 /* Read original configuration */
341 conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG);
342
343 /* Select closest divider */
344 conf = meson_spicc_setup_speed(spicc, conf, xfer->speed_hz);
345
346 /* Setup word width */
347 conf &= ~SPICC_BITLENGTH_MASK;
348 conf |= FIELD_PREP(SPICC_BITLENGTH_MASK,
349 (spicc->bytes_per_word << 3) - 1);
350
351 /* Ignore if unchanged */
352 if (conf != conf_orig)
353 writel_relaxed(conf, spicc->base + SPICC_CONREG);
354}
355
356static int meson_spicc_transfer_one(struct spi_master *master,
357 struct spi_device *spi,
358 struct spi_transfer *xfer)
359{
360 struct meson_spicc_device *spicc = spi_master_get_devdata(master);
361 unsigned int burst_len;
362 u32 irq = 0;
363
364 /* Store current transfer */
365 spicc->xfer = xfer;
366
367 /* Setup transfer parameters */
368 spicc->tx_buf = (u8 *)xfer->tx_buf;
369 spicc->rx_buf = (u8 *)xfer->rx_buf;
370 spicc->xfer_remain = xfer->len;
371
372 /* Pre-calculate word size */
373 spicc->bytes_per_word =
374 DIV_ROUND_UP(spicc->xfer->bits_per_word, 8);
375
376 /* Setup transfer parameters */
377 meson_spicc_setup_xfer(spicc, xfer);
378
379 burst_len = min_t(unsigned int,
380 spicc->xfer_remain / spicc->bytes_per_word,
381 SPICC_BURST_MAX);
382
383 meson_spicc_setup_burst(spicc, burst_len);
384
385 irq = meson_spicc_setup_rx_irq(spicc, irq);
386
387 /* Start burst */
388 writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG);
389
390 /* Enable interrupts */
391 writel_relaxed(irq, spicc->base + SPICC_INTREG);
392
393 return 1;
394}
395
396static int meson_spicc_prepare_message(struct spi_master *master,
397 struct spi_message *message)
398{
399 struct meson_spicc_device *spicc = spi_master_get_devdata(master);
400 struct spi_device *spi = message->spi;
401 u32 conf = 0;
402
403 /* Store current message */
404 spicc->message = message;
405
406 /* Enable Master */
407 conf |= SPICC_ENABLE;
408 conf |= SPICC_MODE_MASTER;
409
410 /* SMC = 0 */
411
412 /* Setup transfer mode */
413 if (spi->mode & SPI_CPOL)
414 conf |= SPICC_POL;
415 else
416 conf &= ~SPICC_POL;
417
418 if (spi->mode & SPI_CPHA)
419 conf |= SPICC_PHA;
420 else
421 conf &= ~SPICC_PHA;
422
423 /* SSCTL = 0 */
424
425 if (spi->mode & SPI_CS_HIGH)
426 conf |= SPICC_SSPOL;
427 else
428 conf &= ~SPICC_SSPOL;
429
430 if (spi->mode & SPI_READY)
431 conf |= FIELD_PREP(SPICC_DRCTL_MASK, SPICC_DRCTL_LOWLEVEL);
432 else
433 conf |= FIELD_PREP(SPICC_DRCTL_MASK, SPICC_DRCTL_IGNORE);
434
435 /* Select CS */
436 conf |= FIELD_PREP(SPICC_CS_MASK, spi->chip_select);
437
438 /* Default Clock rate core/4 */
439
440 /* Default 8bit word */
441 conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1);
442
443 writel_relaxed(conf, spicc->base + SPICC_CONREG);
444
445 /* Setup no wait cycles by default */
446 writel_relaxed(0, spicc->base + SPICC_PERIODREG);
447
448 writel_bits_relaxed(BIT(24), BIT(24), spicc->base + SPICC_TESTREG);
449
450 return 0;
451}
452
453static int meson_spicc_unprepare_transfer(struct spi_master *master)
454{
455 struct meson_spicc_device *spicc = spi_master_get_devdata(master);
456
457 /* Disable all IRQs */
458 writel(0, spicc->base + SPICC_INTREG);
459
460 /* Disable controller */
461 writel_bits_relaxed(SPICC_ENABLE, 0, spicc->base + SPICC_CONREG);
462
463 device_reset_optional(&spicc->pdev->dev);
464
465 return 0;
466}
467
468static int meson_spicc_setup(struct spi_device *spi)
469{
470 int ret = 0;
471
472 if (!spi->controller_state)
473 spi->controller_state = spi_master_get_devdata(spi->master);
474 else if (gpio_is_valid(spi->cs_gpio))
475 goto out_gpio;
476 else if (spi->cs_gpio == -ENOENT)
477 return 0;
478
479 if (gpio_is_valid(spi->cs_gpio)) {
480 ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
481 if (ret) {
482 dev_err(&spi->dev, "failed to request cs gpio\n");
483 return ret;
484 }
485 }
486
487out_gpio:
488 ret = gpio_direction_output(spi->cs_gpio,
489 !(spi->mode & SPI_CS_HIGH));
490
491 return ret;
492}
493
494static void meson_spicc_cleanup(struct spi_device *spi)
495{
496 if (gpio_is_valid(spi->cs_gpio))
497 gpio_free(spi->cs_gpio);
498
499 spi->controller_state = NULL;
500}
501
502static int meson_spicc_probe(struct platform_device *pdev)
503{
504 struct spi_master *master;
505 struct meson_spicc_device *spicc;
506 struct resource *res;
507 int ret, irq, rate;
508
509 master = spi_alloc_master(&pdev->dev, sizeof(*spicc));
510 if (!master) {
511 dev_err(&pdev->dev, "master allocation failed\n");
512 return -ENOMEM;
513 }
514 spicc = spi_master_get_devdata(master);
515 spicc->master = master;
516
517 spicc->pdev = pdev;
518 platform_set_drvdata(pdev, spicc);
519
520 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
521 spicc->base = devm_ioremap_resource(&pdev->dev, res);
522 if (IS_ERR(spicc->base)) {
523 dev_err(&pdev->dev, "io resource mapping failed\n");
524 ret = PTR_ERR(spicc->base);
525 goto out_master;
526 }
527
528 /* Disable all IRQs */
529 writel_relaxed(0, spicc->base + SPICC_INTREG);
530
531 irq = platform_get_irq(pdev, 0);
532 ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq,
533 0, NULL, spicc);
534 if (ret) {
535 dev_err(&pdev->dev, "irq request failed\n");
536 goto out_master;
537 }
538
539 spicc->core = devm_clk_get(&pdev->dev, "core");
540 if (IS_ERR(spicc->core)) {
541 dev_err(&pdev->dev, "core clock request failed\n");
542 ret = PTR_ERR(spicc->core);
543 goto out_master;
544 }
545
546 ret = clk_prepare_enable(spicc->core);
547 if (ret) {
548 dev_err(&pdev->dev, "core clock enable failed\n");
549 goto out_master;
550 }
551 rate = clk_get_rate(spicc->core);
552
553 device_reset_optional(&pdev->dev);
554
555 master->num_chipselect = 4;
556 master->dev.of_node = pdev->dev.of_node;
557 master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH;
558 master->bits_per_word_mask = SPI_BPW_MASK(32) |
559 SPI_BPW_MASK(24) |
560 SPI_BPW_MASK(16) |
561 SPI_BPW_MASK(8);
562 master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX);
563 master->min_speed_hz = rate >> 9;
564 master->setup = meson_spicc_setup;
565 master->cleanup = meson_spicc_cleanup;
566 master->prepare_message = meson_spicc_prepare_message;
567 master->unprepare_transfer_hardware = meson_spicc_unprepare_transfer;
568 master->transfer_one = meson_spicc_transfer_one;
569
570 /* Setup max rate according to the Meson GX datasheet */
571 if ((rate >> 2) > SPICC_MAX_FREQ)
572 master->max_speed_hz = SPICC_MAX_FREQ;
573 else
574 master->max_speed_hz = rate >> 2;
575
576 ret = devm_spi_register_master(&pdev->dev, master);
577 if (!ret)
578 return 0;
579
580 dev_err(&pdev->dev, "spi master registration failed\n");
581
582out_master:
583 spi_master_put(master);
584
585 return ret;
586}
587
588static int meson_spicc_remove(struct platform_device *pdev)
589{
590 struct meson_spicc_device *spicc = platform_get_drvdata(pdev);
591
592 /* Disable SPI */
593 writel(0, spicc->base + SPICC_CONREG);
594
595 clk_disable_unprepare(spicc->core);
596
597 return 0;
598}
599
600static const struct of_device_id meson_spicc_of_match[] = {
601 { .compatible = "amlogic,meson-gx-spicc", },
602 { /* sentinel */ }
603};
604MODULE_DEVICE_TABLE(of, meson_spicc_of_match);
605
606static struct platform_driver meson_spicc_driver = {
607 .probe = meson_spicc_probe,
608 .remove = meson_spicc_remove,
609 .driver = {
610 .name = "meson-spicc",
611 .of_match_table = of_match_ptr(meson_spicc_of_match),
612 },
613};
614
615module_platform_driver(meson_spicc_driver);
616
617MODULE_DESCRIPTION("Meson SPI Communication Controller driver");
618MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
619MODULE_LICENSE("GPL");