Lines Matching +full:fifo +full:- +full:watermark +full:- +full:aligned

1 // SPDX-License-Identifier: GPL-2.0
7 // Copyright 2007-2010 Freescale Semiconductor, Inc.
16 #include <linux/dma-mapping.h>
72 /** fsl_dma_private: p-substream DMA data
74 * Each substream has a 1-to-1 association with a DMA channel.
76 * The link[] array is first because it needs to be aligned on a 32-byte
120 * Since each link descriptor has a 32-bit byte count field, we set
121 * period_bytes_max to the largest 32-bit number. We also have no maximum
137 .period_bytes_max = (u32) -1,
139 .periods_max = (unsigned int) -1,
155 * fsl_dma_update_pointers - update LD pointers to point to the next period
163 &dma_private->link[dma_private->current_link]; in fsl_dma_update_pointers()
165 /* Update our link descriptors to point to the next period. On a 36-bit in fsl_dma_update_pointers()
169 if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_dma_update_pointers()
170 link->source_addr = cpu_to_be32(dma_private->dma_buf_next); in fsl_dma_update_pointers()
172 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | in fsl_dma_update_pointers()
173 upper_32_bits(dma_private->dma_buf_next)); in fsl_dma_update_pointers()
176 link->dest_addr = cpu_to_be32(dma_private->dma_buf_next); in fsl_dma_update_pointers()
178 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | in fsl_dma_update_pointers()
179 upper_32_bits(dma_private->dma_buf_next)); in fsl_dma_update_pointers()
184 dma_private->dma_buf_next += dma_private->period_size; in fsl_dma_update_pointers()
186 if (dma_private->dma_buf_next >= dma_private->dma_buf_end) in fsl_dma_update_pointers()
187 dma_private->dma_buf_next = dma_private->dma_buf_phys; in fsl_dma_update_pointers()
189 if (++dma_private->current_link >= NUM_DMA_LINKS) in fsl_dma_update_pointers()
190 dma_private->current_link = 0; in fsl_dma_update_pointers()
202 struct snd_pcm_substream *substream = dma_private->substream; in fsl_dma_isr()
204 struct device *dev = rtd->dev; in fsl_dma_isr()
205 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; in fsl_dma_isr()
212 sr = in_be32(&dma_channel->sr); in fsl_dma_isr()
248 if (dma_private->num_periods != NUM_DMA_LINKS) in fsl_dma_isr()
262 out_be32(&dma_channel->sr, sr2); in fsl_dma_isr()
274 * snd_dma_alloc_pages() is just a front-end to dma_alloc_coherent(), which
277 * memory, but we support for 36-bit physical addresses anyway.
280 * technically DMA to any 36-bit address, we do need to set the DMA mask to 36.
285 struct snd_card *card = rtd->card->snd_card; in fsl_dma_new()
286 struct snd_pcm *pcm = rtd->pcm; in fsl_dma_new()
289 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(36)); in fsl_dma_new()
297 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { in fsl_dma_new()
298 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, in fsl_dma_new()
300 &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); in fsl_dma_new()
302 dev_err(card->dev, "can't alloc playback dma buffer\n"); in fsl_dma_new()
307 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { in fsl_dma_new()
308 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, in fsl_dma_new()
310 &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer); in fsl_dma_new()
312 dev_err(card->dev, "can't alloc capture dma buffer\n"); in fsl_dma_new()
313 snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); in fsl_dma_new()
327 * descriptors that ping-pong from one period to the next. For example, if
336 * | |->| |->|
352 * | |->| |->|
386 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_open()
387 struct device *dev = component->dev; in fsl_dma_open()
389 container_of(component->driver, struct dma_object, dai); in fsl_dma_open()
411 channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; in fsl_dma_open()
413 if (dma->assigned) { in fsl_dma_open()
415 return -EBUSY; in fsl_dma_open()
422 return -ENOMEM; in fsl_dma_open()
424 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in fsl_dma_open()
425 dma_private->ssi_sxx_phys = dma->ssi_stx_phys; in fsl_dma_open()
427 dma_private->ssi_sxx_phys = dma->ssi_srx_phys; in fsl_dma_open()
429 dma_private->ssi_fifo_depth = dma->ssi_fifo_depth; in fsl_dma_open()
430 dma_private->dma_channel = dma->channel; in fsl_dma_open()
431 dma_private->irq = dma->irq; in fsl_dma_open()
432 dma_private->substream = substream; in fsl_dma_open()
433 dma_private->ld_buf_phys = ld_buf_phys; in fsl_dma_open()
434 dma_private->dma_buf_phys = substream->dma_buffer.addr; in fsl_dma_open()
436 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio", in fsl_dma_open()
440 dma_private->irq, ret); in fsl_dma_open()
442 dma_private, dma_private->ld_buf_phys); in fsl_dma_open()
446 dma->assigned = true; in fsl_dma_open()
448 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); in fsl_dma_open()
450 runtime->private_data = dma_private; in fsl_dma_open()
454 dma_channel = dma_private->dma_channel; in fsl_dma_open()
456 temp_link = dma_private->ld_buf_phys + in fsl_dma_open()
460 dma_private->link[i].next = cpu_to_be64(temp_link); in fsl_dma_open()
465 dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); in fsl_dma_open()
468 out_be32(&dma_channel->clndar, in fsl_dma_open()
469 CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); in fsl_dma_open()
470 out_be32(&dma_channel->eclndar, in fsl_dma_open()
471 CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); in fsl_dma_open()
474 out_be32(&dma_channel->bcr, 0); in fsl_dma_open()
480 mr = in_be32(&dma_channel->mr) & in fsl_dma_open()
489 * We want End-Of-Segment Interrupts enabled, because this will generate in fsl_dma_open()
496 * the DMA controller is mis-programmed somehow. in fsl_dma_open()
503 mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? in fsl_dma_open()
506 out_be32(&dma_channel->mr, mr); in fsl_dma_open()
517 * One drawback of big-endian is that when copying integers of different
518 * sizes to a fixed-sized register, the address to which the integer must be
521 * For example, if P is the address of a 32-bit register, and X is a 32-bit
522 * integer, then X should be copied to address P. However, if X is a 16-bit
523 * integer, then it should be copied to P+2. If X is an 8-bit register,
526 * So for playback of 8-bit samples, the DMA controller must transfer single
528 * offset by 3 bytes. For 16-bit samples, the offset is two bytes.
530 * For 24-bit samples, the offset is 1 byte. However, the DMA controller
531 * does not support 3-byte copies (the DAHTS register supports only 1, 2, 4,
532 * and 8 bytes at a time). So we do not support packed 24-bit samples.
533 * 24-bit data must be padded to 32 bits.
539 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_hw_params()
540 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_hw_params()
541 struct device *dev = component->dev; in fsl_dma_hw_params()
551 dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; in fsl_dma_hw_params()
560 dma_addr_t temp_addr = substream->dma_buffer.addr; in fsl_dma_hw_params()
563 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; in fsl_dma_hw_params()
570 dma_private->period_size = period_size; in fsl_dma_hw_params()
571 dma_private->num_periods = params_periods(hw_params); in fsl_dma_hw_params()
572 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; in fsl_dma_hw_params()
573 dma_private->dma_buf_next = dma_private->dma_buf_phys + in fsl_dma_hw_params()
576 if (dma_private->dma_buf_next >= dma_private->dma_buf_end) in fsl_dma_hw_params()
578 dma_private->dma_buf_next = dma_private->dma_buf_phys; in fsl_dma_hw_params()
580 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | in fsl_dma_hw_params()
603 return -EINVAL; in fsl_dma_hw_params()
610 * whole frames. Each frame occupies two slots in the FIFO. The in fsl_dma_hw_params()
615 * less than or equal to the FIFO watermark. For playback, this ensures in fsl_dma_hw_params()
616 * that we transfer the maximum amount without overrunning the FIFO. in fsl_dma_hw_params()
618 * underrunning the FIFO. in fsl_dma_hw_params()
620 * f = SSI FIFO depth in fsl_dma_hw_params()
621 * w = SSI watermark value (which equals f - 2) in fsl_dma_hw_params()
625 * For playback, we never transmit more than the transmit FIFO in fsl_dma_hw_params()
626 * watermark, otherwise we might write more data than the FIFO can hold. in fsl_dma_hw_params()
627 * The watermark is equal to the FIFO depth minus two. in fsl_dma_hw_params()
630 * w > f - (b / s) in fsl_dma_hw_params()
635 * (dma_private->ssi_fifo_depth - 2) * sample_bytes. in fsl_dma_hw_params()
637 mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes); in fsl_dma_hw_params()
639 out_be32(&dma_channel->mr, mr); in fsl_dma_hw_params()
642 struct fsl_dma_link_descriptor *link = &dma_private->link[i]; in fsl_dma_hw_params()
644 link->count = cpu_to_be32(period_size); in fsl_dma_hw_params()
663 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_dma_hw_params()
664 link->source_addr = cpu_to_be32(temp_addr); in fsl_dma_hw_params()
665 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | in fsl_dma_hw_params()
668 link->dest_addr = cpu_to_be32(ssi_sxx_phys); in fsl_dma_hw_params()
669 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP | in fsl_dma_hw_params()
672 link->source_addr = cpu_to_be32(ssi_sxx_phys); in fsl_dma_hw_params()
673 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP | in fsl_dma_hw_params()
676 link->dest_addr = cpu_to_be32(temp_addr); in fsl_dma_hw_params()
677 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | in fsl_dma_hw_params()
702 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_pointer()
703 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_pointer()
704 struct device *dev = component->dev; in fsl_dma_pointer()
705 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; in fsl_dma_pointer()
710 * only have 32-bit DMA addresses. This function is typically called in fsl_dma_pointer()
713 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_dma_pointer()
714 position = in_be32(&dma_channel->sar); in fsl_dma_pointer()
716 position |= (u64)(in_be32(&dma_channel->satr) & in fsl_dma_pointer()
720 position = in_be32(&dma_channel->dar); in fsl_dma_pointer()
722 position |= (u64)(in_be32(&dma_channel->datr) & in fsl_dma_pointer()
728 * When capture is started, the SSI immediately starts to fill its FIFO. in fsl_dma_pointer()
729 * This means that the DMA controller is not started until the FIFO is in fsl_dma_pointer()
737 if ((position < dma_private->dma_buf_phys) || in fsl_dma_pointer()
738 (position > dma_private->dma_buf_end)) { in fsl_dma_pointer()
743 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys); in fsl_dma_pointer()
749 if (frames == runtime->buffer_size) in fsl_dma_pointer()
758 * Release the resources allocated in fsl_dma_hw_params() and de-program the
766 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_hw_free()
767 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_hw_free()
772 dma_channel = dma_private->dma_channel; in fsl_dma_hw_free()
775 out_be32(&dma_channel->mr, CCSR_DMA_MR_CA); in fsl_dma_hw_free()
776 out_be32(&dma_channel->mr, 0); in fsl_dma_hw_free()
779 out_be32(&dma_channel->sr, -1); in fsl_dma_hw_free()
780 out_be32(&dma_channel->clndar, 0); in fsl_dma_hw_free()
781 out_be32(&dma_channel->eclndar, 0); in fsl_dma_hw_free()
782 out_be32(&dma_channel->satr, 0); in fsl_dma_hw_free()
783 out_be32(&dma_channel->sar, 0); in fsl_dma_hw_free()
784 out_be32(&dma_channel->datr, 0); in fsl_dma_hw_free()
785 out_be32(&dma_channel->dar, 0); in fsl_dma_hw_free()
786 out_be32(&dma_channel->bcr, 0); in fsl_dma_hw_free()
787 out_be32(&dma_channel->nlndar, 0); in fsl_dma_hw_free()
788 out_be32(&dma_channel->enlndar, 0); in fsl_dma_hw_free()
800 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_close()
801 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_close()
802 struct device *dev = component->dev; in fsl_dma_close()
804 container_of(component->driver, struct dma_object, dai); in fsl_dma_close()
807 if (dma_private->irq) in fsl_dma_close()
808 free_irq(dma_private->irq, dma_private); in fsl_dma_close()
812 dma_private, dma_private->ld_buf_phys); in fsl_dma_close()
813 substream->runtime->private_data = NULL; in fsl_dma_close()
816 dma->assigned = false; in fsl_dma_close()
830 for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) { in fsl_dma_free_dma_buffers()
831 substream = pcm->streams[i].substream; in fsl_dma_free_dma_buffers()
833 snd_dma_free_pages(&substream->dma_buffer); in fsl_dma_free_dma_buffers()
834 substream->dma_buffer.area = NULL; in fsl_dma_free_dma_buffers()
835 substream->dma_buffer.addr = 0; in fsl_dma_free_dma_buffers()
841 * find_ssi_node -- returns the SSI node that points to its DMA channel node
846 * a pointer from the DMA channel node to the SSI node -- the pointer goes the
855 for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") { in find_ssi_node()
859 np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0); in find_ssi_node()
864 np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0); in find_ssi_node()
876 struct device_node *np = pdev->dev.of_node; in fsl_soc_dma_probe()
885 dev_err(&pdev->dev, "cannot find parent SSI node\n"); in fsl_soc_dma_probe()
886 return -ENODEV; in fsl_soc_dma_probe()
891 dev_err(&pdev->dev, "could not determine resources for %pOF\n", in fsl_soc_dma_probe()
900 return -ENOMEM; in fsl_soc_dma_probe()
903 dma->dai.name = DRV_NAME; in fsl_soc_dma_probe()
904 dma->dai.open = fsl_dma_open; in fsl_soc_dma_probe()
905 dma->dai.close = fsl_dma_close; in fsl_soc_dma_probe()
906 dma->dai.hw_params = fsl_dma_hw_params; in fsl_soc_dma_probe()
907 dma->dai.hw_free = fsl_dma_hw_free; in fsl_soc_dma_probe()
908 dma->dai.pointer = fsl_dma_pointer; in fsl_soc_dma_probe()
909 dma->dai.pcm_construct = fsl_dma_new; in fsl_soc_dma_probe()
910 dma->dai.pcm_destruct = fsl_dma_free_dma_buffers; in fsl_soc_dma_probe()
912 /* Store the SSI-specific information that we need */ in fsl_soc_dma_probe()
913 dma->ssi_stx_phys = res.start + REG_SSI_STX0; in fsl_soc_dma_probe()
914 dma->ssi_srx_phys = res.start + REG_SSI_SRX0; in fsl_soc_dma_probe()
916 iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); in fsl_soc_dma_probe()
918 dma->ssi_fifo_depth = be32_to_cpup(iprop); in fsl_soc_dma_probe()
920 /* Older 8610 DTs didn't have the fifo-depth property */ in fsl_soc_dma_probe()
921 dma->ssi_fifo_depth = 8; in fsl_soc_dma_probe()
925 ret = devm_snd_soc_register_component(&pdev->dev, &dma->dai, NULL, 0); in fsl_soc_dma_probe()
927 dev_err(&pdev->dev, "could not register platform\n"); in fsl_soc_dma_probe()
932 dma->channel = of_iomap(np, 0); in fsl_soc_dma_probe()
933 dma->irq = irq_of_parse_and_map(np, 0); in fsl_soc_dma_probe()
935 dev_set_drvdata(&pdev->dev, dma); in fsl_soc_dma_probe()
942 struct dma_object *dma = dev_get_drvdata(&pdev->dev); in fsl_soc_dma_remove()
944 iounmap(dma->channel); in fsl_soc_dma_remove()
945 irq_dispose_mapping(dma->irq); in fsl_soc_dma_remove()
952 { .compatible = "fsl,ssi-dma-channel", },
959 .name = "fsl-pcm-audio",