diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-02-14 06:36:51 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-02-14 06:36:51 -0500 |
commit | 0670e7157f75ec6d2231fbc6f67b075d6b6d486f (patch) | |
tree | 64591858de42da54afc979338ee083d1e6d672a0 | |
parent | 80cc07af0f6692a7d8fdc5087594d1988a701266 (diff) | |
parent | 4aa5f366431fef0afca0df348ca9782c63ac9911 (diff) |
Merge branch 'dw_dmac' into dmaengine
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap700x.c | 6 | ||||
-rw-r--r-- | drivers/dma/dw_dmac.c | 36 | ||||
-rw-r--r-- | include/linux/dw_dmac.h | 5 |
3 files changed, 33 insertions, 14 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index e67c99945428..2747cde8c9a7 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
@@ -2048,6 +2048,8 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, | |||
2048 | rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT; | 2048 | rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT; |
2049 | rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); | 2049 | rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); |
2050 | rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); | 2050 | rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); |
2051 | rx_dws->src_master = 0; | ||
2052 | rx_dws->dst_master = 1; | ||
2051 | } | 2053 | } |
2052 | 2054 | ||
2053 | /* Check if DMA slave interface for playback should be configured. */ | 2055 | /* 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 | tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT; | 2058 | tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT; |
2057 | tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); | 2059 | tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); |
2058 | tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); | 2060 | tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); |
2061 | rx_dws->src_master = 0; | ||
2062 | rx_dws->dst_master = 1; | ||
2059 | } | 2063 | } |
2060 | 2064 | ||
2061 | if (platform_device_add_data(pdev, data, | 2065 | if (platform_device_add_data(pdev, data, |
@@ -2128,6 +2132,8 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) | |||
2128 | dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT; | 2132 | dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT; |
2129 | dws->cfg_hi = DWC_CFGH_DST_PER(2); | 2133 | dws->cfg_hi = DWC_CFGH_DST_PER(2); |
2130 | dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); | 2134 | dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); |
2135 | dws->src_master = 0; | ||
2136 | dws->dst_master = 1; | ||
2131 | 2137 | ||
2132 | if (platform_device_add_data(pdev, data, | 2138 | if (platform_device_add_data(pdev, data, |
2133 | sizeof(struct atmel_abdac_pdata))) | 2139 | sizeof(struct atmel_abdac_pdata))) |
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index a3991ab0d67e..08dab3badad2 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -32,15 +32,18 @@ | |||
32 | * which does not support descriptor writeback. | 32 | * which does not support descriptor writeback. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | /* NOTE: DMS+SMS is system-specific. We should get this information | 35 | #define DWC_DEFAULT_CTLLO(private) ({ \ |
36 | * from the platform code somehow. | 36 | struct dw_dma_slave *__slave = (private); \ |
37 | */ | 37 | int dms = __slave ? __slave->dst_master : 0; \ |
38 | #define DWC_DEFAULT_CTLLO (DWC_CTLL_DST_MSIZE(0) \ | 38 | int sms = __slave ? __slave->src_master : 1; \ |
39 | | DWC_CTLL_SRC_MSIZE(0) \ | 39 | \ |
40 | | DWC_CTLL_DMS(0) \ | 40 | (DWC_CTLL_DST_MSIZE(0) \ |
41 | | DWC_CTLL_SMS(1) \ | 41 | | DWC_CTLL_SRC_MSIZE(0) \ |
42 | | DWC_CTLL_LLP_D_EN \ | 42 | | DWC_CTLL_LLP_D_EN \ |
43 | | DWC_CTLL_LLP_S_EN) | 43 | | DWC_CTLL_LLP_S_EN \ |
44 | | DWC_CTLL_DMS(dms) \ | ||
45 | | DWC_CTLL_SMS(sms)); \ | ||
46 | }) | ||
44 | 47 | ||
45 | /* | 48 | /* |
46 | * This is configuration-dependent and usually a funny size like 4095. | 49 | * 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 | return; | 294 | return; |
292 | } | 295 | } |
293 | 296 | ||
297 | if (list_empty(&dwc->active_list)) | ||
298 | return; | ||
299 | |||
294 | dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); | 300 | dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); |
295 | 301 | ||
296 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { | 302 | 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 | else | 594 | else |
589 | src_width = dst_width = 0; | 595 | src_width = dst_width = 0; |
590 | 596 | ||
591 | ctllo = DWC_DEFAULT_CTLLO | 597 | ctllo = DWC_DEFAULT_CTLLO(chan->private) |
592 | | DWC_CTLL_DST_WIDTH(dst_width) | 598 | | DWC_CTLL_DST_WIDTH(dst_width) |
593 | | DWC_CTLL_SRC_WIDTH(src_width) | 599 | | DWC_CTLL_SRC_WIDTH(src_width) |
594 | | DWC_CTLL_DST_INC | 600 | | DWC_CTLL_DST_INC |
@@ -669,7 +675,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
669 | 675 | ||
670 | switch (direction) { | 676 | switch (direction) { |
671 | case DMA_TO_DEVICE: | 677 | case DMA_TO_DEVICE: |
672 | ctllo = (DWC_DEFAULT_CTLLO | 678 | ctllo = (DWC_DEFAULT_CTLLO(chan->private) |
673 | | DWC_CTLL_DST_WIDTH(reg_width) | 679 | | DWC_CTLL_DST_WIDTH(reg_width) |
674 | | DWC_CTLL_DST_FIX | 680 | | DWC_CTLL_DST_FIX |
675 | | DWC_CTLL_SRC_INC | 681 | | DWC_CTLL_SRC_INC |
@@ -714,7 +720,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
714 | } | 720 | } |
715 | break; | 721 | break; |
716 | case DMA_FROM_DEVICE: | 722 | case DMA_FROM_DEVICE: |
717 | ctllo = (DWC_DEFAULT_CTLLO | 723 | ctllo = (DWC_DEFAULT_CTLLO(chan->private) |
718 | | DWC_CTLL_SRC_WIDTH(reg_width) | 724 | | DWC_CTLL_SRC_WIDTH(reg_width) |
719 | | DWC_CTLL_DST_INC | 725 | | DWC_CTLL_DST_INC |
720 | | DWC_CTLL_SRC_FIX | 726 | | DWC_CTLL_SRC_FIX |
@@ -1126,7 +1132,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | |||
1126 | case DMA_TO_DEVICE: | 1132 | case DMA_TO_DEVICE: |
1127 | desc->lli.dar = dws->tx_reg; | 1133 | desc->lli.dar = dws->tx_reg; |
1128 | desc->lli.sar = buf_addr + (period_len * i); | 1134 | desc->lli.sar = buf_addr + (period_len * i); |
1129 | desc->lli.ctllo = (DWC_DEFAULT_CTLLO | 1135 | desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan->private) |
1130 | | DWC_CTLL_DST_WIDTH(reg_width) | 1136 | | DWC_CTLL_DST_WIDTH(reg_width) |
1131 | | DWC_CTLL_SRC_WIDTH(reg_width) | 1137 | | DWC_CTLL_SRC_WIDTH(reg_width) |
1132 | | DWC_CTLL_DST_FIX | 1138 | | DWC_CTLL_DST_FIX |
@@ -1137,7 +1143,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | |||
1137 | case DMA_FROM_DEVICE: | 1143 | case DMA_FROM_DEVICE: |
1138 | desc->lli.dar = buf_addr + (period_len * i); | 1144 | desc->lli.dar = buf_addr + (period_len * i); |
1139 | desc->lli.sar = dws->rx_reg; | 1145 | desc->lli.sar = dws->rx_reg; |
1140 | desc->lli.ctllo = (DWC_DEFAULT_CTLLO | 1146 | desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan->private) |
1141 | | DWC_CTLL_SRC_WIDTH(reg_width) | 1147 | | DWC_CTLL_SRC_WIDTH(reg_width) |
1142 | | DWC_CTLL_DST_WIDTH(reg_width) | 1148 | | DWC_CTLL_DST_WIDTH(reg_width) |
1143 | | DWC_CTLL_DST_INC | 1149 | | DWC_CTLL_DST_INC |
@@ -1335,6 +1341,8 @@ static int __init dw_probe(struct platform_device *pdev) | |||
1335 | 1341 | ||
1336 | dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); | 1342 | dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); |
1337 | dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); | 1343 | dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); |
1344 | if (pdata->is_private) | ||
1345 | dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask); | ||
1338 | dw->dma.dev = &pdev->dev; | 1346 | dw->dma.dev = &pdev->dev; |
1339 | dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources; | 1347 | dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources; |
1340 | dw->dma.device_free_chan_resources = dwc_free_chan_resources; | 1348 | dw->dma.device_free_chan_resources = dwc_free_chan_resources; |
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h index c8aad713a046..deec66b37180 100644 --- a/include/linux/dw_dmac.h +++ b/include/linux/dw_dmac.h | |||
@@ -16,9 +16,12 @@ | |||
16 | /** | 16 | /** |
17 | * struct dw_dma_platform_data - Controller configuration parameters | 17 | * struct dw_dma_platform_data - Controller configuration parameters |
18 | * @nr_channels: Number of channels supported by hardware (max 8) | 18 | * @nr_channels: Number of channels supported by hardware (max 8) |
19 | * @is_private: The device channels should be marked as private and not for | ||
20 | * by the general purpose DMA channel allocator. | ||
19 | */ | 21 | */ |
20 | struct dw_dma_platform_data { | 22 | struct dw_dma_platform_data { |
21 | unsigned int nr_channels; | 23 | unsigned int nr_channels; |
24 | bool is_private; | ||
22 | }; | 25 | }; |
23 | 26 | ||
24 | /** | 27 | /** |
@@ -52,6 +55,8 @@ struct dw_dma_slave { | |||
52 | enum dw_dma_slave_width reg_width; | 55 | enum dw_dma_slave_width reg_width; |
53 | u32 cfg_hi; | 56 | u32 cfg_hi; |
54 | u32 cfg_lo; | 57 | u32 cfg_lo; |
58 | int src_master; | ||
59 | int dst_master; | ||
55 | }; | 60 | }; |
56 | 61 | ||
57 | /* Platform-configurable bits in CFG_HI */ | 62 | /* Platform-configurable bits in CFG_HI */ |