diff options
Diffstat (limited to 'sound/soc/fsl/fsl_dma.c')
-rw-r--r-- | sound/soc/fsl/fsl_dma.c | 181 |
1 files changed, 87 insertions, 94 deletions
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 64993eda5679..b3eb8570cd7b 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -142,7 +142,8 @@ static const struct snd_pcm_hardware fsl_dma_hardware = { | |||
142 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 142 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
143 | SNDRV_PCM_INFO_MMAP | | 143 | SNDRV_PCM_INFO_MMAP | |
144 | SNDRV_PCM_INFO_MMAP_VALID | | 144 | SNDRV_PCM_INFO_MMAP_VALID | |
145 | SNDRV_PCM_INFO_JOINT_DUPLEX, | 145 | SNDRV_PCM_INFO_JOINT_DUPLEX | |
146 | SNDRV_PCM_INFO_PAUSE, | ||
146 | .formats = FSLDMA_PCM_FORMATS, | 147 | .formats = FSLDMA_PCM_FORMATS, |
147 | .rates = FSLDMA_PCM_RATES, | 148 | .rates = FSLDMA_PCM_RATES, |
148 | .rate_min = 5512, | 149 | .rate_min = 5512, |
@@ -464,11 +465,7 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) | |||
464 | sizeof(struct fsl_dma_link_descriptor); | 465 | sizeof(struct fsl_dma_link_descriptor); |
465 | 466 | ||
466 | for (i = 0; i < NUM_DMA_LINKS; i++) { | 467 | for (i = 0; i < NUM_DMA_LINKS; i++) { |
467 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | 468 | dma_private->link[i].next = cpu_to_be64(temp_link); |
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 | 469 | ||
473 | temp_link += sizeof(struct fsl_dma_link_descriptor); | 470 | temp_link += sizeof(struct fsl_dma_link_descriptor); |
474 | } | 471 | } |
@@ -525,79 +522,9 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) | |||
525 | * This function obtains hardware parameters about the opened stream and | 522 | * This function obtains hardware parameters about the opened stream and |
526 | * programs the DMA controller accordingly. | 523 | * programs the DMA controller accordingly. |
527 | * | 524 | * |
528 | * Note that due to a quirk of the SSI's STX register, the target address | 525 | * One drawback of big-endian is that when copying integers of different |
529 | * for the DMA operations depends on the sample size. So we don't program | 526 | * sizes to a fixed-sized register, the address to which the integer must be |
530 | * the dest_addr (for playback -- source_addr for capture) fields in the | 527 | * copied is dependent on the size of the integer. |
531 | * link descriptors here. We do that in fsl_dma_prepare() | ||
532 | */ | ||
533 | static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | ||
534 | struct snd_pcm_hw_params *hw_params) | ||
535 | { | ||
536 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
537 | struct fsl_dma_private *dma_private = runtime->private_data; | ||
538 | |||
539 | dma_addr_t temp_addr; /* Pointer to next period */ | ||
540 | |||
541 | unsigned int i; | ||
542 | |||
543 | /* Get all the parameters we need */ | ||
544 | size_t buffer_size = params_buffer_bytes(hw_params); | ||
545 | size_t period_size = params_period_bytes(hw_params); | ||
546 | |||
547 | /* Initialize our DMA tracking variables */ | ||
548 | dma_private->period_size = period_size; | ||
549 | dma_private->num_periods = params_periods(hw_params); | ||
550 | dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; | ||
551 | dma_private->dma_buf_next = dma_private->dma_buf_phys + | ||
552 | (NUM_DMA_LINKS * period_size); | ||
553 | if (dma_private->dma_buf_next >= dma_private->dma_buf_end) | ||
554 | dma_private->dma_buf_next = dma_private->dma_buf_phys; | ||
555 | |||
556 | /* | ||
557 | * The actual address in STX0 (destination for playback, source for | ||
558 | * capture) is based on the sample size, but we don't know the sample | ||
559 | * size in this function, so we'll have to adjust that later. See | ||
560 | * comments in fsl_dma_prepare(). | ||
561 | * | ||
562 | * The DMA controller does not have a cache, so the CPU does not | ||
563 | * need to tell it to flush its cache. However, the DMA | ||
564 | * controller does need to tell the CPU to flush its cache. | ||
565 | * That's what the SNOOP bit does. | ||
566 | * | ||
567 | * Also, even though the DMA controller supports 36-bit addressing, for | ||
568 | * simplicity we currently support only 32-bit addresses for the audio | ||
569 | * buffer itself. | ||
570 | */ | ||
571 | temp_addr = substream->dma_buffer.addr; | ||
572 | |||
573 | for (i = 0; i < NUM_DMA_LINKS; i++) { | ||
574 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | ||
575 | |||
576 | link->count = cpu_to_be32(period_size); | ||
577 | |||
578 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
579 | link->source_addr = cpu_to_be32(temp_addr); | ||
580 | else | ||
581 | link->dest_addr = cpu_to_be32(temp_addr); | ||
582 | |||
583 | temp_addr += period_size; | ||
584 | } | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | /** | ||
590 | * fsl_dma_prepare - prepare the DMA registers for playback. | ||
591 | * | ||
592 | * This function is called after the specifics of the audio data are known, | ||
593 | * i.e. snd_pcm_runtime is initialized. | ||
594 | * | ||
595 | * In this function, we finish programming the registers of the DMA | ||
596 | * controller that are dependent on the sample size. | ||
597 | * | ||
598 | * One of the drawbacks with big-endian is that when copying integers of | ||
599 | * different sizes to a fixed-sized register, the address to which the | ||
600 | * integer must be copied is dependent on the size of the integer. | ||
601 | * | 528 | * |
602 | * For example, if P is the address of a 32-bit register, and X is a 32-bit | 529 | * For example, if P is the address of a 32-bit register, and X is a 32-bit |
603 | * integer, then X should be copied to address P. However, if X is a 16-bit | 530 | * integer, then X should be copied to address P. However, if X is a 16-bit |
@@ -613,22 +540,58 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
613 | * and 8 bytes at a time). So we do not support packed 24-bit samples. | 540 | * and 8 bytes at a time). So we do not support packed 24-bit samples. |
614 | * 24-bit data must be padded to 32 bits. | 541 | * 24-bit data must be padded to 32 bits. |
615 | */ | 542 | */ |
616 | static int fsl_dma_prepare(struct snd_pcm_substream *substream) | 543 | static int fsl_dma_hw_params(struct snd_pcm_substream *substream, |
544 | struct snd_pcm_hw_params *hw_params) | ||
617 | { | 545 | { |
618 | struct snd_pcm_runtime *runtime = substream->runtime; | 546 | struct snd_pcm_runtime *runtime = substream->runtime; |
619 | struct fsl_dma_private *dma_private = runtime->private_data; | 547 | struct fsl_dma_private *dma_private = runtime->private_data; |
548 | |||
549 | /* Number of bits per sample */ | ||
550 | unsigned int sample_size = | ||
551 | snd_pcm_format_physical_width(params_format(hw_params)); | ||
552 | |||
553 | /* Number of bytes per frame */ | ||
554 | unsigned int frame_size = 2 * (sample_size / 8); | ||
555 | |||
556 | /* Bus address of SSI STX register */ | ||
557 | dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; | ||
558 | |||
559 | /* Size of the DMA buffer, in bytes */ | ||
560 | size_t buffer_size = params_buffer_bytes(hw_params); | ||
561 | |||
562 | /* Number of bytes per period */ | ||
563 | size_t period_size = params_period_bytes(hw_params); | ||
564 | |||
565 | /* Pointer to next period */ | ||
566 | dma_addr_t temp_addr = substream->dma_buffer.addr; | ||
567 | |||
568 | /* Pointer to DMA controller */ | ||
620 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; | 569 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; |
621 | u32 mr; | 570 | |
571 | u32 mr; /* DMA Mode Register */ | ||
572 | |||
622 | unsigned int i; | 573 | unsigned int i; |
623 | dma_addr_t ssi_sxx_phys; /* Bus address of SSI STX register */ | ||
624 | unsigned int frame_size; /* Number of bytes per frame */ | ||
625 | 574 | ||
626 | ssi_sxx_phys = dma_private->ssi_sxx_phys; | 575 | /* Initialize our DMA tracking variables */ |
576 | dma_private->period_size = period_size; | ||
577 | dma_private->num_periods = params_periods(hw_params); | ||
578 | dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; | ||
579 | dma_private->dma_buf_next = dma_private->dma_buf_phys + | ||
580 | (NUM_DMA_LINKS * period_size); | ||
581 | |||
582 | if (dma_private->dma_buf_next >= dma_private->dma_buf_end) | ||
583 | /* This happens if the number of periods == NUM_DMA_LINKS */ | ||
584 | dma_private->dma_buf_next = dma_private->dma_buf_phys; | ||
627 | 585 | ||
628 | mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | | 586 | mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | |
629 | CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK); | 587 | CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK); |
630 | 588 | ||
631 | switch (runtime->sample_bits) { | 589 | /* Due to a quirk of the SSI's STX register, the target address |
590 | * for the DMA operations depends on the sample size. So we calculate | ||
591 | * that offset here. While we're at it, also tell the DMA controller | ||
592 | * how much data to transfer per sample. | ||
593 | */ | ||
594 | switch (sample_size) { | ||
632 | case 8: | 595 | case 8: |
633 | mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; | 596 | mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; |
634 | ssi_sxx_phys += 3; | 597 | ssi_sxx_phys += 3; |
@@ -641,12 +604,12 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream) | |||
641 | mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4; | 604 | mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4; |
642 | break; | 605 | break; |
643 | default: | 606 | default: |
607 | /* We should never get here */ | ||
644 | dev_err(substream->pcm->card->dev, | 608 | dev_err(substream->pcm->card->dev, |
645 | "unsupported sample size %u\n", runtime->sample_bits); | 609 | "unsupported sample size %u\n", sample_size); |
646 | return -EINVAL; | 610 | return -EINVAL; |
647 | } | 611 | } |
648 | 612 | ||
649 | frame_size = runtime->frame_bits / 8; | ||
650 | /* | 613 | /* |
651 | * BWC should always be a multiple of the frame size. BWC determines | 614 | * BWC should always be a multiple of the frame size. BWC determines |
652 | * how many bytes are sent/received before the DMA controller checks the | 615 | * how many bytes are sent/received before the DMA controller checks the |
@@ -655,7 +618,6 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream) | |||
655 | * capture, the receive FIFO is triggered when it contains one frame, so | 618 | * capture, the receive FIFO is triggered when it contains one frame, so |
656 | * we want to receive one frame at a time. | 619 | * we want to receive one frame at a time. |
657 | */ | 620 | */ |
658 | |||
659 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 621 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
660 | mr |= CCSR_DMA_MR_BWC(2 * frame_size); | 622 | mr |= CCSR_DMA_MR_BWC(2 * frame_size); |
661 | else | 623 | else |
@@ -663,16 +625,48 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream) | |||
663 | 625 | ||
664 | out_be32(&dma_channel->mr, mr); | 626 | out_be32(&dma_channel->mr, mr); |
665 | 627 | ||
666 | /* | ||
667 | * Program the address of the DMA transfer to/from the SSI. | ||
668 | */ | ||
669 | for (i = 0; i < NUM_DMA_LINKS; i++) { | 628 | for (i = 0; i < NUM_DMA_LINKS; i++) { |
670 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | 629 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; |
671 | 630 | ||
672 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 631 | link->count = cpu_to_be32(period_size); |
632 | |||
633 | /* Even though the DMA controller supports 36-bit addressing, | ||
634 | * for simplicity we allow only 32-bit addresses for the audio | ||
635 | * buffer itself. This was enforced in fsl_dma_new() with the | ||
636 | * DMA mask. | ||
637 | * | ||
638 | * The snoop bit tells the DMA controller whether it should tell | ||
639 | * the ECM to snoop during a read or write to an address. For | ||
640 | * audio, we use DMA to transfer data between memory and an I/O | ||
641 | * device (the SSI's STX0 or SRX0 register). Snooping is only | ||
642 | * needed if there is a cache, so we need to snoop memory | ||
643 | * addresses only. For playback, that means we snoop the source | ||
644 | * but not the destination. For capture, we snoop the | ||
645 | * destination but not the source. | ||
646 | * | ||
647 | * Note that failing to snoop properly is unlikely to cause | ||
648 | * cache incoherency if the period size is larger than the | ||
649 | * size of L1 cache. This is because filling in one period will | ||
650 | * flush out the data for the previous period. So if you | ||
651 | * increased period_bytes_min to a large enough size, you might | ||
652 | * get more performance by not snooping, and you'll still be | ||
653 | * okay. | ||
654 | */ | ||
655 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
656 | link->source_addr = cpu_to_be32(temp_addr); | ||
657 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
658 | |||
673 | link->dest_addr = cpu_to_be32(ssi_sxx_phys); | 659 | link->dest_addr = cpu_to_be32(ssi_sxx_phys); |
674 | else | 660 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); |
661 | } else { | ||
675 | link->source_addr = cpu_to_be32(ssi_sxx_phys); | 662 | link->source_addr = cpu_to_be32(ssi_sxx_phys); |
663 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); | ||
664 | |||
665 | link->dest_addr = cpu_to_be32(temp_addr); | ||
666 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
667 | } | ||
668 | |||
669 | temp_addr += period_size; | ||
676 | } | 670 | } |
677 | 671 | ||
678 | return 0; | 672 | return 0; |
@@ -808,7 +802,6 @@ static struct snd_pcm_ops fsl_dma_ops = { | |||
808 | .ioctl = snd_pcm_lib_ioctl, | 802 | .ioctl = snd_pcm_lib_ioctl, |
809 | .hw_params = fsl_dma_hw_params, | 803 | .hw_params = fsl_dma_hw_params, |
810 | .hw_free = fsl_dma_hw_free, | 804 | .hw_free = fsl_dma_hw_free, |
811 | .prepare = fsl_dma_prepare, | ||
812 | .pointer = fsl_dma_pointer, | 805 | .pointer = fsl_dma_pointer, |
813 | }; | 806 | }; |
814 | 807 | ||