Lines Matching +full:rx +full:- +full:sample +full:- +full:delay +full:- +full:ns
3 * Author: Addy Ke <addy.ke@rock-chips.com>
26 #define DRIVER_NAME "rockchip-spi"
71 /* ss_n to sclk_out delay */
152 * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However,
196 void *rx; member
215 writel_relaxed((enable ? 1 : 0), rs->regs + ROCKCHIP_SPI_SSIENR); in spi_enable_chip()
220 writel_relaxed(div, rs->regs + ROCKCHIP_SPI_BAUDR); in spi_set_clk()
225 while (readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR)) in flush_fifo()
226 readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); in flush_fifo()
234 if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)) in wait_for_idle()
238 dev_warn(rs->dev, "spi controller is in busy state!\n"); in wait_for_idle()
246 writel_relaxed(fifo, rs->regs + ROCKCHIP_SPI_TXFTLR); in get_fifo_len()
247 if (fifo != readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFTLR)) in get_fifo_len()
251 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_TXFTLR); in get_fifo_len()
260 tx_left = (rs->tx_end - rs->tx) / rs->n_bytes; in tx_max()
261 tx_room = rs->fifo_len - readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFLR); in tx_max()
268 u32 rx_left = (rs->rx_end - rs->rx) / rs->n_bytes; in rx_max()
269 u32 rx_room = (u32)readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR); in rx_max()
276 struct spi_master *master = spi->master; in rockchip_spi_set_cs()
280 /* Return immediately for no-op */ in rockchip_spi_set_cs()
281 if (cs_asserted == rs->cs_asserted[spi->chip_select]) in rockchip_spi_set_cs()
286 pm_runtime_get_sync(rs->dev); in rockchip_spi_set_cs()
288 ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, in rockchip_spi_set_cs()
289 BIT(spi->chip_select)); in rockchip_spi_set_cs()
291 ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, in rockchip_spi_set_cs()
292 BIT(spi->chip_select)); in rockchip_spi_set_cs()
295 pm_runtime_put(rs->dev); in rockchip_spi_set_cs()
298 rs->cs_asserted[spi->chip_select] = cs_asserted; in rockchip_spi_set_cs()
305 struct spi_device *spi = msg->spi; in rockchip_spi_prepare_message()
307 rs->mode = spi->mode; in rockchip_spi_prepare_message()
318 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_handle_err()
326 if (rs->use_dma) { in rockchip_spi_handle_err()
327 if (rs->state & RXBUSY) { in rockchip_spi_handle_err()
328 dmaengine_terminate_async(rs->dma_rx.ch); in rockchip_spi_handle_err()
332 if (rs->state & TXBUSY) in rockchip_spi_handle_err()
333 dmaengine_terminate_async(rs->dma_tx.ch); in rockchip_spi_handle_err()
336 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_handle_err()
354 while (max--) { in rockchip_spi_pio_writer()
355 if (rs->n_bytes == 1) in rockchip_spi_pio_writer()
356 txw = *(u8 *)(rs->tx); in rockchip_spi_pio_writer()
358 txw = *(u16 *)(rs->tx); in rockchip_spi_pio_writer()
360 writel_relaxed(txw, rs->regs + ROCKCHIP_SPI_TXDR); in rockchip_spi_pio_writer()
361 rs->tx += rs->n_bytes; in rockchip_spi_pio_writer()
370 while (max--) { in rockchip_spi_pio_reader()
371 rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); in rockchip_spi_pio_reader()
372 if (rs->n_bytes == 1) in rockchip_spi_pio_reader()
373 *(u8 *)(rs->rx) = (u8)rxw; in rockchip_spi_pio_reader()
375 *(u16 *)(rs->rx) = (u16)rxw; in rockchip_spi_pio_reader()
376 rs->rx += rs->n_bytes; in rockchip_spi_pio_reader()
385 if (rs->tx) { in rockchip_spi_pio_transfer()
386 remain = rs->tx_end - rs->tx; in rockchip_spi_pio_transfer()
390 if (rs->rx) { in rockchip_spi_pio_transfer()
391 remain = rs->rx_end - rs->rx; in rockchip_spi_pio_transfer()
399 if (rs->tx) in rockchip_spi_pio_transfer()
412 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_dma_rxcb()
414 rs->state &= ~RXBUSY; in rockchip_spi_dma_rxcb()
415 if (!(rs->state & TXBUSY)) { in rockchip_spi_dma_rxcb()
417 spi_finalize_current_transfer(rs->master); in rockchip_spi_dma_rxcb()
420 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_dma_rxcb()
431 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_dma_txcb()
433 rs->state &= ~TXBUSY; in rockchip_spi_dma_txcb()
434 if (!(rs->state & RXBUSY)) { in rockchip_spi_dma_txcb()
436 spi_finalize_current_transfer(rs->master); in rockchip_spi_dma_txcb()
439 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_dma_txcb()
451 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_prepare_dma()
452 rs->state &= ~RXBUSY; in rockchip_spi_prepare_dma()
453 rs->state &= ~TXBUSY; in rockchip_spi_prepare_dma()
454 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_prepare_dma()
457 if (rs->rx) { in rockchip_spi_prepare_dma()
458 rxconf.direction = rs->dma_rx.direction; in rockchip_spi_prepare_dma()
459 rxconf.src_addr = rs->dma_rx.addr; in rockchip_spi_prepare_dma()
460 rxconf.src_addr_width = rs->n_bytes; in rockchip_spi_prepare_dma()
461 if (rs->dma_caps.max_burst > 4) in rockchip_spi_prepare_dma()
465 dmaengine_slave_config(rs->dma_rx.ch, &rxconf); in rockchip_spi_prepare_dma()
468 rs->dma_rx.ch, in rockchip_spi_prepare_dma()
469 rs->rx_sg.sgl, rs->rx_sg.nents, in rockchip_spi_prepare_dma()
470 rs->dma_rx.direction, DMA_PREP_INTERRUPT); in rockchip_spi_prepare_dma()
472 return -EINVAL; in rockchip_spi_prepare_dma()
474 rxdesc->callback = rockchip_spi_dma_rxcb; in rockchip_spi_prepare_dma()
475 rxdesc->callback_param = rs; in rockchip_spi_prepare_dma()
479 if (rs->tx) { in rockchip_spi_prepare_dma()
480 txconf.direction = rs->dma_tx.direction; in rockchip_spi_prepare_dma()
481 txconf.dst_addr = rs->dma_tx.addr; in rockchip_spi_prepare_dma()
482 txconf.dst_addr_width = rs->n_bytes; in rockchip_spi_prepare_dma()
483 if (rs->dma_caps.max_burst > 4) in rockchip_spi_prepare_dma()
487 dmaengine_slave_config(rs->dma_tx.ch, &txconf); in rockchip_spi_prepare_dma()
490 rs->dma_tx.ch, in rockchip_spi_prepare_dma()
491 rs->tx_sg.sgl, rs->tx_sg.nents, in rockchip_spi_prepare_dma()
492 rs->dma_tx.direction, DMA_PREP_INTERRUPT); in rockchip_spi_prepare_dma()
495 dmaengine_terminate_sync(rs->dma_rx.ch); in rockchip_spi_prepare_dma()
496 return -EINVAL; in rockchip_spi_prepare_dma()
499 txdesc->callback = rockchip_spi_dma_txcb; in rockchip_spi_prepare_dma()
500 txdesc->callback_param = rs; in rockchip_spi_prepare_dma()
503 /* rx must be started before tx due to spi instinct */ in rockchip_spi_prepare_dma()
505 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_prepare_dma()
506 rs->state |= RXBUSY; in rockchip_spi_prepare_dma()
507 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_prepare_dma()
509 dma_async_issue_pending(rs->dma_rx.ch); in rockchip_spi_prepare_dma()
513 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_prepare_dma()
514 rs->state |= TXBUSY; in rockchip_spi_prepare_dma()
515 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_prepare_dma()
517 dma_async_issue_pending(rs->dma_tx.ch); in rockchip_spi_prepare_dma()
533 cr0 |= (rs->n_bytes << CR0_DFS_OFFSET); in rockchip_spi_config()
534 cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET); in rockchip_spi_config()
535 cr0 |= (rs->tmode << CR0_XFM_OFFSET); in rockchip_spi_config()
536 cr0 |= (rs->type << CR0_FRF_OFFSET); in rockchip_spi_config()
538 if (rs->use_dma) { in rockchip_spi_config()
539 if (rs->tx) in rockchip_spi_config()
541 if (rs->rx) in rockchip_spi_config()
545 if (WARN_ON(rs->speed > MAX_SCLK_OUT)) in rockchip_spi_config()
546 rs->speed = MAX_SCLK_OUT; in rockchip_spi_config()
549 if (rs->max_freq < 2 * rs->speed) { in rockchip_spi_config()
550 clk_set_rate(rs->spiclk, 2 * rs->speed); in rockchip_spi_config()
551 rs->max_freq = clk_get_rate(rs->spiclk); in rockchip_spi_config()
555 div = DIV_ROUND_UP(rs->max_freq, rs->speed); in rockchip_spi_config()
558 /* Rx sample delay is expressed in parent clock cycles (max 3) */ in rockchip_spi_config()
559 rsd = DIV_ROUND_CLOSEST(rs->rsd_nsecs * (rs->max_freq >> 8), in rockchip_spi_config()
561 if (!rsd && rs->rsd_nsecs) { in rockchip_spi_config()
562 pr_warn_once("rockchip-spi: %u Hz are too slow to express %u ns delay\n", in rockchip_spi_config()
563 rs->max_freq, rs->rsd_nsecs); in rockchip_spi_config()
566 pr_warn_once("rockchip-spi: %u Hz are too fast to express %u ns delay, clamping at %u ns\n", in rockchip_spi_config()
567 rs->max_freq, rs->rsd_nsecs, in rockchip_spi_config()
568 rsd * 1000000000U / rs->max_freq); in rockchip_spi_config()
572 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0); in rockchip_spi_config()
574 if (rs->n_bytes == 1) in rockchip_spi_config()
575 writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); in rockchip_spi_config()
576 else if (rs->n_bytes == 2) in rockchip_spi_config()
577 writel_relaxed((rs->len / 2) - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); in rockchip_spi_config()
579 writel_relaxed((rs->len * 2) - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); in rockchip_spi_config()
581 writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_TXFTLR); in rockchip_spi_config()
582 writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR); in rockchip_spi_config()
584 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMATDLR); in rockchip_spi_config()
585 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMARDLR); in rockchip_spi_config()
586 writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR); in rockchip_spi_config()
590 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div); in rockchip_spi_config()
606 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && in rockchip_spi_transfer_one()
607 (readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)); in rockchip_spi_transfer_one()
609 if (!xfer->tx_buf && !xfer->rx_buf) { in rockchip_spi_transfer_one()
610 dev_err(rs->dev, "No buffer for transfer\n"); in rockchip_spi_transfer_one()
611 return -EINVAL; in rockchip_spi_transfer_one()
614 if (xfer->len > ROCKCHIP_SPI_MAX_TRANLEN) { in rockchip_spi_transfer_one()
615 dev_err(rs->dev, "Transfer is too long (%d)\n", xfer->len); in rockchip_spi_transfer_one()
616 return -EINVAL; in rockchip_spi_transfer_one()
619 rs->speed = xfer->speed_hz; in rockchip_spi_transfer_one()
620 rs->bpw = xfer->bits_per_word; in rockchip_spi_transfer_one()
621 rs->n_bytes = rs->bpw >> 3; in rockchip_spi_transfer_one()
623 rs->tx = xfer->tx_buf; in rockchip_spi_transfer_one()
624 rs->tx_end = rs->tx + xfer->len; in rockchip_spi_transfer_one()
625 rs->rx = xfer->rx_buf; in rockchip_spi_transfer_one()
626 rs->rx_end = rs->rx + xfer->len; in rockchip_spi_transfer_one()
627 rs->len = xfer->len; in rockchip_spi_transfer_one()
629 rs->tx_sg = xfer->tx_sg; in rockchip_spi_transfer_one()
630 rs->rx_sg = xfer->rx_sg; in rockchip_spi_transfer_one()
632 if (rs->tx && rs->rx) in rockchip_spi_transfer_one()
633 rs->tmode = CR0_XFM_TR; in rockchip_spi_transfer_one()
634 else if (rs->tx) in rockchip_spi_transfer_one()
635 rs->tmode = CR0_XFM_TO; in rockchip_spi_transfer_one()
636 else if (rs->rx) in rockchip_spi_transfer_one()
637 rs->tmode = CR0_XFM_RO; in rockchip_spi_transfer_one()
640 if (master->can_dma && master->can_dma(master, spi, xfer)) in rockchip_spi_transfer_one()
641 rs->use_dma = 1; in rockchip_spi_transfer_one()
643 rs->use_dma = 0; in rockchip_spi_transfer_one()
647 if (rs->use_dma) { in rockchip_spi_transfer_one()
648 if (rs->tmode == CR0_XFM_RO) { in rockchip_spi_transfer_one()
649 /* rx: dma must be prepared first */ in rockchip_spi_transfer_one()
673 return (xfer->len > rs->fifo_len); in rockchip_spi_can_dma()
684 master = spi_alloc_master(&pdev->dev, sizeof(struct rockchip_spi)); in rockchip_spi_probe()
686 return -ENOMEM; in rockchip_spi_probe()
694 rs->regs = devm_ioremap_resource(&pdev->dev, mem); in rockchip_spi_probe()
695 if (IS_ERR(rs->regs)) { in rockchip_spi_probe()
696 ret = PTR_ERR(rs->regs); in rockchip_spi_probe()
700 rs->apb_pclk = devm_clk_get(&pdev->dev, "apb_pclk"); in rockchip_spi_probe()
701 if (IS_ERR(rs->apb_pclk)) { in rockchip_spi_probe()
702 dev_err(&pdev->dev, "Failed to get apb_pclk\n"); in rockchip_spi_probe()
703 ret = PTR_ERR(rs->apb_pclk); in rockchip_spi_probe()
707 rs->spiclk = devm_clk_get(&pdev->dev, "spiclk"); in rockchip_spi_probe()
708 if (IS_ERR(rs->spiclk)) { in rockchip_spi_probe()
709 dev_err(&pdev->dev, "Failed to get spi_pclk\n"); in rockchip_spi_probe()
710 ret = PTR_ERR(rs->spiclk); in rockchip_spi_probe()
714 ret = clk_prepare_enable(rs->apb_pclk); in rockchip_spi_probe()
716 dev_err(&pdev->dev, "Failed to enable apb_pclk\n"); in rockchip_spi_probe()
720 ret = clk_prepare_enable(rs->spiclk); in rockchip_spi_probe()
722 dev_err(&pdev->dev, "Failed to enable spi_clk\n"); in rockchip_spi_probe()
728 rs->type = SSI_MOTO_SPI; in rockchip_spi_probe()
729 rs->master = master; in rockchip_spi_probe()
730 rs->dev = &pdev->dev; in rockchip_spi_probe()
731 rs->max_freq = clk_get_rate(rs->spiclk); in rockchip_spi_probe()
733 if (!of_property_read_u32(pdev->dev.of_node, "rx-sample-delay-ns", in rockchip_spi_probe()
735 rs->rsd_nsecs = rsd_nsecs; in rockchip_spi_probe()
737 rs->fifo_len = get_fifo_len(rs); in rockchip_spi_probe()
738 if (!rs->fifo_len) { in rockchip_spi_probe()
739 dev_err(&pdev->dev, "Failed to get fifo length\n"); in rockchip_spi_probe()
740 ret = -EINVAL; in rockchip_spi_probe()
744 spin_lock_init(&rs->lock); in rockchip_spi_probe()
746 pm_runtime_set_active(&pdev->dev); in rockchip_spi_probe()
747 pm_runtime_enable(&pdev->dev); in rockchip_spi_probe()
749 master->auto_runtime_pm = true; in rockchip_spi_probe()
750 master->bus_num = pdev->id; in rockchip_spi_probe()
751 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP; in rockchip_spi_probe()
752 master->num_chipselect = ROCKCHIP_SPI_MAX_CS_NUM; in rockchip_spi_probe()
753 master->dev.of_node = pdev->dev.of_node; in rockchip_spi_probe()
754 master->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8); in rockchip_spi_probe()
756 master->set_cs = rockchip_spi_set_cs; in rockchip_spi_probe()
757 master->prepare_message = rockchip_spi_prepare_message; in rockchip_spi_probe()
758 master->unprepare_message = rockchip_spi_unprepare_message; in rockchip_spi_probe()
759 master->transfer_one = rockchip_spi_transfer_one; in rockchip_spi_probe()
760 master->max_transfer_size = rockchip_spi_max_transfer_size; in rockchip_spi_probe()
761 master->handle_err = rockchip_spi_handle_err; in rockchip_spi_probe()
762 master->flags = SPI_MASTER_GPIO_SS; in rockchip_spi_probe()
764 rs->dma_tx.ch = dma_request_chan(rs->dev, "tx"); in rockchip_spi_probe()
765 if (IS_ERR(rs->dma_tx.ch)) { in rockchip_spi_probe()
767 if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) { in rockchip_spi_probe()
768 ret = -EPROBE_DEFER; in rockchip_spi_probe()
771 dev_warn(rs->dev, "Failed to request TX DMA channel\n"); in rockchip_spi_probe()
772 rs->dma_tx.ch = NULL; in rockchip_spi_probe()
775 rs->dma_rx.ch = dma_request_chan(rs->dev, "rx"); in rockchip_spi_probe()
776 if (IS_ERR(rs->dma_rx.ch)) { in rockchip_spi_probe()
777 if (PTR_ERR(rs->dma_rx.ch) == -EPROBE_DEFER) { in rockchip_spi_probe()
778 ret = -EPROBE_DEFER; in rockchip_spi_probe()
781 dev_warn(rs->dev, "Failed to request RX DMA channel\n"); in rockchip_spi_probe()
782 rs->dma_rx.ch = NULL; in rockchip_spi_probe()
785 if (rs->dma_tx.ch && rs->dma_rx.ch) { in rockchip_spi_probe()
786 dma_get_slave_caps(rs->dma_rx.ch, &(rs->dma_caps)); in rockchip_spi_probe()
787 rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); in rockchip_spi_probe()
788 rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); in rockchip_spi_probe()
789 rs->dma_tx.direction = DMA_MEM_TO_DEV; in rockchip_spi_probe()
790 rs->dma_rx.direction = DMA_DEV_TO_MEM; in rockchip_spi_probe()
792 master->can_dma = rockchip_spi_can_dma; in rockchip_spi_probe()
793 master->dma_tx = rs->dma_tx.ch; in rockchip_spi_probe()
794 master->dma_rx = rs->dma_rx.ch; in rockchip_spi_probe()
797 ret = devm_spi_register_master(&pdev->dev, master); in rockchip_spi_probe()
799 dev_err(&pdev->dev, "Failed to register master\n"); in rockchip_spi_probe()
806 if (rs->dma_rx.ch) in rockchip_spi_probe()
807 dma_release_channel(rs->dma_rx.ch); in rockchip_spi_probe()
809 if (rs->dma_tx.ch) in rockchip_spi_probe()
810 dma_release_channel(rs->dma_tx.ch); in rockchip_spi_probe()
812 pm_runtime_disable(&pdev->dev); in rockchip_spi_probe()
814 clk_disable_unprepare(rs->spiclk); in rockchip_spi_probe()
816 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_probe()
828 pm_runtime_get_sync(&pdev->dev); in rockchip_spi_remove()
830 clk_disable_unprepare(rs->spiclk); in rockchip_spi_remove()
831 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_remove()
833 pm_runtime_put_noidle(&pdev->dev); in rockchip_spi_remove()
834 pm_runtime_disable(&pdev->dev); in rockchip_spi_remove()
835 pm_runtime_set_suspended(&pdev->dev); in rockchip_spi_remove()
837 if (rs->dma_tx.ch) in rockchip_spi_remove()
838 dma_release_channel(rs->dma_tx.ch); in rockchip_spi_remove()
839 if (rs->dma_rx.ch) in rockchip_spi_remove()
840 dma_release_channel(rs->dma_rx.ch); in rockchip_spi_remove()
854 ret = spi_master_suspend(rs->master); in rockchip_spi_suspend()
879 ret = spi_master_resume(rs->master); in rockchip_spi_resume()
881 clk_disable_unprepare(rs->spiclk); in rockchip_spi_resume()
882 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_resume()
895 clk_disable_unprepare(rs->spiclk); in rockchip_spi_runtime_suspend()
896 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_runtime_suspend()
907 ret = clk_prepare_enable(rs->apb_pclk); in rockchip_spi_runtime_resume()
911 ret = clk_prepare_enable(rs->spiclk); in rockchip_spi_runtime_resume()
913 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_runtime_resume()
926 { .compatible = "rockchip,rv1108-spi", },
927 { .compatible = "rockchip,rk3036-spi", },
928 { .compatible = "rockchip,rk3066-spi", },
929 { .compatible = "rockchip,rk3188-spi", },
930 { .compatible = "rockchip,rk3228-spi", },
931 { .compatible = "rockchip,rk3288-spi", },
932 { .compatible = "rockchip,rk3368-spi", },
933 { .compatible = "rockchip,rk3399-spi", },
950 MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");