|
@@ -328,6 +328,8 @@ static int rockchip_spi_unprepare_message(struct spi_master *master,
|
|
|
|
|
|
spin_unlock_irqrestore(&rs->lock, flags);
|
|
spin_unlock_irqrestore(&rs->lock, flags);
|
|
|
|
|
|
|
|
+ spi_enable_chip(rs, 0);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -384,6 +386,8 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs)
|
|
if (rs->tx)
|
|
if (rs->tx)
|
|
wait_for_idle(rs);
|
|
wait_for_idle(rs);
|
|
|
|
|
|
|
|
+ spi_enable_chip(rs, 0);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -395,8 +399,10 @@ static void rockchip_spi_dma_rxcb(void *data)
|
|
spin_lock_irqsave(&rs->lock, flags);
|
|
spin_lock_irqsave(&rs->lock, flags);
|
|
|
|
|
|
rs->state &= ~RXBUSY;
|
|
rs->state &= ~RXBUSY;
|
|
- if (!(rs->state & TXBUSY))
|
|
|
|
|
|
+ if (!(rs->state & TXBUSY)) {
|
|
|
|
+ spi_enable_chip(rs, 0);
|
|
spi_finalize_current_transfer(rs->master);
|
|
spi_finalize_current_transfer(rs->master);
|
|
|
|
+ }
|
|
|
|
|
|
spin_unlock_irqrestore(&rs->lock, flags);
|
|
spin_unlock_irqrestore(&rs->lock, flags);
|
|
}
|
|
}
|
|
@@ -512,8 +518,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
|
|
div = max_t(u32, rs->max_freq / rs->speed, 1);
|
|
div = max_t(u32, rs->max_freq / rs->speed, 1);
|
|
div = (div + 1) & 0xfffe;
|
|
div = (div + 1) & 0xfffe;
|
|
|
|
|
|
- spi_enable_chip(rs, 0);
|
|
|
|
-
|
|
|
|
writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
|
|
writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
|
|
|
|
|
|
writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
|
|
writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
|
|
@@ -527,8 +531,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
|
|
spi_set_clk(rs, div);
|
|
spi_set_clk(rs, div);
|
|
|
|
|
|
dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
|
|
dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
|
|
-
|
|
|
|
- spi_enable_chip(rs, 1);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int rockchip_spi_transfer_one(
|
|
static int rockchip_spi_transfer_one(
|
|
@@ -536,7 +538,7 @@ static int rockchip_spi_transfer_one(
|
|
struct spi_device *spi,
|
|
struct spi_device *spi,
|
|
struct spi_transfer *xfer)
|
|
struct spi_transfer *xfer)
|
|
{
|
|
{
|
|
- int ret = 0;
|
|
|
|
|
|
+ int ret = 1;
|
|
struct rockchip_spi *rs = spi_master_get_devdata(master);
|
|
struct rockchip_spi *rs = spi_master_get_devdata(master);
|
|
|
|
|
|
WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
|
|
WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
|
|
@@ -568,17 +570,27 @@ static int rockchip_spi_transfer_one(
|
|
rs->tmode = CR0_XFM_RO;
|
|
rs->tmode = CR0_XFM_RO;
|
|
|
|
|
|
/* we need prepare dma before spi was enabled */
|
|
/* we need prepare dma before spi was enabled */
|
|
- if (master->can_dma && master->can_dma(master, spi, xfer)) {
|
|
|
|
|
|
+ if (master->can_dma && master->can_dma(master, spi, xfer))
|
|
rs->use_dma = 1;
|
|
rs->use_dma = 1;
|
|
- rockchip_spi_prepare_dma(rs);
|
|
|
|
- } else {
|
|
|
|
|
|
+ else
|
|
rs->use_dma = 0;
|
|
rs->use_dma = 0;
|
|
- }
|
|
|
|
|
|
|
|
rockchip_spi_config(rs);
|
|
rockchip_spi_config(rs);
|
|
|
|
|
|
- if (!rs->use_dma)
|
|
|
|
|
|
+ if (rs->use_dma) {
|
|
|
|
+ if (rs->tmode == CR0_XFM_RO) {
|
|
|
|
+ /* rx: dma must be prepared first */
|
|
|
|
+ rockchip_spi_prepare_dma(rs);
|
|
|
|
+ spi_enable_chip(rs, 1);
|
|
|
|
+ } else {
|
|
|
|
+ /* tx or tr: spi must be enabled first */
|
|
|
|
+ spi_enable_chip(rs, 1);
|
|
|
|
+ rockchip_spi_prepare_dma(rs);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ spi_enable_chip(rs, 1);
|
|
ret = rockchip_spi_pio_transfer(rs);
|
|
ret = rockchip_spi_pio_transfer(rs);
|
|
|
|
+ }
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|