Lines Matching +full:armada +full:- +full:3700 +full:- +full:spi
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Marvell Armada-3700 SPI controller driver
8 * Author: Romain Perier <romain.perier@free-electrons.com>
22 #include <linux/spi/spi.h>
30 /* SPI Register Offest */
118 return readl(a3700_spi->base + offset); in spireg_read()
123 writel(data, a3700_spi->base + offset); in spireg_write()
171 /* RX during address reception uses 4-pin */ in a3700_spi_pin_mode_set()
176 dev_err(&a3700_spi->host->dev, "wrong pin mode %u", pin_mode); in a3700_spi_pin_mode_set()
177 return -EINVAL; in a3700_spi_pin_mode_set()
223 prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); in a3700_spi_clock_set()
256 a3700_spi->byte_len = len; in a3700_spi_bytelen_set()
268 while (--timeout) { in a3700_spi_fifo_flush()
275 return -ETIMEDOUT; in a3700_spi_fifo_flush()
280 struct spi_controller *host = a3700_spi->host; in a3700_spi_init()
284 /* Reset SPI unit */ in a3700_spi_init()
295 /* Disable AUTO_CS and deactivate all chip-selects */ in a3700_spi_init()
297 for (i = 0; i < host->num_chipselect; i++) in a3700_spi_init()
303 /* Set SPI mode */ in a3700_spi_init()
304 a3700_spi_mode_set(a3700_spi, host->mode_bits); in a3700_spi_init()
326 if (!cause || !(a3700_spi->wait_mask & cause)) in a3700_spi_interrupt()
329 /* mask and acknowledge the SPI interrupts */ in a3700_spi_interrupt()
334 complete(&a3700_spi->done); in a3700_spi_interrupt()
339 static bool a3700_spi_wait_completion(struct spi_device *spi) in a3700_spi_wait_completion() argument
346 a3700_spi = spi_controller_get_devdata(spi->controller); in a3700_spi_wait_completion()
348 /* SPI interrupt is edge-triggered, which means an interrupt will in a3700_spi_wait_completion()
355 if (a3700_spi->wait_mask & ctrl_reg) in a3700_spi_wait_completion()
358 reinit_completion(&a3700_spi->done); in a3700_spi_wait_completion()
361 a3700_spi->wait_mask); in a3700_spi_wait_completion()
364 time_left = wait_for_completion_timeout(&a3700_spi->done, in a3700_spi_wait_completion()
367 a3700_spi->wait_mask = 0; in a3700_spi_wait_completion()
381 if (a3700_spi->wait_mask & ctrl_reg) in a3700_spi_wait_completion()
390 static bool a3700_spi_transfer_wait(struct spi_device *spi, in a3700_spi_transfer_wait() argument
395 a3700_spi = spi_controller_get_devdata(spi->controller); in a3700_spi_transfer_wait()
396 a3700_spi->wait_mask = bit_mask; in a3700_spi_transfer_wait()
398 return a3700_spi_wait_completion(spi); in a3700_spi_transfer_wait()
408 val |= (bytes - 1) << A3700_SPI_RFIFO_THRS_BIT; in a3700_spi_fifo_thres_set()
410 val |= (7 - bytes) << A3700_SPI_WFIFO_THRS_BIT; in a3700_spi_fifo_thres_set()
414 static void a3700_spi_transfer_setup(struct spi_device *spi, in a3700_spi_transfer_setup() argument
419 a3700_spi = spi_controller_get_devdata(spi->controller); in a3700_spi_transfer_setup()
421 a3700_spi_clock_set(a3700_spi, xfer->speed_hz); in a3700_spi_transfer_setup()
424 * with the remaining bytes for non 4-bytes aligned transfers. in a3700_spi_transfer_setup()
429 a3700_spi->tx_buf = xfer->tx_buf; in a3700_spi_transfer_setup()
430 a3700_spi->rx_buf = xfer->rx_buf; in a3700_spi_transfer_setup()
431 a3700_spi->buf_len = xfer->len; in a3700_spi_transfer_setup()
434 static void a3700_spi_set_cs(struct spi_device *spi, bool enable) in a3700_spi_set_cs() argument
436 struct a3700_spi *a3700_spi = spi_controller_get_devdata(spi->controller); in a3700_spi_set_cs()
439 a3700_spi_activate_cs(a3700_spi, spi_get_chipselect(spi, 0)); in a3700_spi_set_cs()
441 a3700_spi_deactivate_cs(a3700_spi, spi_get_chipselect(spi, 0)); in a3700_spi_set_cs()
456 if (a3700_spi->tx_buf) { in a3700_spi_header_set()
459 * bytes out of SPI output register, since it always shifts out in a3700_spi_header_set()
461 * some devices. To avoid that, use SPI header count feature to in a3700_spi_header_set()
463 * of data 4-byte aligned. in a3700_spi_header_set()
465 addr_cnt = a3700_spi->buf_len % 4; in a3700_spi_header_set()
472 a3700_spi->buf_len -= addr_cnt; in a3700_spi_header_set()
476 while (addr_cnt--) { in a3700_spi_header_set()
477 val = (val << 8) | a3700_spi->tx_buf[0]; in a3700_spi_header_set()
478 a3700_spi->tx_buf++; in a3700_spi_header_set()
497 while (!a3700_is_wfifo_full(a3700_spi) && a3700_spi->buf_len) { in a3700_spi_fifo_write()
498 val = *(u32 *)a3700_spi->tx_buf; in a3700_spi_fifo_write()
500 a3700_spi->buf_len -= 4; in a3700_spi_fifo_write()
501 a3700_spi->tx_buf += 4; in a3700_spi_fifo_write()
518 while (!a3700_is_rfifo_empty(a3700_spi) && a3700_spi->buf_len) { in a3700_spi_fifo_read()
520 if (a3700_spi->buf_len >= 4) { in a3700_spi_fifo_read()
522 memcpy(a3700_spi->rx_buf, &val, 4); in a3700_spi_fifo_read()
524 a3700_spi->buf_len -= 4; in a3700_spi_fifo_read()
525 a3700_spi->rx_buf += 4; in a3700_spi_fifo_read()
532 while (a3700_spi->buf_len) { in a3700_spi_fifo_read()
533 *a3700_spi->rx_buf = val & 0xff; in a3700_spi_fifo_read()
536 a3700_spi->buf_len--; in a3700_spi_fifo_read()
537 a3700_spi->rx_buf++; in a3700_spi_fifo_read()
554 while (--timeout) { in a3700_spi_transfer_abort_fifo()
571 struct spi_device *spi = message->spi; in a3700_spi_prepare_message() local
574 ret = clk_enable(a3700_spi->clk); in a3700_spi_prepare_message()
576 dev_err(&spi->dev, "failed to enable clk with error %d\n", ret); in a3700_spi_prepare_message()
585 a3700_spi_mode_set(a3700_spi, spi->mode); in a3700_spi_prepare_message()
591 struct spi_device *spi, in a3700_spi_transfer_one_fifo() argument
603 byte_len = xfer->bits_per_word >> 3; in a3700_spi_transfer_one_fifo()
606 if (xfer->tx_buf) in a3700_spi_transfer_one_fifo()
607 nbits = xfer->tx_nbits; in a3700_spi_transfer_one_fifo()
608 else if (xfer->rx_buf) in a3700_spi_transfer_one_fifo()
609 nbits = xfer->rx_nbits; in a3700_spi_transfer_one_fifo()
611 a3700_spi_pin_mode_set(a3700_spi, nbits, xfer->rx_buf ? true : false); in a3700_spi_transfer_one_fifo()
616 /* Transfer first bytes of data when buffer is not 4-byte aligned */ in a3700_spi_transfer_one_fifo()
619 if (xfer->rx_buf) { in a3700_spi_transfer_one_fifo()
627 a3700_spi->buf_len); in a3700_spi_transfer_one_fifo()
633 } else if (xfer->tx_buf) { in a3700_spi_transfer_one_fifo()
640 * If there are data to be written to the SPI device, xmit_data in a3700_spi_transfer_one_fifo()
642 * not require data to be written to the SPI device, then in a3700_spi_transfer_one_fifo()
645 a3700_spi->xmit_data = (a3700_spi->buf_len != 0); in a3700_spi_transfer_one_fifo()
648 while (a3700_spi->buf_len) { in a3700_spi_transfer_one_fifo()
649 if (a3700_spi->tx_buf) { in a3700_spi_transfer_one_fifo()
651 if (!a3700_spi_transfer_wait(spi, in a3700_spi_transfer_one_fifo()
653 dev_err(&spi->dev, in a3700_spi_transfer_one_fifo()
655 ret = -ETIMEDOUT; in a3700_spi_transfer_one_fifo()
662 } else if (a3700_spi->rx_buf) { in a3700_spi_transfer_one_fifo()
664 if (!a3700_spi_transfer_wait(spi, in a3700_spi_transfer_one_fifo()
666 dev_err(&spi->dev, in a3700_spi_transfer_one_fifo()
668 ret = -ETIMEDOUT; in a3700_spi_transfer_one_fifo()
680 * - wait all the bytes in wfifo to be shifted out in a3700_spi_transfer_one_fifo()
681 * - set XFER_STOP bit in a3700_spi_transfer_one_fifo()
682 * - wait XFER_START bit clear in a3700_spi_transfer_one_fifo()
683 * - clear XFER_STOP bit in a3700_spi_transfer_one_fifo()
685 * - the hardware is to reset the XFER_START bit in a3700_spi_transfer_one_fifo()
688 * - just wait XFER_START bit clear in a3700_spi_transfer_one_fifo()
690 if (a3700_spi->tx_buf) { in a3700_spi_transfer_one_fifo()
691 if (a3700_spi->xmit_data) { in a3700_spi_transfer_one_fifo()
693 * If there are data written to the SPI device, wait in a3700_spi_transfer_one_fifo()
697 if (!a3700_spi_transfer_wait(spi, in a3700_spi_transfer_one_fifo()
699 dev_err(&spi->dev, "wait wfifo empty timed out\n"); in a3700_spi_transfer_one_fifo()
700 return -ETIMEDOUT; in a3700_spi_transfer_one_fifo()
704 if (!a3700_spi_transfer_wait(spi, A3700_SPI_XFER_RDY)) { in a3700_spi_transfer_one_fifo()
705 dev_err(&spi->dev, "wait xfer ready timed out\n"); in a3700_spi_transfer_one_fifo()
706 return -ETIMEDOUT; in a3700_spi_transfer_one_fifo()
714 while (--timeout) { in a3700_spi_transfer_one_fifo()
722 dev_err(&spi->dev, "wait transfer start clear timed out\n"); in a3700_spi_transfer_one_fifo()
723 ret = -ETIMEDOUT; in a3700_spi_transfer_one_fifo()
740 struct spi_device *spi, in a3700_spi_transfer_one_full_duplex() argument
749 while (a3700_spi->buf_len) { in a3700_spi_transfer_one_full_duplex()
754 if (a3700_spi->buf_len < 4) in a3700_spi_transfer_one_full_duplex()
757 if (a3700_spi->byte_len == 1) in a3700_spi_transfer_one_full_duplex()
758 val = *a3700_spi->tx_buf; in a3700_spi_transfer_one_full_duplex()
760 val = *(u32 *)a3700_spi->tx_buf; in a3700_spi_transfer_one_full_duplex()
771 memcpy(a3700_spi->rx_buf, &val, a3700_spi->byte_len); in a3700_spi_transfer_one_full_duplex()
773 a3700_spi->buf_len -= a3700_spi->byte_len; in a3700_spi_transfer_one_full_duplex()
774 a3700_spi->tx_buf += a3700_spi->byte_len; in a3700_spi_transfer_one_full_duplex()
775 a3700_spi->rx_buf += a3700_spi->byte_len; in a3700_spi_transfer_one_full_duplex()
785 struct spi_device *spi, in a3700_spi_transfer_one() argument
788 a3700_spi_transfer_setup(spi, xfer); in a3700_spi_transfer_one()
790 if (xfer->tx_buf && xfer->rx_buf) in a3700_spi_transfer_one()
791 return a3700_spi_transfer_one_full_duplex(host, spi, xfer); in a3700_spi_transfer_one()
793 return a3700_spi_transfer_one_fifo(host, spi, xfer); in a3700_spi_transfer_one()
801 clk_disable(a3700_spi->clk); in a3700_spi_unprepare_message()
807 { .compatible = "marvell,armada-3700-spi", .data = NULL },
815 struct device *dev = &pdev->dev; in a3700_spi_probe()
816 struct device_node *of_node = dev->of_node; in a3700_spi_probe()
818 struct a3700_spi *spi; in a3700_spi_probe() local
822 host = spi_alloc_host(dev, sizeof(*spi)); in a3700_spi_probe()
825 ret = -ENOMEM; in a3700_spi_probe()
829 if (of_property_read_u32(of_node, "num-cs", &num_cs)) { in a3700_spi_probe()
830 dev_err(dev, "could not find num-cs\n"); in a3700_spi_probe()
831 ret = -ENXIO; in a3700_spi_probe()
835 host->bus_num = pdev->id; in a3700_spi_probe()
836 host->dev.of_node = of_node; in a3700_spi_probe()
837 host->mode_bits = SPI_MODE_3; in a3700_spi_probe()
838 host->num_chipselect = num_cs; in a3700_spi_probe()
839 host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32); in a3700_spi_probe()
840 host->prepare_message = a3700_spi_prepare_message; in a3700_spi_probe()
841 host->transfer_one = a3700_spi_transfer_one; in a3700_spi_probe()
842 host->unprepare_message = a3700_spi_unprepare_message; in a3700_spi_probe()
843 host->set_cs = a3700_spi_set_cs; in a3700_spi_probe()
844 host->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL | in a3700_spi_probe()
849 spi = spi_controller_get_devdata(host); in a3700_spi_probe()
851 spi->host = host; in a3700_spi_probe()
853 spi->base = devm_platform_ioremap_resource(pdev, 0); in a3700_spi_probe()
854 if (IS_ERR(spi->base)) { in a3700_spi_probe()
855 ret = PTR_ERR(spi->base); in a3700_spi_probe()
861 ret = -ENXIO; in a3700_spi_probe()
864 spi->irq = irq; in a3700_spi_probe()
866 init_completion(&spi->done); in a3700_spi_probe()
868 spi->clk = devm_clk_get_prepared(dev, NULL); in a3700_spi_probe()
869 if (IS_ERR(spi->clk)) { in a3700_spi_probe()
870 dev_err(dev, "could not find clk: %ld\n", PTR_ERR(spi->clk)); in a3700_spi_probe()
874 host->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ, in a3700_spi_probe()
875 clk_get_rate(spi->clk)); in a3700_spi_probe()
876 host->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk), in a3700_spi_probe()
879 a3700_spi_init(spi); in a3700_spi_probe()
881 ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0, in a3700_spi_probe()
912 MODULE_DESCRIPTION("Armada-3700 SPI driver");