1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* 3 * Microsemi SoCs spi driver 4 * 5 * Copyright (c) 2018 Microsemi Corporation 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <malloc.h> 12 #include <spi.h> 13 #include <dm.h> 14 #include <asm/gpio.h> 15 #include <asm/io.h> 16 #include <linux/delay.h> 17 18 struct mscc_bb_priv { 19 void __iomem *regs; 20 u32 deactivate_delay_us; 21 bool cs_active; /* State flag as to whether CS is asserted */ 22 int cs_num; 23 u32 svalue; /* Value to start transfer with */ 24 u32 clk1; /* Clock value start */ 25 u32 clk2; /* Clock value 2nd phase */ 26 }; 27 28 /* Delay 24 instructions for this particular application */ 29 #define hold_time_delay() mscc_vcoreiii_nop_delay(3) 30 31 static int mscc_bb_spi_cs_activate(struct mscc_bb_priv *priv, int mode, int cs) 32 { 33 if (!priv->cs_active) { 34 int cpha = mode & SPI_CPHA; 35 u32 cs_value; 36 37 priv->cs_num = cs; 38 39 if (cpha) { 40 /* Initial clock starts SCK=1 */ 41 priv->clk1 = ICPU_SW_MODE_SW_SPI_SCK; 42 priv->clk2 = 0; 43 } else { 44 /* Initial clock starts SCK=0 */ 45 priv->clk1 = 0; 46 priv->clk2 = ICPU_SW_MODE_SW_SPI_SCK; 47 } 48 49 /* Enable bitbang, SCK_OE, SDO_OE */ 50 priv->svalue = (ICPU_SW_MODE_SW_PIN_CTRL_MODE | /* Bitbang */ 51 ICPU_SW_MODE_SW_SPI_SCK_OE | /* SCK_OE */ 52 ICPU_SW_MODE_SW_SPI_SDO_OE); /* SDO OE */ 53 54 /* Add CS */ 55 if (cs >= 0) { 56 cs_value = 57 ICPU_SW_MODE_SW_SPI_CS_OE(BIT(cs)) | 58 ICPU_SW_MODE_SW_SPI_CS(BIT(cs)); 59 } else { 60 cs_value = 0; 61 } 62 63 priv->svalue |= cs_value; 64 65 /* Enable the CS in HW, Initial clock value */ 66 writel(priv->svalue | priv->clk2, priv->regs); 67 68 priv->cs_active = true; 69 debug("Activated CS%d\n", priv->cs_num); 70 } 71 72 return 0; 73 } 74 75 static int mscc_bb_spi_cs_deactivate(struct mscc_bb_priv *priv, int deact_delay) 76 { 77 if (priv->cs_active) { 78 /* Keep driving the CLK to its current value while 79 * actively deselecting CS. 80 */ 81 u32 value = readl(priv->regs); 82 83 value &= ~ICPU_SW_MODE_SW_SPI_CS_M; 84 writel(value, priv->regs); 85 hold_time_delay(); 86 87 /* Stop driving the clock, but keep CS with nCS == 1 */ 88 value &= ~ICPU_SW_MODE_SW_SPI_SCK_OE; 89 writel(value, priv->regs); 90 91 /* Deselect hold time delay */ 92 if (deact_delay) 93 udelay(deact_delay); 94 95 /* Drop everything */ 96 writel(0, priv->regs); 97 98 priv->cs_active = false; 99 debug("Deactivated CS%d\n", priv->cs_num); 100 } 101 102 return 0; 103 } 104 105 int mscc_bb_spi_claim_bus(struct udevice *dev) 106 { 107 return 0; 108 } 109 110 int mscc_bb_spi_release_bus(struct udevice *dev) 111 { 112 return 0; 113 } 114 115 int mscc_bb_spi_xfer(struct udevice *dev, unsigned int bitlen, 116 const void *dout, void *din, unsigned long flags) 117 { 118 struct udevice *bus = dev_get_parent(dev); 119 struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); 120 struct mscc_bb_priv *priv = dev_get_priv(bus); 121 u32 i, count; 122 const u8 *txd = dout; 123 u8 *rxd = din; 124 125 debug("spi_xfer: slave %s:%s cs%d mode %d, dout %p din %p bitlen %u\n", 126 dev->parent->name, dev->name, plat->cs, plat->mode, dout, 127 din, bitlen); 128 129 if (flags & SPI_XFER_BEGIN) 130 mscc_bb_spi_cs_activate(priv, plat->mode, plat->cs); 131 132 count = bitlen / 8; 133 for (i = 0; i < count; i++) { 134 u32 rx = 0, mask = 0x80, value; 135 136 while (mask) { 137 /* Initial condition: CLK is low. */ 138 value = priv->svalue; 139 if (txd && txd[i] & mask) 140 value |= ICPU_SW_MODE_SW_SPI_SDO; 141 142 /* Drive data while taking CLK low. The device 143 * we're accessing will sample on the 144 * following rising edge and will output data 145 * on this edge for us to be sampled at the 146 * end of this loop. 147 */ 148 writel(value | priv->clk1, priv->regs); 149 150 /* Wait for t_setup. All devices do have a 151 * setup-time, so we always insert some delay 152 * here. Some devices have a very long 153 * setup-time, which can be adjusted by the 154 * user through vcoreiii_device->delay. 155 */ 156 hold_time_delay(); 157 158 /* Drive the clock high. */ 159 writel(value | priv->clk2, priv->regs); 160 161 /* Wait for t_hold. See comment about t_setup 162 * above. 163 */ 164 hold_time_delay(); 165 166 /* We sample as close to the next falling edge 167 * as possible. 168 */ 169 value = readl(priv->regs); 170 if (value & ICPU_SW_MODE_SW_SPI_SDI) 171 rx |= mask; 172 mask >>= 1; 173 } 174 if (rxd) { 175 debug("Read 0x%02x\n", rx); 176 rxd[i] = (u8)rx; 177 } 178 debug("spi_xfer: byte %d/%d\n", i + 1, count); 179 } 180 181 debug("spi_xfer: done\n"); 182 183 if (flags & SPI_XFER_END) 184 mscc_bb_spi_cs_deactivate(priv, priv->deactivate_delay_us); 185 186 return 0; 187 } 188 189 int mscc_bb_spi_set_speed(struct udevice *dev, unsigned int speed) 190 { 191 /* Accept any speed */ 192 return 0; 193 } 194 195 int mscc_bb_spi_set_mode(struct udevice *dev, unsigned int mode) 196 { 197 return 0; 198 } 199 200 static const struct dm_spi_ops mscc_bb_ops = { 201 .claim_bus = mscc_bb_spi_claim_bus, 202 .release_bus = mscc_bb_spi_release_bus, 203 .xfer = mscc_bb_spi_xfer, 204 .set_speed = mscc_bb_spi_set_speed, 205 .set_mode = mscc_bb_spi_set_mode, 206 }; 207 208 static const struct udevice_id mscc_bb_ids[] = { 209 { .compatible = "mscc,luton-bb-spi" }, 210 { } 211 }; 212 213 static int mscc_bb_spi_probe(struct udevice *bus) 214 { 215 struct mscc_bb_priv *priv = dev_get_priv(bus); 216 217 debug("%s: loaded, priv %p\n", __func__, priv); 218 219 priv->regs = (void __iomem *)dev_read_addr(bus); 220 221 priv->deactivate_delay_us = 222 dev_read_u32_default(bus, "spi-deactivate-delay", 0); 223 224 priv->cs_active = false; 225 226 return 0; 227 } 228 229 U_BOOT_DRIVER(mscc_bb) = { 230 .name = "mscc_bb", 231 .id = UCLASS_SPI, 232 .of_match = mscc_bb_ids, 233 .ops = &mscc_bb_ops, 234 .priv_auto_alloc_size = sizeof(struct mscc_bb_priv), 235 .probe = mscc_bb_spi_probe, 236 }; 237