Commit 107d0644 authored by Vinod Koul's avatar Vinod Koul

dmaengine: imx-sdma: remove dma_slave_config direction usage and leave sdma_event_enable()

dma_slave_config direction was marked as deprecated quite some
time back, remove the usage from this driver so that the field
can be removed

ENBLn bit should be set before any dma request triggered, please
refer to the below information from i.mx6sololite RM. Otherwise,
spi/uart test will be fail because there is dma request from tx
fifo always before dmaengine_prep_slave_sg() in where ENBLn set
and violate the below rule.

https://www.nxp.com/docs/en/reference-manual/IMX6SLRM.pdf:

40.8.28 Channel Enable RAM (SDMAARM_CHNENBLn)
"It is thus essential for the Arm platform to program them before
any DMA request is triggered to the SDMA, otherwise an unpredictable
combination of channels may be started".
Signed-off-by: default avatarRobin Gong <yibin.gong@nxp.com>
[vkoul: sqashed patch from Robin into direction change]
Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 56b94b02
...@@ -335,6 +335,7 @@ struct sdma_desc { ...@@ -335,6 +335,7 @@ struct sdma_desc {
* @sdma: pointer to the SDMA engine for this channel * @sdma: pointer to the SDMA engine for this channel
* @channel: the channel number, matches dmaengine chan_id + 1 * @channel: the channel number, matches dmaengine chan_id + 1
* @direction: transfer type. Needed for setting SDMA script * @direction: transfer type. Needed for setting SDMA script
* @slave_config Slave configuration
* @peripheral_type: Peripheral type. Needed for setting SDMA script * @peripheral_type: Peripheral type. Needed for setting SDMA script
* @event_id0: aka dma request line * @event_id0: aka dma request line
* @event_id1: for channels that use 2 events * @event_id1: for channels that use 2 events
...@@ -362,6 +363,7 @@ struct sdma_channel { ...@@ -362,6 +363,7 @@ struct sdma_channel {
struct sdma_engine *sdma; struct sdma_engine *sdma;
unsigned int channel; unsigned int channel;
enum dma_transfer_direction direction; enum dma_transfer_direction direction;
struct dma_slave_config slave_config;
enum sdma_peripheral_type peripheral_type; enum sdma_peripheral_type peripheral_type;
unsigned int event_id0; unsigned int event_id0;
unsigned int event_id1; unsigned int event_id1;
...@@ -440,6 +442,10 @@ struct sdma_engine { ...@@ -440,6 +442,10 @@ struct sdma_engine {
struct sdma_buffer_descriptor *bd0; struct sdma_buffer_descriptor *bd0;
}; };
static int sdma_config_write(struct dma_chan *chan,
struct dma_slave_config *dmaengine_cfg,
enum dma_transfer_direction direction);
static struct sdma_driver_data sdma_imx31 = { static struct sdma_driver_data sdma_imx31 = {
.chnenbl0 = SDMA_CHNENBL0_IMX31, .chnenbl0 = SDMA_CHNENBL0_IMX31,
.num_events = 32, .num_events = 32,
...@@ -1104,18 +1110,6 @@ static int sdma_config_channel(struct dma_chan *chan) ...@@ -1104,18 +1110,6 @@ static int sdma_config_channel(struct dma_chan *chan)
sdmac->shp_addr = 0; sdmac->shp_addr = 0;
sdmac->per_addr = 0; sdmac->per_addr = 0;
if (sdmac->event_id0) {
if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
return -EINVAL;
sdma_event_enable(sdmac, sdmac->event_id0);
}
if (sdmac->event_id1) {
if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
return -EINVAL;
sdma_event_enable(sdmac, sdmac->event_id1);
}
switch (sdmac->peripheral_type) { switch (sdmac->peripheral_type) {
case IMX_DMATYPE_DSP: case IMX_DMATYPE_DSP:
sdma_config_ownership(sdmac, false, true, true); sdma_config_ownership(sdmac, false, true, true);
...@@ -1415,6 +1409,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( ...@@ -1415,6 +1409,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
struct scatterlist *sg; struct scatterlist *sg;
struct sdma_desc *desc; struct sdma_desc *desc;
sdma_config_write(chan, &sdmac->slave_config, direction);
desc = sdma_transfer_init(sdmac, direction, sg_len); desc = sdma_transfer_init(sdmac, direction, sg_len);
if (!desc) if (!desc)
goto err_out; goto err_out;
...@@ -1499,6 +1495,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( ...@@ -1499,6 +1495,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
sdma_config_write(chan, &sdmac->slave_config, direction);
desc = sdma_transfer_init(sdmac, direction, num_periods); desc = sdma_transfer_init(sdmac, direction, num_periods);
if (!desc) if (!desc)
goto err_out; goto err_out;
...@@ -1554,17 +1552,18 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( ...@@ -1554,17 +1552,18 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
return NULL; return NULL;
} }
static int sdma_config(struct dma_chan *chan, static int sdma_config_write(struct dma_chan *chan,
struct dma_slave_config *dmaengine_cfg) struct dma_slave_config *dmaengine_cfg,
enum dma_transfer_direction direction)
{ {
struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_channel *sdmac = to_sdma_chan(chan);
if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) {
sdmac->per_address = dmaengine_cfg->src_addr; sdmac->per_address = dmaengine_cfg->src_addr;
sdmac->watermark_level = dmaengine_cfg->src_maxburst * sdmac->watermark_level = dmaengine_cfg->src_maxburst *
dmaengine_cfg->src_addr_width; dmaengine_cfg->src_addr_width;
sdmac->word_size = dmaengine_cfg->src_addr_width; sdmac->word_size = dmaengine_cfg->src_addr_width;
} else if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) { } else if (direction == DMA_DEV_TO_DEV) {
sdmac->per_address2 = dmaengine_cfg->src_addr; sdmac->per_address2 = dmaengine_cfg->src_addr;
sdmac->per_address = dmaengine_cfg->dst_addr; sdmac->per_address = dmaengine_cfg->dst_addr;
sdmac->watermark_level = dmaengine_cfg->src_maxburst & sdmac->watermark_level = dmaengine_cfg->src_maxburst &
...@@ -1578,10 +1577,33 @@ static int sdma_config(struct dma_chan *chan, ...@@ -1578,10 +1577,33 @@ static int sdma_config(struct dma_chan *chan,
dmaengine_cfg->dst_addr_width; dmaengine_cfg->dst_addr_width;
sdmac->word_size = dmaengine_cfg->dst_addr_width; sdmac->word_size = dmaengine_cfg->dst_addr_width;
} }
sdmac->direction = dmaengine_cfg->direction; sdmac->direction = direction;
return sdma_config_channel(chan); return sdma_config_channel(chan);
} }
static int sdma_config(struct dma_chan *chan,
struct dma_slave_config *dmaengine_cfg)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
/* Set ENBLn earlier to make sure dma request triggered after that */
if (sdmac->event_id0) {
if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
return -EINVAL;
sdma_event_enable(sdmac, sdmac->event_id0);
}
if (sdmac->event_id1) {
if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
return -EINVAL;
sdma_event_enable(sdmac, sdmac->event_id1);
}
return 0;
}
static enum dma_status sdma_tx_status(struct dma_chan *chan, static enum dma_status sdma_tx_status(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t cookie,
struct dma_tx_state *txstate) struct dma_tx_state *txstate)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment