1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SPI-Engine SPI controller driver 4 * Copyright 2015 Analog Devices Inc. 5 * Author: Lars-Peter Clausen <lars@metafoo.de> 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/interrupt.h> 10 #include <linux/io.h> 11 #include <linux/of.h> 12 #include <linux/module.h> 13 #include <linux/platform_device.h> 14 #include <linux/spi/spi.h> 15 16 #define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff) 17 #define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff) 18 #define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff) 19 20 #define SPI_ENGINE_REG_VERSION 0x00 21 22 #define SPI_ENGINE_REG_RESET 0x40 23 24 #define SPI_ENGINE_REG_INT_ENABLE 0x80 25 #define SPI_ENGINE_REG_INT_PENDING 0x84 26 #define SPI_ENGINE_REG_INT_SOURCE 0x88 27 28 #define SPI_ENGINE_REG_SYNC_ID 0xc0 29 30 #define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xd0 31 #define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xd4 32 #define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xd8 33 34 #define SPI_ENGINE_REG_CMD_FIFO 0xe0 35 #define SPI_ENGINE_REG_SDO_DATA_FIFO 0xe4 36 #define SPI_ENGINE_REG_SDI_DATA_FIFO 0xe8 37 #define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xec 38 39 #define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0) 40 #define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1) 41 #define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2) 42 #define SPI_ENGINE_INT_SYNC BIT(3) 43 44 #define SPI_ENGINE_CONFIG_CPHA BIT(0) 45 #define SPI_ENGINE_CONFIG_CPOL BIT(1) 46 #define SPI_ENGINE_CONFIG_3WIRE BIT(2) 47 48 #define SPI_ENGINE_INST_TRANSFER 0x0 49 #define SPI_ENGINE_INST_ASSERT 0x1 50 #define SPI_ENGINE_INST_WRITE 0x2 51 #define SPI_ENGINE_INST_MISC 0x3 52 53 #define SPI_ENGINE_CMD_REG_CLK_DIV 0x0 54 #define SPI_ENGINE_CMD_REG_CONFIG 0x1 55 56 #define SPI_ENGINE_MISC_SYNC 0x0 57 #define SPI_ENGINE_MISC_SLEEP 0x1 58 59 #define SPI_ENGINE_TRANSFER_WRITE 0x1 60 #define SPI_ENGINE_TRANSFER_READ 0x2 61 62 #define SPI_ENGINE_CMD(inst, arg1, arg2) \ 63 (((inst) << 12) | ((arg1) << 8) | (arg2)) 64 65 #define SPI_ENGINE_CMD_TRANSFER(flags, n) \ 66 SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, (flags), (n)) 67 #define SPI_ENGINE_CMD_ASSERT(delay, cs) \ 68 SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, (delay), (cs)) 69 #define SPI_ENGINE_CMD_WRITE(reg, val) \ 70 SPI_ENGINE_CMD(SPI_ENGINE_INST_WRITE, (reg), (val)) 71 #define SPI_ENGINE_CMD_SLEEP(delay) \ 72 SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SLEEP, (delay)) 73 #define SPI_ENGINE_CMD_SYNC(id) \ 74 SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SYNC, (id)) 75 76 struct spi_engine_program { 77 unsigned int length; 78 uint16_t instructions[]; 79 }; 80 81 struct spi_engine { 82 struct clk *clk; 83 struct clk *ref_clk; 84 85 spinlock_t lock; 86 87 void __iomem *base; 88 89 struct spi_message *msg; 90 struct spi_engine_program *p; 91 unsigned cmd_length; 92 const uint16_t *cmd_buf; 93 94 struct spi_transfer *tx_xfer; 95 unsigned int tx_length; 96 const uint8_t *tx_buf; 97 98 struct spi_transfer *rx_xfer; 99 unsigned int rx_length; 100 uint8_t *rx_buf; 101 102 unsigned int sync_id; 103 unsigned int completed_id; 104 105 unsigned int int_enable; 106 }; 107 108 static void spi_engine_program_add_cmd(struct spi_engine_program *p, 109 bool dry, uint16_t cmd) 110 { 111 if (!dry) 112 p->instructions[p->length] = cmd; 113 p->length++; 114 } 115 116 static unsigned int spi_engine_get_config(struct spi_device *spi) 117 { 118 unsigned int config = 0; 119 120 if (spi->mode & SPI_CPOL) 121 config |= SPI_ENGINE_CONFIG_CPOL; 122 if (spi->mode & SPI_CPHA) 123 config |= SPI_ENGINE_CONFIG_CPHA; 124 if (spi->mode & SPI_3WIRE) 125 config |= SPI_ENGINE_CONFIG_3WIRE; 126 127 return config; 128 } 129 130 static unsigned int spi_engine_get_clk_div(struct spi_engine *spi_engine, 131 struct spi_device *spi, struct spi_transfer *xfer) 132 { 133 unsigned int clk_div; 134 135 clk_div = DIV_ROUND_UP(clk_get_rate(spi_engine->ref_clk), 136 xfer->speed_hz * 2); 137 if (clk_div > 255) 138 clk_div = 255; 139 else if (clk_div > 0) 140 clk_div -= 1; 141 142 return clk_div; 143 } 144 145 static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry, 146 struct spi_transfer *xfer) 147 { 148 unsigned int len = xfer->len; 149 150 while (len) { 151 unsigned int n = min(len, 256U); 152 unsigned int flags = 0; 153 154 if (xfer->tx_buf) 155 flags |= SPI_ENGINE_TRANSFER_WRITE; 156 if (xfer->rx_buf) 157 flags |= SPI_ENGINE_TRANSFER_READ; 158 159 spi_engine_program_add_cmd(p, dry, 160 SPI_ENGINE_CMD_TRANSFER(flags, n - 1)); 161 len -= n; 162 } 163 } 164 165 static void spi_engine_gen_sleep(struct spi_engine_program *p, bool dry, 166 struct spi_engine *spi_engine, unsigned int clk_div, 167 struct spi_transfer *xfer) 168 { 169 unsigned int spi_clk = clk_get_rate(spi_engine->ref_clk); 170 unsigned int t; 171 int delay; 172 173 delay = spi_delay_to_ns(&xfer->delay, xfer); 174 if (delay < 0) 175 return; 176 delay /= 1000; 177 178 if (delay == 0) 179 return; 180 181 t = DIV_ROUND_UP(delay * spi_clk, (clk_div + 1) * 2); 182 while (t) { 183 unsigned int n = min(t, 256U); 184 185 spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_SLEEP(n - 1)); 186 t -= n; 187 } 188 } 189 190 static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry, 191 struct spi_device *spi, bool assert) 192 { 193 unsigned int mask = 0xff; 194 195 if (assert) 196 mask ^= BIT(spi->chip_select); 197 198 spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_ASSERT(1, mask)); 199 } 200 201 static int spi_engine_compile_message(struct spi_engine *spi_engine, 202 struct spi_message *msg, bool dry, struct spi_engine_program *p) 203 { 204 struct spi_device *spi = msg->spi; 205 struct spi_transfer *xfer; 206 int clk_div, new_clk_div; 207 bool cs_change = true; 208 209 clk_div = -1; 210 211 spi_engine_program_add_cmd(p, dry, 212 SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CONFIG, 213 spi_engine_get_config(spi))); 214 215 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 216 new_clk_div = spi_engine_get_clk_div(spi_engine, spi, xfer); 217 if (new_clk_div != clk_div) { 218 clk_div = new_clk_div; 219 spi_engine_program_add_cmd(p, dry, 220 SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CLK_DIV, 221 clk_div)); 222 } 223 224 if (cs_change) 225 spi_engine_gen_cs(p, dry, spi, true); 226 227 spi_engine_gen_xfer(p, dry, xfer); 228 spi_engine_gen_sleep(p, dry, spi_engine, clk_div, xfer); 229 230 cs_change = xfer->cs_change; 231 if (list_is_last(&xfer->transfer_list, &msg->transfers)) 232 cs_change = !cs_change; 233 234 if (cs_change) 235 spi_engine_gen_cs(p, dry, spi, false); 236 } 237 238 return 0; 239 } 240 241 static void spi_engine_xfer_next(struct spi_engine *spi_engine, 242 struct spi_transfer **_xfer) 243 { 244 struct spi_message *msg = spi_engine->msg; 245 struct spi_transfer *xfer = *_xfer; 246 247 if (!xfer) { 248 xfer = list_first_entry(&msg->transfers, 249 struct spi_transfer, transfer_list); 250 } else if (list_is_last(&xfer->transfer_list, &msg->transfers)) { 251 xfer = NULL; 252 } else { 253 xfer = list_next_entry(xfer, transfer_list); 254 } 255 256 *_xfer = xfer; 257 } 258 259 static void spi_engine_tx_next(struct spi_engine *spi_engine) 260 { 261 struct spi_transfer *xfer = spi_engine->tx_xfer; 262 263 do { 264 spi_engine_xfer_next(spi_engine, &xfer); 265 } while (xfer && !xfer->tx_buf); 266 267 spi_engine->tx_xfer = xfer; 268 if (xfer) { 269 spi_engine->tx_length = xfer->len; 270 spi_engine->tx_buf = xfer->tx_buf; 271 } else { 272 spi_engine->tx_buf = NULL; 273 } 274 } 275 276 static void spi_engine_rx_next(struct spi_engine *spi_engine) 277 { 278 struct spi_transfer *xfer = spi_engine->rx_xfer; 279 280 do { 281 spi_engine_xfer_next(spi_engine, &xfer); 282 } while (xfer && !xfer->rx_buf); 283 284 spi_engine->rx_xfer = xfer; 285 if (xfer) { 286 spi_engine->rx_length = xfer->len; 287 spi_engine->rx_buf = xfer->rx_buf; 288 } else { 289 spi_engine->rx_buf = NULL; 290 } 291 } 292 293 static bool spi_engine_write_cmd_fifo(struct spi_engine *spi_engine) 294 { 295 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_CMD_FIFO; 296 unsigned int n, m, i; 297 const uint16_t *buf; 298 299 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_CMD_FIFO_ROOM); 300 while (n && spi_engine->cmd_length) { 301 m = min(n, spi_engine->cmd_length); 302 buf = spi_engine->cmd_buf; 303 for (i = 0; i < m; i++) 304 writel_relaxed(buf[i], addr); 305 spi_engine->cmd_buf += m; 306 spi_engine->cmd_length -= m; 307 n -= m; 308 } 309 310 return spi_engine->cmd_length != 0; 311 } 312 313 static bool spi_engine_write_tx_fifo(struct spi_engine *spi_engine) 314 { 315 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDO_DATA_FIFO; 316 unsigned int n, m, i; 317 const uint8_t *buf; 318 319 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDO_FIFO_ROOM); 320 while (n && spi_engine->tx_length) { 321 m = min(n, spi_engine->tx_length); 322 buf = spi_engine->tx_buf; 323 for (i = 0; i < m; i++) 324 writel_relaxed(buf[i], addr); 325 spi_engine->tx_buf += m; 326 spi_engine->tx_length -= m; 327 n -= m; 328 if (spi_engine->tx_length == 0) 329 spi_engine_tx_next(spi_engine); 330 } 331 332 return spi_engine->tx_length != 0; 333 } 334 335 static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine) 336 { 337 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDI_DATA_FIFO; 338 unsigned int n, m, i; 339 uint8_t *buf; 340 341 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDI_FIFO_LEVEL); 342 while (n && spi_engine->rx_length) { 343 m = min(n, spi_engine->rx_length); 344 buf = spi_engine->rx_buf; 345 for (i = 0; i < m; i++) 346 buf[i] = readl_relaxed(addr); 347 spi_engine->rx_buf += m; 348 spi_engine->rx_length -= m; 349 n -= m; 350 if (spi_engine->rx_length == 0) 351 spi_engine_rx_next(spi_engine); 352 } 353 354 return spi_engine->rx_length != 0; 355 } 356 357 static irqreturn_t spi_engine_irq(int irq, void *devid) 358 { 359 struct spi_master *master = devid; 360 struct spi_engine *spi_engine = spi_master_get_devdata(master); 361 unsigned int disable_int = 0; 362 unsigned int pending; 363 364 pending = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_INT_PENDING); 365 366 if (pending & SPI_ENGINE_INT_SYNC) { 367 writel_relaxed(SPI_ENGINE_INT_SYNC, 368 spi_engine->base + SPI_ENGINE_REG_INT_PENDING); 369 spi_engine->completed_id = readl_relaxed( 370 spi_engine->base + SPI_ENGINE_REG_SYNC_ID); 371 } 372 373 spin_lock(&spi_engine->lock); 374 375 if (pending & SPI_ENGINE_INT_CMD_ALMOST_EMPTY) { 376 if (!spi_engine_write_cmd_fifo(spi_engine)) 377 disable_int |= SPI_ENGINE_INT_CMD_ALMOST_EMPTY; 378 } 379 380 if (pending & SPI_ENGINE_INT_SDO_ALMOST_EMPTY) { 381 if (!spi_engine_write_tx_fifo(spi_engine)) 382 disable_int |= SPI_ENGINE_INT_SDO_ALMOST_EMPTY; 383 } 384 385 if (pending & (SPI_ENGINE_INT_SDI_ALMOST_FULL | SPI_ENGINE_INT_SYNC)) { 386 if (!spi_engine_read_rx_fifo(spi_engine)) 387 disable_int |= SPI_ENGINE_INT_SDI_ALMOST_FULL; 388 } 389 390 if (pending & SPI_ENGINE_INT_SYNC) { 391 if (spi_engine->msg && 392 spi_engine->completed_id == spi_engine->sync_id) { 393 struct spi_message *msg = spi_engine->msg; 394 395 kfree(spi_engine->p); 396 msg->status = 0; 397 msg->actual_length = msg->frame_length; 398 spi_engine->msg = NULL; 399 spi_finalize_current_message(master); 400 disable_int |= SPI_ENGINE_INT_SYNC; 401 } 402 } 403 404 if (disable_int) { 405 spi_engine->int_enable &= ~disable_int; 406 writel_relaxed(spi_engine->int_enable, 407 spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); 408 } 409 410 spin_unlock(&spi_engine->lock); 411 412 return IRQ_HANDLED; 413 } 414 415 static int spi_engine_transfer_one_message(struct spi_master *master, 416 struct spi_message *msg) 417 { 418 struct spi_engine_program p_dry, *p; 419 struct spi_engine *spi_engine = spi_master_get_devdata(master); 420 unsigned int int_enable = 0; 421 unsigned long flags; 422 size_t size; 423 424 p_dry.length = 0; 425 spi_engine_compile_message(spi_engine, msg, true, &p_dry); 426 427 size = sizeof(*p->instructions) * (p_dry.length + 1); 428 p = kzalloc(sizeof(*p) + size, GFP_KERNEL); 429 if (!p) 430 return -ENOMEM; 431 spi_engine_compile_message(spi_engine, msg, false, p); 432 433 spin_lock_irqsave(&spi_engine->lock, flags); 434 spi_engine->sync_id = (spi_engine->sync_id + 1) & 0xff; 435 spi_engine_program_add_cmd(p, false, 436 SPI_ENGINE_CMD_SYNC(spi_engine->sync_id)); 437 438 spi_engine->msg = msg; 439 spi_engine->p = p; 440 441 spi_engine->cmd_buf = p->instructions; 442 spi_engine->cmd_length = p->length; 443 if (spi_engine_write_cmd_fifo(spi_engine)) 444 int_enable |= SPI_ENGINE_INT_CMD_ALMOST_EMPTY; 445 446 spi_engine_tx_next(spi_engine); 447 if (spi_engine_write_tx_fifo(spi_engine)) 448 int_enable |= SPI_ENGINE_INT_SDO_ALMOST_EMPTY; 449 450 spi_engine_rx_next(spi_engine); 451 if (spi_engine->rx_length != 0) 452 int_enable |= SPI_ENGINE_INT_SDI_ALMOST_FULL; 453 454 int_enable |= SPI_ENGINE_INT_SYNC; 455 456 writel_relaxed(int_enable, 457 spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); 458 spi_engine->int_enable = int_enable; 459 spin_unlock_irqrestore(&spi_engine->lock, flags); 460 461 return 0; 462 } 463 464 static int spi_engine_probe(struct platform_device *pdev) 465 { 466 struct spi_engine *spi_engine; 467 struct spi_master *master; 468 unsigned int version; 469 int irq; 470 int ret; 471 472 irq = platform_get_irq(pdev, 0); 473 if (irq <= 0) 474 return -ENXIO; 475 476 spi_engine = devm_kzalloc(&pdev->dev, sizeof(*spi_engine), GFP_KERNEL); 477 if (!spi_engine) 478 return -ENOMEM; 479 480 master = spi_alloc_master(&pdev->dev, 0); 481 if (!master) 482 return -ENOMEM; 483 484 spi_master_set_devdata(master, spi_engine); 485 486 spin_lock_init(&spi_engine->lock); 487 488 spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); 489 if (IS_ERR(spi_engine->clk)) { 490 ret = PTR_ERR(spi_engine->clk); 491 goto err_put_master; 492 } 493 494 spi_engine->ref_clk = devm_clk_get(&pdev->dev, "spi_clk"); 495 if (IS_ERR(spi_engine->ref_clk)) { 496 ret = PTR_ERR(spi_engine->ref_clk); 497 goto err_put_master; 498 } 499 500 ret = clk_prepare_enable(spi_engine->clk); 501 if (ret) 502 goto err_put_master; 503 504 ret = clk_prepare_enable(spi_engine->ref_clk); 505 if (ret) 506 goto err_clk_disable; 507 508 spi_engine->base = devm_platform_ioremap_resource(pdev, 0); 509 if (IS_ERR(spi_engine->base)) { 510 ret = PTR_ERR(spi_engine->base); 511 goto err_ref_clk_disable; 512 } 513 514 version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION); 515 if (SPI_ENGINE_VERSION_MAJOR(version) != 1) { 516 dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n", 517 SPI_ENGINE_VERSION_MAJOR(version), 518 SPI_ENGINE_VERSION_MINOR(version), 519 SPI_ENGINE_VERSION_PATCH(version)); 520 ret = -ENODEV; 521 goto err_ref_clk_disable; 522 } 523 524 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET); 525 writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); 526 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); 527 528 ret = request_irq(irq, spi_engine_irq, 0, pdev->name, master); 529 if (ret) 530 goto err_ref_clk_disable; 531 532 master->dev.of_node = pdev->dev.of_node; 533 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE; 534 master->bits_per_word_mask = SPI_BPW_MASK(8); 535 master->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2; 536 master->transfer_one_message = spi_engine_transfer_one_message; 537 master->num_chipselect = 8; 538 539 ret = spi_register_master(master); 540 if (ret) 541 goto err_free_irq; 542 543 platform_set_drvdata(pdev, master); 544 545 return 0; 546 err_free_irq: 547 free_irq(irq, master); 548 err_ref_clk_disable: 549 clk_disable_unprepare(spi_engine->ref_clk); 550 err_clk_disable: 551 clk_disable_unprepare(spi_engine->clk); 552 err_put_master: 553 spi_master_put(master); 554 return ret; 555 } 556 557 static int spi_engine_remove(struct platform_device *pdev) 558 { 559 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 560 struct spi_engine *spi_engine = spi_master_get_devdata(master); 561 int irq = platform_get_irq(pdev, 0); 562 563 spi_unregister_master(master); 564 565 free_irq(irq, master); 566 567 spi_master_put(master); 568 569 writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); 570 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); 571 writel_relaxed(0x01, spi_engine->base + SPI_ENGINE_REG_RESET); 572 573 clk_disable_unprepare(spi_engine->ref_clk); 574 clk_disable_unprepare(spi_engine->clk); 575 576 return 0; 577 } 578 579 static const struct of_device_id spi_engine_match_table[] = { 580 { .compatible = "adi,axi-spi-engine-1.00.a" }, 581 { }, 582 }; 583 MODULE_DEVICE_TABLE(of, spi_engine_match_table); 584 585 static struct platform_driver spi_engine_driver = { 586 .probe = spi_engine_probe, 587 .remove = spi_engine_remove, 588 .driver = { 589 .name = "spi-engine", 590 .of_match_table = spi_engine_match_table, 591 }, 592 }; 593 module_platform_driver(spi_engine_driver); 594 595 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 596 MODULE_DESCRIPTION("Analog Devices SPI engine peripheral driver"); 597 MODULE_LICENSE("GPL"); 598