Skip to content

Commit

Permalink
spi: dw-mid: split dma_setup() from dma_transfer()
Browse files Browse the repository at this point in the history
The patch splits DMA preparatory code to dma_setup() callback. The change also
converts transfer_one() to program DMA whenever the transfer is DMA mapped. The
change is a follow up of the converion to use SPI core transfer_one_message().
Since the DMA mapped transfers can be interleaved with PIO ones the DMA related
configuration should respect that.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Andy Shevchenko authored and Mark Brown committed Mar 9, 2015
1 parent e31abce commit 9f14538
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 23 deletions.
17 changes: 6 additions & 11 deletions drivers/spi/spi-dw-mid.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,10 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws)
return rxdesc;
}

static void dw_spi_dma_setup(struct dw_spi *dws)
static int mid_spi_dma_setup(struct dw_spi *dws)
{
u16 dma_ctrl = 0;

spi_enable_chip(dws, 0);

dw_writew(dws, DW_SPI_DMARDLR, 0xf);
dw_writew(dws, DW_SPI_DMATDLR, 0x10);

Expand All @@ -222,21 +220,17 @@ static void dw_spi_dma_setup(struct dw_spi *dws)
dma_ctrl |= SPI_DMA_RDMAE;
dw_writew(dws, DW_SPI_DMACR, dma_ctrl);

spi_enable_chip(dws, 1);
return 0;
}

static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
static int mid_spi_dma_transfer(struct dw_spi *dws)
{
struct dma_async_tx_descriptor *txdesc, *rxdesc;

/* 1. setup DMA related registers */
if (cs_change)
dw_spi_dma_setup(dws);

/* 2. Prepare the TX dma transfer */
/* Prepare the TX dma transfer */
txdesc = dw_spi_dma_prepare_tx(dws);

/* 3. Prepare the RX dma transfer */
/* Prepare the RX dma transfer */
rxdesc = dw_spi_dma_prepare_rx(dws);

/* rx must be started before tx due to spi instinct */
Expand All @@ -258,6 +252,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
static struct dw_spi_dma_ops mid_dma_ops = {
.dma_init = mid_spi_dma_init,
.dma_exit = mid_spi_dma_exit,
.dma_setup = mid_spi_dma_setup,
.dma_transfer = mid_spi_dma_transfer,
};
#endif
Expand Down
23 changes: 13 additions & 10 deletions drivers/spi/spi-dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,11 @@ static int dw_spi_transfer_one(struct spi_master *master,
struct dw_spi *dws = spi_master_get_devdata(master);
struct chip_data *chip = spi_get_ctldata(spi);
u8 imask = 0;
u8 cs_change = 0;
u16 txlevel = 0;
u16 clk_div = 0;
u32 speed = 0;
u32 cr0 = 0;
int ret;

dws->n_bytes = chip->n_bytes;
dws->dma_width = chip->dma_width;
Expand All @@ -332,8 +332,6 @@ static int dw_spi_transfer_one(struct spi_master *master,
dws->rx = transfer->rx_buf;
dws->rx_end = dws->rx + transfer->len;
dws->len = transfer->len;
if (chip != dws->prev_chip)
cs_change = 1;

spi_enable_chip(dws, 0);

Expand Down Expand Up @@ -397,7 +395,13 @@ static int dw_spi_transfer_one(struct spi_master *master,
* Interrupt mode
* we only need set the TXEI IRQ, as TX/RX always happen syncronizely
*/
if (!dws->dma_mapped && !chip->poll_mode) {
if (dws->dma_mapped) {
ret = dws->dma_ops->dma_setup(dws);
if (ret < 0) {
spi_enable_chip(dws, 1);
return ret;
}
} else if (!chip->poll_mode) {
txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes);
dw_writew(dws, DW_SPI_TXFLTR, txlevel);

Expand All @@ -411,11 +415,11 @@ static int dw_spi_transfer_one(struct spi_master *master,

spi_enable_chip(dws, 1);

if (cs_change)
dws->prev_chip = chip;

if (dws->dma_mapped)
dws->dma_ops->dma_transfer(dws, cs_change);
if (dws->dma_mapped) {
ret = dws->dma_ops->dma_transfer(dws);
if (ret < 0)
return ret;
}

if (chip->poll_mode)
return poll_transfer(dws);
Expand Down Expand Up @@ -546,7 +550,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)

dws->master = master;
dws->type = SSI_MOTO_SPI;
dws->prev_chip = NULL;
dws->dma_inited = 0;
dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num);
Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/spi-dw.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ struct dw_spi;
struct dw_spi_dma_ops {
int (*dma_init)(struct dw_spi *dws);
void (*dma_exit)(struct dw_spi *dws);
int (*dma_transfer)(struct dw_spi *dws, int cs_change);
int (*dma_setup)(struct dw_spi *dws);
int (*dma_transfer)(struct dw_spi *dws);
};

struct dw_spi {
Expand All @@ -109,7 +110,6 @@ struct dw_spi {
u16 num_cs; /* supported slave numbers */

/* Current message transfer state info */
struct chip_data *prev_chip;
size_t len;
void *tx;
void *tx_end;
Expand Down

0 comments on commit 9f14538

Please sign in to comment.