diff options
author | Mark Brown <broonie@kernel.org> | 2018-10-21 18:00:14 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-10-21 18:00:14 +0200 |
commit | 4b51c747e4a52175e63d125db8365b38b06f0343 (patch) | |
tree | cd03133d8efbf5a039c7cb369aa7eaa8c27d8ebe /drivers/spi/spi-rockchip.c | |
parent | Merge branch 'spi-4.19' into spi-linus (diff) | |
parent | spi: lpspi: add imx8qxp compatible string (diff) | |
download | linux-4b51c747e4a52175e63d125db8365b38b06f0343.tar.xz linux-4b51c747e4a52175e63d125db8365b38b06f0343.zip |
Merge branch 'spi-4.20' into spi-next
Diffstat (limited to 'drivers/spi/spi-rockchip.c')
-rw-r--r-- | drivers/spi/spi-rockchip.c | 59 |
1 files changed, 19 insertions, 40 deletions
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 185bbdce62b1..51ef632bca52 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -164,7 +164,6 @@ enum rockchip_ssi_type { struct rockchip_spi_dma_data { struct dma_chan *ch; - enum dma_transfer_direction direction; dma_addr_t addr; }; @@ -202,12 +201,11 @@ struct rockchip_spi { bool cs_asserted[ROCKCHIP_SPI_MAX_CS_NUM]; - u32 use_dma; + bool use_dma; struct sg_table tx_sg; struct sg_table rx_sg; struct rockchip_spi_dma_data dma_rx; struct rockchip_spi_dma_data dma_tx; - struct dma_slave_caps dma_caps; }; static inline void spi_enable_chip(struct rockchip_spi *rs, int enable) @@ -381,6 +379,8 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs) { int remain = 0; + spi_enable_chip(rs, 1); + do { if (rs->tx) { remain = rs->tx_end - rs->tx; @@ -455,19 +455,16 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) rxdesc = NULL; if (rs->rx) { - rxconf.direction = rs->dma_rx.direction; + rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = rs->dma_rx.addr; rxconf.src_addr_width = rs->n_bytes; - if (rs->dma_caps.max_burst > 4) - rxconf.src_maxburst = 4; - else - rxconf.src_maxburst = 1; + rxconf.src_maxburst = 1; dmaengine_slave_config(rs->dma_rx.ch, &rxconf); rxdesc = dmaengine_prep_slave_sg( rs->dma_rx.ch, rs->rx_sg.sgl, rs->rx_sg.nents, - rs->dma_rx.direction, DMA_PREP_INTERRUPT); + DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); if (!rxdesc) return -EINVAL; @@ -477,19 +474,16 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) txdesc = NULL; if (rs->tx) { - txconf.direction = rs->dma_tx.direction; + txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = rs->dma_tx.addr; txconf.dst_addr_width = rs->n_bytes; - if (rs->dma_caps.max_burst > 4) - txconf.dst_maxburst = 4; - else - txconf.dst_maxburst = 1; + txconf.dst_maxburst = rs->fifo_len / 2; dmaengine_slave_config(rs->dma_tx.ch, &txconf); txdesc = dmaengine_prep_slave_sg( rs->dma_tx.ch, rs->tx_sg.sgl, rs->tx_sg.nents, - rs->dma_tx.direction, DMA_PREP_INTERRUPT); + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); if (!txdesc) { if (rxdesc) dmaengine_terminate_sync(rs->dma_rx.ch); @@ -509,6 +503,8 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) dma_async_issue_pending(rs->dma_rx.ch); } + spi_enable_chip(rs, 1); + if (txdesc) { spin_lock_irqsave(&rs->lock, flags); rs->state |= TXBUSY; @@ -517,7 +513,8 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) dma_async_issue_pending(rs->dma_tx.ch); } - return 0; + /* 1 means the transfer is in progress */ + return 1; } static void rockchip_spi_config(struct rockchip_spi *rs) @@ -581,7 +578,7 @@ static void rockchip_spi_config(struct rockchip_spi *rs) writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_TXFTLR); writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR); - writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMATDLR); + writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_DMATDLR); writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMARDLR); writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR); @@ -600,7 +597,6 @@ static int rockchip_spi_transfer_one( struct spi_device *spi, struct spi_transfer *xfer) { - int ret = 0; struct rockchip_spi *rs = spi_master_get_devdata(master); WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && @@ -638,30 +634,16 @@ static int rockchip_spi_transfer_one( /* we need prepare dma before spi was enabled */ if (master->can_dma && master->can_dma(master, spi, xfer)) - rs->use_dma = 1; + rs->use_dma = true; else - rs->use_dma = 0; + rs->use_dma = false; rockchip_spi_config(rs); - if (rs->use_dma) { - if (rs->tmode == CR0_XFM_RO) { - /* rx: dma must be prepared first */ - ret = rockchip_spi_prepare_dma(rs); - spi_enable_chip(rs, 1); - } else { - /* tx or tr: spi must be enabled first */ - spi_enable_chip(rs, 1); - ret = rockchip_spi_prepare_dma(rs); - } - /* successful DMA prepare means the transfer is in progress */ - ret = ret ? ret : 1; - } else { - spi_enable_chip(rs, 1); - ret = rockchip_spi_pio_transfer(rs); - } + if (rs->use_dma) + return rockchip_spi_prepare_dma(rs); - return ret; + return rockchip_spi_pio_transfer(rs); } static bool rockchip_spi_can_dma(struct spi_master *master, @@ -783,11 +765,8 @@ static int rockchip_spi_probe(struct platform_device *pdev) } if (rs->dma_tx.ch && rs->dma_rx.ch) { - dma_get_slave_caps(rs->dma_rx.ch, &(rs->dma_caps)); rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); - rs->dma_tx.direction = DMA_MEM_TO_DEV; - rs->dma_rx.direction = DMA_DEV_TO_MEM; master->can_dma = rockchip_spi_can_dma; master->dma_tx = rs->dma_tx.ch; |