Commit 0670e715 authored by Dan Williams's avatar Dan Williams

Merge branch 'dw_dmac' into dmaengine

parents 80cc07af 4aa5f366
...@@ -2048,6 +2048,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, ...@@ -2048,6 +2048,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT; rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);
rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
rx_dws->src_master = 0;
rx_dws->dst_master = 1;
} }
/* Check if DMA slave interface for playback should be configured. */ /* Check if DMA slave interface for playback should be configured. */
...@@ -2056,6 +2058,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, ...@@ -2056,6 +2058,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT; tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);
tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
rx_dws->src_master = 0;
rx_dws->dst_master = 1;
} }
if (platform_device_add_data(pdev, data, if (platform_device_add_data(pdev, data,
...@@ -2128,6 +2132,8 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) ...@@ -2128,6 +2132,8 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT; dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
dws->cfg_hi = DWC_CFGH_DST_PER(2); dws->cfg_hi = DWC_CFGH_DST_PER(2);
dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
dws->src_master = 0;
dws->dst_master = 1;
if (platform_device_add_data(pdev, data, if (platform_device_add_data(pdev, data,
sizeof(struct atmel_abdac_pdata))) sizeof(struct atmel_abdac_pdata)))
......
...@@ -32,15 +32,18 @@ ...@@ -32,15 +32,18 @@
* which does not support descriptor writeback. * which does not support descriptor writeback.
*/ */
/* NOTE: DMS+SMS is system-specific. We should get this information #define DWC_DEFAULT_CTLLO(private) ({ \
* from the platform code somehow. struct dw_dma_slave *__slave = (private); \
*/ int dms = __slave ? __slave->dst_master : 0; \
#define DWC_DEFAULT_CTLLO (DWC_CTLL_DST_MSIZE(0) \ int sms = __slave ? __slave->src_master : 1; \
| DWC_CTLL_SRC_MSIZE(0) \ \
| DWC_CTLL_DMS(0) \ (DWC_CTLL_DST_MSIZE(0) \
| DWC_CTLL_SMS(1) \ | DWC_CTLL_SRC_MSIZE(0) \
| DWC_CTLL_LLP_D_EN \ | DWC_CTLL_LLP_D_EN \
| DWC_CTLL_LLP_S_EN) | DWC_CTLL_LLP_S_EN \
| DWC_CTLL_DMS(dms) \
| DWC_CTLL_SMS(sms)); \
})
/* /*
* This is configuration-dependent and usually a funny size like 4095. * This is configuration-dependent and usually a funny size like 4095.
...@@ -291,6 +294,9 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) ...@@ -291,6 +294,9 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
return; return;
} }
if (list_empty(&dwc->active_list))
return;
dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp);
list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
...@@ -588,7 +594,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, ...@@ -588,7 +594,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
else else
src_width = dst_width = 0; src_width = dst_width = 0;
ctllo = DWC_DEFAULT_CTLLO ctllo = DWC_DEFAULT_CTLLO(chan->private)
| DWC_CTLL_DST_WIDTH(dst_width) | DWC_CTLL_DST_WIDTH(dst_width)
| DWC_CTLL_SRC_WIDTH(src_width) | DWC_CTLL_SRC_WIDTH(src_width)
| DWC_CTLL_DST_INC | DWC_CTLL_DST_INC
...@@ -669,7 +675,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -669,7 +675,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
switch (direction) { switch (direction) {
case DMA_TO_DEVICE: case DMA_TO_DEVICE:
ctllo = (DWC_DEFAULT_CTLLO ctllo = (DWC_DEFAULT_CTLLO(chan->private)
| DWC_CTLL_DST_WIDTH(reg_width) | DWC_CTLL_DST_WIDTH(reg_width)
| DWC_CTLL_DST_FIX | DWC_CTLL_DST_FIX
| DWC_CTLL_SRC_INC | DWC_CTLL_SRC_INC
...@@ -714,7 +720,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -714,7 +720,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
} }
break; break;
case DMA_FROM_DEVICE: case DMA_FROM_DEVICE:
ctllo = (DWC_DEFAULT_CTLLO ctllo = (DWC_DEFAULT_CTLLO(chan->private)
| DWC_CTLL_SRC_WIDTH(reg_width) | DWC_CTLL_SRC_WIDTH(reg_width)
| DWC_CTLL_DST_INC | DWC_CTLL_DST_INC
| DWC_CTLL_SRC_FIX | DWC_CTLL_SRC_FIX
...@@ -1126,7 +1132,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, ...@@ -1126,7 +1132,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
case DMA_TO_DEVICE: case DMA_TO_DEVICE:
desc->lli.dar = dws->tx_reg; desc->lli.dar = dws->tx_reg;
desc->lli.sar = buf_addr + (period_len * i); desc->lli.sar = buf_addr + (period_len * i);
desc->lli.ctllo = (DWC_DEFAULT_CTLLO desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan->private)
| DWC_CTLL_DST_WIDTH(reg_width) | DWC_CTLL_DST_WIDTH(reg_width)
| DWC_CTLL_SRC_WIDTH(reg_width) | DWC_CTLL_SRC_WIDTH(reg_width)
| DWC_CTLL_DST_FIX | DWC_CTLL_DST_FIX
...@@ -1137,7 +1143,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, ...@@ -1137,7 +1143,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
case DMA_FROM_DEVICE: case DMA_FROM_DEVICE:
desc->lli.dar = buf_addr + (period_len * i); desc->lli.dar = buf_addr + (period_len * i);
desc->lli.sar = dws->rx_reg; desc->lli.sar = dws->rx_reg;
desc->lli.ctllo = (DWC_DEFAULT_CTLLO desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan->private)
| DWC_CTLL_SRC_WIDTH(reg_width) | DWC_CTLL_SRC_WIDTH(reg_width)
| DWC_CTLL_DST_WIDTH(reg_width) | DWC_CTLL_DST_WIDTH(reg_width)
| DWC_CTLL_DST_INC | DWC_CTLL_DST_INC
...@@ -1335,6 +1341,8 @@ static int __init dw_probe(struct platform_device *pdev) ...@@ -1335,6 +1341,8 @@ static int __init dw_probe(struct platform_device *pdev)
dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
if (pdata->is_private)
dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
dw->dma.dev = &pdev->dev; dw->dma.dev = &pdev->dev;
dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources; dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
dw->dma.device_free_chan_resources = dwc_free_chan_resources; dw->dma.device_free_chan_resources = dwc_free_chan_resources;
......
...@@ -16,9 +16,12 @@ ...@@ -16,9 +16,12 @@
/** /**
* struct dw_dma_platform_data - Controller configuration parameters * struct dw_dma_platform_data - Controller configuration parameters
* @nr_channels: Number of channels supported by hardware (max 8) * @nr_channels: Number of channels supported by hardware (max 8)
* @is_private: The device channels should be marked as private and not for
* by the general purpose DMA channel allocator.
*/ */
struct dw_dma_platform_data { struct dw_dma_platform_data {
unsigned int nr_channels; unsigned int nr_channels;
bool is_private;
}; };
/** /**
...@@ -52,6 +55,8 @@ struct dw_dma_slave { ...@@ -52,6 +55,8 @@ struct dw_dma_slave {
enum dw_dma_slave_width reg_width; enum dw_dma_slave_width reg_width;
u32 cfg_hi; u32 cfg_hi;
u32 cfg_lo; u32 cfg_lo;
int src_master;
int dst_master;
}; };
/* Platform-configurable bits in CFG_HI */ /* Platform-configurable bits in CFG_HI */
......
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