1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com> 4 * 5 * Derived from linux/drivers/spi/spi-bcm63xx.c: 6 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org> 7 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> 8 */ 9 10 #include <common.h> 11 #include <clk.h> 12 #include <dm.h> 13 #include <spi.h> 14 #include <reset.h> 15 #include <wait_bit.h> 16 #include <asm/io.h> 17 18 /* BCM6348 SPI core */ 19 #define SPI_6348_CLK 0x06 20 #define SPI_6348_CMD 0x00 21 #define SPI_6348_CTL 0x40 22 #define SPI_6348_CTL_SHIFT 6 23 #define SPI_6348_FILL 0x07 24 #define SPI_6348_IR_MASK 0x04 25 #define SPI_6348_IR_STAT 0x02 26 #define SPI_6348_RX 0x80 27 #define SPI_6348_RX_SIZE 0x3f 28 #define SPI_6348_TX 0x41 29 #define SPI_6348_TX_SIZE 0x3f 30 31 /* BCM6358 SPI core */ 32 #define SPI_6358_CLK 0x706 33 #define SPI_6358_CMD 0x700 34 #define SPI_6358_CTL 0x000 35 #define SPI_6358_CTL_SHIFT 14 36 #define SPI_6358_FILL 0x707 37 #define SPI_6358_IR_MASK 0x702 38 #define SPI_6358_IR_STAT 0x704 39 #define SPI_6358_RX 0x400 40 #define SPI_6358_RX_SIZE 0x220 41 #define SPI_6358_TX 0x002 42 #define SPI_6358_TX_SIZE 0x21e 43 44 /* SPI Clock register */ 45 #define SPI_CLK_SHIFT 0 46 #define SPI_CLK_20MHZ (0 << SPI_CLK_SHIFT) 47 #define SPI_CLK_0_391MHZ (1 << SPI_CLK_SHIFT) 48 #define SPI_CLK_0_781MHZ (2 << SPI_CLK_SHIFT) 49 #define SPI_CLK_1_563MHZ (3 << SPI_CLK_SHIFT) 50 #define SPI_CLK_3_125MHZ (4 << SPI_CLK_SHIFT) 51 #define SPI_CLK_6_250MHZ (5 << SPI_CLK_SHIFT) 52 #define SPI_CLK_12_50MHZ (6 << SPI_CLK_SHIFT) 53 #define SPI_CLK_25MHZ (7 << SPI_CLK_SHIFT) 54 #define SPI_CLK_MASK (7 << SPI_CLK_SHIFT) 55 #define SPI_CLK_SSOFF_SHIFT 3 56 #define SPI_CLK_SSOFF_2 (2 << SPI_CLK_SSOFF_SHIFT) 57 #define SPI_CLK_SSOFF_MASK (7 << SPI_CLK_SSOFF_SHIFT) 58 #define SPI_CLK_BSWAP_SHIFT 7 59 #define SPI_CLK_BSWAP_MASK (1 << SPI_CLK_BSWAP_SHIFT) 60 61 /* SPI Command register */ 62 #define SPI_CMD_OP_SHIFT 0 63 #define SPI_CMD_OP_START (0x3 << SPI_CMD_OP_SHIFT) 64 #define SPI_CMD_SLAVE_SHIFT 4 65 #define SPI_CMD_SLAVE_MASK (0xf << SPI_CMD_SLAVE_SHIFT) 66 #define SPI_CMD_PREPEND_SHIFT 8 67 #define SPI_CMD_PREPEND_BYTES 0xf 68 #define SPI_CMD_3WIRE_SHIFT 12 69 #define SPI_CMD_3WIRE_MASK (1 << SPI_CMD_3WIRE_SHIFT) 70 71 /* SPI Control register */ 72 #define SPI_CTL_TYPE_FD_RW 0 73 #define SPI_CTL_TYPE_HD_W 1 74 #define SPI_CTL_TYPE_HD_R 2 75 76 /* SPI Interrupt registers */ 77 #define SPI_IR_DONE_SHIFT 0 78 #define SPI_IR_DONE_MASK (1 << SPI_IR_DONE_SHIFT) 79 #define SPI_IR_RXOVER_SHIFT 1 80 #define SPI_IR_RXOVER_MASK (1 << SPI_IR_RXOVER_SHIFT) 81 #define SPI_IR_TXUNDER_SHIFT 2 82 #define SPI_IR_TXUNDER_MASK (1 << SPI_IR_TXUNDER_SHIFT) 83 #define SPI_IR_TXOVER_SHIFT 3 84 #define SPI_IR_TXOVER_MASK (1 << SPI_IR_TXOVER_SHIFT) 85 #define SPI_IR_RXUNDER_SHIFT 4 86 #define SPI_IR_RXUNDER_MASK (1 << SPI_IR_RXUNDER_SHIFT) 87 #define SPI_IR_CLEAR_MASK (SPI_IR_DONE_MASK |\ 88 SPI_IR_RXOVER_MASK |\ 89 SPI_IR_TXUNDER_MASK |\ 90 SPI_IR_TXOVER_MASK |\ 91 SPI_IR_RXUNDER_MASK) 92 93 enum bcm63xx_regs_spi { 94 SPI_CLK, 95 SPI_CMD, 96 SPI_CTL, 97 SPI_CTL_SHIFT, 98 SPI_FILL, 99 SPI_IR_MASK, 100 SPI_IR_STAT, 101 SPI_RX, 102 SPI_RX_SIZE, 103 SPI_TX, 104 SPI_TX_SIZE, 105 }; 106 107 struct bcm63xx_spi_priv { 108 const unsigned long *regs; 109 void __iomem *base; 110 size_t tx_bytes; 111 uint8_t num_cs; 112 }; 113 114 #define SPI_CLK_CNT 8 115 static const unsigned bcm63xx_spi_freq_table[SPI_CLK_CNT][2] = { 116 { 25000000, SPI_CLK_25MHZ }, 117 { 20000000, SPI_CLK_20MHZ }, 118 { 12500000, SPI_CLK_12_50MHZ }, 119 { 6250000, SPI_CLK_6_250MHZ }, 120 { 3125000, SPI_CLK_3_125MHZ }, 121 { 1563000, SPI_CLK_1_563MHZ }, 122 { 781000, SPI_CLK_0_781MHZ }, 123 { 391000, SPI_CLK_0_391MHZ } 124 }; 125 126 static int bcm63xx_spi_cs_info(struct udevice *bus, uint cs, 127 struct spi_cs_info *info) 128 { 129 struct bcm63xx_spi_priv *priv = dev_get_priv(bus); 130 131 if (cs >= priv->num_cs) { 132 printf("no cs %u\n", cs); 133 return -ENODEV; 134 } 135 136 return 0; 137 } 138 139 static int bcm63xx_spi_set_mode(struct udevice *bus, uint mode) 140 { 141 struct bcm63xx_spi_priv *priv = dev_get_priv(bus); 142 const unsigned long *regs = priv->regs; 143 144 if (mode & SPI_LSB_FIRST) 145 setbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK); 146 else 147 clrbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK); 148 149 return 0; 150 } 151 152 static int bcm63xx_spi_set_speed(struct udevice *bus, uint speed) 153 { 154 struct bcm63xx_spi_priv *priv = dev_get_priv(bus); 155 const unsigned long *regs = priv->regs; 156 uint8_t clk_cfg; 157 int i; 158 159 /* default to lowest clock configuration */ 160 clk_cfg = SPI_CLK_0_391MHZ; 161 162 /* find the closest clock configuration */ 163 for (i = 0; i < SPI_CLK_CNT; i++) { 164 if (speed >= bcm63xx_spi_freq_table[i][0]) { 165 clk_cfg = bcm63xx_spi_freq_table[i][1]; 166 break; 167 } 168 } 169 170 /* write clock configuration */ 171 clrsetbits_8(priv->base + regs[SPI_CLK], 172 SPI_CLK_SSOFF_MASK | SPI_CLK_MASK, 173 clk_cfg | SPI_CLK_SSOFF_2); 174 175 return 0; 176 } 177 178 /* 179 * BCM63xx SPI driver doesn't allow keeping CS active between transfers since 180 * they are HW controlled. 181 * However, it provides a mechanism to prepend write transfers prior to read 182 * transfers (with a maximum prepend of 15 bytes), which is usually enough for 183 * SPI-connected flashes since reading requires prepending a write transfer of 184 * 5 bytes. 185 * 186 * This implementation takes advantage of the prepend mechanism and combines 187 * multiple transfers into a single one where possible (single/multiple write 188 * transfer(s) followed by a final read/write transfer). 189 * However, it's not possible to buffer reads, which means that read transfers 190 * should always be done as the final ones. 191 * On the other hand, take into account that combining write transfers into 192 * a single one is just buffering and doesn't require prepend mechanism. 193 */ 194 static int bcm63xx_spi_xfer(struct udevice *dev, unsigned int bitlen, 195 const void *dout, void *din, unsigned long flags) 196 { 197 struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent); 198 const unsigned long *regs = priv->regs; 199 size_t data_bytes = bitlen / 8; 200 201 if (flags & SPI_XFER_BEGIN) { 202 /* clear prepends */ 203 priv->tx_bytes = 0; 204 205 /* initialize hardware */ 206 writeb_be(0, priv->base + regs[SPI_IR_MASK]); 207 } 208 209 if (din) { 210 /* buffering reads not possible since cs is hw controlled */ 211 if (!(flags & SPI_XFER_END)) { 212 printf("unable to buffer reads\n"); 213 return -EINVAL; 214 } 215 216 /* check rx size */ 217 if (data_bytes > regs[SPI_RX_SIZE]) { 218 printf("max rx bytes exceeded\n"); 219 return -EMSGSIZE; 220 } 221 } 222 223 if (dout) { 224 /* check tx size */ 225 if (priv->tx_bytes + data_bytes > regs[SPI_TX_SIZE]) { 226 printf("max tx bytes exceeded\n"); 227 return -EMSGSIZE; 228 } 229 230 /* copy tx data */ 231 memcpy_toio(priv->base + regs[SPI_TX] + priv->tx_bytes, 232 dout, data_bytes); 233 priv->tx_bytes += data_bytes; 234 } 235 236 if (flags & SPI_XFER_END) { 237 struct dm_spi_slave_platdata *plat = 238 dev_get_parent_platdata(dev); 239 uint16_t val, cmd; 240 int ret; 241 242 /* determine control config */ 243 if (dout && !din) { 244 /* buffered write transfers */ 245 val = priv->tx_bytes; 246 val |= (SPI_CTL_TYPE_HD_W << regs[SPI_CTL_SHIFT]); 247 priv->tx_bytes = 0; 248 } else { 249 if (dout && din && (flags & SPI_XFER_ONCE)) { 250 /* full duplex read/write */ 251 val = data_bytes; 252 val |= (SPI_CTL_TYPE_FD_RW << 253 regs[SPI_CTL_SHIFT]); 254 priv->tx_bytes = 0; 255 } else { 256 /* prepended write transfer */ 257 val = data_bytes; 258 val |= (SPI_CTL_TYPE_HD_R << 259 regs[SPI_CTL_SHIFT]); 260 if (priv->tx_bytes > SPI_CMD_PREPEND_BYTES) { 261 printf("max prepend bytes exceeded\n"); 262 return -EMSGSIZE; 263 } 264 } 265 } 266 267 if (regs[SPI_CTL_SHIFT] >= 8) 268 writew_be(val, priv->base + regs[SPI_CTL]); 269 else 270 writeb_be(val, priv->base + regs[SPI_CTL]); 271 272 /* clear interrupts */ 273 writeb_be(SPI_IR_CLEAR_MASK, priv->base + regs[SPI_IR_STAT]); 274 275 /* issue the transfer */ 276 cmd = SPI_CMD_OP_START; 277 cmd |= (plat->cs << SPI_CMD_SLAVE_SHIFT) & SPI_CMD_SLAVE_MASK; 278 cmd |= (priv->tx_bytes << SPI_CMD_PREPEND_SHIFT); 279 if (plat->mode & SPI_3WIRE) 280 cmd |= SPI_CMD_3WIRE_MASK; 281 writew_be(cmd, priv->base + regs[SPI_CMD]); 282 283 /* enable interrupts */ 284 writeb_be(SPI_IR_DONE_MASK, priv->base + regs[SPI_IR_MASK]); 285 286 ret = wait_for_bit_8(priv->base + regs[SPI_IR_STAT], 287 SPI_IR_DONE_MASK, true, 1000, false); 288 if (ret) { 289 printf("interrupt timeout\n"); 290 return ret; 291 } 292 293 /* copy rx data */ 294 if (din) 295 memcpy_fromio(din, priv->base + regs[SPI_RX], 296 data_bytes); 297 } 298 299 return 0; 300 } 301 302 static const struct dm_spi_ops bcm63xx_spi_ops = { 303 .cs_info = bcm63xx_spi_cs_info, 304 .set_mode = bcm63xx_spi_set_mode, 305 .set_speed = bcm63xx_spi_set_speed, 306 .xfer = bcm63xx_spi_xfer, 307 }; 308 309 static const unsigned long bcm6348_spi_regs[] = { 310 [SPI_CLK] = SPI_6348_CLK, 311 [SPI_CMD] = SPI_6348_CMD, 312 [SPI_CTL] = SPI_6348_CTL, 313 [SPI_CTL_SHIFT] = SPI_6348_CTL_SHIFT, 314 [SPI_FILL] = SPI_6348_FILL, 315 [SPI_IR_MASK] = SPI_6348_IR_MASK, 316 [SPI_IR_STAT] = SPI_6348_IR_STAT, 317 [SPI_RX] = SPI_6348_RX, 318 [SPI_RX_SIZE] = SPI_6348_RX_SIZE, 319 [SPI_TX] = SPI_6348_TX, 320 [SPI_TX_SIZE] = SPI_6348_TX_SIZE, 321 }; 322 323 static const unsigned long bcm6358_spi_regs[] = { 324 [SPI_CLK] = SPI_6358_CLK, 325 [SPI_CMD] = SPI_6358_CMD, 326 [SPI_CTL] = SPI_6358_CTL, 327 [SPI_CTL_SHIFT] = SPI_6358_CTL_SHIFT, 328 [SPI_FILL] = SPI_6358_FILL, 329 [SPI_IR_MASK] = SPI_6358_IR_MASK, 330 [SPI_IR_STAT] = SPI_6358_IR_STAT, 331 [SPI_RX] = SPI_6358_RX, 332 [SPI_RX_SIZE] = SPI_6358_RX_SIZE, 333 [SPI_TX] = SPI_6358_TX, 334 [SPI_TX_SIZE] = SPI_6358_TX_SIZE, 335 }; 336 337 static const struct udevice_id bcm63xx_spi_ids[] = { 338 { 339 .compatible = "brcm,bcm6348-spi", 340 .data = (ulong)&bcm6348_spi_regs, 341 }, { 342 .compatible = "brcm,bcm6358-spi", 343 .data = (ulong)&bcm6358_spi_regs, 344 }, { /* sentinel */ } 345 }; 346 347 static int bcm63xx_spi_child_pre_probe(struct udevice *dev) 348 { 349 struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent); 350 const unsigned long *regs = priv->regs; 351 struct spi_slave *slave = dev_get_parent_priv(dev); 352 struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); 353 354 /* check cs */ 355 if (plat->cs >= priv->num_cs) { 356 printf("no cs %u\n", plat->cs); 357 return -ENODEV; 358 } 359 360 /* max read/write sizes */ 361 slave->max_read_size = regs[SPI_RX_SIZE]; 362 slave->max_write_size = regs[SPI_TX_SIZE]; 363 364 return 0; 365 } 366 367 static int bcm63xx_spi_probe(struct udevice *dev) 368 { 369 struct bcm63xx_spi_priv *priv = dev_get_priv(dev); 370 const unsigned long *regs = 371 (const unsigned long *)dev_get_driver_data(dev); 372 struct reset_ctl rst_ctl; 373 struct clk clk; 374 int ret; 375 376 priv->base = dev_remap_addr(dev); 377 if (!priv->base) 378 return -EINVAL; 379 380 priv->regs = regs; 381 priv->num_cs = dev_read_u32_default(dev, "num-cs", 8); 382 383 /* enable clock */ 384 ret = clk_get_by_index(dev, 0, &clk); 385 if (ret < 0) 386 return ret; 387 388 ret = clk_enable(&clk); 389 if (ret < 0) 390 return ret; 391 392 ret = clk_free(&clk); 393 if (ret < 0) 394 return ret; 395 396 /* perform reset */ 397 ret = reset_get_by_index(dev, 0, &rst_ctl); 398 if (ret < 0) 399 return ret; 400 401 ret = reset_deassert(&rst_ctl); 402 if (ret < 0) 403 return ret; 404 405 ret = reset_free(&rst_ctl); 406 if (ret < 0) 407 return ret; 408 409 /* initialize hardware */ 410 writeb_be(0, priv->base + regs[SPI_IR_MASK]); 411 412 /* set fill register */ 413 writeb_be(0xff, priv->base + regs[SPI_FILL]); 414 415 return 0; 416 } 417 418 U_BOOT_DRIVER(bcm63xx_spi) = { 419 .name = "bcm63xx_spi", 420 .id = UCLASS_SPI, 421 .of_match = bcm63xx_spi_ids, 422 .ops = &bcm63xx_spi_ops, 423 .priv_auto_alloc_size = sizeof(struct bcm63xx_spi_priv), 424 .child_pre_probe = bcm63xx_spi_child_pre_probe, 425 .probe = bcm63xx_spi_probe, 426 }; 427