1 /* 2 * Designware master SPI core controller driver 3 * 4 * Copyright (C) 2014 Stefan Roese <sr@denx.de> 5 * 6 * Very loosely based on the Linux driver: 7 * drivers/spi/spi-dw.c, which is: 8 * Copyright (c) 2009, Intel Corporation. 9 * 10 * SPDX-License-Identifier: GPL-2.0 11 */ 12 13 #include <common.h> 14 #include <clk.h> 15 #include <dm.h> 16 #include <errno.h> 17 #include <malloc.h> 18 #include <spi.h> 19 #include <fdtdec.h> 20 #include <linux/compat.h> 21 #include <asm/io.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 /* Register offsets */ 26 #define DW_SPI_CTRL0 0x00 27 #define DW_SPI_CTRL1 0x04 28 #define DW_SPI_SSIENR 0x08 29 #define DW_SPI_MWCR 0x0c 30 #define DW_SPI_SER 0x10 31 #define DW_SPI_BAUDR 0x14 32 #define DW_SPI_TXFLTR 0x18 33 #define DW_SPI_RXFLTR 0x1c 34 #define DW_SPI_TXFLR 0x20 35 #define DW_SPI_RXFLR 0x24 36 #define DW_SPI_SR 0x28 37 #define DW_SPI_IMR 0x2c 38 #define DW_SPI_ISR 0x30 39 #define DW_SPI_RISR 0x34 40 #define DW_SPI_TXOICR 0x38 41 #define DW_SPI_RXOICR 0x3c 42 #define DW_SPI_RXUICR 0x40 43 #define DW_SPI_MSTICR 0x44 44 #define DW_SPI_ICR 0x48 45 #define DW_SPI_DMACR 0x4c 46 #define DW_SPI_DMATDLR 0x50 47 #define DW_SPI_DMARDLR 0x54 48 #define DW_SPI_IDR 0x58 49 #define DW_SPI_VERSION 0x5c 50 #define DW_SPI_DR 0x60 51 52 /* Bit fields in CTRLR0 */ 53 #define SPI_DFS_OFFSET 0 54 55 #define SPI_FRF_OFFSET 4 56 #define SPI_FRF_SPI 0x0 57 #define SPI_FRF_SSP 0x1 58 #define SPI_FRF_MICROWIRE 0x2 59 #define SPI_FRF_RESV 0x3 60 61 #define SPI_MODE_OFFSET 6 62 #define SPI_SCPH_OFFSET 6 63 #define SPI_SCOL_OFFSET 7 64 65 #define SPI_TMOD_OFFSET 8 66 #define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET) 67 #define SPI_TMOD_TR 0x0 /* xmit & recv */ 68 #define SPI_TMOD_TO 0x1 /* xmit only */ 69 #define SPI_TMOD_RO 0x2 /* recv only */ 70 #define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ 71 72 #define SPI_SLVOE_OFFSET 10 73 #define SPI_SRL_OFFSET 11 74 #define SPI_CFS_OFFSET 12 75 76 /* Bit fields in SR, 7 bits */ 77 #define SR_MASK GENMASK(6, 0) /* cover 7 bits */ 78 #define SR_BUSY BIT(0) 79 #define SR_TF_NOT_FULL BIT(1) 80 #define SR_TF_EMPT BIT(2) 81 #define SR_RF_NOT_EMPT BIT(3) 82 #define SR_RF_FULL BIT(4) 83 #define SR_TX_ERR BIT(5) 84 #define SR_DCOL BIT(6) 85 86 #define RX_TIMEOUT 1000 /* timeout in ms */ 87 88 struct dw_spi_platdata { 89 s32 frequency; /* Default clock frequency, -1 for none */ 90 void __iomem *regs; 91 }; 92 93 struct dw_spi_priv { 94 void __iomem *regs; 95 unsigned int freq; /* Default frequency */ 96 unsigned int mode; 97 struct clk clk; 98 unsigned long bus_clk_rate; 99 100 int bits_per_word; 101 u8 cs; /* chip select pin */ 102 u8 tmode; /* TR/TO/RO/EEPROM */ 103 u8 type; /* SPI/SSP/MicroWire */ 104 int len; 105 106 u32 fifo_len; /* depth of the FIFO buffer */ 107 void *tx; 108 void *tx_end; 109 void *rx; 110 void *rx_end; 111 }; 112 113 static inline u32 dw_readl(struct dw_spi_priv *priv, u32 offset) 114 { 115 return __raw_readl(priv->regs + offset); 116 } 117 118 static inline void dw_writel(struct dw_spi_priv *priv, u32 offset, u32 val) 119 { 120 __raw_writel(val, priv->regs + offset); 121 } 122 123 static inline u16 dw_readw(struct dw_spi_priv *priv, u32 offset) 124 { 125 return __raw_readw(priv->regs + offset); 126 } 127 128 static inline void dw_writew(struct dw_spi_priv *priv, u32 offset, u16 val) 129 { 130 __raw_writew(val, priv->regs + offset); 131 } 132 133 static int dw_spi_ofdata_to_platdata(struct udevice *bus) 134 { 135 struct dw_spi_platdata *plat = bus->platdata; 136 const void *blob = gd->fdt_blob; 137 int node = dev_of_offset(bus); 138 139 plat->regs = (struct dw_spi *)devfdt_get_addr(bus); 140 141 /* Use 500KHz as a suitable default */ 142 plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", 143 500000); 144 debug("%s: regs=%p max-frequency=%d\n", __func__, plat->regs, 145 plat->frequency); 146 147 return 0; 148 } 149 150 static inline void spi_enable_chip(struct dw_spi_priv *priv, int enable) 151 { 152 dw_writel(priv, DW_SPI_SSIENR, (enable ? 1 : 0)); 153 } 154 155 /* Restart the controller, disable all interrupts, clean rx fifo */ 156 static void spi_hw_init(struct dw_spi_priv *priv) 157 { 158 spi_enable_chip(priv, 0); 159 dw_writel(priv, DW_SPI_IMR, 0xff); 160 spi_enable_chip(priv, 1); 161 162 /* 163 * Try to detect the FIFO depth if not set by interface driver, 164 * the depth could be from 2 to 256 from HW spec 165 */ 166 if (!priv->fifo_len) { 167 u32 fifo; 168 169 for (fifo = 1; fifo < 256; fifo++) { 170 dw_writew(priv, DW_SPI_TXFLTR, fifo); 171 if (fifo != dw_readw(priv, DW_SPI_TXFLTR)) 172 break; 173 } 174 175 priv->fifo_len = (fifo == 1) ? 0 : fifo; 176 dw_writew(priv, DW_SPI_TXFLTR, 0); 177 } 178 debug("%s: fifo_len=%d\n", __func__, priv->fifo_len); 179 } 180 181 /* 182 * We define dw_spi_get_clk function as 'weak' as some targets 183 * (like SOCFPGA_GEN5 and SOCFPGA_ARRIA10) don't use standard clock API 184 * and implement dw_spi_get_clk their own way in their clock manager. 185 */ 186 __weak int dw_spi_get_clk(struct udevice *bus, ulong *rate) 187 { 188 struct dw_spi_priv *priv = dev_get_priv(bus); 189 int ret; 190 191 ret = clk_get_by_index(bus, 0, &priv->clk); 192 if (ret) 193 return ret; 194 195 ret = clk_enable(&priv->clk); 196 if (ret && ret != -ENOSYS && ret != -ENOTSUPP) 197 return ret; 198 199 *rate = clk_get_rate(&priv->clk); 200 if (!*rate) 201 goto err_rate; 202 203 debug("%s: get spi controller clk via device tree: %lu Hz\n", 204 __func__, *rate); 205 206 return 0; 207 208 err_rate: 209 clk_disable(&priv->clk); 210 clk_free(&priv->clk); 211 212 return -EINVAL; 213 } 214 215 static int dw_spi_probe(struct udevice *bus) 216 { 217 struct dw_spi_platdata *plat = dev_get_platdata(bus); 218 struct dw_spi_priv *priv = dev_get_priv(bus); 219 int ret; 220 221 priv->regs = plat->regs; 222 priv->freq = plat->frequency; 223 224 ret = dw_spi_get_clk(bus, &priv->bus_clk_rate); 225 if (ret) 226 return ret; 227 228 /* Currently only bits_per_word == 8 supported */ 229 priv->bits_per_word = 8; 230 231 priv->tmode = 0; /* Tx & Rx */ 232 233 /* Basic HW init */ 234 spi_hw_init(priv); 235 236 return 0; 237 } 238 239 /* Return the max entries we can fill into tx fifo */ 240 static inline u32 tx_max(struct dw_spi_priv *priv) 241 { 242 u32 tx_left, tx_room, rxtx_gap; 243 244 tx_left = (priv->tx_end - priv->tx) / (priv->bits_per_word >> 3); 245 tx_room = priv->fifo_len - dw_readw(priv, DW_SPI_TXFLR); 246 247 /* 248 * Another concern is about the tx/rx mismatch, we 249 * thought about using (priv->fifo_len - rxflr - txflr) as 250 * one maximum value for tx, but it doesn't cover the 251 * data which is out of tx/rx fifo and inside the 252 * shift registers. So a control from sw point of 253 * view is taken. 254 */ 255 rxtx_gap = ((priv->rx_end - priv->rx) - (priv->tx_end - priv->tx)) / 256 (priv->bits_per_word >> 3); 257 258 return min3(tx_left, tx_room, (u32)(priv->fifo_len - rxtx_gap)); 259 } 260 261 /* Return the max entries we should read out of rx fifo */ 262 static inline u32 rx_max(struct dw_spi_priv *priv) 263 { 264 u32 rx_left = (priv->rx_end - priv->rx) / (priv->bits_per_word >> 3); 265 266 return min_t(u32, rx_left, dw_readw(priv, DW_SPI_RXFLR)); 267 } 268 269 static void dw_writer(struct dw_spi_priv *priv) 270 { 271 u32 max = tx_max(priv); 272 u16 txw = 0; 273 274 while (max--) { 275 /* Set the tx word if the transfer's original "tx" is not null */ 276 if (priv->tx_end - priv->len) { 277 if (priv->bits_per_word == 8) 278 txw = *(u8 *)(priv->tx); 279 else 280 txw = *(u16 *)(priv->tx); 281 } 282 dw_writew(priv, DW_SPI_DR, txw); 283 debug("%s: tx=0x%02x\n", __func__, txw); 284 priv->tx += priv->bits_per_word >> 3; 285 } 286 } 287 288 static int dw_reader(struct dw_spi_priv *priv) 289 { 290 unsigned start = get_timer(0); 291 u32 max; 292 u16 rxw; 293 294 /* Wait for rx data to be ready */ 295 while (rx_max(priv) == 0) { 296 if (get_timer(start) > RX_TIMEOUT) 297 return -ETIMEDOUT; 298 } 299 300 max = rx_max(priv); 301 302 while (max--) { 303 rxw = dw_readw(priv, DW_SPI_DR); 304 debug("%s: rx=0x%02x\n", __func__, rxw); 305 306 /* 307 * Care about rx only if the transfer's original "rx" is 308 * not null 309 */ 310 if (priv->rx_end - priv->len) { 311 if (priv->bits_per_word == 8) 312 *(u8 *)(priv->rx) = rxw; 313 else 314 *(u16 *)(priv->rx) = rxw; 315 } 316 priv->rx += priv->bits_per_word >> 3; 317 } 318 319 return 0; 320 } 321 322 static int poll_transfer(struct dw_spi_priv *priv) 323 { 324 int ret; 325 326 do { 327 dw_writer(priv); 328 ret = dw_reader(priv); 329 if (ret < 0) 330 return ret; 331 } while (priv->rx_end > priv->rx); 332 333 return 0; 334 } 335 336 static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen, 337 const void *dout, void *din, unsigned long flags) 338 { 339 struct udevice *bus = dev->parent; 340 struct dw_spi_priv *priv = dev_get_priv(bus); 341 const u8 *tx = dout; 342 u8 *rx = din; 343 int ret = 0; 344 u32 cr0 = 0; 345 u32 cs; 346 347 /* spi core configured to do 8 bit transfers */ 348 if (bitlen % 8) { 349 debug("Non byte aligned SPI transfer.\n"); 350 return -1; 351 } 352 353 cr0 = (priv->bits_per_word - 1) | (priv->type << SPI_FRF_OFFSET) | 354 (priv->mode << SPI_MODE_OFFSET) | 355 (priv->tmode << SPI_TMOD_OFFSET); 356 357 if (rx && tx) 358 priv->tmode = SPI_TMOD_TR; 359 else if (rx) 360 priv->tmode = SPI_TMOD_RO; 361 else 362 priv->tmode = SPI_TMOD_TO; 363 364 cr0 &= ~SPI_TMOD_MASK; 365 cr0 |= (priv->tmode << SPI_TMOD_OFFSET); 366 367 priv->len = bitlen >> 3; 368 debug("%s: rx=%p tx=%p len=%d [bytes]\n", __func__, rx, tx, priv->len); 369 370 priv->tx = (void *)tx; 371 priv->tx_end = priv->tx + priv->len; 372 priv->rx = rx; 373 priv->rx_end = priv->rx + priv->len; 374 375 /* Disable controller before writing control registers */ 376 spi_enable_chip(priv, 0); 377 378 debug("%s: cr0=%08x\n", __func__, cr0); 379 /* Reprogram cr0 only if changed */ 380 if (dw_readw(priv, DW_SPI_CTRL0) != cr0) 381 dw_writew(priv, DW_SPI_CTRL0, cr0); 382 383 /* 384 * Configure the desired SS (slave select 0...3) in the controller 385 * The DW SPI controller will activate and deactivate this CS 386 * automatically. So no cs_activate() etc is needed in this driver. 387 */ 388 cs = spi_chip_select(dev); 389 dw_writel(priv, DW_SPI_SER, 1 << cs); 390 391 /* Enable controller after writing control registers */ 392 spi_enable_chip(priv, 1); 393 394 /* Start transfer in a polling loop */ 395 ret = poll_transfer(priv); 396 397 return ret; 398 } 399 400 static int dw_spi_set_speed(struct udevice *bus, uint speed) 401 { 402 struct dw_spi_platdata *plat = bus->platdata; 403 struct dw_spi_priv *priv = dev_get_priv(bus); 404 u16 clk_div; 405 406 if (speed > plat->frequency) 407 speed = plat->frequency; 408 409 /* Disable controller before writing control registers */ 410 spi_enable_chip(priv, 0); 411 412 /* clk_div doesn't support odd number */ 413 clk_div = priv->bus_clk_rate / speed; 414 clk_div = (clk_div + 1) & 0xfffe; 415 dw_writel(priv, DW_SPI_BAUDR, clk_div); 416 417 /* Enable controller after writing control registers */ 418 spi_enable_chip(priv, 1); 419 420 priv->freq = speed; 421 debug("%s: regs=%p speed=%d clk_div=%d\n", __func__, priv->regs, 422 priv->freq, clk_div); 423 424 return 0; 425 } 426 427 static int dw_spi_set_mode(struct udevice *bus, uint mode) 428 { 429 struct dw_spi_priv *priv = dev_get_priv(bus); 430 431 /* 432 * Can't set mode yet. Since this depends on if rx, tx, or 433 * rx & tx is requested. So we have to defer this to the 434 * real transfer function. 435 */ 436 priv->mode = mode; 437 debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode); 438 439 return 0; 440 } 441 442 static const struct dm_spi_ops dw_spi_ops = { 443 .xfer = dw_spi_xfer, 444 .set_speed = dw_spi_set_speed, 445 .set_mode = dw_spi_set_mode, 446 /* 447 * cs_info is not needed, since we require all chip selects to be 448 * in the device tree explicitly 449 */ 450 }; 451 452 static const struct udevice_id dw_spi_ids[] = { 453 { .compatible = "snps,dw-apb-ssi" }, 454 { } 455 }; 456 457 U_BOOT_DRIVER(dw_spi) = { 458 .name = "dw_spi", 459 .id = UCLASS_SPI, 460 .of_match = dw_spi_ids, 461 .ops = &dw_spi_ops, 462 .ofdata_to_platdata = dw_spi_ofdata_to_platdata, 463 .platdata_auto_alloc_size = sizeof(struct dw_spi_platdata), 464 .priv_auto_alloc_size = sizeof(struct dw_spi_priv), 465 .probe = dw_spi_probe, 466 }; 467