Commit 01b09b6c605ed119fba75b82582f017e44dd4a55
Exists in
master
and in
7 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: ASoC: fix SNDCTL_DSP_SYNC support in Freescale 8610 sound drivers
Showing 1 changed file Side-by-side Diff
sound/soc/fsl/fsl_dma.c
... | ... | @@ -327,14 +327,75 @@ |
327 | 327 | * fsl_dma_open: open a new substream. |
328 | 328 | * |
329 | 329 | * Each substream has its own DMA buffer. |
330 | + * | |
331 | + * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link | |
332 | + * descriptors that ping-pong from one period to the next. For example, if | |
333 | + * there are six periods and two link descriptors, this is how they look | |
334 | + * before playback starts: | |
335 | + * | |
336 | + * The last link descriptor | |
337 | + * ____________ points back to the first | |
338 | + * | | | |
339 | + * V | | |
340 | + * ___ ___ | | |
341 | + * | |->| |->| | |
342 | + * |___| |___| | |
343 | + * | | | |
344 | + * | | | |
345 | + * V V | |
346 | + * _________________________________________ | |
347 | + * | | | | | | | The DMA buffer is | |
348 | + * | | | | | | | divided into 6 parts | |
349 | + * |______|______|______|______|______|______| | |
350 | + * | |
351 | + * and here's how they look after the first period is finished playing: | |
352 | + * | |
353 | + * ____________ | |
354 | + * | | | |
355 | + * V | | |
356 | + * ___ ___ | | |
357 | + * | |->| |->| | |
358 | + * |___| |___| | |
359 | + * | | | |
360 | + * |______________ | |
361 | + * | | | |
362 | + * V V | |
363 | + * _________________________________________ | |
364 | + * | | | | | | | | |
365 | + * | | | | | | | | |
366 | + * |______|______|______|______|______|______| | |
367 | + * | |
368 | + * The first link descriptor now points to the third period. The DMA | |
369 | + * controller is currently playing the second period. When it finishes, it | |
370 | + * will jump back to the first descriptor and play the third period. | |
371 | + * | |
372 | + * There are four reasons we do this: | |
373 | + * | |
374 | + * 1. The only way to get the DMA controller to automatically restart the | |
375 | + * transfer when it gets to the end of the buffer is to use chaining | |
376 | + * mode. Basic direct mode doesn't offer that feature. | |
377 | + * 2. We need to receive an interrupt at the end of every period. The DMA | |
378 | + * controller can generate an interrupt at the end of every link transfer | |
379 | + * (aka segment). Making each period into a DMA segment will give us the | |
380 | + * interrupts we need. | |
381 | + * 3. By creating only two link descriptors, regardless of the number of | |
382 | + * periods, we do not need to reallocate the link descriptors if the | |
383 | + * number of periods changes. | |
384 | + * 4. All of the audio data is still stored in a single, contiguous DMA | |
385 | + * buffer, which is what ALSA expects. We're just dividing it into | |
386 | + * contiguous parts, and creating a link descriptor for each one. | |
330 | 387 | */ |
331 | 388 | static int fsl_dma_open(struct snd_pcm_substream *substream) |
332 | 389 | { |
333 | 390 | struct snd_pcm_runtime *runtime = substream->runtime; |
334 | 391 | struct fsl_dma_private *dma_private; |
392 | + struct ccsr_dma_channel __iomem *dma_channel; | |
335 | 393 | dma_addr_t ld_buf_phys; |
394 | + u64 temp_link; /* Pointer to next link descriptor */ | |
395 | + u32 mr; | |
336 | 396 | unsigned int channel; |
337 | 397 | int ret = 0; |
398 | + unsigned int i; | |
338 | 399 | |
339 | 400 | /* |
340 | 401 | * Reject any DMA buffer whose size is not a multiple of the period |
341 | 402 | |
342 | 403 | |
343 | 404 | |
... | ... | @@ -395,69 +456,75 @@ |
395 | 456 | snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); |
396 | 457 | runtime->private_data = dma_private; |
397 | 458 | |
459 | + /* Program the fixed DMA controller parameters */ | |
460 | + | |
461 | + dma_channel = dma_private->dma_channel; | |
462 | + | |
463 | + temp_link = dma_private->ld_buf_phys + | |
464 | + sizeof(struct fsl_dma_link_descriptor); | |
465 | + | |
466 | + for (i = 0; i < NUM_DMA_LINKS; i++) { | |
467 | + struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | |
468 | + | |
469 | + link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | |
470 | + link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | |
471 | + link->next = cpu_to_be64(temp_link); | |
472 | + | |
473 | + temp_link += sizeof(struct fsl_dma_link_descriptor); | |
474 | + } | |
475 | + /* The last link descriptor points to the first */ | |
476 | + dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); | |
477 | + | |
478 | + /* Tell the DMA controller where the first link descriptor is */ | |
479 | + out_be32(&dma_channel->clndar, | |
480 | + CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); | |
481 | + out_be32(&dma_channel->eclndar, | |
482 | + CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); | |
483 | + | |
484 | + /* The manual says the BCR must be clear before enabling EMP */ | |
485 | + out_be32(&dma_channel->bcr, 0); | |
486 | + | |
487 | + /* | |
488 | + * Program the mode register for interrupts, external master control, | |
489 | + * and source/destination hold. Also clear the Channel Abort bit. | |
490 | + */ | |
491 | + mr = in_be32(&dma_channel->mr) & | |
492 | + ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); | |
493 | + | |
494 | + /* | |
495 | + * We want External Master Start and External Master Pause enabled, | |
496 | + * because the SSI is controlling the DMA controller. We want the DMA | |
497 | + * controller to be set up in advance, and then we signal only the SSI | |
498 | + * to start transferring. | |
499 | + * | |
500 | + * We want End-Of-Segment Interrupts enabled, because this will generate | |
501 | + * an interrupt at the end of each segment (each link descriptor | |
502 | + * represents one segment). Each DMA segment is the same thing as an | |
503 | + * ALSA period, so this is how we get an interrupt at the end of every | |
504 | + * period. | |
505 | + * | |
506 | + * We want Error Interrupt enabled, so that we can get an error if | |
507 | + * the DMA controller is mis-programmed somehow. | |
508 | + */ | |
509 | + mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | | |
510 | + CCSR_DMA_MR_EMS_EN; | |
511 | + | |
512 | + /* For playback, we want the destination address to be held. For | |
513 | + capture, set the source address to be held. */ | |
514 | + mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | |
515 | + CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; | |
516 | + | |
517 | + out_be32(&dma_channel->mr, mr); | |
518 | + | |
398 | 519 | return 0; |
399 | 520 | } |
400 | 521 | |
401 | 522 | /** |
402 | - * fsl_dma_hw_params: allocate the DMA buffer and the DMA link descriptors. | |
523 | + * fsl_dma_hw_params: continue initializing the DMA links | |
403 | 524 | * |
404 | - * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link | |
405 | - * descriptors that ping-pong from one period to the next. For example, if | |
406 | - * there are six periods and two link descriptors, this is how they look | |
407 | - * before playback starts: | |
525 | + * This function obtains hardware parameters about the opened stream and | |
526 | + * programs the DMA controller accordingly. | |
408 | 527 | * |
409 | - * The last link descriptor | |
410 | - * ____________ points back to the first | |
411 | - * | | | |
412 | - * V | | |
413 | - * ___ ___ | | |
414 | - * | |->| |->| | |
415 | - * |___| |___| | |
416 | - * | | | |
417 | - * | | | |
418 | - * V V | |
419 | - * _________________________________________ | |
420 | - * | | | | | | | The DMA buffer is | |
421 | - * | | | | | | | divided into 6 parts | |
422 | - * |______|______|______|______|______|______| | |
423 | - * | |
424 | - * and here's how they look after the first period is finished playing: | |
425 | - * | |
426 | - * ____________ | |
427 | - * | | | |
428 | - * V | | |
429 | - * ___ ___ | | |
430 | - * | |->| |->| | |
431 | - * |___| |___| | |
432 | - * | | | |
433 | - * |______________ | |
434 | - * | | | |
435 | - * V V | |
436 | - * _________________________________________ | |
437 | - * | | | | | | | | |
438 | - * | | | | | | | | |
439 | - * |______|______|______|______|______|______| | |
440 | - * | |
441 | - * The first link descriptor now points to the third period. The DMA | |
442 | - * controller is currently playing the second period. When it finishes, it | |
443 | - * will jump back to the first descriptor and play the third period. | |
444 | - * | |
445 | - * There are four reasons we do this: | |
446 | - * | |
447 | - * 1. The only way to get the DMA controller to automatically restart the | |
448 | - * transfer when it gets to the end of the buffer is to use chaining | |
449 | - * mode. Basic direct mode doesn't offer that feature. | |
450 | - * 2. We need to receive an interrupt at the end of every period. The DMA | |
451 | - * controller can generate an interrupt at the end of every link transfer | |
452 | - * (aka segment). Making each period into a DMA segment will give us the | |
453 | - * interrupts we need. | |
454 | - * 3. By creating only two link descriptors, regardless of the number of | |
455 | - * periods, we do not need to reallocate the link descriptors if the | |
456 | - * number of periods changes. | |
457 | - * 4. All of the audio data is still stored in a single, contiguous DMA | |
458 | - * buffer, which is what ALSA expects. We're just dividing it into | |
459 | - * contiguous parts, and creating a link descriptor for each one. | |
460 | - * | |
461 | 528 | * Note that due to a quirk of the SSI's STX register, the target address |
462 | 529 | * for the DMA operations depends on the sample size. So we don't program |
463 | 530 | * the dest_addr (for playback -- source_addr for capture) fields in the |
464 | 531 | |
... | ... | @@ -468,11 +535,8 @@ |
468 | 535 | { |
469 | 536 | struct snd_pcm_runtime *runtime = substream->runtime; |
470 | 537 | struct fsl_dma_private *dma_private = runtime->private_data; |
471 | - struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; | |
472 | 538 | |
473 | 539 | dma_addr_t temp_addr; /* Pointer to next period */ |
474 | - u64 temp_link; /* Pointer to next link descriptor */ | |
475 | - u32 mr; /* Temporary variable for MR register */ | |
476 | 540 | |
477 | 541 | unsigned int i; |
478 | 542 | |
... | ... | @@ -490,8 +554,6 @@ |
490 | 554 | dma_private->dma_buf_next = dma_private->dma_buf_phys; |
491 | 555 | |
492 | 556 | /* |
493 | - * Initialize each link descriptor. | |
494 | - * | |
495 | 557 | * The actual address in STX0 (destination for playback, source for |
496 | 558 | * capture) is based on the sample size, but we don't know the sample |
497 | 559 | * size in this function, so we'll have to adjust that later. See |
498 | 560 | |
... | ... | @@ -507,16 +569,11 @@ |
507 | 569 | * buffer itself. |
508 | 570 | */ |
509 | 571 | temp_addr = substream->dma_buffer.addr; |
510 | - temp_link = dma_private->ld_buf_phys + | |
511 | - sizeof(struct fsl_dma_link_descriptor); | |
512 | 572 | |
513 | 573 | for (i = 0; i < NUM_DMA_LINKS; i++) { |
514 | 574 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; |
515 | 575 | |
516 | 576 | link->count = cpu_to_be32(period_size); |
517 | - link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | |
518 | - link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | |
519 | - link->next = cpu_to_be64(temp_link); | |
520 | 577 | |
521 | 578 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
522 | 579 | link->source_addr = cpu_to_be32(temp_addr); |
523 | 580 | |
... | ... | @@ -524,51 +581,7 @@ |
524 | 581 | link->dest_addr = cpu_to_be32(temp_addr); |
525 | 582 | |
526 | 583 | temp_addr += period_size; |
527 | - temp_link += sizeof(struct fsl_dma_link_descriptor); | |
528 | 584 | } |
529 | - /* The last link descriptor points to the first */ | |
530 | - dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); | |
531 | - | |
532 | - /* Tell the DMA controller where the first link descriptor is */ | |
533 | - out_be32(&dma_channel->clndar, | |
534 | - CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); | |
535 | - out_be32(&dma_channel->eclndar, | |
536 | - CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); | |
537 | - | |
538 | - /* The manual says the BCR must be clear before enabling EMP */ | |
539 | - out_be32(&dma_channel->bcr, 0); | |
540 | - | |
541 | - /* | |
542 | - * Program the mode register for interrupts, external master control, | |
543 | - * and source/destination hold. Also clear the Channel Abort bit. | |
544 | - */ | |
545 | - mr = in_be32(&dma_channel->mr) & | |
546 | - ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); | |
547 | - | |
548 | - /* | |
549 | - * We want External Master Start and External Master Pause enabled, | |
550 | - * because the SSI is controlling the DMA controller. We want the DMA | |
551 | - * controller to be set up in advance, and then we signal only the SSI | |
552 | - * to start transfering. | |
553 | - * | |
554 | - * We want End-Of-Segment Interrupts enabled, because this will generate | |
555 | - * an interrupt at the end of each segment (each link descriptor | |
556 | - * represents one segment). Each DMA segment is the same thing as an | |
557 | - * ALSA period, so this is how we get an interrupt at the end of every | |
558 | - * period. | |
559 | - * | |
560 | - * We want Error Interrupt enabled, so that we can get an error if | |
561 | - * the DMA controller is mis-programmed somehow. | |
562 | - */ | |
563 | - mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | | |
564 | - CCSR_DMA_MR_EMS_EN; | |
565 | - | |
566 | - /* For playback, we want the destination address to be held. For | |
567 | - capture, set the source address to be held. */ | |
568 | - mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | |
569 | - CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; | |
570 | - | |
571 | - out_be32(&dma_channel->mr, mr); | |
572 | 585 | |
573 | 586 | return 0; |
574 | 587 | } |