• Home
  • Raw
  • Download

Lines Matching full:rs

213 static inline void spi_enable_chip(struct rockchip_spi *rs, int enable)  in spi_enable_chip()  argument
215 writel_relaxed((enable ? 1 : 0), rs->regs + ROCKCHIP_SPI_SSIENR); in spi_enable_chip()
218 static inline void spi_set_clk(struct rockchip_spi *rs, u16 div) in spi_set_clk() argument
220 writel_relaxed(div, rs->regs + ROCKCHIP_SPI_BAUDR); in spi_set_clk()
223 static inline void flush_fifo(struct rockchip_spi *rs) in flush_fifo() argument
225 while (readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR)) in flush_fifo()
226 readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); in flush_fifo()
229 static inline void wait_for_idle(struct rockchip_spi *rs) in wait_for_idle() argument
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()
241 static u32 get_fifo_len(struct rockchip_spi *rs) in get_fifo_len() argument
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()
256 static inline u32 tx_max(struct rockchip_spi *rs) in tx_max() argument
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()
266 static inline u32 rx_max(struct rockchip_spi *rs) in rx_max() argument
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()
277 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_set_cs() local
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()
291 ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 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()
304 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_prepare_message() local
307 rs->mode = spi->mode; in rockchip_spi_prepare_message()
316 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_handle_err() local
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()
329 flush_fifo(rs); 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()
342 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_unprepare_message() local
344 spi_enable_chip(rs, 0); in rockchip_spi_unprepare_message()
349 static void rockchip_spi_pio_writer(struct rockchip_spi *rs) in rockchip_spi_pio_writer() argument
351 u32 max = tx_max(rs); 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()
365 static void rockchip_spi_pio_reader(struct rockchip_spi *rs) in rockchip_spi_pio_reader() argument
367 u32 max = rx_max(rs); 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()
380 static int rockchip_spi_pio_transfer(struct rockchip_spi *rs) in rockchip_spi_pio_transfer() argument
385 if (rs->tx) { in rockchip_spi_pio_transfer()
386 remain = rs->tx_end - rs->tx; in rockchip_spi_pio_transfer()
387 rockchip_spi_pio_writer(rs); 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()
392 rockchip_spi_pio_reader(rs); in rockchip_spi_pio_transfer()
399 if (rs->tx) in rockchip_spi_pio_transfer()
400 wait_for_idle(rs); in rockchip_spi_pio_transfer()
402 spi_enable_chip(rs, 0); in rockchip_spi_pio_transfer()
410 struct rockchip_spi *rs = data; in rockchip_spi_dma_rxcb() local
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()
416 spi_enable_chip(rs, 0); 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()
426 struct rockchip_spi *rs = data; in rockchip_spi_dma_txcb() local
429 wait_for_idle(rs); in rockchip_spi_dma_txcb()
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()
435 spi_enable_chip(rs, 0); 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()
442 static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) in rockchip_spi_prepare_dma() argument
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()
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()
500 txdesc->callback_param = rs; 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()
523 static void rockchip_spi_config(struct rockchip_spi *rs) in rockchip_spi_config() argument
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()
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()
563 rs->max_freq, rs->rsd_nsecs); 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()
588 spi_set_clk(rs, div); in rockchip_spi_config()
590 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div); in rockchip_spi_config()
604 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_transfer_one() local
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()
610 dev_err(rs->dev, "No buffer for transfer\n"); in rockchip_spi_transfer_one()
615 dev_err(rs->dev, "Transfer is too long (%d)\n", xfer->len); 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()
641 rs->use_dma = 1; in rockchip_spi_transfer_one()
643 rs->use_dma = 0; in rockchip_spi_transfer_one()
645 rockchip_spi_config(rs); 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()
650 ret = rockchip_spi_prepare_dma(rs); in rockchip_spi_transfer_one()
651 spi_enable_chip(rs, 1); in rockchip_spi_transfer_one()
654 spi_enable_chip(rs, 1); in rockchip_spi_transfer_one()
655 ret = rockchip_spi_prepare_dma(rs); in rockchip_spi_transfer_one()
660 spi_enable_chip(rs, 1); in rockchip_spi_transfer_one()
661 ret = rockchip_spi_pio_transfer(rs); in rockchip_spi_transfer_one()
671 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_can_dma() local
673 return (xfer->len > rs->fifo_len); in rockchip_spi_can_dma()
679 struct rockchip_spi *rs; in rockchip_spi_probe() local
690 rs = spi_master_get_devdata(master); 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()
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()
710 ret = PTR_ERR(rs->spiclk); in rockchip_spi_probe()
714 ret = clk_prepare_enable(rs->apb_pclk); in rockchip_spi_probe()
720 ret = clk_prepare_enable(rs->spiclk); in rockchip_spi_probe()
726 spi_enable_chip(rs, 0); 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()
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()
744 spin_lock_init(&rs->lock); 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()
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()
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()
793 master->dma_tx = rs->dma_tx.ch; in rockchip_spi_probe()
794 master->dma_rx = rs->dma_rx.ch; 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()
814 clk_disable_unprepare(rs->spiclk); in rockchip_spi_probe()
816 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_probe()
826 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_remove() local
830 clk_disable_unprepare(rs->spiclk); in rockchip_spi_remove()
831 clk_disable_unprepare(rs->apb_pclk); 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()
852 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_suspend() local
854 ret = spi_master_suspend(rs->master); in rockchip_spi_suspend()
871 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_resume() local
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()
893 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_runtime_suspend() local
895 clk_disable_unprepare(rs->spiclk); in rockchip_spi_runtime_suspend()
896 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_runtime_suspend()
905 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_runtime_resume() local
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()