Loading drivers/dma/imx-sdma.c +39 −17 Original line number Diff line number Diff line Loading @@ -335,6 +335,7 @@ struct sdma_desc { * @sdma: pointer to the SDMA engine for this channel * @channel: the channel number, matches dmaengine chan_id + 1 * @direction: transfer type. Needed for setting SDMA script * @slave_config Slave configuration * @peripheral_type: Peripheral type. Needed for setting SDMA script * @event_id0: aka dma request line * @event_id1: for channels that use 2 events Loading Loading @@ -362,6 +363,7 @@ struct sdma_channel { struct sdma_engine *sdma; unsigned int channel; enum dma_transfer_direction direction; struct dma_slave_config slave_config; enum sdma_peripheral_type peripheral_type; unsigned int event_id0; unsigned int event_id1; Loading Loading @@ -440,6 +442,10 @@ struct sdma_engine { 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 = { .chnenbl0 = SDMA_CHNENBL0_IMX31, .num_events = 32, Loading Loading @@ -1104,18 +1110,6 @@ static int sdma_config_channel(struct dma_chan *chan) sdmac->shp_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) { case IMX_DMATYPE_DSP: sdma_config_ownership(sdmac, false, true, true); Loading Loading @@ -1415,6 +1409,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct scatterlist *sg; struct sdma_desc *desc; sdma_config_write(chan, &sdmac->slave_config, direction); desc = sdma_transfer_init(sdmac, direction, sg_len); if (!desc) goto err_out; Loading Loading @@ -1499,6 +1495,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( 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); if (!desc) goto err_out; Loading Loading @@ -1554,17 +1552,18 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( return NULL; } static int sdma_config(struct dma_chan *chan, struct dma_slave_config *dmaengine_cfg) static int sdma_config_write(struct dma_chan *chan, struct dma_slave_config *dmaengine_cfg, enum dma_transfer_direction direction) { 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->watermark_level = dmaengine_cfg->src_maxburst * 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_address = dmaengine_cfg->dst_addr; sdmac->watermark_level = dmaengine_cfg->src_maxburst & Loading @@ -1578,10 +1577,33 @@ static int sdma_config(struct dma_chan *chan, 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); } 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, dma_cookie_t cookie, struct dma_tx_state *txstate) Loading drivers/dma/mmp_pdma.c +23 −5 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ struct mmp_pdma_chan { struct dma_async_tx_descriptor desc; struct mmp_pdma_phy *phy; enum dma_transfer_direction dir; struct dma_slave_config slave_config; struct mmp_pdma_desc_sw *cyclic_first; /* first desc_sw if channel * is in cyclic mode */ Loading Loading @@ -140,6 +141,10 @@ struct mmp_pdma_device { #define to_mmp_pdma_dev(dmadev) \ container_of(dmadev, struct mmp_pdma_device, device) static int mmp_pdma_config_write(struct dma_chan *dchan, struct dma_slave_config *cfg, enum dma_transfer_direction direction); static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr) { u32 reg = (phy->idx << 4) + DDADR; Loading Loading @@ -537,6 +542,8 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, chan->byte_align = false; mmp_pdma_config_write(dchan, &chan->slave_config, dir); for_each_sg(sgl, sg, sg_len, i) { addr = sg_dma_address(sg); avail = sg_dma_len(sgl); Loading Loading @@ -619,6 +626,7 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, return NULL; chan = to_mmp_pdma_chan(dchan); mmp_pdma_config_write(dchan, &chan->slave_config, direction); switch (direction) { case DMA_MEM_TO_DEV: Loading Loading @@ -684,8 +692,9 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, return NULL; } static int mmp_pdma_config(struct dma_chan *dchan, struct dma_slave_config *cfg) static int mmp_pdma_config_write(struct dma_chan *dchan, struct dma_slave_config *cfg, enum dma_transfer_direction direction) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); u32 maxburst = 0, addr = 0; Loading @@ -694,12 +703,12 @@ static int mmp_pdma_config(struct dma_chan *dchan, if (!dchan) return -EINVAL; if (cfg->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) { chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; maxburst = cfg->src_maxburst; width = cfg->src_addr_width; addr = cfg->src_addr; } else if (cfg->direction == DMA_MEM_TO_DEV) { } else if (direction == DMA_MEM_TO_DEV) { chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; maxburst = cfg->dst_maxburst; width = cfg->dst_addr_width; Loading @@ -720,7 +729,7 @@ static int mmp_pdma_config(struct dma_chan *dchan, else if (maxburst == 32) chan->dcmd |= DCMD_BURST32; chan->dir = cfg->direction; chan->dir = direction; chan->dev_addr = addr; /* FIXME: drivers should be ported over to use the filter * function. Once that's done, the following two lines can Loading @@ -732,6 +741,15 @@ static int mmp_pdma_config(struct dma_chan *dchan, return 0; } static int mmp_pdma_config(struct dma_chan *dchan, struct dma_slave_config *cfg) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); memcpy(&chan->slave_config, cfg, sizeof(*cfg)); return 0; } static int mmp_pdma_terminate_all(struct dma_chan *dchan) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); Loading drivers/dma/pl330.c +24 −4 Original line number Diff line number Diff line Loading @@ -448,6 +448,7 @@ struct dma_pl330_chan { /* DMA-mapped view of the FIFO; may differ if an IOMMU is present */ dma_addr_t fifo_dma; enum dma_data_direction dir; struct dma_slave_config slave_config; /* for cyclic capability */ bool cyclic; Loading Loading @@ -542,6 +543,10 @@ struct _xfer_spec { struct dma_pl330_desc *desc; }; static int pl330_config_write(struct dma_chan *chan, struct dma_slave_config *slave_config, enum dma_transfer_direction direction); static inline bool _queue_full(struct pl330_thread *thrd) { return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; Loading Loading @@ -2220,20 +2225,21 @@ static int fixup_burst_len(int max_burst_len, int quirks) return max_burst_len; } static int pl330_config(struct dma_chan *chan, struct dma_slave_config *slave_config) static int pl330_config_write(struct dma_chan *chan, struct dma_slave_config *slave_config, enum dma_transfer_direction direction) { struct dma_pl330_chan *pch = to_pchan(chan); pl330_unprep_slave_fifo(pch); if (slave_config->direction == DMA_MEM_TO_DEV) { if (direction == DMA_MEM_TO_DEV) { if (slave_config->dst_addr) pch->fifo_addr = slave_config->dst_addr; if (slave_config->dst_addr_width) pch->burst_sz = __ffs(slave_config->dst_addr_width); pch->burst_len = fixup_burst_len(slave_config->dst_maxburst, pch->dmac->quirks); } else if (slave_config->direction == DMA_DEV_TO_MEM) { } else if (direction == DMA_DEV_TO_MEM) { if (slave_config->src_addr) pch->fifo_addr = slave_config->src_addr; if (slave_config->src_addr_width) Loading @@ -2245,6 +2251,16 @@ static int pl330_config(struct dma_chan *chan, return 0; } static int pl330_config(struct dma_chan *chan, struct dma_slave_config *slave_config) { struct dma_pl330_chan *pch = to_pchan(chan); memcpy(&pch->slave_config, slave_config, sizeof(*slave_config)); return 0; } static int pl330_terminate_all(struct dma_chan *chan) { struct dma_pl330_chan *pch = to_pchan(chan); Loading Loading @@ -2661,6 +2677,8 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( return NULL; } pl330_config_write(chan, &pch->slave_config, direction); if (!pl330_prep_slave_fifo(pch, direction)) return NULL; Loading Loading @@ -2815,6 +2833,8 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (unlikely(!pch || !sgl || !sg_len)) return NULL; pl330_config_write(chan, &pch->slave_config, direction); if (!pl330_prep_slave_fifo(pch, direction)) return NULL; Loading drivers/dma/ste_dma40.c +25 −6 Original line number Diff line number Diff line Loading @@ -442,6 +442,7 @@ struct d40_base; * @queue: Queued jobs. * @prepare_queue: Prepared jobs. * @dma_cfg: The client configuration of this dma channel. * @slave_config: DMA slave configuration. * @configured: whether the dma_cfg configuration is valid * @base: Pointer to the device instance struct. * @src_def_cfg: Default cfg register setting for src. Loading @@ -468,6 +469,7 @@ struct d40_chan { struct list_head queue; struct list_head prepare_queue; struct stedma40_chan_cfg dma_cfg; struct dma_slave_config slave_config; bool configured; struct d40_base *base; /* Default register configurations */ Loading Loading @@ -625,6 +627,10 @@ static void __iomem *chan_base(struct d40_chan *chan) #define chan_err(d40c, format, arg...) \ d40_err(chan2dev(d40c), format, ## arg) static int d40_set_runtime_config_write(struct dma_chan *chan, struct dma_slave_config *config, enum dma_transfer_direction direction); static int d40_pool_lli_alloc(struct d40_chan *d40c, struct d40_desc *d40d, int lli_len) { Loading Loading @@ -2216,6 +2222,8 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, return NULL; } d40_set_runtime_config_write(dchan, &chan->slave_config, direction); spin_lock_irqsave(&chan->lock, flags); desc = d40_prep_desc(chan, sg_src, sg_len, dma_flags); Loading Loading @@ -2634,11 +2642,22 @@ dma40_config_to_halfchannel(struct d40_chan *d40c, return 0; } /* Runtime reconfiguration extension */ static int d40_set_runtime_config(struct dma_chan *chan, struct dma_slave_config *config) { struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); memcpy(&d40c->slave_config, config, sizeof(*config)); return 0; } /* Runtime reconfiguration extension */ static int d40_set_runtime_config_write(struct dma_chan *chan, struct dma_slave_config *config, enum dma_transfer_direction direction) { struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); struct stedma40_chan_cfg *cfg = &d40c->dma_cfg; enum dma_slave_buswidth src_addr_width, dst_addr_width; dma_addr_t config_addr; Loading @@ -2655,7 +2674,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_addr_width = config->dst_addr_width; dst_maxburst = config->dst_maxburst; if (config->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) { config_addr = config->src_addr; if (cfg->dir != DMA_DEV_TO_MEM) Loading @@ -2671,7 +2690,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (dst_maxburst == 0) dst_maxburst = src_maxburst; } else if (config->direction == DMA_MEM_TO_DEV) { } else if (direction == DMA_MEM_TO_DEV) { config_addr = config->dst_addr; if (cfg->dir != DMA_MEM_TO_DEV) Loading @@ -2689,7 +2708,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, } else { dev_err(d40c->base->dev, "unrecognized channel direction %d\n", config->direction); direction); return -EINVAL; } Loading Loading @@ -2746,12 +2765,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, /* These settings will take precedence later */ d40c->runtime_addr = config_addr; d40c->runtime_direction = config->direction; d40c->runtime_direction = direction; dev_dbg(d40c->base->dev, "configured channel %s for %s, data width %d/%d, " "maxburst %d/%d elements, LE, no flow control\n", dma_chan_name(chan), (config->direction == DMA_DEV_TO_MEM) ? "RX" : "TX", (direction == DMA_DEV_TO_MEM) ? "RX" : "TX", src_addr_width, dst_addr_width, src_maxburst, dst_maxburst); Loading Loading
drivers/dma/imx-sdma.c +39 −17 Original line number Diff line number Diff line Loading @@ -335,6 +335,7 @@ struct sdma_desc { * @sdma: pointer to the SDMA engine for this channel * @channel: the channel number, matches dmaengine chan_id + 1 * @direction: transfer type. Needed for setting SDMA script * @slave_config Slave configuration * @peripheral_type: Peripheral type. Needed for setting SDMA script * @event_id0: aka dma request line * @event_id1: for channels that use 2 events Loading Loading @@ -362,6 +363,7 @@ struct sdma_channel { struct sdma_engine *sdma; unsigned int channel; enum dma_transfer_direction direction; struct dma_slave_config slave_config; enum sdma_peripheral_type peripheral_type; unsigned int event_id0; unsigned int event_id1; Loading Loading @@ -440,6 +442,10 @@ struct sdma_engine { 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 = { .chnenbl0 = SDMA_CHNENBL0_IMX31, .num_events = 32, Loading Loading @@ -1104,18 +1110,6 @@ static int sdma_config_channel(struct dma_chan *chan) sdmac->shp_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) { case IMX_DMATYPE_DSP: sdma_config_ownership(sdmac, false, true, true); Loading Loading @@ -1415,6 +1409,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct scatterlist *sg; struct sdma_desc *desc; sdma_config_write(chan, &sdmac->slave_config, direction); desc = sdma_transfer_init(sdmac, direction, sg_len); if (!desc) goto err_out; Loading Loading @@ -1499,6 +1495,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( 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); if (!desc) goto err_out; Loading Loading @@ -1554,17 +1552,18 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( return NULL; } static int sdma_config(struct dma_chan *chan, struct dma_slave_config *dmaengine_cfg) static int sdma_config_write(struct dma_chan *chan, struct dma_slave_config *dmaengine_cfg, enum dma_transfer_direction direction) { 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->watermark_level = dmaengine_cfg->src_maxburst * 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_address = dmaengine_cfg->dst_addr; sdmac->watermark_level = dmaengine_cfg->src_maxburst & Loading @@ -1578,10 +1577,33 @@ static int sdma_config(struct dma_chan *chan, 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); } 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, dma_cookie_t cookie, struct dma_tx_state *txstate) Loading
drivers/dma/mmp_pdma.c +23 −5 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ struct mmp_pdma_chan { struct dma_async_tx_descriptor desc; struct mmp_pdma_phy *phy; enum dma_transfer_direction dir; struct dma_slave_config slave_config; struct mmp_pdma_desc_sw *cyclic_first; /* first desc_sw if channel * is in cyclic mode */ Loading Loading @@ -140,6 +141,10 @@ struct mmp_pdma_device { #define to_mmp_pdma_dev(dmadev) \ container_of(dmadev, struct mmp_pdma_device, device) static int mmp_pdma_config_write(struct dma_chan *dchan, struct dma_slave_config *cfg, enum dma_transfer_direction direction); static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr) { u32 reg = (phy->idx << 4) + DDADR; Loading Loading @@ -537,6 +542,8 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, chan->byte_align = false; mmp_pdma_config_write(dchan, &chan->slave_config, dir); for_each_sg(sgl, sg, sg_len, i) { addr = sg_dma_address(sg); avail = sg_dma_len(sgl); Loading Loading @@ -619,6 +626,7 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, return NULL; chan = to_mmp_pdma_chan(dchan); mmp_pdma_config_write(dchan, &chan->slave_config, direction); switch (direction) { case DMA_MEM_TO_DEV: Loading Loading @@ -684,8 +692,9 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, return NULL; } static int mmp_pdma_config(struct dma_chan *dchan, struct dma_slave_config *cfg) static int mmp_pdma_config_write(struct dma_chan *dchan, struct dma_slave_config *cfg, enum dma_transfer_direction direction) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); u32 maxburst = 0, addr = 0; Loading @@ -694,12 +703,12 @@ static int mmp_pdma_config(struct dma_chan *dchan, if (!dchan) return -EINVAL; if (cfg->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) { chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; maxburst = cfg->src_maxburst; width = cfg->src_addr_width; addr = cfg->src_addr; } else if (cfg->direction == DMA_MEM_TO_DEV) { } else if (direction == DMA_MEM_TO_DEV) { chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; maxburst = cfg->dst_maxburst; width = cfg->dst_addr_width; Loading @@ -720,7 +729,7 @@ static int mmp_pdma_config(struct dma_chan *dchan, else if (maxburst == 32) chan->dcmd |= DCMD_BURST32; chan->dir = cfg->direction; chan->dir = direction; chan->dev_addr = addr; /* FIXME: drivers should be ported over to use the filter * function. Once that's done, the following two lines can Loading @@ -732,6 +741,15 @@ static int mmp_pdma_config(struct dma_chan *dchan, return 0; } static int mmp_pdma_config(struct dma_chan *dchan, struct dma_slave_config *cfg) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); memcpy(&chan->slave_config, cfg, sizeof(*cfg)); return 0; } static int mmp_pdma_terminate_all(struct dma_chan *dchan) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); Loading
drivers/dma/pl330.c +24 −4 Original line number Diff line number Diff line Loading @@ -448,6 +448,7 @@ struct dma_pl330_chan { /* DMA-mapped view of the FIFO; may differ if an IOMMU is present */ dma_addr_t fifo_dma; enum dma_data_direction dir; struct dma_slave_config slave_config; /* for cyclic capability */ bool cyclic; Loading Loading @@ -542,6 +543,10 @@ struct _xfer_spec { struct dma_pl330_desc *desc; }; static int pl330_config_write(struct dma_chan *chan, struct dma_slave_config *slave_config, enum dma_transfer_direction direction); static inline bool _queue_full(struct pl330_thread *thrd) { return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; Loading Loading @@ -2220,20 +2225,21 @@ static int fixup_burst_len(int max_burst_len, int quirks) return max_burst_len; } static int pl330_config(struct dma_chan *chan, struct dma_slave_config *slave_config) static int pl330_config_write(struct dma_chan *chan, struct dma_slave_config *slave_config, enum dma_transfer_direction direction) { struct dma_pl330_chan *pch = to_pchan(chan); pl330_unprep_slave_fifo(pch); if (slave_config->direction == DMA_MEM_TO_DEV) { if (direction == DMA_MEM_TO_DEV) { if (slave_config->dst_addr) pch->fifo_addr = slave_config->dst_addr; if (slave_config->dst_addr_width) pch->burst_sz = __ffs(slave_config->dst_addr_width); pch->burst_len = fixup_burst_len(slave_config->dst_maxburst, pch->dmac->quirks); } else if (slave_config->direction == DMA_DEV_TO_MEM) { } else if (direction == DMA_DEV_TO_MEM) { if (slave_config->src_addr) pch->fifo_addr = slave_config->src_addr; if (slave_config->src_addr_width) Loading @@ -2245,6 +2251,16 @@ static int pl330_config(struct dma_chan *chan, return 0; } static int pl330_config(struct dma_chan *chan, struct dma_slave_config *slave_config) { struct dma_pl330_chan *pch = to_pchan(chan); memcpy(&pch->slave_config, slave_config, sizeof(*slave_config)); return 0; } static int pl330_terminate_all(struct dma_chan *chan) { struct dma_pl330_chan *pch = to_pchan(chan); Loading Loading @@ -2661,6 +2677,8 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( return NULL; } pl330_config_write(chan, &pch->slave_config, direction); if (!pl330_prep_slave_fifo(pch, direction)) return NULL; Loading Loading @@ -2815,6 +2833,8 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (unlikely(!pch || !sgl || !sg_len)) return NULL; pl330_config_write(chan, &pch->slave_config, direction); if (!pl330_prep_slave_fifo(pch, direction)) return NULL; Loading
drivers/dma/ste_dma40.c +25 −6 Original line number Diff line number Diff line Loading @@ -442,6 +442,7 @@ struct d40_base; * @queue: Queued jobs. * @prepare_queue: Prepared jobs. * @dma_cfg: The client configuration of this dma channel. * @slave_config: DMA slave configuration. * @configured: whether the dma_cfg configuration is valid * @base: Pointer to the device instance struct. * @src_def_cfg: Default cfg register setting for src. Loading @@ -468,6 +469,7 @@ struct d40_chan { struct list_head queue; struct list_head prepare_queue; struct stedma40_chan_cfg dma_cfg; struct dma_slave_config slave_config; bool configured; struct d40_base *base; /* Default register configurations */ Loading Loading @@ -625,6 +627,10 @@ static void __iomem *chan_base(struct d40_chan *chan) #define chan_err(d40c, format, arg...) \ d40_err(chan2dev(d40c), format, ## arg) static int d40_set_runtime_config_write(struct dma_chan *chan, struct dma_slave_config *config, enum dma_transfer_direction direction); static int d40_pool_lli_alloc(struct d40_chan *d40c, struct d40_desc *d40d, int lli_len) { Loading Loading @@ -2216,6 +2222,8 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, return NULL; } d40_set_runtime_config_write(dchan, &chan->slave_config, direction); spin_lock_irqsave(&chan->lock, flags); desc = d40_prep_desc(chan, sg_src, sg_len, dma_flags); Loading Loading @@ -2634,11 +2642,22 @@ dma40_config_to_halfchannel(struct d40_chan *d40c, return 0; } /* Runtime reconfiguration extension */ static int d40_set_runtime_config(struct dma_chan *chan, struct dma_slave_config *config) { struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); memcpy(&d40c->slave_config, config, sizeof(*config)); return 0; } /* Runtime reconfiguration extension */ static int d40_set_runtime_config_write(struct dma_chan *chan, struct dma_slave_config *config, enum dma_transfer_direction direction) { struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); struct stedma40_chan_cfg *cfg = &d40c->dma_cfg; enum dma_slave_buswidth src_addr_width, dst_addr_width; dma_addr_t config_addr; Loading @@ -2655,7 +2674,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_addr_width = config->dst_addr_width; dst_maxburst = config->dst_maxburst; if (config->direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) { config_addr = config->src_addr; if (cfg->dir != DMA_DEV_TO_MEM) Loading @@ -2671,7 +2690,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (dst_maxburst == 0) dst_maxburst = src_maxburst; } else if (config->direction == DMA_MEM_TO_DEV) { } else if (direction == DMA_MEM_TO_DEV) { config_addr = config->dst_addr; if (cfg->dir != DMA_MEM_TO_DEV) Loading @@ -2689,7 +2708,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, } else { dev_err(d40c->base->dev, "unrecognized channel direction %d\n", config->direction); direction); return -EINVAL; } Loading Loading @@ -2746,12 +2765,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, /* These settings will take precedence later */ d40c->runtime_addr = config_addr; d40c->runtime_direction = config->direction; d40c->runtime_direction = direction; dev_dbg(d40c->base->dev, "configured channel %s for %s, data width %d/%d, " "maxburst %d/%d elements, LE, no flow control\n", dma_chan_name(chan), (config->direction == DMA_DEV_TO_MEM) ? "RX" : "TX", (direction == DMA_DEV_TO_MEM) ? "RX" : "TX", src_addr_width, dst_addr_width, src_maxburst, dst_maxburst); Loading