.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * TI QSPI driver |
---|
3 | 4 | * |
---|
4 | | - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com |
---|
| 5 | + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com |
---|
5 | 6 | * Author: Sourav Poddar <sourav.poddar@ti.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or |
---|
8 | | - * modify it under the terms of the GPLv2. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, |
---|
11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the |
---|
13 | | - * GNU General Public License for more details. |
---|
14 | 7 | */ |
---|
15 | 8 | |
---|
16 | 9 | #include <linux/kernel.h> |
---|
.. | .. |
---|
86 | 79 | #define QSPI_SPI_DATA_REG_3 (0x70) |
---|
87 | 80 | |
---|
88 | 81 | #define QSPI_COMPLETION_TIMEOUT msecs_to_jiffies(2000) |
---|
89 | | - |
---|
90 | | -#define QSPI_FCLK 192000000 |
---|
91 | 82 | |
---|
92 | 83 | /* Clock Control */ |
---|
93 | 84 | #define QSPI_CLK_EN (1 << 31) |
---|
.. | .. |
---|
324 | 315 | { |
---|
325 | 316 | int wlen; |
---|
326 | 317 | unsigned int cmd; |
---|
| 318 | + u32 rx; |
---|
| 319 | + u8 rxlen, rx_wlen; |
---|
327 | 320 | u8 *rxbuf; |
---|
328 | 321 | |
---|
329 | 322 | rxbuf = t->rx_buf; |
---|
.. | .. |
---|
340 | 333 | break; |
---|
341 | 334 | } |
---|
342 | 335 | wlen = t->bits_per_word >> 3; /* in bytes */ |
---|
| 336 | + rx_wlen = wlen; |
---|
343 | 337 | |
---|
344 | 338 | while (count) { |
---|
345 | 339 | dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); |
---|
346 | 340 | if (qspi_is_busy(qspi)) |
---|
347 | 341 | return -EBUSY; |
---|
348 | 342 | |
---|
| 343 | + switch (wlen) { |
---|
| 344 | + case 1: |
---|
| 345 | + /* |
---|
| 346 | + * Optimize the 8-bit words transfers, as used by |
---|
| 347 | + * the SPI flash devices. |
---|
| 348 | + */ |
---|
| 349 | + if (count >= QSPI_WLEN_MAX_BYTES) { |
---|
| 350 | + rxlen = QSPI_WLEN_MAX_BYTES; |
---|
| 351 | + } else { |
---|
| 352 | + rxlen = min(count, 4); |
---|
| 353 | + } |
---|
| 354 | + rx_wlen = rxlen << 3; |
---|
| 355 | + cmd &= ~QSPI_WLEN_MASK; |
---|
| 356 | + cmd |= QSPI_WLEN(rx_wlen); |
---|
| 357 | + break; |
---|
| 358 | + default: |
---|
| 359 | + rxlen = wlen; |
---|
| 360 | + break; |
---|
| 361 | + } |
---|
| 362 | + |
---|
349 | 363 | ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); |
---|
350 | 364 | if (ti_qspi_poll_wc(qspi)) { |
---|
351 | 365 | dev_err(qspi->dev, "read timed out\n"); |
---|
352 | 366 | return -ETIMEDOUT; |
---|
353 | 367 | } |
---|
| 368 | + |
---|
354 | 369 | switch (wlen) { |
---|
355 | 370 | case 1: |
---|
356 | | - *rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG); |
---|
| 371 | + /* |
---|
| 372 | + * Optimize the 8-bit words transfers, as used by |
---|
| 373 | + * the SPI flash devices. |
---|
| 374 | + */ |
---|
| 375 | + if (count >= QSPI_WLEN_MAX_BYTES) { |
---|
| 376 | + u32 *rxp = (u32 *) rxbuf; |
---|
| 377 | + rx = readl(qspi->base + QSPI_SPI_DATA_REG_3); |
---|
| 378 | + *rxp++ = be32_to_cpu(rx); |
---|
| 379 | + rx = readl(qspi->base + QSPI_SPI_DATA_REG_2); |
---|
| 380 | + *rxp++ = be32_to_cpu(rx); |
---|
| 381 | + rx = readl(qspi->base + QSPI_SPI_DATA_REG_1); |
---|
| 382 | + *rxp++ = be32_to_cpu(rx); |
---|
| 383 | + rx = readl(qspi->base + QSPI_SPI_DATA_REG); |
---|
| 384 | + *rxp++ = be32_to_cpu(rx); |
---|
| 385 | + } else { |
---|
| 386 | + u8 *rxp = rxbuf; |
---|
| 387 | + rx = readl(qspi->base + QSPI_SPI_DATA_REG); |
---|
| 388 | + if (rx_wlen >= 8) |
---|
| 389 | + *rxp++ = rx >> (rx_wlen - 8); |
---|
| 390 | + if (rx_wlen >= 16) |
---|
| 391 | + *rxp++ = rx >> (rx_wlen - 16); |
---|
| 392 | + if (rx_wlen >= 24) |
---|
| 393 | + *rxp++ = rx >> (rx_wlen - 24); |
---|
| 394 | + if (rx_wlen >= 32) |
---|
| 395 | + *rxp++ = rx; |
---|
| 396 | + } |
---|
357 | 397 | break; |
---|
358 | 398 | case 2: |
---|
359 | 399 | *((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG); |
---|
.. | .. |
---|
362 | 402 | *((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG); |
---|
363 | 403 | break; |
---|
364 | 404 | } |
---|
365 | | - rxbuf += wlen; |
---|
366 | | - count -= wlen; |
---|
| 405 | + rxbuf += rxlen; |
---|
| 406 | + count -= rxlen; |
---|
367 | 407 | } |
---|
368 | 408 | |
---|
369 | 409 | return 0; |
---|
.. | .. |
---|
408 | 448 | enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; |
---|
409 | 449 | struct dma_async_tx_descriptor *tx; |
---|
410 | 450 | int ret; |
---|
| 451 | + unsigned long time_left; |
---|
411 | 452 | |
---|
412 | 453 | tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags); |
---|
413 | 454 | if (!tx) { |
---|
.. | .. |
---|
427 | 468 | } |
---|
428 | 469 | |
---|
429 | 470 | dma_async_issue_pending(chan); |
---|
430 | | - ret = wait_for_completion_timeout(&qspi->transfer_complete, |
---|
| 471 | + time_left = wait_for_completion_timeout(&qspi->transfer_complete, |
---|
431 | 472 | msecs_to_jiffies(len)); |
---|
432 | | - if (ret <= 0) { |
---|
| 473 | + if (time_left == 0) { |
---|
433 | 474 | dmaengine_terminate_sync(chan); |
---|
434 | 475 | dev_err(qspi->dev, "DMA wait_for_completion_timeout\n"); |
---|
435 | 476 | return -ETIMEDOUT; |
---|
.. | .. |
---|
535 | 576 | QSPI_SPI_SETUP_REG(spi->chip_select)); |
---|
536 | 577 | } |
---|
537 | 578 | |
---|
| 579 | +static int ti_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) |
---|
| 580 | +{ |
---|
| 581 | + struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->master); |
---|
| 582 | + size_t max_len; |
---|
| 583 | + |
---|
| 584 | + if (op->data.dir == SPI_MEM_DATA_IN) { |
---|
| 585 | + if (op->addr.val < qspi->mmap_size) { |
---|
| 586 | + /* Limit MMIO to the mmaped region */ |
---|
| 587 | + if (op->addr.val + op->data.nbytes > qspi->mmap_size) { |
---|
| 588 | + max_len = qspi->mmap_size - op->addr.val; |
---|
| 589 | + op->data.nbytes = min((size_t) op->data.nbytes, |
---|
| 590 | + max_len); |
---|
| 591 | + } |
---|
| 592 | + } else { |
---|
| 593 | + /* |
---|
| 594 | + * Use fallback mode (SW generated transfers) above the |
---|
| 595 | + * mmaped region. |
---|
| 596 | + * Adjust size to comply with the QSPI max frame length. |
---|
| 597 | + */ |
---|
| 598 | + max_len = QSPI_FRAME; |
---|
| 599 | + max_len -= 1 + op->addr.nbytes + op->dummy.nbytes; |
---|
| 600 | + op->data.nbytes = min((size_t) op->data.nbytes, |
---|
| 601 | + max_len); |
---|
| 602 | + } |
---|
| 603 | + } |
---|
| 604 | + |
---|
| 605 | + return 0; |
---|
| 606 | +} |
---|
| 607 | + |
---|
538 | 608 | static int ti_qspi_exec_mem_op(struct spi_mem *mem, |
---|
539 | 609 | const struct spi_mem_op *op) |
---|
540 | 610 | { |
---|
.. | .. |
---|
585 | 655 | |
---|
586 | 656 | static const struct spi_controller_mem_ops ti_qspi_mem_ops = { |
---|
587 | 657 | .exec_op = ti_qspi_exec_mem_op, |
---|
| 658 | + .adjust_op_size = ti_qspi_adjust_op_size, |
---|
588 | 659 | }; |
---|
589 | 660 | |
---|
590 | 661 | static int ti_qspi_start_transfer_one(struct spi_master *master, |
---|
.. | .. |
---|
739 | 810 | |
---|
740 | 811 | irq = platform_get_irq(pdev, 0); |
---|
741 | 812 | if (irq < 0) { |
---|
742 | | - dev_err(&pdev->dev, "no irq resource?\n"); |
---|
743 | 813 | ret = irq; |
---|
744 | 814 | goto free_master; |
---|
745 | 815 | } |
---|