aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/ste_dma40.c63
-rw-r--r--drivers/dma/ste_dma40_ll.c43
-rw-r--r--include/linux/platform_data/dma-ste-dma40.h9
-rw-r--r--sound/soc/ux500/ux500_pcm.c10
4 files changed, 60 insertions, 65 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 483da1660eae..76c255fcdc2d 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -80,11 +80,11 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
80 .mode = STEDMA40_MODE_PHYSICAL, 80 .mode = STEDMA40_MODE_PHYSICAL,
81 .dir = DMA_MEM_TO_MEM, 81 .dir = DMA_MEM_TO_MEM,
82 82
83 .src_info.data_width = STEDMA40_BYTE_WIDTH, 83 .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
84 .src_info.psize = STEDMA40_PSIZE_PHY_1, 84 .src_info.psize = STEDMA40_PSIZE_PHY_1,
85 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 85 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
86 86
87 .dst_info.data_width = STEDMA40_BYTE_WIDTH, 87 .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
88 .dst_info.psize = STEDMA40_PSIZE_PHY_1, 88 .dst_info.psize = STEDMA40_PSIZE_PHY_1,
89 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 89 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
90}; 90};
@@ -94,11 +94,11 @@ struct stedma40_chan_cfg dma40_memcpy_conf_log = {
94 .mode = STEDMA40_MODE_LOGICAL, 94 .mode = STEDMA40_MODE_LOGICAL,
95 .dir = DMA_MEM_TO_MEM, 95 .dir = DMA_MEM_TO_MEM,
96 96
97 .src_info.data_width = STEDMA40_BYTE_WIDTH, 97 .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
98 .src_info.psize = STEDMA40_PSIZE_LOG_1, 98 .src_info.psize = STEDMA40_PSIZE_LOG_1,
99 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 99 .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
100 100
101 .dst_info.data_width = STEDMA40_BYTE_WIDTH, 101 .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
102 .dst_info.psize = STEDMA40_PSIZE_LOG_1, 102 .dst_info.psize = STEDMA40_PSIZE_LOG_1,
103 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, 103 .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
104}; 104};
@@ -1005,20 +1005,21 @@ static int d40_psize_2_burst_size(bool is_log, int psize)
1005 1005
1006/* 1006/*
1007 * The dma only supports transmitting packages up to 1007 * The dma only supports transmitting packages up to
1008 * STEDMA40_MAX_SEG_SIZE << data_width. Calculate the total number of 1008 * STEDMA40_MAX_SEG_SIZE * data_width, where data_width is stored in Bytes.
1009 * dma elements required to send the entire sg list 1009 *
1010 * Calculate the total number of dma elements required to send the entire sg list.
1010 */ 1011 */
1011static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2) 1012static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2)
1012{ 1013{
1013 int dmalen; 1014 int dmalen;
1014 u32 max_w = max(data_width1, data_width2); 1015 u32 max_w = max(data_width1, data_width2);
1015 u32 min_w = min(data_width1, data_width2); 1016 u32 min_w = min(data_width1, data_width2);
1016 u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); 1017 u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
1017 1018
1018 if (seg_max > STEDMA40_MAX_SEG_SIZE) 1019 if (seg_max > STEDMA40_MAX_SEG_SIZE)
1019 seg_max -= (1 << max_w); 1020 seg_max -= max_w;
1020 1021
1021 if (!IS_ALIGNED(size, 1 << max_w)) 1022 if (!IS_ALIGNED(size, max_w))
1022 return -EINVAL; 1023 return -EINVAL;
1023 1024
1024 if (size <= seg_max) 1025 if (size <= seg_max)
@@ -1464,7 +1465,7 @@ static u32 d40_residue(struct d40_chan *d40c)
1464 >> D40_SREG_ELEM_PHY_ECNT_POS; 1465 >> D40_SREG_ELEM_PHY_ECNT_POS;
1465 } 1466 }
1466 1467
1467 return num_elt * (1 << d40c->dma_cfg.dst_info.data_width); 1468 return num_elt * d40c->dma_cfg.dst_info.data_width;
1468} 1469}
1469 1470
1470static bool d40_tx_is_linked(struct d40_chan *d40c) 1471static bool d40_tx_is_linked(struct d40_chan *d40c)
@@ -1784,9 +1785,9 @@ static int d40_validate_conf(struct d40_chan *d40c,
1784 } 1785 }
1785 1786
1786 if (d40_psize_2_burst_size(is_log, conf->src_info.psize) * 1787 if (d40_psize_2_burst_size(is_log, conf->src_info.psize) *
1787 (1 << conf->src_info.data_width) != 1788 conf->src_info.data_width !=
1788 d40_psize_2_burst_size(is_log, conf->dst_info.psize) * 1789 d40_psize_2_burst_size(is_log, conf->dst_info.psize) *
1789 (1 << conf->dst_info.data_width)) { 1790 conf->dst_info.data_width) {
1790 /* 1791 /*
1791 * The DMAC hardware only supports 1792 * The DMAC hardware only supports
1792 * src (burst x width) == dst (burst x width) 1793 * src (burst x width) == dst (burst x width)
@@ -2673,33 +2674,10 @@ static void d40_terminate_all(struct dma_chan *chan)
2673static int 2674static int
2674dma40_config_to_halfchannel(struct d40_chan *d40c, 2675dma40_config_to_halfchannel(struct d40_chan *d40c,
2675 struct stedma40_half_channel_info *info, 2676 struct stedma40_half_channel_info *info,
2676 enum dma_slave_buswidth width,
2677 u32 maxburst) 2677 u32 maxburst)
2678{ 2678{
2679 enum stedma40_periph_data_width addr_width;
2680 int psize; 2679 int psize;
2681 2680
2682 switch (width) {
2683 case DMA_SLAVE_BUSWIDTH_1_BYTE:
2684 addr_width = STEDMA40_BYTE_WIDTH;
2685 break;
2686 case DMA_SLAVE_BUSWIDTH_2_BYTES:
2687 addr_width = STEDMA40_HALFWORD_WIDTH;
2688 break;
2689 case DMA_SLAVE_BUSWIDTH_4_BYTES:
2690 addr_width = STEDMA40_WORD_WIDTH;
2691 break;
2692 case DMA_SLAVE_BUSWIDTH_8_BYTES:
2693 addr_width = STEDMA40_DOUBLEWORD_WIDTH;
2694 break;
2695 default:
2696 dev_err(d40c->base->dev,
2697 "illegal peripheral address width "
2698 "requested (%d)\n",
2699 width);
2700 return -EINVAL;
2701 }
2702
2703 if (chan_is_logical(d40c)) { 2681 if (chan_is_logical(d40c)) {
2704 if (maxburst >= 16) 2682 if (maxburst >= 16)
2705 psize = STEDMA40_PSIZE_LOG_16; 2683 psize = STEDMA40_PSIZE_LOG_16;
@@ -2720,7 +2698,6 @@ dma40_config_to_halfchannel(struct d40_chan *d40c,
2720 psize = STEDMA40_PSIZE_PHY_1; 2698 psize = STEDMA40_PSIZE_PHY_1;
2721 } 2699 }
2722 2700
2723 info->data_width = addr_width;
2724 info->psize = psize; 2701 info->psize = psize;
2725 info->flow_ctrl = STEDMA40_NO_FLOW_CTRL; 2702 info->flow_ctrl = STEDMA40_NO_FLOW_CTRL;
2726 2703
@@ -2804,14 +2781,24 @@ static int d40_set_runtime_config(struct dma_chan *chan,
2804 src_maxburst = dst_maxburst * dst_addr_width / src_addr_width; 2781 src_maxburst = dst_maxburst * dst_addr_width / src_addr_width;
2805 } 2782 }
2806 2783
2784 /* Only valid widths are; 1, 2, 4 and 8. */
2785 if (src_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED ||
2786 src_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES ||
2787 dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED ||
2788 dst_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES ||
2789 ((src_addr_width > 1) && (src_addr_width & 1)) ||
2790 ((dst_addr_width > 1) && (dst_addr_width & 1)))
2791 return -EINVAL;
2792
2793 cfg->src_info.data_width = src_addr_width;
2794 cfg->dst_info.data_width = dst_addr_width;
2795
2807 ret = dma40_config_to_halfchannel(d40c, &cfg->src_info, 2796 ret = dma40_config_to_halfchannel(d40c, &cfg->src_info,
2808 src_addr_width,
2809 src_maxburst); 2797 src_maxburst);
2810 if (ret) 2798 if (ret)
2811 return ret; 2799 return ret;
2812 2800
2813 ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info, 2801 ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info,
2814 dst_addr_width,
2815 dst_maxburst); 2802 dst_maxburst);
2816 if (ret) 2803 if (ret)
2817 return ret; 2804 return ret;
diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c
index 5ddd724dcdc5..a035dfeab6cb 100644
--- a/drivers/dma/ste_dma40_ll.c
+++ b/drivers/dma/ste_dma40_ll.c
@@ -10,6 +10,18 @@
10 10
11#include "ste_dma40_ll.h" 11#include "ste_dma40_ll.h"
12 12
13u8 d40_width_to_bits(enum dma_slave_buswidth width)
14{
15 if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
16 return STEDMA40_ESIZE_8_BIT;
17 else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
18 return STEDMA40_ESIZE_16_BIT;
19 else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES)
20 return STEDMA40_ESIZE_64_BIT;
21 else
22 return STEDMA40_ESIZE_32_BIT;
23}
24
13/* Sets up proper LCSP1 and LCSP3 register for a logical channel */ 25/* Sets up proper LCSP1 and LCSP3 register for a logical channel */
14void d40_log_cfg(struct stedma40_chan_cfg *cfg, 26void d40_log_cfg(struct stedma40_chan_cfg *cfg,
15 u32 *lcsp1, u32 *lcsp3) 27 u32 *lcsp1, u32 *lcsp3)
@@ -39,11 +51,13 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg,
39 51
40 l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS); 52 l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS);
41 l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; 53 l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS;
42 l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; 54 l3 |= d40_width_to_bits(cfg->dst_info.data_width)
55 << D40_MEM_LCSP3_DCFG_ESIZE_POS;
43 56
44 l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS); 57 l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS);
45 l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; 58 l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS;
46 l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; 59 l1 |= d40_width_to_bits(cfg->src_info.data_width)
60 << D40_MEM_LCSP1_SCFG_ESIZE_POS;
47 61
48 *lcsp1 = l1; 62 *lcsp1 = l1;
49 *lcsp3 = l3; 63 *lcsp3 = l3;
@@ -95,8 +109,10 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg)
95 } 109 }
96 110
97 /* Element size */ 111 /* Element size */
98 src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; 112 src |= d40_width_to_bits(cfg->src_info.data_width)
99 dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; 113 << D40_SREG_CFG_ESIZE_POS;
114 dst |= d40_width_to_bits(cfg->dst_info.data_width)
115 << D40_SREG_CFG_ESIZE_POS;
100 116
101 /* Set the priority bit to high for the physical channel */ 117 /* Set the priority bit to high for the physical channel */
102 if (cfg->high_priority) { 118 if (cfg->high_priority) {
@@ -133,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
133 num_elems = 2 << psize; 149 num_elems = 2 << psize;
134 150
135 /* Must be aligned */ 151 /* Must be aligned */
136 if (!IS_ALIGNED(data, 0x1 << data_width)) 152 if (!IS_ALIGNED(data, data_width))
137 return -EINVAL; 153 return -EINVAL;
138 154
139 /* Transfer size can't be smaller than (num_elms * elem_size) */ 155 /* Transfer size can't be smaller than (num_elms * elem_size) */
140 if (data_size < num_elems * (0x1 << data_width)) 156 if (data_size < num_elems * data_width)
141 return -EINVAL; 157 return -EINVAL;
142 158
143 /* The number of elements. IE now many chunks */ 159 /* The number of elements. IE now many chunks */
144 lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; 160 lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS;
145 161
146 /* 162 /*
147 * Distance to next element sized entry. 163 * Distance to next element sized entry.
148 * Usually the size of the element unless you want gaps. 164 * Usually the size of the element unless you want gaps.
149 */ 165 */
150 if (addr_inc) 166 if (addr_inc)
151 lli->reg_elt |= (0x1 << data_width) << 167 lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS;
152 D40_SREG_ELEM_PHY_EIDX_POS;
153 168
154 /* Where the data is */ 169 /* Where the data is */
155 lli->reg_ptr = data; 170 lli->reg_ptr = data;
@@ -177,16 +192,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2)
177{ 192{
178 u32 max_w = max(data_width1, data_width2); 193 u32 max_w = max(data_width1, data_width2);
179 u32 min_w = min(data_width1, data_width2); 194 u32 min_w = min(data_width1, data_width2);
180 u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); 195 u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
181 196
182 if (seg_max > STEDMA40_MAX_SEG_SIZE) 197 if (seg_max > STEDMA40_MAX_SEG_SIZE)
183 seg_max -= (1 << max_w); 198 seg_max -= max_w;
184 199
185 if (size <= seg_max) 200 if (size <= seg_max)
186 return size; 201 return size;
187 202
188 if (size <= 2 * seg_max) 203 if (size <= 2 * seg_max)
189 return ALIGN(size / 2, 1 << max_w); 204 return ALIGN(size / 2, max_w);
190 205
191 return seg_max; 206 return seg_max;
192} 207}
@@ -352,10 +367,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli,
352 lli->lcsp13 = reg_cfg; 367 lli->lcsp13 = reg_cfg;
353 368
354 /* The number of elements to transfer */ 369 /* The number of elements to transfer */
355 lli->lcsp02 = ((data_size >> data_width) << 370 lli->lcsp02 = ((data_size / data_width) <<
356 D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; 371 D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK;
357 372
358 BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE); 373 BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE);
359 374
360 /* 16 LSBs address of the current element */ 375 /* 16 LSBs address of the current element */
361 lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; 376 lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK;
diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h
index 54ddca615cb4..ceba6dc566a9 100644
--- a/include/linux/platform_data/dma-ste-dma40.h
+++ b/include/linux/platform_data/dma-ste-dma40.h
@@ -70,13 +70,6 @@ enum stedma40_flow_ctrl {
70 STEDMA40_FLOW_CTRL, 70 STEDMA40_FLOW_CTRL,
71}; 71};
72 72
73enum stedma40_periph_data_width {
74 STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
75 STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
76 STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT,
77 STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT
78};
79
80/** 73/**
81 * struct stedma40_half_channel_info - dst/src channel configuration 74 * struct stedma40_half_channel_info - dst/src channel configuration
82 * 75 *
@@ -87,7 +80,7 @@ enum stedma40_periph_data_width {
87 */ 80 */
88struct stedma40_half_channel_info { 81struct stedma40_half_channel_info {
89 bool big_endian; 82 bool big_endian;
90 enum stedma40_periph_data_width data_width; 83 enum dma_slave_buswidth data_width;
91 int psize; 84 int psize;
92 enum stedma40_flow_ctrl flow_ctrl; 85 enum stedma40_flow_ctrl flow_ctrl;
93}; 86};
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index b6e5ae277299..31f9bbc74521 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -76,20 +76,20 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
76 dma_params = snd_soc_dai_get_dma_data(dai, substream); 76 dma_params = snd_soc_dai_get_dma_data(dai, substream);
77 dma_cfg = dma_params->dma_cfg; 77 dma_cfg = dma_params->dma_cfg;
78 78
79 mem_data_width = STEDMA40_HALFWORD_WIDTH; 79 mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
80 80
81 switch (dma_params->data_size) { 81 switch (dma_params->data_size) {
82 case 32: 82 case 32:
83 per_data_width = STEDMA40_WORD_WIDTH; 83 per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
84 break; 84 break;
85 case 16: 85 case 16:
86 per_data_width = STEDMA40_HALFWORD_WIDTH; 86 per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
87 break; 87 break;
88 case 8: 88 case 8:
89 per_data_width = STEDMA40_BYTE_WIDTH; 89 per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
90 break; 90 break;
91 default: 91 default:
92 per_data_width = STEDMA40_WORD_WIDTH; 92 per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
93 } 93 }
94 94
95 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 95 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {