aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2011-01-25 05:18:30 -0500
committerDan Williams <dan.j.williams@intel.com>2011-01-31 01:27:20 -0500
commit7f933bed96e9872131014ea2bdd5b012e43fc316 (patch)
tree32e54ca912ab509ba5b66f45e0d276bad51a9ae5
parent1f7622ca55b1f5875e32140b4781759f800aded3 (diff)
dma40: use flags to reduce parameter count
Acked-by: Per Forlin <per.forlin@stericsson.com> Acked-by: Jonas Aaberg <jonas.aberg@stericsson.com> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/dma/ste_dma40_ll.c84
-rw-r--r--drivers/dma/ste_dma40_ll.h5
2 files changed, 52 insertions, 37 deletions
diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c
index 876aad2c838a..88b9e371be2f 100644
--- a/drivers/dma/ste_dma40_ll.c
+++ b/drivers/dma/ste_dma40_ll.c
@@ -127,10 +127,11 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
127 u32 data_size, 127 u32 data_size,
128 dma_addr_t next_lli, 128 dma_addr_t next_lli,
129 u32 reg_cfg, 129 u32 reg_cfg,
130 bool term_int, 130 struct stedma40_half_channel_info *info,
131 bool is_device, 131 unsigned int flags)
132 struct stedma40_half_channel_info *info)
133{ 132{
133 bool addr_inc = flags & LLI_ADDR_INC;
134 bool term_int = flags & LLI_TERM_INT;
134 unsigned int data_width = info->data_width; 135 unsigned int data_width = info->data_width;
135 int psize = info->psize; 136 int psize = info->psize;
136 int num_elems; 137 int num_elems;
@@ -155,7 +156,7 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
155 * Distance to next element sized entry. 156 * Distance to next element sized entry.
156 * Usually the size of the element unless you want gaps. 157 * Usually the size of the element unless you want gaps.
157 */ 158 */
158 if (!is_device) 159 if (addr_inc)
159 lli->reg_elt |= (0x1 << data_width) << 160 lli->reg_elt |= (0x1 << data_width) <<
160 D40_SREG_ELEM_PHY_EIDX_POS; 161 D40_SREG_ELEM_PHY_EIDX_POS;
161 162
@@ -201,40 +202,45 @@ static int d40_seg_size(int size, int data_width1, int data_width2)
201 202
202static struct d40_phy_lli * 203static struct d40_phy_lli *
203d40_phy_buf_to_lli(struct d40_phy_lli *lli, dma_addr_t addr, u32 size, 204d40_phy_buf_to_lli(struct d40_phy_lli *lli, dma_addr_t addr, u32 size,
204 dma_addr_t lli_phys, u32 reg_cfg, bool term_int, 205 dma_addr_t lli_phys, u32 reg_cfg,
205 bool is_device, struct stedma40_half_channel_info *info, 206 struct stedma40_half_channel_info *info,
206 struct stedma40_half_channel_info *otherinfo) 207 struct stedma40_half_channel_info *otherinfo,
208 unsigned long flags)
207{ 209{
210 bool addr_inc = flags & LLI_ADDR_INC;
211 bool term_int = flags & LLI_TERM_INT;
208 int err; 212 int err;
209 dma_addr_t next = lli_phys; 213 dma_addr_t next = lli_phys;
210 int size_rest = size; 214 int size_rest = size;
211 int size_seg = 0; 215 int size_seg = 0;
212 216
217 /*
218 * This piece may be split up based on d40_seg_size(); we only want the
219 * term int on the last part.
220 */
221 if (term_int)
222 flags &= ~LLI_TERM_INT;
223
213 do { 224 do {
214 size_seg = d40_seg_size(size_rest, info->data_width, 225 size_seg = d40_seg_size(size_rest, info->data_width,
215 otherinfo->data_width); 226 otherinfo->data_width);
216 size_rest -= size_seg; 227 size_rest -= size_seg;
217 228
218 if (term_int && size_rest == 0) 229 if (term_int && size_rest == 0) {
219 next = 0; 230 next = 0;
220 else 231 flags |= LLI_TERM_INT;
232 } else
221 next = ALIGN(next + sizeof(struct d40_phy_lli), 233 next = ALIGN(next + sizeof(struct d40_phy_lli),
222 D40_LLI_ALIGN); 234 D40_LLI_ALIGN);
223 235
224 err = d40_phy_fill_lli(lli, 236 err = d40_phy_fill_lli(lli, addr, size_seg, next,
225 addr, 237 reg_cfg, info, flags);
226 size_seg,
227 next,
228 reg_cfg,
229 !next,
230 is_device,
231 info);
232 238
233 if (err) 239 if (err)
234 goto err; 240 goto err;
235 241
236 lli++; 242 lli++;
237 if (!is_device) 243 if (addr_inc)
238 addr += size_seg; 244 addr += size_seg;
239 } while (size_rest); 245 } while (size_rest);
240 246
@@ -256,31 +262,29 @@ int d40_phy_sg_to_lli(struct scatterlist *sg,
256 int total_size = 0; 262 int total_size = 0;
257 int i; 263 int i;
258 struct scatterlist *current_sg = sg; 264 struct scatterlist *current_sg = sg;
259 dma_addr_t dst;
260 struct d40_phy_lli *lli = lli_sg; 265 struct d40_phy_lli *lli = lli_sg;
261 dma_addr_t l_phys = lli_phys; 266 dma_addr_t l_phys = lli_phys;
267 unsigned long flags = 0;
268
269 if (!target)
270 flags |= LLI_ADDR_INC;
262 271
263 for_each_sg(sg, current_sg, sg_len, i) { 272 for_each_sg(sg, current_sg, sg_len, i) {
273 dma_addr_t sg_addr = sg_dma_address(current_sg);
274 unsigned int len = sg_dma_len(current_sg);
275 dma_addr_t dst = target ?: sg_addr;
264 276
265 total_size += sg_dma_len(current_sg); 277 total_size += sg_dma_len(current_sg);
266 278
267 if (target) 279 if (i == sg_len - 1)
268 dst = target; 280 flags |= LLI_TERM_INT;
269 else
270 dst = sg_dma_address(current_sg);
271 281
272 l_phys = ALIGN(lli_phys + (lli - lli_sg) * 282 l_phys = ALIGN(lli_phys + (lli - lli_sg) *
273 sizeof(struct d40_phy_lli), D40_LLI_ALIGN); 283 sizeof(struct d40_phy_lli), D40_LLI_ALIGN);
274 284
275 lli = d40_phy_buf_to_lli(lli, 285 lli = d40_phy_buf_to_lli(lli, dst, len, l_phys,
276 dst, 286 reg_cfg, info, otherinfo, flags);
277 sg_dma_len(current_sg), 287
278 l_phys,
279 reg_cfg,
280 sg_len - 1 == i,
281 target == dst,
282 info,
283 otherinfo);
284 if (lli == NULL) 288 if (lli == NULL)
285 return -EINVAL; 289 return -EINVAL;
286 } 290 }
@@ -343,8 +347,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli,
343 dma_addr_t data, u32 data_size, 347 dma_addr_t data, u32 data_size,
344 u32 reg_cfg, 348 u32 reg_cfg,
345 u32 data_width, 349 u32 data_width,
346 bool addr_inc) 350 unsigned int flags)
347{ 351{
352 bool addr_inc = flags & LLI_ADDR_INC;
353
348 lli->lcsp13 = reg_cfg; 354 lli->lcsp13 = reg_cfg;
349 355
350 /* The number of elements to transfer */ 356 /* The number of elements to transfer */
@@ -369,8 +375,9 @@ static struct d40_log_lli *d40_log_buf_to_lli(struct d40_log_lli *lli_sg,
369 u32 lcsp13, /* src or dst*/ 375 u32 lcsp13, /* src or dst*/
370 u32 data_width1, 376 u32 data_width1,
371 u32 data_width2, 377 u32 data_width2,
372 bool addr_inc) 378 unsigned int flags)
373{ 379{
380 bool addr_inc = flags & LLI_ADDR_INC;
374 struct d40_log_lli *lli = lli_sg; 381 struct d40_log_lli *lli = lli_sg;
375 int size_rest = size; 382 int size_rest = size;
376 int size_seg = 0; 383 int size_seg = 0;
@@ -383,7 +390,7 @@ static struct d40_log_lli *d40_log_buf_to_lli(struct d40_log_lli *lli_sg,
383 addr, 390 addr,
384 size_seg, 391 size_seg,
385 lcsp13, data_width1, 392 lcsp13, data_width1,
386 addr_inc); 393 flags);
387 if (addr_inc) 394 if (addr_inc)
388 addr += size_seg; 395 addr += size_seg;
389 lli++; 396 lli++;
@@ -403,7 +410,10 @@ int d40_log_sg_to_lli(struct scatterlist *sg,
403 struct scatterlist *current_sg = sg; 410 struct scatterlist *current_sg = sg;
404 int i; 411 int i;
405 struct d40_log_lli *lli = lli_sg; 412 struct d40_log_lli *lli = lli_sg;
406 bool autoinc = !dev_addr; 413 unsigned long flags = 0;
414
415 if (!dev_addr)
416 flags |= LLI_ADDR_INC;
407 417
408 for_each_sg(sg, current_sg, sg_len, i) { 418 for_each_sg(sg, current_sg, sg_len, i) {
409 dma_addr_t sg_addr = sg_dma_address(current_sg); 419 dma_addr_t sg_addr = sg_dma_address(current_sg);
@@ -416,7 +426,7 @@ int d40_log_sg_to_lli(struct scatterlist *sg,
416 lcsp13, 426 lcsp13,
417 data_width1, 427 data_width1,
418 data_width2, 428 data_width2,
419 autoinc); 429 flags);
420 } 430 }
421 431
422 return total_size; 432 return total_size;
diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h
index 4626c8874374..59e72f0cc901 100644
--- a/drivers/dma/ste_dma40_ll.h
+++ b/drivers/dma/ste_dma40_ll.h
@@ -293,6 +293,11 @@ struct d40_def_lcsp {
293 293
294/* Physical channels */ 294/* Physical channels */
295 295
296enum d40_lli_flags {
297 LLI_ADDR_INC = 1 << 0,
298 LLI_TERM_INT = 1 << 1,
299};
300
296void d40_phy_cfg(struct stedma40_chan_cfg *cfg, 301void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
297 u32 *src_cfg, 302 u32 *src_cfg,
298 u32 *dst_cfg, 303 u32 *dst_cfg,