Lines Matching +full:ssi +full:- +full:controller

1 // SPDX-License-Identifier: GPL-2.0
7 // Copyright 2007-2010 Freescale Semiconductor, Inc.
9 // This driver implements ASoC support for the Elo DMA controller, which is
10 // the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms,
16 #include <linux/dma-mapping.h>
39 * The formats that the DMA controller supports, which is anything
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
112 * The PCM hardware is the Freescale DMA controller. This structure defines
116 * controller, we specify no limits for those values. The only exception is
118 * DMA controller from generating too many interrupts per second.
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
125 * limitation in the SSI driver requires the sample rates for playback and
137 .period_bytes_max = (u32) -1,
139 .periods_max = (unsigned int) -1,
146 * This function should be called by the ISR whenever the DMA controller
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()
194 * fsl_dma_isr: interrupt handler for the DMA controller
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()
294 card->dev, in fsl_dma_new()
304 * descriptors that ping-pong from one period to the next. For example, if
313 * | |->| |->|
329 * | |->| |->|
341 * controller is currently playing the second period. When it finishes, it
346 * 1. The only way to get the DMA controller to automatically restart the
350 * controller can generate an interrupt at the end of every link transfer
363 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_open()
364 struct device *dev = component->dev; in fsl_dma_open()
366 container_of(component->driver, struct dma_object, dai); in fsl_dma_open()
387 if (dma->assigned) { in fsl_dma_open()
389 return -EBUSY; in fsl_dma_open()
396 return -ENOMEM; in fsl_dma_open()
398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in fsl_dma_open()
399 dma_private->ssi_sxx_phys = dma->ssi_stx_phys; in fsl_dma_open()
401 dma_private->ssi_sxx_phys = dma->ssi_srx_phys; in fsl_dma_open()
403 dma_private->ssi_fifo_depth = dma->ssi_fifo_depth; in fsl_dma_open()
404 dma_private->dma_channel = dma->channel; in fsl_dma_open()
405 dma_private->irq = dma->irq; in fsl_dma_open()
406 dma_private->substream = substream; in fsl_dma_open()
407 dma_private->ld_buf_phys = ld_buf_phys; in fsl_dma_open()
408 dma_private->dma_buf_phys = substream->dma_buffer.addr; in fsl_dma_open()
410 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio", in fsl_dma_open()
414 dma_private->irq, ret); in fsl_dma_open()
416 dma_private, dma_private->ld_buf_phys); in fsl_dma_open()
420 dma->assigned = true; in fsl_dma_open()
423 runtime->private_data = dma_private; in fsl_dma_open()
425 /* Program the fixed DMA controller parameters */ in fsl_dma_open()
427 dma_channel = dma_private->dma_channel; in fsl_dma_open()
429 temp_link = dma_private->ld_buf_phys + in fsl_dma_open()
433 dma_private->link[i].next = cpu_to_be64(temp_link); in fsl_dma_open()
438 dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); in fsl_dma_open()
440 /* Tell the DMA controller where the first link descriptor is */ in fsl_dma_open()
441 out_be32(&dma_channel->clndar, in fsl_dma_open()
442 CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); in fsl_dma_open()
443 out_be32(&dma_channel->eclndar, in fsl_dma_open()
444 CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); in fsl_dma_open()
447 out_be32(&dma_channel->bcr, 0); in fsl_dma_open()
453 mr = in_be32(&dma_channel->mr) & in fsl_dma_open()
458 * because the SSI is controlling the DMA controller. We want the DMA in fsl_dma_open()
459 * controller to be set up in advance, and then we signal only the SSI in fsl_dma_open()
462 * We want End-Of-Segment Interrupts enabled, because this will generate in fsl_dma_open()
469 * the DMA controller is mis-programmed somehow. in fsl_dma_open()
476 mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? in fsl_dma_open()
479 out_be32(&dma_channel->mr, mr); in fsl_dma_open()
488 * programs the DMA controller accordingly.
490 * One drawback of big-endian is that when copying integers of different
491 * sizes to a fixed-sized register, the address to which the integer must be
494 * For example, if P is the address of a 32-bit register, and X is a 32-bit
495 * integer, then X should be copied to address P. However, if X is a 16-bit
496 * integer, then it should be copied to P+2. If X is an 8-bit register,
499 * So for playback of 8-bit samples, the DMA controller must transfer single
501 * offset by 3 bytes. For 16-bit samples, the offset is two bytes.
503 * For 24-bit samples, the offset is 1 byte. However, the DMA controller
504 * does not support 3-byte copies (the DAHTS register supports only 1, 2, 4,
505 * and 8 bytes at a time). So we do not support packed 24-bit samples.
506 * 24-bit data must be padded to 32 bits.
512 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_hw_params()
513 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_hw_params()
514 struct device *dev = component->dev; in fsl_dma_hw_params()
523 /* Bus address of SSI STX register */ in fsl_dma_hw_params()
524 dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; in fsl_dma_hw_params()
533 dma_addr_t temp_addr = substream->dma_buffer.addr; in fsl_dma_hw_params()
535 /* Pointer to DMA controller */ in fsl_dma_hw_params()
536 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; in fsl_dma_hw_params()
543 dma_private->period_size = period_size; in fsl_dma_hw_params()
544 dma_private->num_periods = params_periods(hw_params); in fsl_dma_hw_params()
545 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size; in fsl_dma_hw_params()
546 dma_private->dma_buf_next = dma_private->dma_buf_phys + in fsl_dma_hw_params()
549 if (dma_private->dma_buf_next >= dma_private->dma_buf_end) in fsl_dma_hw_params()
551 dma_private->dma_buf_next = dma_private->dma_buf_phys; in fsl_dma_hw_params()
553 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | in fsl_dma_hw_params()
556 /* Due to a quirk of the SSI's STX register, the target address in fsl_dma_hw_params()
558 * that offset here. While we're at it, also tell the DMA controller in fsl_dma_hw_params()
576 return -EINVAL; in fsl_dma_hw_params()
581 * controller checks the SSI to see if it needs to stop. BWC should in fsl_dma_hw_params()
593 * f = SSI FIFO depth in fsl_dma_hw_params()
594 * w = SSI watermark value (which equals f - 2) in fsl_dma_hw_params()
603 * w > f - (b / s) in fsl_dma_hw_params()
608 * (dma_private->ssi_fifo_depth - 2) * sample_bytes. in fsl_dma_hw_params()
610 mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes); in fsl_dma_hw_params()
612 out_be32(&dma_channel->mr, mr); in fsl_dma_hw_params()
615 struct fsl_dma_link_descriptor *link = &dma_private->link[i]; in fsl_dma_hw_params()
617 link->count = cpu_to_be32(period_size); in fsl_dma_hw_params()
619 /* The snoop bit tells the DMA controller whether it should tell in fsl_dma_hw_params()
622 * device (the SSI's STX0 or SRX0 register). Snooping is only in fsl_dma_hw_params()
636 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_dma_hw_params()
637 link->source_addr = cpu_to_be32(temp_addr); in fsl_dma_hw_params()
638 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | in fsl_dma_hw_params()
641 link->dest_addr = cpu_to_be32(ssi_sxx_phys); in fsl_dma_hw_params()
642 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP | in fsl_dma_hw_params()
645 link->source_addr = cpu_to_be32(ssi_sxx_phys); in fsl_dma_hw_params()
646 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP | in fsl_dma_hw_params()
649 link->dest_addr = cpu_to_be32(temp_addr); in fsl_dma_hw_params()
650 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | in fsl_dma_hw_params()
675 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_pointer()
676 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_pointer()
677 struct device *dev = component->dev; in fsl_dma_pointer()
678 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; in fsl_dma_pointer()
683 * only have 32-bit DMA addresses. This function is typically called in fsl_dma_pointer()
686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_dma_pointer()
687 position = in_be32(&dma_channel->sar); in fsl_dma_pointer()
689 position |= (u64)(in_be32(&dma_channel->satr) & in fsl_dma_pointer()
693 position = in_be32(&dma_channel->dar); in fsl_dma_pointer()
695 position |= (u64)(in_be32(&dma_channel->datr) & in fsl_dma_pointer()
701 * When capture is started, the SSI immediately starts to fill its FIFO. in fsl_dma_pointer()
702 * This means that the DMA controller is not started until the FIFO is in fsl_dma_pointer()
710 if ((position < dma_private->dma_buf_phys) || in fsl_dma_pointer()
711 (position > dma_private->dma_buf_end)) { in fsl_dma_pointer()
716 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys); in fsl_dma_pointer()
722 if (frames == runtime->buffer_size) in fsl_dma_pointer()
731 * Release the resources allocated in fsl_dma_hw_params() and de-program the
739 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_hw_free()
740 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_hw_free()
745 dma_channel = dma_private->dma_channel; in fsl_dma_hw_free()
748 out_be32(&dma_channel->mr, CCSR_DMA_MR_CA); in fsl_dma_hw_free()
749 out_be32(&dma_channel->mr, 0); in fsl_dma_hw_free()
752 out_be32(&dma_channel->sr, -1); in fsl_dma_hw_free()
753 out_be32(&dma_channel->clndar, 0); in fsl_dma_hw_free()
754 out_be32(&dma_channel->eclndar, 0); in fsl_dma_hw_free()
755 out_be32(&dma_channel->satr, 0); in fsl_dma_hw_free()
756 out_be32(&dma_channel->sar, 0); in fsl_dma_hw_free()
757 out_be32(&dma_channel->datr, 0); in fsl_dma_hw_free()
758 out_be32(&dma_channel->dar, 0); in fsl_dma_hw_free()
759 out_be32(&dma_channel->bcr, 0); in fsl_dma_hw_free()
760 out_be32(&dma_channel->nlndar, 0); in fsl_dma_hw_free()
761 out_be32(&dma_channel->enlndar, 0); in fsl_dma_hw_free()
773 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_dma_close()
774 struct fsl_dma_private *dma_private = runtime->private_data; in fsl_dma_close()
775 struct device *dev = component->dev; in fsl_dma_close()
777 container_of(component->driver, struct dma_object, dai); in fsl_dma_close()
780 if (dma_private->irq) in fsl_dma_close()
781 free_irq(dma_private->irq, dma_private); in fsl_dma_close()
785 dma_private, dma_private->ld_buf_phys); in fsl_dma_close()
786 substream->runtime->private_data = NULL; in fsl_dma_close()
789 dma->assigned = false; in fsl_dma_close()
795 * find_ssi_node -- returns the SSI node that points to its DMA channel node
798 * devices, it still needs to determine some information about the SSI device
800 * a pointer from the DMA channel node to the SSI node -- the pointer goes the
801 * other way. So we need to scan the device tree for SSI nodes until we find
809 for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") { in find_ssi_node()
813 np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0); in find_ssi_node()
818 np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0); in find_ssi_node()
830 struct device_node *np = pdev->dev.of_node; in fsl_soc_dma_probe()
836 /* Find the SSI node that points to us. */ in fsl_soc_dma_probe()
839 dev_err(&pdev->dev, "cannot find parent SSI node\n"); in fsl_soc_dma_probe()
840 return -ENODEV; in fsl_soc_dma_probe()
845 dev_err(&pdev->dev, "could not determine resources for %pOF\n", in fsl_soc_dma_probe()
854 return -ENOMEM; in fsl_soc_dma_probe()
857 dma->dai.name = DRV_NAME; in fsl_soc_dma_probe()
858 dma->dai.open = fsl_dma_open; in fsl_soc_dma_probe()
859 dma->dai.close = fsl_dma_close; in fsl_soc_dma_probe()
860 dma->dai.hw_params = fsl_dma_hw_params; in fsl_soc_dma_probe()
861 dma->dai.hw_free = fsl_dma_hw_free; in fsl_soc_dma_probe()
862 dma->dai.pointer = fsl_dma_pointer; in fsl_soc_dma_probe()
863 dma->dai.pcm_construct = fsl_dma_new; in fsl_soc_dma_probe()
865 /* Store the SSI-specific information that we need */ in fsl_soc_dma_probe()
866 dma->ssi_stx_phys = res.start + REG_SSI_STX0; in fsl_soc_dma_probe()
867 dma->ssi_srx_phys = res.start + REG_SSI_SRX0; in fsl_soc_dma_probe()
869 iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); in fsl_soc_dma_probe()
871 dma->ssi_fifo_depth = be32_to_cpup(iprop); in fsl_soc_dma_probe()
873 /* Older 8610 DTs didn't have the fifo-depth property */ in fsl_soc_dma_probe()
874 dma->ssi_fifo_depth = 8; in fsl_soc_dma_probe()
878 ret = devm_snd_soc_register_component(&pdev->dev, &dma->dai, NULL, 0); in fsl_soc_dma_probe()
880 dev_err(&pdev->dev, "could not register platform\n"); in fsl_soc_dma_probe()
885 dma->channel = of_iomap(np, 0); in fsl_soc_dma_probe()
886 dma->irq = irq_of_parse_and_map(np, 0); in fsl_soc_dma_probe()
888 dev_set_drvdata(&pdev->dev, dma); in fsl_soc_dma_probe()
895 struct dma_object *dma = dev_get_drvdata(&pdev->dev); in fsl_soc_dma_remove()
897 iounmap(dma->channel); in fsl_soc_dma_remove()
898 irq_dispose_mapping(dma->irq); in fsl_soc_dma_remove()
903 { .compatible = "fsl,ssi-dma-channel", },
910 .name = "fsl-pcm-audio",