提交 edc329fb 编写于 作者: V Vinod Koul

Merge branch 'topic/dirn_remove' into for-linus

...@@ -1320,7 +1320,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, ...@@ -1320,7 +1320,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
if (unlikely(!is_slave_direction(direction))) if (unlikely(!is_slave_direction(direction)))
goto err_out; goto err_out;
if (sconfig->direction == DMA_MEM_TO_DEV) if (direction == DMA_MEM_TO_DEV)
reg_width = convert_buswidth(sconfig->dst_addr_width); reg_width = convert_buswidth(sconfig->dst_addr_width);
else else
reg_width = convert_buswidth(sconfig->src_addr_width); reg_width = convert_buswidth(sconfig->src_addr_width);
......
...@@ -778,14 +778,6 @@ static int bcm2835_dma_slave_config(struct dma_chan *chan, ...@@ -778,14 +778,6 @@ static int bcm2835_dma_slave_config(struct dma_chan *chan,
{ {
struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
if ((cfg->direction == DMA_DEV_TO_MEM &&
cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
(cfg->direction == DMA_MEM_TO_DEV &&
cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
!is_slave_direction(cfg->direction)) {
return -EINVAL;
}
c->cfg = *cfg; c->cfg = *cfg;
return 0; return 0;
......
...@@ -1306,6 +1306,7 @@ struct coh901318_chan { ...@@ -1306,6 +1306,7 @@ struct coh901318_chan {
unsigned long nbr_active_done; unsigned long nbr_active_done;
unsigned long busy; unsigned long busy;
struct dma_slave_config config;
u32 addr; u32 addr;
u32 ctrl; u32 ctrl;
...@@ -1402,6 +1403,10 @@ static inline struct coh901318_chan *to_coh901318_chan(struct dma_chan *chan) ...@@ -1402,6 +1403,10 @@ static inline struct coh901318_chan *to_coh901318_chan(struct dma_chan *chan)
return container_of(chan, struct coh901318_chan, chan); return container_of(chan, struct coh901318_chan, chan);
} }
static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
struct dma_slave_config *config,
enum dma_transfer_direction direction);
static inline const struct coh901318_params * static inline const struct coh901318_params *
cohc_chan_param(struct coh901318_chan *cohc) cohc_chan_param(struct coh901318_chan *cohc)
{ {
...@@ -2360,6 +2365,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -2360,6 +2365,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if (lli == NULL) if (lli == NULL)
goto err_dma_alloc; goto err_dma_alloc;
coh901318_dma_set_runtimeconfig(chan, &cohc->config, direction);
/* initiate allocated lli list */ /* initiate allocated lli list */
ret = coh901318_lli_fill_sg(&cohc->base->pool, lli, sgl, sg_len, ret = coh901318_lli_fill_sg(&cohc->base->pool, lli, sgl, sg_len,
cohc->addr, cohc->addr,
...@@ -2499,7 +2506,8 @@ static const struct burst_table burst_sizes[] = { ...@@ -2499,7 +2506,8 @@ static const struct burst_table burst_sizes[] = {
}; };
static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan, static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
struct dma_slave_config *config) struct dma_slave_config *config,
enum dma_transfer_direction direction)
{ {
struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_chan *cohc = to_coh901318_chan(chan);
dma_addr_t addr; dma_addr_t addr;
...@@ -2509,11 +2517,11 @@ static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan, ...@@ -2509,11 +2517,11 @@ static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
int i = 0; int i = 0;
/* We only support mem to per or per to mem transfers */ /* We only support mem to per or per to mem transfers */
if (config->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) {
addr = config->src_addr; addr = config->src_addr;
addr_width = config->src_addr_width; addr_width = config->src_addr_width;
maxburst = config->src_maxburst; maxburst = config->src_maxburst;
} else if (config->direction == DMA_MEM_TO_DEV) { } else if (direction == DMA_MEM_TO_DEV) {
addr = config->dst_addr; addr = config->dst_addr;
addr_width = config->dst_addr_width; addr_width = config->dst_addr_width;
maxburst = config->dst_maxburst; maxburst = config->dst_maxburst;
...@@ -2579,6 +2587,16 @@ static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan, ...@@ -2579,6 +2587,16 @@ static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
return 0; return 0;
} }
static int coh901318_dma_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
struct coh901318_chan *cohc = to_coh901318_chan(chan);
memcpy(&cohc->config, config, sizeof(*config));
return 0;
}
static void coh901318_base_init(struct dma_device *dma, const int *pick_chans, static void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
struct coh901318_base *base) struct coh901318_base *base)
{ {
...@@ -2684,7 +2702,7 @@ static int __init coh901318_probe(struct platform_device *pdev) ...@@ -2684,7 +2702,7 @@ static int __init coh901318_probe(struct platform_device *pdev)
base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg;
base->dma_slave.device_tx_status = coh901318_tx_status; base->dma_slave.device_tx_status = coh901318_tx_status;
base->dma_slave.device_issue_pending = coh901318_issue_pending; base->dma_slave.device_issue_pending = coh901318_issue_pending;
base->dma_slave.device_config = coh901318_dma_set_runtimeconfig; base->dma_slave.device_config = coh901318_dma_slave_config;
base->dma_slave.device_pause = coh901318_pause; base->dma_slave.device_pause = coh901318_pause;
base->dma_slave.device_resume = coh901318_resume; base->dma_slave.device_resume = coh901318_resume;
base->dma_slave.device_terminate_all = coh901318_terminate_all; base->dma_slave.device_terminate_all = coh901318_terminate_all;
...@@ -2707,7 +2725,7 @@ static int __init coh901318_probe(struct platform_device *pdev) ...@@ -2707,7 +2725,7 @@ static int __init coh901318_probe(struct platform_device *pdev)
base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy;
base->dma_memcpy.device_tx_status = coh901318_tx_status; base->dma_memcpy.device_tx_status = coh901318_tx_status;
base->dma_memcpy.device_issue_pending = coh901318_issue_pending; base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
base->dma_memcpy.device_config = coh901318_dma_set_runtimeconfig; base->dma_memcpy.device_config = coh901318_dma_slave_config;
base->dma_memcpy.device_pause = coh901318_pause; base->dma_memcpy.device_pause = coh901318_pause;
base->dma_memcpy.device_resume = coh901318_resume; base->dma_memcpy.device_resume = coh901318_resume;
base->dma_memcpy.device_terminate_all = coh901318_terminate_all; base->dma_memcpy.device_terminate_all = coh901318_terminate_all;
......
...@@ -113,6 +113,7 @@ struct jz4740_dma_desc { ...@@ -113,6 +113,7 @@ struct jz4740_dma_desc {
struct jz4740_dmaengine_chan { struct jz4740_dmaengine_chan {
struct virt_dma_chan vchan; struct virt_dma_chan vchan;
unsigned int id; unsigned int id;
struct dma_slave_config config;
dma_addr_t fifo_addr; dma_addr_t fifo_addr;
unsigned int transfer_shift; unsigned int transfer_shift;
...@@ -203,8 +204,9 @@ static enum jz4740_dma_transfer_size jz4740_dma_maxburst(u32 maxburst) ...@@ -203,8 +204,9 @@ static enum jz4740_dma_transfer_size jz4740_dma_maxburst(u32 maxburst)
return JZ4740_DMA_TRANSFER_SIZE_32BYTE; return JZ4740_DMA_TRANSFER_SIZE_32BYTE;
} }
static int jz4740_dma_slave_config(struct dma_chan *c, static int jz4740_dma_slave_config_write(struct dma_chan *c,
struct dma_slave_config *config) struct dma_slave_config *config,
enum dma_transfer_direction direction)
{ {
struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan); struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
...@@ -214,7 +216,7 @@ static int jz4740_dma_slave_config(struct dma_chan *c, ...@@ -214,7 +216,7 @@ static int jz4740_dma_slave_config(struct dma_chan *c,
enum jz4740_dma_flags flags; enum jz4740_dma_flags flags;
uint32_t cmd; uint32_t cmd;
switch (config->direction) { switch (direction) {
case DMA_MEM_TO_DEV: case DMA_MEM_TO_DEV:
flags = JZ4740_DMA_SRC_AUTOINC; flags = JZ4740_DMA_SRC_AUTOINC;
transfer_size = jz4740_dma_maxburst(config->dst_maxburst); transfer_size = jz4740_dma_maxburst(config->dst_maxburst);
...@@ -265,6 +267,15 @@ static int jz4740_dma_slave_config(struct dma_chan *c, ...@@ -265,6 +267,15 @@ static int jz4740_dma_slave_config(struct dma_chan *c,
return 0; return 0;
} }
static int jz4740_dma_slave_config(struct dma_chan *c,
struct dma_slave_config *config)
{
struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
memcpy(&chan->config, config, sizeof(*config));
return 0;
}
static int jz4740_dma_terminate_all(struct dma_chan *c) static int jz4740_dma_terminate_all(struct dma_chan *c)
{ {
struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
...@@ -407,6 +418,8 @@ static struct dma_async_tx_descriptor *jz4740_dma_prep_slave_sg( ...@@ -407,6 +418,8 @@ static struct dma_async_tx_descriptor *jz4740_dma_prep_slave_sg(
desc->direction = direction; desc->direction = direction;
desc->cyclic = false; desc->cyclic = false;
jz4740_dma_slave_config_write(c, &chan->config, direction);
return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
} }
...@@ -438,6 +451,8 @@ static struct dma_async_tx_descriptor *jz4740_dma_prep_dma_cyclic( ...@@ -438,6 +451,8 @@ static struct dma_async_tx_descriptor *jz4740_dma_prep_dma_cyclic(
desc->direction = direction; desc->direction = direction;
desc->cyclic = true; desc->cyclic = true;
jz4740_dma_slave_config_write(c, &chan->config, direction);
return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
} }
......
...@@ -886,12 +886,7 @@ static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) ...@@ -886,12 +886,7 @@ static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
*/ */
u32 s = dw->pdata->is_idma32 ? 1 : 2; u32 s = dw->pdata->is_idma32 ? 1 : 2;
/* Check if chan will be configured for slave transfers */
if (!is_slave_direction(sconfig->direction))
return -EINVAL;
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
dwc->direction = sconfig->direction;
sc->src_maxburst = sc->src_maxburst > 1 ? fls(sc->src_maxburst) - s : 0; sc->src_maxburst = sc->src_maxburst > 1 ? fls(sc->src_maxburst) - s : 0;
sc->dst_maxburst = sc->dst_maxburst > 1 ? fls(sc->dst_maxburst) - s : 0; sc->dst_maxburst = sc->dst_maxburst > 1 ? fls(sc->dst_maxburst) - s : 0;
......
...@@ -109,6 +109,9 @@ ...@@ -109,6 +109,9 @@
#define DMA_MAX_CHAN_DESCRIPTORS 32 #define DMA_MAX_CHAN_DESCRIPTORS 32
struct ep93xx_dma_engine; struct ep93xx_dma_engine;
static int ep93xx_dma_slave_config_write(struct dma_chan *chan,
enum dma_transfer_direction dir,
struct dma_slave_config *config);
/** /**
* struct ep93xx_dma_desc - EP93xx specific transaction descriptor * struct ep93xx_dma_desc - EP93xx specific transaction descriptor
...@@ -180,6 +183,7 @@ struct ep93xx_dma_chan { ...@@ -180,6 +183,7 @@ struct ep93xx_dma_chan {
struct list_head free_list; struct list_head free_list;
u32 runtime_addr; u32 runtime_addr;
u32 runtime_ctrl; u32 runtime_ctrl;
struct dma_slave_config slave_config;
}; };
/** /**
...@@ -1051,6 +1055,8 @@ ep93xx_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -1051,6 +1055,8 @@ ep93xx_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
return NULL; return NULL;
} }
ep93xx_dma_slave_config_write(chan, dir, &edmac->slave_config);
first = NULL; first = NULL;
for_each_sg(sgl, sg, sg_len, i) { for_each_sg(sgl, sg, sg_len, i) {
size_t len = sg_dma_len(sg); size_t len = sg_dma_len(sg);
...@@ -1136,6 +1142,8 @@ ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, ...@@ -1136,6 +1142,8 @@ ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
return NULL; return NULL;
} }
ep93xx_dma_slave_config_write(chan, dir, &edmac->slave_config);
/* Split the buffer into period size chunks */ /* Split the buffer into period size chunks */
first = NULL; first = NULL;
for (offset = 0; offset < buf_len; offset += period_len) { for (offset = 0; offset < buf_len; offset += period_len) {
...@@ -1227,6 +1235,17 @@ static int ep93xx_dma_slave_config(struct dma_chan *chan, ...@@ -1227,6 +1235,17 @@ static int ep93xx_dma_slave_config(struct dma_chan *chan,
struct dma_slave_config *config) struct dma_slave_config *config)
{ {
struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
memcpy(&edmac->slave_config, config, sizeof(*config));
return 0;
}
static int ep93xx_dma_slave_config_write(struct dma_chan *chan,
enum dma_transfer_direction dir,
struct dma_slave_config *config)
{
struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
enum dma_slave_buswidth width; enum dma_slave_buswidth width;
unsigned long flags; unsigned long flags;
u32 addr, ctrl; u32 addr, ctrl;
...@@ -1234,7 +1253,7 @@ static int ep93xx_dma_slave_config(struct dma_chan *chan, ...@@ -1234,7 +1253,7 @@ static int ep93xx_dma_slave_config(struct dma_chan *chan,
if (!edmac->edma->m2m) if (!edmac->edma->m2m)
return -EINVAL; return -EINVAL;
switch (config->direction) { switch (dir) {
case DMA_DEV_TO_MEM: case DMA_DEV_TO_MEM:
width = config->src_addr_width; width = config->src_addr_width;
addr = config->src_addr; addr = config->src_addr;
......
...@@ -348,10 +348,6 @@ static int hsu_dma_slave_config(struct dma_chan *chan, ...@@ -348,10 +348,6 @@ static int hsu_dma_slave_config(struct dma_chan *chan,
{ {
struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan);
/* Check if chan will be configured for slave transfers */
if (!is_slave_direction(config->direction))
return -EINVAL;
memcpy(&hsuc->config, config, sizeof(hsuc->config)); memcpy(&hsuc->config, config, sizeof(hsuc->config));
return 0; return 0;
......
...@@ -408,10 +408,6 @@ static int idma64_slave_config(struct dma_chan *chan, ...@@ -408,10 +408,6 @@ static int idma64_slave_config(struct dma_chan *chan,
{ {
struct idma64_chan *idma64c = to_idma64_chan(chan); struct idma64_chan *idma64c = to_idma64_chan(chan);
/* Check if chan will be configured for slave transfers */
if (!is_slave_direction(config->direction))
return -EINVAL;
memcpy(&idma64c->config, config, sizeof(idma64c->config)); memcpy(&idma64c->config, config, sizeof(idma64c->config));
convert_burst(&idma64c->config.src_maxburst); convert_burst(&idma64c->config.src_maxburst);
......
...@@ -162,6 +162,7 @@ struct imxdma_channel { ...@@ -162,6 +162,7 @@ struct imxdma_channel {
bool enabled_2d; bool enabled_2d;
int slot_2d; int slot_2d;
unsigned int irq; unsigned int irq;
struct dma_slave_config config;
}; };
enum imx_dma_type { enum imx_dma_type {
...@@ -675,14 +676,15 @@ static int imxdma_terminate_all(struct dma_chan *chan) ...@@ -675,14 +676,15 @@ static int imxdma_terminate_all(struct dma_chan *chan)
return 0; return 0;
} }
static int imxdma_config(struct dma_chan *chan, static int imxdma_config_write(struct dma_chan *chan,
struct dma_slave_config *dmaengine_cfg) struct dma_slave_config *dmaengine_cfg,
enum dma_transfer_direction direction)
{ {
struct imxdma_channel *imxdmac = to_imxdma_chan(chan); struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
struct imxdma_engine *imxdma = imxdmac->imxdma; struct imxdma_engine *imxdma = imxdmac->imxdma;
unsigned int mode = 0; unsigned int mode = 0;
if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) {
imxdmac->per_address = dmaengine_cfg->src_addr; imxdmac->per_address = dmaengine_cfg->src_addr;
imxdmac->watermark_level = dmaengine_cfg->src_maxburst; imxdmac->watermark_level = dmaengine_cfg->src_maxburst;
imxdmac->word_size = dmaengine_cfg->src_addr_width; imxdmac->word_size = dmaengine_cfg->src_addr_width;
...@@ -723,6 +725,16 @@ static int imxdma_config(struct dma_chan *chan, ...@@ -723,6 +725,16 @@ static int imxdma_config(struct dma_chan *chan,
return 0; return 0;
} }
static int imxdma_config(struct dma_chan *chan,
struct dma_slave_config *dmaengine_cfg)
{
struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
memcpy(&imxdmac->config, dmaengine_cfg, sizeof(*dmaengine_cfg));
return 0;
}
static enum dma_status imxdma_tx_status(struct dma_chan *chan, static enum dma_status imxdma_tx_status(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t cookie,
struct dma_tx_state *txstate) struct dma_tx_state *txstate)
...@@ -905,6 +917,8 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( ...@@ -905,6 +917,8 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
desc->desc.callback = NULL; desc->desc.callback = NULL;
desc->desc.callback_param = NULL; desc->desc.callback_param = NULL;
imxdma_config_write(chan, &imxdmac->config, direction);
return &desc->desc; return &desc->desc;
} }
......
...@@ -87,10 +87,10 @@ struct k3_dma_chan { ...@@ -87,10 +87,10 @@ struct k3_dma_chan {
struct virt_dma_chan vc; struct virt_dma_chan vc;
struct k3_dma_phy *phy; struct k3_dma_phy *phy;
struct list_head node; struct list_head node;
enum dma_transfer_direction dir;
dma_addr_t dev_addr; dma_addr_t dev_addr;
enum dma_status status; enum dma_status status;
bool cyclic; bool cyclic;
struct dma_slave_config slave_config;
}; };
struct k3_dma_phy { struct k3_dma_phy {
...@@ -118,6 +118,10 @@ struct k3_dma_dev { ...@@ -118,6 +118,10 @@ struct k3_dma_dev {
#define to_k3_dma(dmadev) container_of(dmadev, struct k3_dma_dev, slave) #define to_k3_dma(dmadev) container_of(dmadev, struct k3_dma_dev, slave)
static int k3_dma_config_write(struct dma_chan *chan,
enum dma_transfer_direction dir,
struct dma_slave_config *cfg);
static struct k3_dma_chan *to_k3_chan(struct dma_chan *chan) static struct k3_dma_chan *to_k3_chan(struct dma_chan *chan)
{ {
return container_of(chan, struct k3_dma_chan, vc.chan); return container_of(chan, struct k3_dma_chan, vc.chan);
...@@ -501,14 +505,8 @@ static struct dma_async_tx_descriptor *k3_dma_prep_memcpy( ...@@ -501,14 +505,8 @@ static struct dma_async_tx_descriptor *k3_dma_prep_memcpy(
copy = min_t(size_t, len, DMA_MAX_SIZE); copy = min_t(size_t, len, DMA_MAX_SIZE);
k3_dma_fill_desc(ds, dst, src, copy, num++, c->ccfg); k3_dma_fill_desc(ds, dst, src, copy, num++, c->ccfg);
if (c->dir == DMA_MEM_TO_DEV) { src += copy;
src += copy; dst += copy;
} else if (c->dir == DMA_DEV_TO_MEM) {
dst += copy;
} else {
src += copy;
dst += copy;
}
len -= copy; len -= copy;
} while (len); } while (len);
...@@ -542,6 +540,7 @@ static struct dma_async_tx_descriptor *k3_dma_prep_slave_sg( ...@@ -542,6 +540,7 @@ static struct dma_async_tx_descriptor *k3_dma_prep_slave_sg(
if (!ds) if (!ds)
return NULL; return NULL;
num = 0; num = 0;
k3_dma_config_write(chan, dir, &c->slave_config);
for_each_sg(sgl, sg, sglen, i) { for_each_sg(sgl, sg, sglen, i) {
addr = sg_dma_address(sg); addr = sg_dma_address(sg);
...@@ -602,6 +601,7 @@ k3_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, ...@@ -602,6 +601,7 @@ k3_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
avail = buf_len; avail = buf_len;
total = avail; total = avail;
num = 0; num = 0;
k3_dma_config_write(chan, dir, &c->slave_config);
if (period_len < modulo) if (period_len < modulo)
modulo = period_len; modulo = period_len;
...@@ -642,18 +642,26 @@ static int k3_dma_config(struct dma_chan *chan, ...@@ -642,18 +642,26 @@ static int k3_dma_config(struct dma_chan *chan,
struct dma_slave_config *cfg) struct dma_slave_config *cfg)
{ {
struct k3_dma_chan *c = to_k3_chan(chan); struct k3_dma_chan *c = to_k3_chan(chan);
memcpy(&c->slave_config, cfg, sizeof(*cfg));
return 0;
}
static int k3_dma_config_write(struct dma_chan *chan,
enum dma_transfer_direction dir,
struct dma_slave_config *cfg)
{
struct k3_dma_chan *c = to_k3_chan(chan);
u32 maxburst = 0, val = 0; u32 maxburst = 0, val = 0;
enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED; enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
if (cfg == NULL) if (dir == DMA_DEV_TO_MEM) {
return -EINVAL;
c->dir = cfg->direction;
if (c->dir == DMA_DEV_TO_MEM) {
c->ccfg = CX_CFG_DSTINCR; c->ccfg = CX_CFG_DSTINCR;
c->dev_addr = cfg->src_addr; c->dev_addr = cfg->src_addr;
maxburst = cfg->src_maxburst; maxburst = cfg->src_maxburst;
width = cfg->src_addr_width; width = cfg->src_addr_width;
} else if (c->dir == DMA_MEM_TO_DEV) { } else if (dir == DMA_MEM_TO_DEV) {
c->ccfg = CX_CFG_SRCINCR; c->ccfg = CX_CFG_SRCINCR;
c->dev_addr = cfg->dst_addr; c->dev_addr = cfg->dst_addr;
maxburst = cfg->dst_maxburst; maxburst = cfg->dst_maxburst;
......
...@@ -116,6 +116,7 @@ struct mmp_tdma_chan { ...@@ -116,6 +116,7 @@ struct mmp_tdma_chan {
u32 burst_sz; u32 burst_sz;
enum dma_slave_buswidth buswidth; enum dma_slave_buswidth buswidth;
enum dma_status status; enum dma_status status;
struct dma_slave_config slave_config;
int idx; int idx;
enum mmp_tdma_type type; enum mmp_tdma_type type;
...@@ -139,6 +140,10 @@ struct mmp_tdma_device { ...@@ -139,6 +140,10 @@ struct mmp_tdma_device {
#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan) #define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)
static int mmp_tdma_config_write(struct dma_chan *chan,
enum dma_transfer_direction dir,
struct dma_slave_config *dmaengine_cfg);
static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys) static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys)
{ {
writel(phys, tdmac->reg_base + TDNDPR); writel(phys, tdmac->reg_base + TDNDPR);
...@@ -442,6 +447,8 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( ...@@ -442,6 +447,8 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic(
if (!desc) if (!desc)
goto err_out; goto err_out;
mmp_tdma_config_write(chan, direction, &tdmac->slave_config);
while (buf < buf_len) { while (buf < buf_len) {
desc = &tdmac->desc_arr[i]; desc = &tdmac->desc_arr[i];
...@@ -495,7 +502,18 @@ static int mmp_tdma_config(struct dma_chan *chan, ...@@ -495,7 +502,18 @@ static int mmp_tdma_config(struct dma_chan *chan,
{ {
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { memcpy(&tdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
return 0;
}
static int mmp_tdma_config_write(struct dma_chan *chan,
enum dma_transfer_direction dir,
struct dma_slave_config *dmaengine_cfg)
{
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
if (dir == DMA_DEV_TO_MEM) {
tdmac->dev_addr = dmaengine_cfg->src_addr; tdmac->dev_addr = dmaengine_cfg->src_addr;
tdmac->burst_sz = dmaengine_cfg->src_maxburst; tdmac->burst_sz = dmaengine_cfg->src_maxburst;
tdmac->buswidth = dmaengine_cfg->src_addr_width; tdmac->buswidth = dmaengine_cfg->src_addr_width;
...@@ -504,7 +522,7 @@ static int mmp_tdma_config(struct dma_chan *chan, ...@@ -504,7 +522,7 @@ static int mmp_tdma_config(struct dma_chan *chan,
tdmac->burst_sz = dmaengine_cfg->dst_maxburst; tdmac->burst_sz = dmaengine_cfg->dst_maxburst;
tdmac->buswidth = dmaengine_cfg->dst_addr_width; tdmac->buswidth = dmaengine_cfg->dst_addr_width;
} }
tdmac->dir = dmaengine_cfg->direction; tdmac->dir = dir;
return mmp_tdma_config_chan(chan); return mmp_tdma_config_chan(chan);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册