Lines Matching refs:rs
204 static inline void spi_enable_chip(struct rockchip_spi *rs, int enable) in spi_enable_chip() argument
206 writel_relaxed((enable ? 1 : 0), rs->regs + ROCKCHIP_SPI_SSIENR); in spi_enable_chip()
209 static inline void spi_set_clk(struct rockchip_spi *rs, u16 div) in spi_set_clk() argument
211 writel_relaxed(div, rs->regs + ROCKCHIP_SPI_BAUDR); in spi_set_clk()
214 static inline void flush_fifo(struct rockchip_spi *rs) in flush_fifo() argument
216 while (readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR)) in flush_fifo()
217 readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); in flush_fifo()
220 static inline void wait_for_idle(struct rockchip_spi *rs) in wait_for_idle() argument
225 if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)) in wait_for_idle()
229 dev_warn(rs->dev, "spi controller is in busy state!\n"); in wait_for_idle()
232 static u32 get_fifo_len(struct rockchip_spi *rs) in get_fifo_len() argument
237 writel_relaxed(fifo, rs->regs + ROCKCHIP_SPI_TXFTLR); in get_fifo_len()
238 if (fifo != readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFTLR)) in get_fifo_len()
242 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_TXFTLR); in get_fifo_len()
247 static inline u32 tx_max(struct rockchip_spi *rs) in tx_max() argument
251 tx_left = (rs->tx_end - rs->tx) / rs->n_bytes; in tx_max()
252 tx_room = rs->fifo_len - readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFLR); in tx_max()
257 static inline u32 rx_max(struct rockchip_spi *rs) in rx_max() argument
259 u32 rx_left = (rs->rx_end - rs->rx) / rs->n_bytes; in rx_max()
260 u32 rx_room = (u32)readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR); in rx_max()
269 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_set_cs() local
271 pm_runtime_get_sync(rs->dev); in rockchip_spi_set_cs()
273 ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK; in rockchip_spi_set_cs()
295 writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER); in rockchip_spi_set_cs()
297 pm_runtime_put_sync(rs->dev); in rockchip_spi_set_cs()
303 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_prepare_message() local
306 rs->mode = spi->mode; in rockchip_spi_prepare_message()
315 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_handle_err() local
317 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_handle_err()
325 if (rs->use_dma) { in rockchip_spi_handle_err()
326 if (rs->state & RXBUSY) { in rockchip_spi_handle_err()
327 dmaengine_terminate_all(rs->dma_rx.ch); in rockchip_spi_handle_err()
328 flush_fifo(rs); in rockchip_spi_handle_err()
331 if (rs->state & TXBUSY) in rockchip_spi_handle_err()
332 dmaengine_terminate_all(rs->dma_tx.ch); in rockchip_spi_handle_err()
335 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_handle_err()
341 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_unprepare_message() local
343 spi_enable_chip(rs, 0); in rockchip_spi_unprepare_message()
348 static void rockchip_spi_pio_writer(struct rockchip_spi *rs) in rockchip_spi_pio_writer() argument
350 u32 max = tx_max(rs); in rockchip_spi_pio_writer()
354 if (rs->n_bytes == 1) in rockchip_spi_pio_writer()
355 txw = *(u8 *)(rs->tx); in rockchip_spi_pio_writer()
357 txw = *(u16 *)(rs->tx); in rockchip_spi_pio_writer()
359 writel_relaxed(txw, rs->regs + ROCKCHIP_SPI_TXDR); in rockchip_spi_pio_writer()
360 rs->tx += rs->n_bytes; in rockchip_spi_pio_writer()
364 static void rockchip_spi_pio_reader(struct rockchip_spi *rs) in rockchip_spi_pio_reader() argument
366 u32 max = rx_max(rs); in rockchip_spi_pio_reader()
370 rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); in rockchip_spi_pio_reader()
371 if (rs->n_bytes == 1) in rockchip_spi_pio_reader()
372 *(u8 *)(rs->rx) = (u8)rxw; in rockchip_spi_pio_reader()
374 *(u16 *)(rs->rx) = (u16)rxw; in rockchip_spi_pio_reader()
375 rs->rx += rs->n_bytes; in rockchip_spi_pio_reader()
379 static int rockchip_spi_pio_transfer(struct rockchip_spi *rs) in rockchip_spi_pio_transfer() argument
384 if (rs->tx) { in rockchip_spi_pio_transfer()
385 remain = rs->tx_end - rs->tx; in rockchip_spi_pio_transfer()
386 rockchip_spi_pio_writer(rs); in rockchip_spi_pio_transfer()
389 if (rs->rx) { in rockchip_spi_pio_transfer()
390 remain = rs->rx_end - rs->rx; in rockchip_spi_pio_transfer()
391 rockchip_spi_pio_reader(rs); in rockchip_spi_pio_transfer()
398 if (rs->tx) in rockchip_spi_pio_transfer()
399 wait_for_idle(rs); in rockchip_spi_pio_transfer()
401 spi_enable_chip(rs, 0); in rockchip_spi_pio_transfer()
409 struct rockchip_spi *rs = data; in rockchip_spi_dma_rxcb() local
411 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_dma_rxcb()
413 rs->state &= ~RXBUSY; in rockchip_spi_dma_rxcb()
414 if (!(rs->state & TXBUSY)) { in rockchip_spi_dma_rxcb()
415 spi_enable_chip(rs, 0); in rockchip_spi_dma_rxcb()
416 spi_finalize_current_transfer(rs->master); in rockchip_spi_dma_rxcb()
419 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_dma_rxcb()
425 struct rockchip_spi *rs = data; in rockchip_spi_dma_txcb() local
428 wait_for_idle(rs); in rockchip_spi_dma_txcb()
430 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_dma_txcb()
432 rs->state &= ~TXBUSY; in rockchip_spi_dma_txcb()
433 if (!(rs->state & RXBUSY)) { in rockchip_spi_dma_txcb()
434 spi_enable_chip(rs, 0); in rockchip_spi_dma_txcb()
435 spi_finalize_current_transfer(rs->master); in rockchip_spi_dma_txcb()
438 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_dma_txcb()
441 static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) in rockchip_spi_prepare_dma() argument
447 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_prepare_dma()
448 rs->state &= ~RXBUSY; in rockchip_spi_prepare_dma()
449 rs->state &= ~TXBUSY; in rockchip_spi_prepare_dma()
450 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_prepare_dma()
453 if (rs->rx) { in rockchip_spi_prepare_dma()
454 rxconf.direction = rs->dma_rx.direction; in rockchip_spi_prepare_dma()
455 rxconf.src_addr = rs->dma_rx.addr; in rockchip_spi_prepare_dma()
456 rxconf.src_addr_width = rs->n_bytes; in rockchip_spi_prepare_dma()
457 rxconf.src_maxburst = rs->n_bytes; in rockchip_spi_prepare_dma()
458 dmaengine_slave_config(rs->dma_rx.ch, &rxconf); in rockchip_spi_prepare_dma()
461 rs->dma_rx.ch, in rockchip_spi_prepare_dma()
462 rs->rx_sg.sgl, rs->rx_sg.nents, in rockchip_spi_prepare_dma()
463 rs->dma_rx.direction, DMA_PREP_INTERRUPT); in rockchip_spi_prepare_dma()
466 rxdesc->callback_param = rs; in rockchip_spi_prepare_dma()
470 if (rs->tx) { in rockchip_spi_prepare_dma()
471 txconf.direction = rs->dma_tx.direction; in rockchip_spi_prepare_dma()
472 txconf.dst_addr = rs->dma_tx.addr; in rockchip_spi_prepare_dma()
473 txconf.dst_addr_width = rs->n_bytes; in rockchip_spi_prepare_dma()
474 txconf.dst_maxburst = rs->n_bytes; in rockchip_spi_prepare_dma()
475 dmaengine_slave_config(rs->dma_tx.ch, &txconf); in rockchip_spi_prepare_dma()
478 rs->dma_tx.ch, in rockchip_spi_prepare_dma()
479 rs->tx_sg.sgl, rs->tx_sg.nents, in rockchip_spi_prepare_dma()
480 rs->dma_tx.direction, DMA_PREP_INTERRUPT); in rockchip_spi_prepare_dma()
483 txdesc->callback_param = rs; in rockchip_spi_prepare_dma()
488 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_prepare_dma()
489 rs->state |= RXBUSY; in rockchip_spi_prepare_dma()
490 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_prepare_dma()
492 dma_async_issue_pending(rs->dma_rx.ch); in rockchip_spi_prepare_dma()
496 spin_lock_irqsave(&rs->lock, flags); in rockchip_spi_prepare_dma()
497 rs->state |= TXBUSY; in rockchip_spi_prepare_dma()
498 spin_unlock_irqrestore(&rs->lock, flags); in rockchip_spi_prepare_dma()
500 dma_async_issue_pending(rs->dma_tx.ch); in rockchip_spi_prepare_dma()
504 static void rockchip_spi_config(struct rockchip_spi *rs) in rockchip_spi_config() argument
513 cr0 |= (rs->n_bytes << CR0_DFS_OFFSET); in rockchip_spi_config()
514 cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET); in rockchip_spi_config()
515 cr0 |= (rs->tmode << CR0_XFM_OFFSET); in rockchip_spi_config()
516 cr0 |= (rs->type << CR0_FRF_OFFSET); in rockchip_spi_config()
518 if (rs->use_dma) { in rockchip_spi_config()
519 if (rs->tx) in rockchip_spi_config()
521 if (rs->rx) in rockchip_spi_config()
525 if (WARN_ON(rs->speed > MAX_SCLK_OUT)) in rockchip_spi_config()
526 rs->speed = MAX_SCLK_OUT; in rockchip_spi_config()
529 if (rs->max_freq < 2 * rs->speed) { in rockchip_spi_config()
530 clk_set_rate(rs->spiclk, 2 * rs->speed); in rockchip_spi_config()
531 rs->max_freq = clk_get_rate(rs->spiclk); in rockchip_spi_config()
535 div = DIV_ROUND_UP(rs->max_freq, rs->speed); in rockchip_spi_config()
539 rsd = DIV_ROUND_CLOSEST(rs->rsd_nsecs * (rs->max_freq >> 8), in rockchip_spi_config()
541 if (!rsd && rs->rsd_nsecs) { in rockchip_spi_config()
543 rs->max_freq, rs->rsd_nsecs); in rockchip_spi_config()
547 rs->max_freq, rs->rsd_nsecs, in rockchip_spi_config()
548 rsd * 1000000000U / rs->max_freq); in rockchip_spi_config()
552 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0); in rockchip_spi_config()
554 writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); in rockchip_spi_config()
555 writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_TXFTLR); in rockchip_spi_config()
556 writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR); in rockchip_spi_config()
558 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMATDLR); in rockchip_spi_config()
559 writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMARDLR); in rockchip_spi_config()
560 writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR); in rockchip_spi_config()
562 spi_set_clk(rs, div); in rockchip_spi_config()
564 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div); in rockchip_spi_config()
573 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_transfer_one() local
575 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && in rockchip_spi_transfer_one()
576 (readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)); in rockchip_spi_transfer_one()
579 dev_err(rs->dev, "No buffer for transfer\n"); in rockchip_spi_transfer_one()
583 rs->speed = xfer->speed_hz; in rockchip_spi_transfer_one()
584 rs->bpw = xfer->bits_per_word; in rockchip_spi_transfer_one()
585 rs->n_bytes = rs->bpw >> 3; in rockchip_spi_transfer_one()
587 rs->tx = xfer->tx_buf; in rockchip_spi_transfer_one()
588 rs->tx_end = rs->tx + xfer->len; in rockchip_spi_transfer_one()
589 rs->rx = xfer->rx_buf; in rockchip_spi_transfer_one()
590 rs->rx_end = rs->rx + xfer->len; in rockchip_spi_transfer_one()
591 rs->len = xfer->len; in rockchip_spi_transfer_one()
593 rs->tx_sg = xfer->tx_sg; in rockchip_spi_transfer_one()
594 rs->rx_sg = xfer->rx_sg; in rockchip_spi_transfer_one()
596 if (rs->tx && rs->rx) in rockchip_spi_transfer_one()
597 rs->tmode = CR0_XFM_TR; in rockchip_spi_transfer_one()
598 else if (rs->tx) in rockchip_spi_transfer_one()
599 rs->tmode = CR0_XFM_TO; in rockchip_spi_transfer_one()
600 else if (rs->rx) in rockchip_spi_transfer_one()
601 rs->tmode = CR0_XFM_RO; in rockchip_spi_transfer_one()
605 rs->use_dma = 1; in rockchip_spi_transfer_one()
607 rs->use_dma = 0; in rockchip_spi_transfer_one()
609 rockchip_spi_config(rs); in rockchip_spi_transfer_one()
611 if (rs->use_dma) { in rockchip_spi_transfer_one()
612 if (rs->tmode == CR0_XFM_RO) { in rockchip_spi_transfer_one()
614 rockchip_spi_prepare_dma(rs); in rockchip_spi_transfer_one()
615 spi_enable_chip(rs, 1); in rockchip_spi_transfer_one()
618 spi_enable_chip(rs, 1); in rockchip_spi_transfer_one()
619 rockchip_spi_prepare_dma(rs); in rockchip_spi_transfer_one()
622 spi_enable_chip(rs, 1); in rockchip_spi_transfer_one()
623 ret = rockchip_spi_pio_transfer(rs); in rockchip_spi_transfer_one()
633 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_can_dma() local
635 return (xfer->len > rs->fifo_len); in rockchip_spi_can_dma()
641 struct rockchip_spi *rs; in rockchip_spi_probe() local
652 rs = spi_master_get_devdata(master); in rockchip_spi_probe()
656 rs->regs = devm_ioremap_resource(&pdev->dev, mem); in rockchip_spi_probe()
657 if (IS_ERR(rs->regs)) { in rockchip_spi_probe()
658 ret = PTR_ERR(rs->regs); in rockchip_spi_probe()
662 rs->apb_pclk = devm_clk_get(&pdev->dev, "apb_pclk"); in rockchip_spi_probe()
663 if (IS_ERR(rs->apb_pclk)) { in rockchip_spi_probe()
665 ret = PTR_ERR(rs->apb_pclk); in rockchip_spi_probe()
669 rs->spiclk = devm_clk_get(&pdev->dev, "spiclk"); in rockchip_spi_probe()
670 if (IS_ERR(rs->spiclk)) { in rockchip_spi_probe()
672 ret = PTR_ERR(rs->spiclk); in rockchip_spi_probe()
676 ret = clk_prepare_enable(rs->apb_pclk); in rockchip_spi_probe()
682 ret = clk_prepare_enable(rs->spiclk); in rockchip_spi_probe()
688 spi_enable_chip(rs, 0); in rockchip_spi_probe()
690 rs->type = SSI_MOTO_SPI; in rockchip_spi_probe()
691 rs->master = master; in rockchip_spi_probe()
692 rs->dev = &pdev->dev; in rockchip_spi_probe()
693 rs->max_freq = clk_get_rate(rs->spiclk); in rockchip_spi_probe()
697 rs->rsd_nsecs = rsd_nsecs; in rockchip_spi_probe()
699 rs->fifo_len = get_fifo_len(rs); in rockchip_spi_probe()
700 if (!rs->fifo_len) { in rockchip_spi_probe()
706 spin_lock_init(&rs->lock); in rockchip_spi_probe()
724 rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx"); in rockchip_spi_probe()
725 if (!rs->dma_tx.ch) in rockchip_spi_probe()
726 dev_warn(rs->dev, "Failed to request TX DMA channel\n"); in rockchip_spi_probe()
728 rs->dma_rx.ch = dma_request_slave_channel(rs->dev, "rx"); in rockchip_spi_probe()
729 if (!rs->dma_rx.ch) { in rockchip_spi_probe()
730 if (rs->dma_tx.ch) { in rockchip_spi_probe()
731 dma_release_channel(rs->dma_tx.ch); in rockchip_spi_probe()
732 rs->dma_tx.ch = NULL; in rockchip_spi_probe()
734 dev_warn(rs->dev, "Failed to request RX DMA channel\n"); in rockchip_spi_probe()
737 if (rs->dma_tx.ch && rs->dma_rx.ch) { in rockchip_spi_probe()
738 rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); in rockchip_spi_probe()
739 rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); in rockchip_spi_probe()
740 rs->dma_tx.direction = DMA_MEM_TO_DEV; in rockchip_spi_probe()
741 rs->dma_rx.direction = DMA_DEV_TO_MEM; in rockchip_spi_probe()
744 master->dma_tx = rs->dma_tx.ch; in rockchip_spi_probe()
745 master->dma_rx = rs->dma_rx.ch; in rockchip_spi_probe()
757 if (rs->dma_tx.ch) in rockchip_spi_probe()
758 dma_release_channel(rs->dma_tx.ch); in rockchip_spi_probe()
759 if (rs->dma_rx.ch) in rockchip_spi_probe()
760 dma_release_channel(rs->dma_rx.ch); in rockchip_spi_probe()
762 clk_disable_unprepare(rs->spiclk); in rockchip_spi_probe()
764 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_probe()
774 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_remove() local
778 clk_disable_unprepare(rs->spiclk); in rockchip_spi_remove()
779 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_remove()
781 if (rs->dma_tx.ch) in rockchip_spi_remove()
782 dma_release_channel(rs->dma_tx.ch); in rockchip_spi_remove()
783 if (rs->dma_rx.ch) in rockchip_spi_remove()
784 dma_release_channel(rs->dma_rx.ch); in rockchip_spi_remove()
794 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_suspend() local
796 ret = spi_master_suspend(rs->master); in rockchip_spi_suspend()
801 clk_disable_unprepare(rs->spiclk); in rockchip_spi_suspend()
802 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_suspend()
812 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_resume() local
815 ret = clk_prepare_enable(rs->apb_pclk); in rockchip_spi_resume()
819 ret = clk_prepare_enable(rs->spiclk); in rockchip_spi_resume()
821 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_resume()
826 ret = spi_master_resume(rs->master); in rockchip_spi_resume()
828 clk_disable_unprepare(rs->spiclk); in rockchip_spi_resume()
829 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_resume()
840 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_runtime_suspend() local
842 clk_disable_unprepare(rs->spiclk); in rockchip_spi_runtime_suspend()
843 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_runtime_suspend()
852 struct rockchip_spi *rs = spi_master_get_devdata(master); in rockchip_spi_runtime_resume() local
854 ret = clk_prepare_enable(rs->apb_pclk); in rockchip_spi_runtime_resume()
858 ret = clk_prepare_enable(rs->spiclk); in rockchip_spi_runtime_resume()
860 clk_disable_unprepare(rs->apb_pclk); in rockchip_spi_runtime_resume()