Lines Matching refs:sspi
117 static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) in sun6i_spi_read() argument
119 return readl(sspi->base_addr + reg); in sun6i_spi_read()
122 static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value) in sun6i_spi_write() argument
124 writel(value, sspi->base_addr + reg); in sun6i_spi_write()
127 static inline u32 sun6i_spi_get_rx_fifo_count(struct sun6i_spi *sspi) in sun6i_spi_get_rx_fifo_count() argument
129 u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); in sun6i_spi_get_rx_fifo_count()
134 static inline u32 sun6i_spi_get_tx_fifo_count(struct sun6i_spi *sspi) in sun6i_spi_get_tx_fifo_count() argument
136 u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); in sun6i_spi_get_tx_fifo_count()
141 static inline void sun6i_spi_disable_interrupt(struct sun6i_spi *sspi, u32 mask) in sun6i_spi_disable_interrupt() argument
143 u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG); in sun6i_spi_disable_interrupt()
146 sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg); in sun6i_spi_disable_interrupt()
149 static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi) in sun6i_spi_drain_fifo() argument
155 len = sun6i_spi_get_rx_fifo_count(sspi); in sun6i_spi_drain_fifo()
158 byte = readb(sspi->base_addr + SUN6I_RXDATA_REG); in sun6i_spi_drain_fifo()
159 if (sspi->rx_buf) in sun6i_spi_drain_fifo()
160 *sspi->rx_buf++ = byte; in sun6i_spi_drain_fifo()
164 static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi) in sun6i_spi_fill_fifo() argument
171 cnt = sspi->cfg->fifo_depth - sun6i_spi_get_tx_fifo_count(sspi); in sun6i_spi_fill_fifo()
173 len = min((int)cnt, sspi->len); in sun6i_spi_fill_fifo()
176 byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; in sun6i_spi_fill_fifo()
177 writeb(byte, sspi->base_addr + SUN6I_TXDATA_REG); in sun6i_spi_fill_fifo()
178 sspi->len--; in sun6i_spi_fill_fifo()
184 struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); in sun6i_spi_set_cs() local
187 reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); in sun6i_spi_set_cs()
196 sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); in sun6i_spi_set_cs()
206 struct sun6i_spi *sspi = param; in sun6i_spi_dma_rx_cb() local
208 complete(&sspi->dma_rx_done); in sun6i_spi_dma_rx_cb()
211 static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, in sun6i_spi_prepare_dma() argument
215 struct spi_master *master = sspi->master; in sun6i_spi_prepare_dma()
221 .src_addr = sspi->dma_addr_rx, in sun6i_spi_prepare_dma()
235 rxdesc->callback_param = sspi; in sun6i_spi_prepare_dma()
243 .dst_addr = sspi->dma_addr_tx, in sun6i_spi_prepare_dma()
279 struct sun6i_spi *sspi = spi_master_get_devdata(master); in sun6i_spi_transfer_one() local
291 reinit_completion(&sspi->done); in sun6i_spi_transfer_one()
292 reinit_completion(&sspi->dma_rx_done); in sun6i_spi_transfer_one()
293 sspi->tx_buf = tfr->tx_buf; in sun6i_spi_transfer_one()
294 sspi->rx_buf = tfr->rx_buf; in sun6i_spi_transfer_one()
295 sspi->len = tfr->len; in sun6i_spi_transfer_one()
299 sun6i_spi_write(sspi, SUN6I_INT_STA_REG, ~0); in sun6i_spi_transfer_one()
302 sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, in sun6i_spi_transfer_one()
314 trig_level = sspi->cfg->fifo_depth / 4 * 3; in sun6i_spi_transfer_one()
321 trig_level = sspi->cfg->fifo_depth / 2; in sun6i_spi_transfer_one()
332 sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, reg); in sun6i_spi_transfer_one()
338 reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); in sun6i_spi_transfer_one()
359 if (sspi->rx_buf) { in sun6i_spi_transfer_one()
369 sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); in sun6i_spi_transfer_one()
371 if (sspi->cfg->has_clk_ctl) { in sun6i_spi_transfer_one()
372 unsigned int mclk_rate = clk_get_rate(sspi->mclk); in sun6i_spi_transfer_one()
376 clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); in sun6i_spi_transfer_one()
377 mclk_rate = clk_get_rate(sspi->mclk); in sun6i_spi_transfer_one()
405 sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); in sun6i_spi_transfer_one()
407 clk_set_rate(sspi->mclk, tfr->speed_hz); in sun6i_spi_transfer_one()
408 tfr->effective_speed_hz = clk_get_rate(sspi->mclk); in sun6i_spi_transfer_one()
419 reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); in sun6i_spi_transfer_one()
427 sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); in sun6i_spi_transfer_one()
431 reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); in sun6i_spi_transfer_one()
433 sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg); in sun6i_spi_transfer_one()
436 if (sspi->tx_buf) { in sun6i_spi_transfer_one()
456 sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG, reg); in sun6i_spi_transfer_one()
457 sun6i_spi_write(sspi, SUN6I_BURST_CNT_REG, tfr->len); in sun6i_spi_transfer_one()
458 sun6i_spi_write(sspi, SUN6I_XMIT_CNT_REG, tx_len); in sun6i_spi_transfer_one()
462 sun6i_spi_fill_fifo(sspi); in sun6i_spi_transfer_one()
464 ret = sun6i_spi_prepare_dma(sspi, tfr); in sun6i_spi_transfer_one()
477 if (rx_len > sspi->cfg->fifo_depth) in sun6i_spi_transfer_one()
479 if (tx_len > sspi->cfg->fifo_depth) in sun6i_spi_transfer_one()
483 sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg); in sun6i_spi_transfer_one()
486 reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); in sun6i_spi_transfer_one()
487 sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); in sun6i_spi_transfer_one()
491 timeout = wait_for_completion_timeout(&sspi->done, in sun6i_spi_transfer_one()
495 sun6i_spi_drain_fifo(sspi); in sun6i_spi_transfer_one()
502 timeout = wait_for_completion_timeout(&sspi->dma_rx_done, in sun6i_spi_transfer_one()
518 sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); in sun6i_spi_transfer_one()
530 struct sun6i_spi *sspi = dev_id; in sun6i_spi_handler() local
531 u32 status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG); in sun6i_spi_handler()
535 sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); in sun6i_spi_handler()
536 complete(&sspi->done); in sun6i_spi_handler()
542 sun6i_spi_drain_fifo(sspi); in sun6i_spi_handler()
544 sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_RF_RDY); in sun6i_spi_handler()
550 sun6i_spi_fill_fifo(sspi); in sun6i_spi_handler()
552 if (!sspi->len) in sun6i_spi_handler()
554 sun6i_spi_disable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ); in sun6i_spi_handler()
557 sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TF_ERQ); in sun6i_spi_handler()
568 struct sun6i_spi *sspi = spi_master_get_devdata(master); in sun6i_spi_runtime_resume() local
571 ret = clk_prepare_enable(sspi->hclk); in sun6i_spi_runtime_resume()
577 ret = clk_prepare_enable(sspi->mclk); in sun6i_spi_runtime_resume()
583 ret = reset_control_deassert(sspi->rstc); in sun6i_spi_runtime_resume()
589 sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, in sun6i_spi_runtime_resume()
595 clk_disable_unprepare(sspi->mclk); in sun6i_spi_runtime_resume()
597 clk_disable_unprepare(sspi->hclk); in sun6i_spi_runtime_resume()
605 struct sun6i_spi *sspi = spi_master_get_devdata(master); in sun6i_spi_runtime_suspend() local
607 reset_control_assert(sspi->rstc); in sun6i_spi_runtime_suspend()
608 clk_disable_unprepare(sspi->mclk); in sun6i_spi_runtime_suspend()
609 clk_disable_unprepare(sspi->hclk); in sun6i_spi_runtime_suspend()
618 struct sun6i_spi *sspi = spi_master_get_devdata(master); in sun6i_spi_can_dma() local
625 return xfer->len > sspi->cfg->fifo_depth; in sun6i_spi_can_dma()
631 struct sun6i_spi *sspi; in sun6i_spi_probe() local
642 sspi = spi_master_get_devdata(master); in sun6i_spi_probe()
644 sspi->base_addr = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); in sun6i_spi_probe()
645 if (IS_ERR(sspi->base_addr)) { in sun6i_spi_probe()
646 ret = PTR_ERR(sspi->base_addr); in sun6i_spi_probe()
657 0, "sun6i-spi", sspi); in sun6i_spi_probe()
663 sspi->master = master; in sun6i_spi_probe()
664 sspi->cfg = of_device_get_match_data(&pdev->dev); in sun6i_spi_probe()
673 sspi->cfg->mode_bits; in sun6i_spi_probe()
679 sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); in sun6i_spi_probe()
680 if (IS_ERR(sspi->hclk)) { in sun6i_spi_probe()
682 ret = PTR_ERR(sspi->hclk); in sun6i_spi_probe()
686 sspi->mclk = devm_clk_get(&pdev->dev, "mod"); in sun6i_spi_probe()
687 if (IS_ERR(sspi->mclk)) { in sun6i_spi_probe()
689 ret = PTR_ERR(sspi->mclk); in sun6i_spi_probe()
693 init_completion(&sspi->done); in sun6i_spi_probe()
694 init_completion(&sspi->dma_rx_done); in sun6i_spi_probe()
696 sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in sun6i_spi_probe()
697 if (IS_ERR(sspi->rstc)) { in sun6i_spi_probe()
699 ret = PTR_ERR(sspi->rstc); in sun6i_spi_probe()
725 sspi->dma_addr_tx = mem->start + SUN6I_TXDATA_REG; in sun6i_spi_probe()
726 sspi->dma_addr_rx = mem->start + SUN6I_RXDATA_REG; in sun6i_spi_probe()