Lines Matching +full:rx +full:- +full:fifo +full:- +full:depth
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2008 - 2014 Xilinx, Inc.
7 * based on Blackfin On-Chip SPI Driver (spi_bfin5xx.c)
25 #define CDNS_SPI_NAME "cdns-spi"
38 #define CDNS_SPI_THLD 0x28 /* Transmit FIFO Watermark Register,RW */
63 * SPI Configuration Register - Baud rate and target select
82 #define CDNS_SPI_IXR_TXOW 0x00000004 /* SPI TX FIFO Overwater */
84 #define CDNS_SPI_IXR_RXNEMTY 0x00000010 /* SPI RX FIFO Not Empty */
102 * struct cdns_spi - This definition defines spi driver instance
109 * @rxbuf: Pointer to the RX buffer
114 * @tx_fifo_depth: Depth of the TX FIFO
136 return readl_relaxed(xspi->regs + offset); in cdns_spi_read()
141 writel_relaxed(val, xspi->regs + offset); in cdns_spi_write()
145 * cdns_spi_init_hw - Initialize the hardware and configure the SPI controller
149 * In host mode baud rate divisor is set to 4, threshold value for TX FIFO
163 if (xspi->is_decoded_cs) in cdns_spi_init_hw()
169 /* Clear the RX FIFO */ in cdns_spi_init_hw()
179 * cdns_spi_chipselect - Select or deselect the chip select line
185 struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller); in cdns_spi_chipselect()
196 if (!(xspi->is_decoded_cs)) in cdns_spi_chipselect()
209 * cdns_spi_config_clock_mode - Sets clock polarity and phase
216 struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller); in cdns_spi_config_clock_mode()
224 if (spi->mode & SPI_CPHA) in cdns_spi_config_clock_mode()
226 if (spi->mode & SPI_CPOL) in cdns_spi_config_clock_mode()
243 * cdns_spi_config_clock_freq - Sets clock frequency
259 struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller); in cdns_spi_config_clock_freq()
263 frequency = xspi->clk_rate; in cdns_spi_config_clock_freq()
268 if (xspi->speed_hz != transfer->speed_hz) { in cdns_spi_config_clock_freq()
272 (frequency / (2 << baud_rate_val)) > transfer->speed_hz) in cdns_spi_config_clock_freq()
278 xspi->speed_hz = frequency / (2 << baud_rate_val); in cdns_spi_config_clock_freq()
284 * cdns_spi_setup_transfer - Configure SPI controller for specified transfer
297 struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller); in cdns_spi_setup_transfer()
301 dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u clock speed\n", in cdns_spi_setup_transfer()
302 __func__, spi->mode, spi->bits_per_word, in cdns_spi_setup_transfer()
303 xspi->speed_hz); in cdns_spi_setup_transfer()
309 * cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO
311 * @ntx: Number of bytes to pack into the TX FIFO
312 * @nrx: Number of bytes to drain from the RX FIFO
316 ntx = clamp(ntx, 0, xspi->tx_bytes); in cdns_spi_process_fifo()
317 nrx = clamp(nrx, 0, xspi->rx_bytes); in cdns_spi_process_fifo()
319 xspi->tx_bytes -= ntx; in cdns_spi_process_fifo()
320 xspi->rx_bytes -= nrx; in cdns_spi_process_fifo()
326 if (xspi->rxbuf) in cdns_spi_process_fifo()
327 *xspi->rxbuf++ = data; in cdns_spi_process_fifo()
329 nrx--; in cdns_spi_process_fifo()
333 if (xspi->txbuf) in cdns_spi_process_fifo()
334 cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); in cdns_spi_process_fifo()
338 ntx--; in cdns_spi_process_fifo()
345 * cdns_spi_irq - Interrupt service routine of the SPI controller
350 * On TX empty interrupt this function reads the received data from RX FIFO and
351 * fills the TX FIFO if there is any data remaining to be transferred.
354 * transferred is non-zero.
372 * transferred is non-zero in cdns_spi_irq()
379 int trans_cnt = xspi->rx_bytes - xspi->tx_bytes; in cdns_spi_irq()
382 trans_cnt -= threshold; in cdns_spi_irq()
385 * less than half fifo in cdns_spi_irq()
387 if (xspi->tx_bytes < xspi->tx_fifo_depth >> 1) in cdns_spi_irq()
390 if (xspi->tx_bytes) { in cdns_spi_irq()
413 cdns_spi_config_clock_mode(msg->spi); in cdns_prepare_message()
418 * cdns_transfer_one - Initiates the SPI transfer
424 * This function in host mode fills the TX FIFO, starts the SPI transfer and
426 * This function in target mode fills the TX FIFO and wait for transfer trigger.
436 xspi->txbuf = transfer->tx_buf; in cdns_transfer_one()
437 xspi->rxbuf = transfer->rx_buf; in cdns_transfer_one()
438 xspi->tx_bytes = transfer->len; in cdns_transfer_one()
439 xspi->rx_bytes = transfer->len; in cdns_transfer_one()
444 /* Set TX empty threshold to half of FIFO depth in cdns_transfer_one()
445 * only if TX bytes are more than FIFO depth. in cdns_transfer_one()
447 if (xspi->tx_bytes > xspi->tx_fifo_depth) in cdns_transfer_one()
448 cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1); in cdns_transfer_one()
457 cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0); in cdns_transfer_one()
460 return transfer->len; in cdns_transfer_one()
464 * cdns_prepare_transfer_hardware - Prepares hardware for transfer.
482 * cdns_unprepare_transfer_hardware - Relaxes hardware after transfer
487 * This function flush out if any pending data in FIFO.
495 unsigned int cnt = xspi->tx_fifo_depth; in cdns_unprepare_transfer_hardware()
498 while (cnt--) in cdns_unprepare_transfer_hardware()
514 * cdns_spi_detect_fifo_depth - Detect the FIFO depth of the hardware
517 * The depth of the TX FIFO is a synthesis configuration parameter of the SPI
518 * IP. The FIFO threshold register is sized so that its maximum value can be the
519 * FIFO size - 1. This is used to detect the size of the FIFO.
523 /* The MSBs will get truncated giving us the size of the FIFO */ in cdns_spi_detect_fifo_depth()
525 xspi->tx_fifo_depth = cdns_spi_read(xspi, CDNS_SPI_THLD) + 1; in cdns_spi_detect_fifo_depth()
532 * cdns_target_abort - Abort target transfer
553 * cdns_spi_probe - Probe method for the SPI driver
568 target = of_property_read_bool(pdev->dev.of_node, "spi-slave"); in cdns_spi_probe()
570 ctlr = spi_alloc_target(&pdev->dev, sizeof(*xspi)); in cdns_spi_probe()
572 ctlr = spi_alloc_host(&pdev->dev, sizeof(*xspi)); in cdns_spi_probe()
575 return -ENOMEM; in cdns_spi_probe()
578 ctlr->dev.of_node = pdev->dev.of_node; in cdns_spi_probe()
581 xspi->regs = devm_platform_ioremap_resource(pdev, 0); in cdns_spi_probe()
582 if (IS_ERR(xspi->regs)) { in cdns_spi_probe()
583 ret = PTR_ERR(xspi->regs); in cdns_spi_probe()
587 xspi->pclk = devm_clk_get_enabled(&pdev->dev, "pclk"); in cdns_spi_probe()
588 if (IS_ERR(xspi->pclk)) { in cdns_spi_probe()
589 dev_err(&pdev->dev, "pclk clock not found.\n"); in cdns_spi_probe()
590 ret = PTR_ERR(xspi->pclk); in cdns_spi_probe()
594 xspi->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, "spi"); in cdns_spi_probe()
595 if (IS_ERR(xspi->rstc)) { in cdns_spi_probe()
596 ret = dev_err_probe(&pdev->dev, PTR_ERR(xspi->rstc), in cdns_spi_probe()
601 reset_control_assert(xspi->rstc); in cdns_spi_probe()
602 reset_control_deassert(xspi->rstc); in cdns_spi_probe()
604 xspi->ref_clk = devm_clk_get_enabled(&pdev->dev, "ref_clk"); in cdns_spi_probe()
605 if (IS_ERR(xspi->ref_clk)) { in cdns_spi_probe()
606 dev_err(&pdev->dev, "ref_clk clock not found.\n"); in cdns_spi_probe()
607 ret = PTR_ERR(xspi->ref_clk); in cdns_spi_probe()
612 pm_runtime_use_autosuspend(&pdev->dev); in cdns_spi_probe()
613 pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); in cdns_spi_probe()
614 pm_runtime_get_noresume(&pdev->dev); in cdns_spi_probe()
615 pm_runtime_set_active(&pdev->dev); in cdns_spi_probe()
616 pm_runtime_enable(&pdev->dev); in cdns_spi_probe()
618 ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); in cdns_spi_probe()
620 ctlr->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; in cdns_spi_probe()
622 ctlr->num_chipselect = num_cs; in cdns_spi_probe()
624 ret = of_property_read_u32(pdev->dev.of_node, "is-decoded-cs", in cdns_spi_probe()
625 &xspi->is_decoded_cs); in cdns_spi_probe()
627 xspi->is_decoded_cs = 0; in cdns_spi_probe()
641 ret = devm_request_irq(&pdev->dev, irq, cdns_spi_irq, in cdns_spi_probe()
642 0, pdev->name, ctlr); in cdns_spi_probe()
644 ret = -ENXIO; in cdns_spi_probe()
645 dev_err(&pdev->dev, "request_irq failed\n"); in cdns_spi_probe()
649 ctlr->use_gpio_descriptors = true; in cdns_spi_probe()
650 ctlr->prepare_transfer_hardware = cdns_prepare_transfer_hardware; in cdns_spi_probe()
651 ctlr->prepare_message = cdns_prepare_message; in cdns_spi_probe()
652 ctlr->transfer_one = cdns_transfer_one; in cdns_spi_probe()
653 ctlr->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; in cdns_spi_probe()
654 ctlr->mode_bits = SPI_CPOL | SPI_CPHA; in cdns_spi_probe()
655 ctlr->bits_per_word_mask = SPI_BPW_MASK(8); in cdns_spi_probe()
658 ctlr->mode_bits |= SPI_CS_HIGH; in cdns_spi_probe()
659 ctlr->set_cs = cdns_spi_chipselect; in cdns_spi_probe()
660 ctlr->auto_runtime_pm = true; in cdns_spi_probe()
661 xspi->clk_rate = clk_get_rate(xspi->ref_clk); in cdns_spi_probe()
663 ctlr->max_speed_hz = xspi->clk_rate / 4; in cdns_spi_probe()
664 xspi->speed_hz = ctlr->max_speed_hz; in cdns_spi_probe()
665 pm_runtime_mark_last_busy(&pdev->dev); in cdns_spi_probe()
666 pm_runtime_put_autosuspend(&pdev->dev); in cdns_spi_probe()
668 ctlr->mode_bits |= SPI_NO_CS; in cdns_spi_probe()
669 ctlr->target_abort = cdns_target_abort; in cdns_spi_probe()
673 dev_err(&pdev->dev, "spi_register_controller failed\n"); in cdns_spi_probe()
681 pm_runtime_disable(&pdev->dev); in cdns_spi_probe()
682 pm_runtime_set_suspended(&pdev->dev); in cdns_spi_probe()
690 * cdns_spi_remove - Remove method for the SPI driver
705 pm_runtime_disable(&pdev->dev); in cdns_spi_remove()
706 pm_runtime_set_suspended(&pdev->dev); in cdns_spi_remove()
713 * cdns_spi_suspend - Suspend method for the SPI driver
729 * cdns_spi_resume - Resume method for the SPI driver
746 * cdns_spi_runtime_resume - Runtime resume method for the SPI driver
759 ret = clk_prepare_enable(xspi->pclk); in cdns_spi_runtime_resume()
765 ret = clk_prepare_enable(xspi->ref_clk); in cdns_spi_runtime_resume()
768 clk_disable_unprepare(xspi->pclk); in cdns_spi_runtime_resume()
775 * cdns_spi_runtime_suspend - Runtime suspend method for the SPI driver
787 clk_disable_unprepare(xspi->ref_clk); in cdns_spi_runtime_suspend()
788 clk_disable_unprepare(xspi->pclk); in cdns_spi_runtime_suspend()
800 { .compatible = "xlnx,zynq-spi-r1p6" },
801 { .compatible = "cdns,spi-r1p6" },
806 /* cdns_spi_driver - This structure defines the SPI subsystem platform driver */