[alsa-devel] Dynamic PCM and Tegra AHUB
Mark, Liam,
Tegra30's AHUB is structured as follows:
+-------------+ +-----+ +--------------+ +-----+ +------+ | FIFO pair 0 |<->| CIF |<->| Cross-bar |<->| CIF |<->| I2S0 |<-> External IO +-------------+ +-----+ | (the "AHUB") | +-----+ +------+ . . . | | . . . +-------------+ +-----+ | | +-----+ +------+ | FIFO pair 3 |<->| CIF |<->| |<->| CIF |<->| I2S4 |<-> External IO +-------------+ +-----+ | | +-----+ +------+ | | | | +-----+ +-------+ | |<->| CIF |<->| SPDIF |<-> External IO | | +-----+ +-------+ | | | | +-----+ +-------+ | |<->| CIF |<->| DAM | | | +-----+ +-------+ +--------------+
Notes on the diagram:
Each FIFO above is a separate TX and RX FIFO. I merged them in the drawing for simplicity, but they operate completely independently; different memory packing formats, data flow rates, ...
The CIF can convert the audio format, e.g. mono<->stereo conversion and change the # of bits in the data in pretty arbitrary combinations. This is true for all CIFs; those that join the AHUB core to either the DMA FIFOs or the I2S/SPDIF/DAM controllers.
The AHUB core is a complete cross-bar; each output selects 1 of the n inputs.
The I2S and SPDIF controllers take audio from the AHUB, format it to the appropriate protocol, and send to external IO (or the other way around). The I2S and SPDIF modules don't perform any additional data rate/width/channel conversion; the CIF must do whatever conversions are needed.
The DAMs take 2 input channels from the AHUB, optionally perform some sample rate conversion and/or bit size conversion beyond what the CIF does, mix them together, and send them back into the AHUB cross-bar.
Questions:
It seems like the whole point of ASoC dynamic PCM is to represent the AHUB core, and at least some of the surrounding boxes above, as an ASoC CODEC.
Initially, I would assume the AHUB CODEC's DAIs would be the DMA FIFOs and the I2S* controllers themselves, i.e. include everything in the above diagram.
If I do that, then the dai_links that the ASoC machine driver registers for I2S->WM8903 would represent a codec DAI <-> codec DAI link rather than a regular CPU DAI <-> codec DAI link. The difference here is the lack of symmetry in struct snd_soc_dai_link: The CPU-side of each DAI link only has a "cpu_dai_name" to identify it, whereas the codec side has both a codec_name (or of node) /plus/ a DAI name. This is important at least in the context of device tree, where to avoid hard-coding specific device names into the dai_link structure's .codec_name field in the machine driver, an of_node is looked up at run-time instead, and then the codec_dai_name interpreted relative to that. Without a CPU-side separation between name/node and dai_name, that's not possible. So, I sent a patch for that in case this is the right approach.
An alternative to expanding struct snd_soc_dai_link might be to add an API so the machine driver could ask the AHUB driver for the globally-unique name of each DAI it exposes, and write that into dai_link.cpu_dai_name. But if we have that API, we could use it for the codec-side of the link to, and just have .codec_dai_name and remove the .codec_name and .codec_of_node fields.
Alternatively, perhaps the DMA FIFOs should be registered as CPU DAIs completely separately from the AHUB CODEC. The AHUB CIFs would then be the DAIs registered by the AHUB CODEC. But then, the machine driver would need to include dai_links for all the DMA FIFO <-> CIF connections, which would end up duplicating that list of links into all Tegra machine drives (or perhaps sharing it in common code).
Very curious for your thoughts...
On Fri, May 25, 2012 at 06:23:48PM -0600, Stephen Warren wrote:
It seems like the whole point of ASoC dynamic PCM is to represent the AHUB core, and at least some of the surrounding boxes above, as an ASoC CODEC.
No, not really though it could do. It's really intended for cases where there's a much tighter coupling between the inputs and the outputs and where the AP needs to manage the DMA on both sides of the hub (it looks like that isn't the case from your diagram). It wasn't especially intended to be used in CODEC devices at all.
Note that the dynamic PCM setup ends up with you having to define links between the components in the machine driver in a similar fashion to that which you're discussing below, though the format is different.
then the codec_dai_name interpreted relative to that. Without a CPU-side separation between name/node and dai_name, that's not possible. So, I sent a patch for that in case this is the right approach.
I think it is, we've just never been encountering naming collisions on the CPU side for obvious reasons.
An alternative to expanding struct snd_soc_dai_link might be to add an API so the machine driver could ask the AHUB driver for the globally-unique name of each DAI it exposes, and write that into dai_link.cpu_dai_name. But if we have that API, we could use it for the codec-side of the link to, and just have .codec_dai_name and remove the .codec_name and .codec_of_node fields.
This seems bad, it's replacing data with code which is the wrong way round.
Alternatively, perhaps the DMA FIFOs should be registered as CPU DAIs completely separately from the AHUB CODEC. The AHUB CIFs would then be the DAIs registered by the AHUB CODEC. But then, the machine driver
This is what I'd expect.
would need to include dai_links for all the DMA FIFO <-> CIF connections, which would end up duplicating that list of links into all Tegra machine drives (or perhaps sharing it in common code).
We should probably just have a "link blob" class of device which can be used by things like SoCs (and may also be useful for things that have lots of derivatives or modular components) and then either placed in the machine driver automatically or referenced by the machine driver somehow.
Though with DT boards perhaps some DT include/refrence stuff can do this transparently, I'd hope so but I'm not optimistic.
On 05/27/2012 04:33 PM, Mark Brown wrote:
On Fri, May 25, 2012 at 06:23:48PM -0600, Stephen Warren wrote:
It seems like the whole point of ASoC dynamic PCM is to represent the AHUB core, and at least some of the surrounding boxes above, as an ASoC CODEC.
No, not really though it could do. It's really intended for cases where there's a much tighter coupling between the inputs and the outputs and where the AP needs to manage the DMA on both sides of the hub (it looks like that isn't the case from your diagram). It wasn't especially intended to be used in CODEC devices at all.
Note that the dynamic PCM setup ends up with you having to define links between the components in the machine driver in a similar fashion to that which you're discussing below, though the format is different.
...
Alternatively, perhaps the DMA FIFOs should be registered as CPU DAIs completely separately from the AHUB CODEC. The AHUB CIFs would then be the DAIs registered by the AHUB CODEC. But then, the machine driver
This is what I'd expect.
OK, so perhaps I'm confusing codec<->codec links and dynamic PCM yet again.
Referring back to my earlier diagram, I assume that the DMA FIFO -> AHUB CIF link would be a completely standard snd_soc_dai_link. There would be another (set of) snd_soc_dai_link for the AHUB CIF -> I2S connections on the right of the diagram, which would set snd_soc_dai_link.no_pcm=1.
So, in other words, snd_soc_dai_link.no_pcm=1 can end up being used either for plain codec<->codec links, or dynamic PCM, whereas snd_soc_dai_link.dynamic is most likely only used for dynamic PCM (I'd kinda assumed that using the .no_pcm field implied dynamic PCM, but perhaps that's not the case).
participants (2)
-
Mark Brown
-
Stephen Warren