2 * (C) Copyright 2017 Whitebox Systems / Northend Systems B.V.
6 * (C) Copyright 2017 Olimex Ltd..
9 * Based on linux spi driver. Original copyright follows:
10 * linux/drivers/spi/spi-sun4i.c
12 * Copyright (C) 2012 - 2014 Allwinner Tech
15 * Copyright (C) 2014 Maxime Ripard
18 * SPDX-License-Identifier: GPL-2.0+
27 #include <fdt_support.h>
30 #include <dm/device_compat.h>
31 #include <linux/bitops.h>
33 #include <asm/bitops.h>
37 #include <linux/iopoll.h>
39 DECLARE_GLOBAL_DATA_PTR;
41 /* sun4i spi registers */
42 #define SUN4I_RXDATA_REG 0x00
43 #define SUN4I_TXDATA_REG 0x04
44 #define SUN4I_CTL_REG 0x08
45 #define SUN4I_CLK_CTL_REG 0x1c
46 #define SUN4I_BURST_CNT_REG 0x20
47 #define SUN4I_XMIT_CNT_REG 0x24
48 #define SUN4I_FIFO_STA_REG 0x28
50 /* sun6i spi registers */
51 #define SUN6I_GBL_CTL_REG 0x04
52 #define SUN6I_TFR_CTL_REG 0x08
53 #define SUN6I_FIFO_CTL_REG 0x18
54 #define SUN6I_FIFO_STA_REG 0x1c
55 #define SUN6I_CLK_CTL_REG 0x24
56 #define SUN6I_BURST_CNT_REG 0x30
57 #define SUN6I_XMIT_CNT_REG 0x34
58 #define SUN6I_BURST_CTL_REG 0x38
59 #define SUN6I_TXDATA_REG 0x200
60 #define SUN6I_RXDATA_REG 0x300
63 #define SUN4I_CTL_ENABLE BIT(0)
64 #define SUN4I_CTL_MASTER BIT(1)
65 #define SUN4I_CLK_CTL_CDR2_MASK 0xff
66 #define SUN4I_CLK_CTL_CDR2(div) ((div) & SUN4I_CLK_CTL_CDR2_MASK)
67 #define SUN4I_CLK_CTL_CDR1_MASK 0xf
68 #define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
69 #define SUN4I_CLK_CTL_DRS BIT(12)
70 #define SUN4I_MAX_XFER_SIZE 0xffffff
71 #define SUN4I_BURST_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE)
72 #define SUN4I_XMIT_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE)
73 #define SUN4I_FIFO_STA_RF_CNT_BITS 0
75 #define SUN4I_SPI_MAX_RATE 24000000
76 #define SUN4I_SPI_MIN_RATE 3000
77 #define SUN4I_SPI_DEFAULT_RATE 1000000
78 #define SUN4I_SPI_TIMEOUT_US 1000000
80 #define SPI_REG(priv, reg) ((priv)->base + \
81 (priv)->variant->regs[reg])
82 #define SPI_BIT(priv, bit) ((priv)->variant->bits[bit])
83 #define SPI_CS(priv, cs) (((cs) << SPI_BIT(priv, SPI_TCR_CS_SEL)) & \
84 SPI_BIT(priv, SPI_TCR_CS_MASK))
86 /* sun spi register set */
100 /* sun spi register bits */
101 enum sun4i_spi_bits {
106 SPI_TCR_CS_ACTIVE_LOW,
117 struct sun4i_spi_variant {
118 const unsigned long *regs;
125 struct sun4i_spi_plat {
126 struct sun4i_spi_variant *variant;
131 struct sun4i_spi_priv {
132 struct sun4i_spi_variant *variant;
133 struct clk clk_ahb, clk_mod;
134 struct reset_ctl reset;
143 static inline void sun4i_spi_drain_fifo(struct sun4i_spi_priv *priv, int len)
148 byte = readb(SPI_REG(priv, SPI_RXD));
150 *priv->rx_buf++ = byte;
154 static inline void sun4i_spi_fill_fifo(struct sun4i_spi_priv *priv, int len)
159 byte = priv->tx_buf ? *priv->tx_buf++ : 0;
160 writeb(byte, SPI_REG(priv, SPI_TXD));
164 static void sun4i_spi_set_cs(struct udevice *bus, u8 cs, bool enable)
166 struct sun4i_spi_priv *priv = dev_get_priv(bus);
169 reg = readl(SPI_REG(priv, SPI_TCR));
171 reg &= ~SPI_BIT(priv, SPI_TCR_CS_MASK);
172 reg |= SPI_CS(priv, cs);
175 reg &= ~SPI_BIT(priv, SPI_TCR_CS_LEVEL);
177 reg |= SPI_BIT(priv, SPI_TCR_CS_LEVEL);
179 writel(reg, SPI_REG(priv, SPI_TCR));
182 static int sun4i_spi_parse_pins(struct udevice *dev)
184 const void *fdt = gd->fdt_blob;
185 const char *pin_name;
188 int drive, pull = 0, pin, i;
192 list = fdt_getprop(fdt, dev_of_offset(dev), "pinctrl-0", &size);
194 printf("WARNING: sun4i_spi: cannot find pinctrl-0 node\n");
199 phandle = fdt32_to_cpu(*list++);
200 size -= sizeof(*list);
202 offset = fdt_node_offset_by_phandle(fdt, phandle);
206 drive = fdt_getprop_u32_default_node(fdt, offset, 0,
207 "drive-strength", 0);
211 else if (drive <= 20)
213 else if (drive <= 30)
218 drive = fdt_getprop_u32_default_node(fdt, offset, 0,
221 drive = min(drive, 3);
224 if (fdt_get_property(fdt, offset, "bias-disable", NULL))
226 else if (fdt_get_property(fdt, offset, "bias-pull-up", NULL))
228 else if (fdt_get_property(fdt, offset, "bias-pull-down", NULL))
231 pull = fdt_getprop_u32_default_node(fdt, offset, 0,
237 pin_name = fdt_stringlist_get(fdt, offset,
240 pin_name = fdt_stringlist_get(fdt, offset,
247 pin = name_to_gpio(pin_name);
251 if (IS_ENABLED(CONFIG_MACH_SUN50I))
252 sunxi_gpio_set_cfgpin(pin, SUN50I_GPC_SPI0);
254 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0);
255 sunxi_gpio_set_drv(pin, drive);
256 sunxi_gpio_set_pull(pin, pull);
262 static inline int sun4i_spi_set_clock(struct udevice *dev, bool enable)
264 struct sun4i_spi_priv *priv = dev_get_priv(dev);
268 clk_disable(&priv->clk_ahb);
269 clk_disable(&priv->clk_mod);
270 if (reset_valid(&priv->reset))
271 reset_assert(&priv->reset);
275 ret = clk_enable(&priv->clk_ahb);
277 dev_err(dev, "failed to enable ahb clock (ret=%d)\n", ret);
281 ret = clk_enable(&priv->clk_mod);
283 dev_err(dev, "failed to enable mod clock (ret=%d)\n", ret);
287 if (reset_valid(&priv->reset)) {
288 ret = reset_deassert(&priv->reset);
290 dev_err(dev, "failed to deassert reset\n");
298 clk_disable(&priv->clk_mod);
300 clk_disable(&priv->clk_ahb);
304 static int sun4i_spi_claim_bus(struct udevice *dev)
306 struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
309 ret = sun4i_spi_set_clock(dev->parent, true);
313 setbits_le32(SPI_REG(priv, SPI_GCR), SUN4I_CTL_ENABLE |
314 SUN4I_CTL_MASTER | SPI_BIT(priv, SPI_GCR_TP));
316 if (priv->variant->has_soft_reset)
317 setbits_le32(SPI_REG(priv, SPI_GCR),
318 SPI_BIT(priv, SPI_GCR_SRST));
320 setbits_le32(SPI_REG(priv, SPI_TCR), SPI_BIT(priv, SPI_TCR_CS_MANUAL) |
321 SPI_BIT(priv, SPI_TCR_CS_ACTIVE_LOW));
326 static int sun4i_spi_release_bus(struct udevice *dev)
328 struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
330 clrbits_le32(SPI_REG(priv, SPI_GCR), SUN4I_CTL_ENABLE);
332 sun4i_spi_set_clock(dev->parent, false);
337 static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
338 const void *dout, void *din, unsigned long flags)
340 struct udevice *bus = dev->parent;
341 struct sun4i_spi_priv *priv = dev_get_priv(bus);
342 struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
344 u32 len = bitlen / 8;
353 debug("%s: non byte-aligned SPI transfer.\n", __func__);
357 if (flags & SPI_XFER_BEGIN)
358 sun4i_spi_set_cs(bus, slave_plat->cs, true);
361 setbits_le32(SPI_REG(priv, SPI_FCR), SPI_BIT(priv, SPI_FCR_RF_RST) |
362 SPI_BIT(priv, SPI_FCR_TF_RST));
365 /* Setup the transfer now... */
366 nbytes = min(len, (priv->variant->fifo_depth - 1));
368 /* Setup the counters */
369 writel(SUN4I_BURST_CNT(nbytes), SPI_REG(priv, SPI_BC));
370 writel(SUN4I_XMIT_CNT(nbytes), SPI_REG(priv, SPI_TC));
372 if (priv->variant->has_burst_ctl)
373 writel(SUN4I_BURST_CNT(nbytes),
374 SPI_REG(priv, SPI_BCTL));
376 /* Fill the TX FIFO */
377 sun4i_spi_fill_fifo(priv, nbytes);
379 /* Start the transfer */
380 setbits_le32(SPI_REG(priv, SPI_TCR),
381 SPI_BIT(priv, SPI_TCR_XCH));
383 /* Wait till RX FIFO to be empty */
384 ret = readl_poll_timeout(SPI_REG(priv, SPI_FSR),
387 SPI_BIT(priv, SPI_FSR_RF_CNT_MASK)) >>
388 SUN4I_FIFO_STA_RF_CNT_BITS) >= nbytes),
389 SUN4I_SPI_TIMEOUT_US);
391 printf("ERROR: sun4i_spi: Timeout transferring data\n");
392 sun4i_spi_set_cs(bus, slave_plat->cs, false);
396 /* Drain the RX FIFO */
397 sun4i_spi_drain_fifo(priv, nbytes);
402 if (flags & SPI_XFER_END)
403 sun4i_spi_set_cs(bus, slave_plat->cs, false);
408 static int sun4i_spi_set_speed(struct udevice *dev, uint speed)
410 struct sun4i_spi_plat *plat = dev_get_plat(dev);
411 struct sun4i_spi_priv *priv = dev_get_priv(dev);
415 if (speed > plat->max_hz)
416 speed = plat->max_hz;
418 if (speed < SUN4I_SPI_MIN_RATE)
419 speed = SUN4I_SPI_MIN_RATE;
421 * Setup clock divider.
423 * We have two choices there. Either we can use the clock
424 * divide rate 1, which is calculated thanks to this formula:
425 * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1))
426 * Or we can use CDR2, which is calculated with the formula:
427 * SPI_CLK = MOD_CLK / (2 * (cdr + 1))
428 * Whether we use the former or the latter is set through the
431 * First try CDR2, and if we can't reach the expected
432 * frequency, fall back to CDR1.
435 div = SUN4I_SPI_MAX_RATE / (2 * speed);
436 reg = readl(SPI_REG(priv, SPI_CCR));
438 if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
442 reg &= ~(SUN4I_CLK_CTL_CDR2_MASK | SUN4I_CLK_CTL_DRS);
443 reg |= SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
445 div = __ilog2(SUN4I_SPI_MAX_RATE) - __ilog2(speed);
446 reg &= ~((SUN4I_CLK_CTL_CDR1_MASK << 8) | SUN4I_CLK_CTL_DRS);
447 reg |= SUN4I_CLK_CTL_CDR1(div);
451 writel(reg, SPI_REG(priv, SPI_CCR));
456 static int sun4i_spi_set_mode(struct udevice *dev, uint mode)
458 struct sun4i_spi_priv *priv = dev_get_priv(dev);
461 reg = readl(SPI_REG(priv, SPI_TCR));
462 reg &= ~(SPI_BIT(priv, SPI_TCR_CPOL) | SPI_BIT(priv, SPI_TCR_CPHA));
465 reg |= SPI_BIT(priv, SPI_TCR_CPOL);
468 reg |= SPI_BIT(priv, SPI_TCR_CPHA);
471 writel(reg, SPI_REG(priv, SPI_TCR));
476 static const struct dm_spi_ops sun4i_spi_ops = {
477 .claim_bus = sun4i_spi_claim_bus,
478 .release_bus = sun4i_spi_release_bus,
479 .xfer = sun4i_spi_xfer,
480 .set_speed = sun4i_spi_set_speed,
481 .set_mode = sun4i_spi_set_mode,
484 static int sun4i_spi_probe(struct udevice *bus)
486 struct sun4i_spi_plat *plat = dev_get_plat(bus);
487 struct sun4i_spi_priv *priv = dev_get_priv(bus);
490 ret = clk_get_by_name(bus, "ahb", &priv->clk_ahb);
492 dev_err(bus, "failed to get ahb clock\n");
496 ret = clk_get_by_name(bus, "mod", &priv->clk_mod);
498 dev_err(bus, "failed to get mod clock\n");
502 ret = reset_get_by_index(bus, 0, &priv->reset);
503 if (ret && ret != -ENOENT) {
504 dev_err(bus, "failed to get reset\n");
508 sun4i_spi_parse_pins(bus);
510 priv->variant = plat->variant;
511 priv->base = plat->base;
512 priv->freq = plat->max_hz;
517 static int sun4i_spi_of_to_plat(struct udevice *bus)
519 struct sun4i_spi_plat *plat = dev_get_plat(bus);
520 int node = dev_of_offset(bus);
522 plat->base = dev_read_addr(bus);
523 plat->variant = (struct sun4i_spi_variant *)dev_get_driver_data(bus);
524 plat->max_hz = fdtdec_get_int(gd->fdt_blob, node,
526 SUN4I_SPI_DEFAULT_RATE);
528 if (plat->max_hz > SUN4I_SPI_MAX_RATE)
529 plat->max_hz = SUN4I_SPI_MAX_RATE;
534 static const unsigned long sun4i_spi_regs[] = {
535 [SPI_GCR] = SUN4I_CTL_REG,
536 [SPI_TCR] = SUN4I_CTL_REG,
537 [SPI_FCR] = SUN4I_CTL_REG,
538 [SPI_FSR] = SUN4I_FIFO_STA_REG,
539 [SPI_CCR] = SUN4I_CLK_CTL_REG,
540 [SPI_BC] = SUN4I_BURST_CNT_REG,
541 [SPI_TC] = SUN4I_XMIT_CNT_REG,
542 [SPI_TXD] = SUN4I_TXDATA_REG,
543 [SPI_RXD] = SUN4I_RXDATA_REG,
546 static const u32 sun4i_spi_bits[] = {
547 [SPI_GCR_TP] = BIT(18),
548 [SPI_TCR_CPHA] = BIT(2),
549 [SPI_TCR_CPOL] = BIT(3),
550 [SPI_TCR_CS_ACTIVE_LOW] = BIT(4),
551 [SPI_TCR_XCH] = BIT(10),
552 [SPI_TCR_CS_SEL] = 12,
553 [SPI_TCR_CS_MASK] = 0x3000,
554 [SPI_TCR_CS_MANUAL] = BIT(16),
555 [SPI_TCR_CS_LEVEL] = BIT(17),
556 [SPI_FCR_TF_RST] = BIT(8),
557 [SPI_FCR_RF_RST] = BIT(9),
558 [SPI_FSR_RF_CNT_MASK] = GENMASK(6, 0),
561 static const unsigned long sun6i_spi_regs[] = {
562 [SPI_GCR] = SUN6I_GBL_CTL_REG,
563 [SPI_TCR] = SUN6I_TFR_CTL_REG,
564 [SPI_FCR] = SUN6I_FIFO_CTL_REG,
565 [SPI_FSR] = SUN6I_FIFO_STA_REG,
566 [SPI_CCR] = SUN6I_CLK_CTL_REG,
567 [SPI_BC] = SUN6I_BURST_CNT_REG,
568 [SPI_TC] = SUN6I_XMIT_CNT_REG,
569 [SPI_BCTL] = SUN6I_BURST_CTL_REG,
570 [SPI_TXD] = SUN6I_TXDATA_REG,
571 [SPI_RXD] = SUN6I_RXDATA_REG,
574 static const u32 sun6i_spi_bits[] = {
575 [SPI_GCR_TP] = BIT(7),
576 [SPI_GCR_SRST] = BIT(31),
577 [SPI_TCR_CPHA] = BIT(0),
578 [SPI_TCR_CPOL] = BIT(1),
579 [SPI_TCR_CS_ACTIVE_LOW] = BIT(2),
580 [SPI_TCR_CS_SEL] = 4,
581 [SPI_TCR_CS_MASK] = 0x30,
582 [SPI_TCR_CS_MANUAL] = BIT(6),
583 [SPI_TCR_CS_LEVEL] = BIT(7),
584 [SPI_TCR_XCH] = BIT(31),
585 [SPI_FCR_RF_RST] = BIT(15),
586 [SPI_FCR_TF_RST] = BIT(31),
587 [SPI_FSR_RF_CNT_MASK] = GENMASK(7, 0),
590 static const struct sun4i_spi_variant sun4i_a10_spi_variant = {
591 .regs = sun4i_spi_regs,
592 .bits = sun4i_spi_bits,
596 static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
597 .regs = sun6i_spi_regs,
598 .bits = sun6i_spi_bits,
600 .has_soft_reset = true,
601 .has_burst_ctl = true,
604 static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
605 .regs = sun6i_spi_regs,
606 .bits = sun6i_spi_bits,
608 .has_soft_reset = true,
609 .has_burst_ctl = true,
612 static const struct udevice_id sun4i_spi_ids[] = {
614 .compatible = "allwinner,sun4i-a10-spi",
615 .data = (ulong)&sun4i_a10_spi_variant,
618 .compatible = "allwinner,sun6i-a31-spi",
619 .data = (ulong)&sun6i_a31_spi_variant,
622 .compatible = "allwinner,sun8i-h3-spi",
623 .data = (ulong)&sun8i_h3_spi_variant,
628 U_BOOT_DRIVER(sun4i_spi) = {
631 .of_match = sun4i_spi_ids,
632 .ops = &sun4i_spi_ops,
633 .of_to_plat = sun4i_spi_of_to_plat,
634 .plat_auto = sizeof(struct sun4i_spi_plat),
635 .priv_auto = sizeof(struct sun4i_spi_priv),
636 .probe = sun4i_spi_probe,