aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/dw/core.c34
-rw-r--r--drivers/dma/hsu/hsu.c13
-rw-r--r--drivers/dma/hsu/hsu.h3
3 files changed, 30 insertions, 20 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 5ad0ec1f0e29..97199b3c25a2 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -130,26 +130,14 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
130static void dwc_initialize(struct dw_dma_chan *dwc) 130static void dwc_initialize(struct dw_dma_chan *dwc)
131{ 131{
132 struct dw_dma *dw = to_dw_dma(dwc->chan.device); 132 struct dw_dma *dw = to_dw_dma(dwc->chan.device);
133 struct dw_dma_slave *dws = dwc->chan.private;
134 u32 cfghi = DWC_CFGH_FIFO_MODE; 133 u32 cfghi = DWC_CFGH_FIFO_MODE;
135 u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority); 134 u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
136 135
137 if (dwc->initialized == true) 136 if (dwc->initialized == true)
138 return; 137 return;
139 138
140 if (dws) { 139 cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
141 /* 140 cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
142 * We need controller-specific data to set up slave
143 * transfers.
144 */
145 BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
146
147 cfghi |= DWC_CFGH_DST_PER(dws->dst_id);
148 cfghi |= DWC_CFGH_SRC_PER(dws->src_id);
149 } else {
150 cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
151 cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
152 }
153 141
154 channel_writel(dwc, CFG_LO, cfglo); 142 channel_writel(dwc, CFG_LO, cfglo);
155 channel_writel(dwc, CFG_HI, cfghi); 143 channel_writel(dwc, CFG_HI, cfghi);
@@ -941,7 +929,7 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
941 struct dw_dma_chan *dwc = to_dw_dma_chan(chan); 929 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
942 struct dw_dma_slave *dws = param; 930 struct dw_dma_slave *dws = param;
943 931
944 if (!dws || dws->dma_dev != chan->device->dev) 932 if (dws->dma_dev != chan->device->dev)
945 return false; 933 return false;
946 934
947 /* We have to copy data since dws can be temporary storage */ 935 /* We have to copy data since dws can be temporary storage */
@@ -1165,6 +1153,14 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
1165 * doesn't mean what you think it means), and status writeback. 1153 * doesn't mean what you think it means), and status writeback.
1166 */ 1154 */
1167 1155
1156 /*
1157 * We need controller-specific data to set up slave transfers.
1158 */
1159 if (chan->private && !dw_dma_filter(chan, chan->private)) {
1160 dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
1161 return -EINVAL;
1162 }
1163
1168 /* Enable controller here if needed */ 1164 /* Enable controller here if needed */
1169 if (!dw->in_use) 1165 if (!dw->in_use)
1170 dw_dma_on(dw); 1166 dw_dma_on(dw);
@@ -1226,6 +1222,14 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
1226 spin_lock_irqsave(&dwc->lock, flags); 1222 spin_lock_irqsave(&dwc->lock, flags);
1227 list_splice_init(&dwc->free_list, &list); 1223 list_splice_init(&dwc->free_list, &list);
1228 dwc->descs_allocated = 0; 1224 dwc->descs_allocated = 0;
1225
1226 /* Clear custom channel configuration */
1227 dwc->src_id = 0;
1228 dwc->dst_id = 0;
1229
1230 dwc->src_master = 0;
1231 dwc->dst_master = 0;
1232
1229 dwc->initialized = false; 1233 dwc->initialized = false;
1230 1234
1231 /* Disable interrupts */ 1235 /* Disable interrupts */
diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index eef145edb936..ee510515ce18 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -64,10 +64,10 @@ static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc)
64 64
65 if (hsuc->direction == DMA_MEM_TO_DEV) { 65 if (hsuc->direction == DMA_MEM_TO_DEV) {
66 bsr = config->dst_maxburst; 66 bsr = config->dst_maxburst;
67 mtsr = config->dst_addr_width; 67 mtsr = config->src_addr_width;
68 } else if (hsuc->direction == DMA_DEV_TO_MEM) { 68 } else if (hsuc->direction == DMA_DEV_TO_MEM) {
69 bsr = config->src_maxburst; 69 bsr = config->src_maxburst;
70 mtsr = config->src_addr_width; 70 mtsr = config->dst_addr_width;
71 } 71 }
72 72
73 hsu_chan_disable(hsuc); 73 hsu_chan_disable(hsuc);
@@ -135,7 +135,7 @@ static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
135 sr = hsu_chan_readl(hsuc, HSU_CH_SR); 135 sr = hsu_chan_readl(hsuc, HSU_CH_SR);
136 spin_unlock_irqrestore(&hsuc->vchan.lock, flags); 136 spin_unlock_irqrestore(&hsuc->vchan.lock, flags);
137 137
138 return sr; 138 return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
139} 139}
140 140
141irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) 141irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
@@ -254,10 +254,13 @@ static void hsu_dma_issue_pending(struct dma_chan *chan)
254static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc) 254static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc)
255{ 255{
256 struct hsu_dma_desc *desc = hsuc->desc; 256 struct hsu_dma_desc *desc = hsuc->desc;
257 size_t bytes = desc->length; 257 size_t bytes = 0;
258 int i; 258 int i;
259 259
260 i = desc->active % HSU_DMA_CHAN_NR_DESC; 260 for (i = desc->active; i < desc->nents; i++)
261 bytes += desc->sg[i].len;
262
263 i = HSU_DMA_CHAN_NR_DESC - 1;
261 do { 264 do {
262 bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i)); 265 bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i));
263 } while (--i >= 0); 266 } while (--i >= 0);
diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h
index 578a8ee8cd05..6b070c22b1df 100644
--- a/drivers/dma/hsu/hsu.h
+++ b/drivers/dma/hsu/hsu.h
@@ -41,6 +41,9 @@
41#define HSU_CH_SR_DESCTO(x) BIT(8 + (x)) 41#define HSU_CH_SR_DESCTO(x) BIT(8 + (x))
42#define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8)) 42#define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8))
43#define HSU_CH_SR_CHE BIT(15) 43#define HSU_CH_SR_CHE BIT(15)
44#define HSU_CH_SR_DESCE(x) BIT(16 + (x))
45#define HSU_CH_SR_DESCE_ANY (BIT(19) | BIT(18) | BIT(17) | BIT(16))
46#define HSU_CH_SR_CDESC_ANY (BIT(31) | BIT(30))
44 47
45/* Bits in HSU_CH_CR */ 48/* Bits in HSU_CH_CR */
46#define HSU_CH_CR_CHA BIT(0) 49#define HSU_CH_CR_CHA BIT(0)