aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci/davinci-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci/davinci-pcm.c')
-rw-r--r--sound/soc/davinci/davinci-pcm.c123
1 files changed, 59 insertions, 64 deletions
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a49e667373bc..d5fe08cc5db7 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
180{ 180{
181 struct davinci_runtime_data *prtd = substream->runtime->private_data; 181 struct davinci_runtime_data *prtd = substream->runtime->private_data;
182 struct snd_pcm_runtime *runtime = substream->runtime; 182 struct snd_pcm_runtime *runtime = substream->runtime;
183 int link = prtd->asp_link[0];
184 unsigned int period_size; 183 unsigned int period_size;
185 unsigned int dma_offset; 184 unsigned int dma_offset;
186 dma_addr_t dma_pos; 185 dma_addr_t dma_pos;
@@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
198 fifo_level = prtd->params->fifo_level; 197 fifo_level = prtd->params->fifo_level;
199 198
200 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 199 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
201 "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); 200 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
201 period_size);
202 202
203 data_type = prtd->params->data_type; 203 data_type = prtd->params->data_type;
204 count = period_size / data_type; 204 count = period_size / data_type;
@@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
222 } 222 }
223 223
224 acnt = prtd->params->acnt; 224 acnt = prtd->params->acnt;
225 edma_set_src(link, src, INCR, W8BIT); 225 edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
226 edma_set_dest(link, dst, INCR, W8BIT); 226 edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
227 227
228 edma_set_src_index(link, src_bidx, src_cidx); 228 edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
229 edma_set_dest_index(link, dst_bidx, dst_cidx); 229 edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
230 230
231 if (!fifo_level) 231 if (!fifo_level)
232 edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); 232 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
233 ASYNC);
233 else 234 else
234 edma_set_transfer_params(link, acnt, fifo_level, count, 235 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
235 fifo_level, ABSYNC); 236 count, fifo_level,
237 ABSYNC);
236} 238}
237 239
238static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 240static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
@@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
305 unsigned int acnt = params->acnt; 307 unsigned int acnt = params->acnt;
306 /* divide by 2 for ping/pong */ 308 /* divide by 2 for ping/pong */
307 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; 309 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
308 int link = prtd->asp_link[1];
309 unsigned int fifo_level = prtd->params->fifo_level; 310 unsigned int fifo_level = prtd->params->fifo_level;
310 unsigned int count; 311 unsigned int count;
311 if ((data_type == 0) || (data_type > 4)) { 312 if ((data_type == 0) || (data_type > 4)) {
@@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
316 dma_addr_t asp_src_pong = iram_dma->addr + ping_size; 317 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
317 ram_src_cidx = ping_size; 318 ram_src_cidx = ping_size;
318 ram_dst_cidx = -ping_size; 319 ram_dst_cidx = -ping_size;
319 edma_set_src(link, asp_src_pong, INCR, W8BIT); 320 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
320 321
321 link = prtd->asp_link[0]; 322 edma_set_src_index(prtd->asp_link[0], data_type,
322 edma_set_src_index(link, data_type, data_type * fifo_level); 323 data_type * fifo_level);
323 link = prtd->asp_link[1]; 324 edma_set_src_index(prtd->asp_link[1], data_type,
324 edma_set_src_index(link, data_type, data_type * fifo_level); 325 data_type * fifo_level);
325 326
326 link = prtd->ram_link; 327 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
327 edma_set_src(link, runtime->dma_addr, INCR, W32BIT);
328 } else { 328 } else {
329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; 329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
330 ram_src_cidx = -ping_size; 330 ram_src_cidx = -ping_size;
331 ram_dst_cidx = ping_size; 331 ram_dst_cidx = ping_size;
332 edma_set_dest(link, asp_dst_pong, INCR, W8BIT); 332 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
333 333
334 link = prtd->asp_link[0]; 334 edma_set_dest_index(prtd->asp_link[0], data_type,
335 edma_set_dest_index(link, data_type, data_type * fifo_level); 335 data_type * fifo_level);
336 link = prtd->asp_link[1]; 336 edma_set_dest_index(prtd->asp_link[1], data_type,
337 edma_set_dest_index(link, data_type, data_type * fifo_level); 337 data_type * fifo_level);
338 338
339 link = prtd->ram_link; 339 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
340 edma_set_dest(link, runtime->dma_addr, INCR, W32BIT);
341 } 340 }
342 341
343 if (!fifo_level) { 342 if (!fifo_level) {
@@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
354 count, fifo_level, ABSYNC); 353 count, fifo_level, ABSYNC);
355 } 354 }
356 355
357 link = prtd->ram_link; 356 edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
358 edma_set_src_index(link, ping_size, ram_src_cidx); 357 edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
359 edma_set_dest_index(link, ping_size, ram_dst_cidx); 358 edma_set_transfer_params(prtd->ram_link, ping_size, 2,
360 edma_set_transfer_params(link, ping_size, 2,
361 runtime->periods, 2, ASYNC); 359 runtime->periods, 2, ASYNC);
362 360
363 /* init master params */ 361 /* init master params */
@@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
406{ 404{
407 dma_addr_t asp_src_ping; 405 dma_addr_t asp_src_ping;
408 dma_addr_t asp_dst_ping; 406 dma_addr_t asp_dst_ping;
409 int link; 407 int ret;
410 struct davinci_pcm_dma_params *params = prtd->params; 408 struct davinci_pcm_dma_params *params = prtd->params;
411 409
412 /* Request ram master channel */ 410 /* Request ram master channel */
413 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, 411 ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
414 davinci_pcm_dma_irq, substream, 412 davinci_pcm_dma_irq, substream,
415 prtd->params->ram_chan_q); 413 prtd->params->ram_chan_q);
416 if (link < 0) 414 if (ret < 0)
417 goto exit1; 415 goto exit1;
418 416
419 /* Request ram link channel */ 417 /* Request ram link channel */
420 link = prtd->ram_link = edma_alloc_slot( 418 ret = prtd->ram_link = edma_alloc_slot(
421 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 419 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
422 if (link < 0) 420 if (ret < 0)
423 goto exit2; 421 goto exit2;
424 422
425 link = prtd->asp_link[1] = edma_alloc_slot( 423 ret = prtd->asp_link[1] = edma_alloc_slot(
426 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 424 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
427 if (link < 0) 425 if (ret < 0)
428 goto exit3; 426 goto exit3;
429 427
430 prtd->ram_link2 = -1; 428 prtd->ram_link2 = -1;
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 429 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
432 link = prtd->ram_link2 = edma_alloc_slot( 430 ret = prtd->ram_link2 = edma_alloc_slot(
433 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 431 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
434 if (link < 0) 432 if (ret < 0)
435 goto exit4; 433 goto exit4;
436 } 434 }
437 /* circle ping-pong buffers */ 435 /* circle ping-pong buffers */
@@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
448 asp_dst_ping = iram_dma->addr; 446 asp_dst_ping = iram_dma->addr;
449 } 447 }
450 /* ping */ 448 /* ping */
451 link = prtd->asp_link[0]; 449 edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
452 edma_set_src(link, asp_src_ping, INCR, W16BIT); 450 edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
453 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 451 edma_set_src_index(prtd->asp_link[0], 0, 0);
454 edma_set_src_index(link, 0, 0); 452 edma_set_dest_index(prtd->asp_link[0], 0, 0);
455 edma_set_dest_index(link, 0, 0);
456 453
457 edma_read_slot(link, &prtd->asp_params); 454 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
458 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); 455 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
459 prtd->asp_params.opt |= TCCHEN | 456 prtd->asp_params.opt |= TCCHEN |
460 EDMA_TCC(prtd->ram_channel & 0x3f); 457 EDMA_TCC(prtd->ram_channel & 0x3f);
461 edma_write_slot(link, &prtd->asp_params); 458 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
462 459
463 /* pong */ 460 /* pong */
464 link = prtd->asp_link[1]; 461 edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
465 edma_set_src(link, asp_src_ping, INCR, W16BIT); 462 edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
466 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 463 edma_set_src_index(prtd->asp_link[1], 0, 0);
467 edma_set_src_index(link, 0, 0); 464 edma_set_dest_index(prtd->asp_link[1], 0, 0);
468 edma_set_dest_index(link, 0, 0);
469 465
470 edma_read_slot(link, &prtd->asp_params); 466 edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
471 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); 467 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
472 /* interrupt after every pong completion */ 468 /* interrupt after every pong completion */
473 prtd->asp_params.opt |= TCINTEN | TCCHEN | 469 prtd->asp_params.opt |= TCINTEN | TCCHEN |
474 EDMA_TCC(prtd->ram_channel & 0x3f); 470 EDMA_TCC(prtd->ram_channel & 0x3f);
475 edma_write_slot(link, &prtd->asp_params); 471 edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
476 472
477 /* ram */ 473 /* ram */
478 link = prtd->ram_link; 474 edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
479 edma_set_src(link, iram_dma->addr, INCR, W32BIT); 475 edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
480 edma_set_dest(link, iram_dma->addr, INCR, W32BIT);
481 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," 476 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
482 "for asp:%u %u %u\n", __func__, 477 "for asp:%u %u %u\n", __func__,
483 prtd->ram_channel, prtd->ram_link, prtd->ram_link2, 478 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
@@ -494,7 +489,7 @@ exit2:
494 edma_free_channel(prtd->ram_channel); 489 edma_free_channel(prtd->ram_channel);
495 prtd->ram_channel = -1; 490 prtd->ram_channel = -1;
496exit1: 491exit1:
497 return link; 492 return ret;
498} 493}
499 494
500static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 495static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
@@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
502 struct snd_dma_buffer *iram_dma; 497 struct snd_dma_buffer *iram_dma;
503 struct davinci_runtime_data *prtd = substream->runtime->private_data; 498 struct davinci_runtime_data *prtd = substream->runtime->private_data;
504 struct davinci_pcm_dma_params *params = prtd->params; 499 struct davinci_pcm_dma_params *params = prtd->params;
505 int link; 500 int ret;
506 501
507 if (!params) 502 if (!params)
508 return -ENODEV; 503 return -ENODEV;
509 504
510 /* Request asp master DMA channel */ 505 /* Request asp master DMA channel */
511 link = prtd->asp_channel = edma_alloc_channel(params->channel, 506 ret = prtd->asp_channel = edma_alloc_channel(params->channel,
512 davinci_pcm_dma_irq, substream, 507 davinci_pcm_dma_irq, substream,
513 prtd->params->asp_chan_q); 508 prtd->params->asp_chan_q);
514 if (link < 0) 509 if (ret < 0)
515 goto exit1; 510 goto exit1;
516 511
517 /* Request asp link channels */ 512 /* Request asp link channels */
518 link = prtd->asp_link[0] = edma_alloc_slot( 513 ret = prtd->asp_link[0] = edma_alloc_slot(
519 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 514 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
520 if (link < 0) 515 if (ret < 0)
521 goto exit2; 516 goto exit2;
522 517
523 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; 518 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
@@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
537 * the buffer and its length (ccnt) ... use it as a template 532 * the buffer and its length (ccnt) ... use it as a template
538 * so davinci_pcm_enqueue_dma() takes less time in IRQ. 533 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
539 */ 534 */
540 edma_read_slot(link, &prtd->asp_params); 535 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
541 prtd->asp_params.opt |= TCINTEN | 536 prtd->asp_params.opt |= TCINTEN |
542 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); 537 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
543 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; 538 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
544 edma_write_slot(link, &prtd->asp_params); 539 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
545 return 0; 540 return 0;
546exit2: 541exit2:
547 edma_free_channel(prtd->asp_channel); 542 edma_free_channel(prtd->asp_channel);
548 prtd->asp_channel = -1; 543 prtd->asp_channel = -1;
549exit1: 544exit1:
550 return link; 545 return ret;
551} 546}
552 547
553static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 548static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)