alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Cezary Rojewski <cezary.rojewski@intel.com>
To: Mark Brown <broonie@kernel.org>
Cc: alsa-devel@alsa-project.org, upstream@semihalf.com,
	harshapriya.n@intel.com, yung-chuan.liao@linux.intel.com,
	rad@semihalf.com, pierre-louis.bossart@linux.intel.com,
	tiwai@suse.com, hdegoede@redhat.com,
	ranjani.sridharan@linux.intel.com,
	amadeuszx.slawinski@linux.intel.com, cujomalainey@chromium.org,
	peter.ujfalusi@linux.intel.com, lma@semihalf.com
Subject: Re: [RFC 18/37] ASoC: Intel: avs: Topology parsing
Date: Wed, 22 Dec 2021 15:21:54 +0100	[thread overview]
Message-ID: <ef9c9b72-a86e-066a-8af4-b08252559840@intel.com> (raw)
In-Reply-To: <YcIRRevkBpM/jIKV@sirena.org.uk>

On 2021-12-21 6:39 PM, Mark Brown wrote:
> On Wed, Dec 08, 2021 at 12:12:42PM +0100, Cezary Rojewski wrote:
> 
>> Implementation of ASoC topology feature for AVS driver. AudioDSP
>> firmware supports a wide range of audio formats, module configurations
>> and multi-pipeline streams. To represent all of this in form of static
>> ALSA topology file, which resides usually in /lib/firmware/, while
>> simultaneously not hindering user from any of the possibilities, 'path
>> template' and its 'path variants' concept is introduced. These are later
>> converted into actual runtime path. This part is explained in follow-up
>> change.
> 
> This sounds like it should be extending the topology code (it's talking
> about "ALSA topologies") but it seems to be outside of that.
> 
>> Path template is just a pattern like its name suggests. It is tied to
>> DAPM widget which represents a FE or a BE and is used during path
>> instantiation when substream is opened for streaming. It carries a range
>> of available variants and only these represent actual implementation of
>> a runtime path in AudioDSP. Only one variant of given path template can
>> be instantiated at a time and selection is based off of audio format
>> provided from userspace and currently selected one on the codec.
> 
> So this sounds like it's baking a table of use cases into the firmware
> rather than a separate UCM type configuration file?
> 
>> AVS topology is split into two major parts: dictionaries - found within
>> ASoC topology manifest - and path templates - found within DAPM widget
>> private data. Dictionaries job is to reduce the total amount of memory
> 
> Or are the use cases baked into the driver code if they're in the DAPM
> widget private data?

I'm sorry for any confusion that arisen in above commit message. 
avs-driver still makes use of typical UCM files, just like 
skylake-driver does. The file has just a different structure (e.g. 
different tokens used) to do both simultaneously: make use of available 
ASoC-topology structs and types while still allowing for shaping streams 
in recommended/optimal manner on ADSP side.

To better understand what I meant by 'shaping': a stream on ADSP side is 
a sequence of pipelines (a sophisticated containers) where each hosts 
one or a number of modules (processing units). The number of pipelines 
and numbers found within them is not constant.
In almost all cases such stream on ADSP side has a beginning and an end. 
'Gateway' is the word used when describing the edges of a stream. There 
is usually a HOST (cpu side) gateway and a LINK (hw side e.g. I2S; 
'codec' comes probably as the closest relative word from ALSA 
dictionary) gateway. To preserve ADSP memory and reduce power 
consumption there are recommendations of how to shape streams.

ADSP firmware supports a large number of configurations and stream 
layouts. Depending on the environment, (even by changing BE/FE formats 
provided), stream layout can differ. Let's assume 3 ADSP module types: 
module1, module2 and module3 and a single playback FE "Speaker" visible 
in userspace.

Your typical playback on FE: "Speaker" for audio format: 16b, 2ch, 48kHz 
could take following shape:

HOST [ [module1] ] -> [ [module2] ] LINK
	pipeline1	pipeline2

However, for a different format (e.g. 44.1Khz), it might be recommended 
to do:

HOST [ [module1] -> [module3] ] -> [ [module2] ] LINK
	pipeline1			pipeline2

HOST: cpu side
LINK: hw side e.g. I2S interface.

And that's why information attached to DAPM widget's private data 
translates to 'set' of concrete stream implementations (i.e. concrete 
data that is later sent to firmware over IPC) rather than a single 
stream implementation. This 'set' has been called 'path template' and 
each entry a 'path variant'. During runtime, depending on the conditions 
provided in hw_params(), a single variant is selected from the set and 
instantiated.

>> +struct avs_tplg_token_parser {
>> +	enum avs_tplg_token token;
>> +	u32 type;
>> +	u32 offset;
>> +	int (*parse)(struct snd_soc_component *comp, void *elem, void *object, u32 offset);
>> +};
>> +
>> +static int
>> +avs_parse_uuid_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
>> +{
>> +	struct snd_soc_tplg_vendor_value_elem *tuple = elem;
>> +	guid_t *val = (guid_t *)((u8 *)object + offset);
>> +
>> +	guid_copy((guid_t *)val, (const guid_t *)&tuple->value);
>> +
>> +	return 0;
>> +}
> 
> I have to say I'm having a hard time telling if these parsers are doing
> the right thing - the interface is a bit obscure and all the void *s
> make it hard to follow, and of course the format is undocumented.  I
> looked through a lot of it but I've definitely not gone through this
> code properly.

Again, I'm sorry for the confusion with the parsing technique used here. 
Ack on the documenting the general idea behind parsing seen in 
topology.c file.

To give some immediate insight:
Each 'struct avs_tplg_token_parser *' instance describes a recipe for 
parsing data coming from UCM topology file and assigning obtained value 
to a field of avs-driver specific structure so it can be used later on 
during runtime - streaming.

Let's take a look at an example:
static const struct avs_tplg_token_parser audio_format_parsers[] = {
	{
		.token = AVS_TKN_AFMT_SAMPLE_RATE_U32
		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
		.offset = offsetof(struct avs_audio_format, sampling_freq),
		.parse = avs_parse_word_token,
	},
(...)
};

Entry found above is meant to parse vendor tuples with 
token=AVS_TKN_AFMT_SAMPLE_RATE_U32 and assign value coupled with that 
token to a field 'sampling_freq' of struct avs_audio_format. Let take a 
look at said struct:

struct avs_audio_format {
         u32 sampling_freq;
         u32 bit_depth;
         u32 channel_map;
         u32 channel_config;
         u32 interleaving;
         u32 num_channels:8;
         u32 valid_bit_depth:8;
         u32 sample_type:8;
         u32 reserved:8;
} __packed;

For every member (except for 'reserved' one of corse) of that struct, a 
parser will be assigned so a complete set of information that comes from 
UCM file can be eventually translated into an instance of 'struct 
avs_audio_format *'. 'offset' and 'type' members of struct 
avs_tplg_token_parser are here to ensure correct field is assigned to 
and specify the value-type of such field.

At the top of topology.c file we have placed several helpers, all of 
that is done to drastically reduce the size of code found below them. 
These helpers are also equipped with sanity-checks - these checks were 
one of the major reasons for separating the helper code into functions 
so all the if-statements are not repeated dozens of times.

Now, in regard to types: standard types supported by vendor tuples are 
uuid, bool, byte, short, word and string. We have added a 'default' 
parser for each of them. Again, let's look at an example:

static int
avs_parse_word_token(struct snd_soc_component *comp, void *elem, void 
*object, u32 offset)
{
         struct snd_soc_tplg_vendor_value_elem *tuple = elem;
         u32 *val = (u32 *)((u8 *)object + offset);

         *val = le32_to_cpu(tuple->value);

         return 0;
}

where:
- comp, a soc component that is tied to topology being currently parsed
- elem, an instance of a vendor tuple that is being parsed
- object, an instance of an object which fields are being assigned to 
during currently ongoing parsing procedure
- offset, offset of a field that is a member of type which 'object' is 
instance of

 From here, the flow is straightforward: obtain the pointer to the field 
to assign value of 'tuple->value' to and assign it.

For all 'more advanced' fields, additional parsers have been provided - 
with more checks and such to maintain sanity.


Regards,
Czarek

  reply	other threads:[~2021-12-22 14:23 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-08 11:12 [RFC 00/37] ASoC: Intel: AVS - Audio DSP for cAVS Cezary Rojewski
2021-12-08 11:12 ` [RFC 01/37] ALSA: hda: Add snd_hdac_ext_bus_link_at() helper Cezary Rojewski
2021-12-08 11:12 ` [RFC 02/37] ALSA: hda: Update and expose snd_hda_codec_device_init() Cezary Rojewski
2021-12-08 11:12 ` [RFC 03/37] ALSA: hda: Update and expose codec register procedures Cezary Rojewski
2021-12-08 11:12 ` [RFC 04/37] ALSA: hda: Expose codec cleanup and power-save functions Cezary Rojewski
2021-12-08 11:12 ` [RFC 05/37] ALSA: hda: Add helper macros for DSP capable devices Cezary Rojewski
2021-12-08 11:12 ` [RFC 06/37] ASoC: Export DAI register and widget ctor and dctor functions Cezary Rojewski
2021-12-21 13:41   ` Mark Brown
2021-12-21 16:40     ` Cezary Rojewski
2021-12-08 11:12 ` [RFC 07/37] ASoC: Intel: Introduce AVS driver Cezary Rojewski
2021-12-08 11:12 ` [RFC 08/37] ASoC: Intel: avs: Inter process communication Cezary Rojewski
2021-12-08 11:12 ` [RFC 09/37] ASoC: Intel: avs: Add code loading requests Cezary Rojewski
2021-12-08 11:12 ` [RFC 10/37] ASoC: Intel: avs: Add pipeline management requests Cezary Rojewski
2021-12-08 11:12 ` [RFC 11/37] ASoC: Intel: avs: Add module " Cezary Rojewski
2021-12-08 11:12 ` [RFC 12/37] ASoC: Intel: avs: Add power " Cezary Rojewski
2021-12-08 11:12 ` [RFC 13/37] ASoC: Intel: avs: Add ROM requests Cezary Rojewski
2021-12-08 11:12 ` [RFC 14/37] ASoC: Intel: avs: Add basefw runtime-parameter requests Cezary Rojewski
2021-12-08 11:12 ` [RFC 15/37] ASoC: Intel: avs: Firmware resources management utilities Cezary Rojewski
2021-12-08 11:12 ` [RFC 16/37] ASoC: Intel: avs: Declare module configuration types Cezary Rojewski
2021-12-08 11:12 ` [RFC 17/37] ASoC: Intel: avs: Dynamic firmware resources management Cezary Rojewski
2021-12-21 14:40   ` Mark Brown
2021-12-21 17:07     ` Cezary Rojewski
2021-12-08 11:12 ` [RFC 18/37] ASoC: Intel: avs: Topology parsing Cezary Rojewski
2021-12-21 17:39   ` Mark Brown
2021-12-22 14:21     ` Cezary Rojewski [this message]
2021-12-08 11:12 ` [RFC 19/37] ASoC: Intel: avs: Path management Cezary Rojewski
2021-12-08 11:12 ` [RFC 20/37] ASoC: Intel: avs: Conditional-path support Cezary Rojewski
2021-12-08 11:12 ` [RFC 21/37] ASoC: Intel: avs: General code loading flow Cezary Rojewski
2021-12-08 11:12 ` [RFC 22/37] ASoC: Intel: avs: Implement CLDMA transfer Cezary Rojewski
2021-12-08 11:12 ` [RFC 23/37] ASoC: Intel: avs: Code loading over CLDMA Cezary Rojewski
2021-12-08 11:12 ` [RFC 24/37] ASoC: Intel: avs: Code loading over HDA Cezary Rojewski
2021-12-08 11:12 ` [RFC 25/37] ASoC: Intel: avs: Generic soc component driver Cezary Rojewski
2021-12-08 11:12 ` [RFC 26/37] ASoC: Intel: avs: Generic PCM FE operations Cezary Rojewski
2021-12-08 11:12 ` [RFC 27/37] ASoC: Intel: avs: non-HDA PCM BE operations Cezary Rojewski
2021-12-08 11:12 ` [RFC 28/37] ASoC: Intel: avs: HDA " Cezary Rojewski
2021-12-08 11:12 ` [RFC 29/37] ASoC: Intel: avs: Coredump and recovery flow Cezary Rojewski
2021-12-08 11:12 ` [RFC 30/37] ASoC: Intel: avs: Prepare for firmware tracing Cezary Rojewski
2021-12-08 11:12 ` [RFC 31/37] ASoC: Intel: avs: D0ix power state support Cezary Rojewski
2021-12-08 11:12 ` [RFC 32/37] ASoC: Intel: avs: Event tracing Cezary Rojewski
2021-12-08 11:12 ` [RFC 33/37] ASoC: Intel: avs: Machine board registration Cezary Rojewski
2021-12-08 11:12 ` [RFC 34/37] ASoC: Intel: avs: PCI driver implementation Cezary Rojewski
2021-12-08 11:12 ` [RFC 35/37] ASoC: Intel: avs: Power management Cezary Rojewski
2021-12-08 11:13 ` [RFC 36/37] ASoC: Intel: avs: SKL-based platforms support Cezary Rojewski
2021-12-08 11:13 ` [RFC 37/37] ASoC: Intel: avs: APL-based " Cezary Rojewski
2021-12-08 16:27 ` [RFC 00/37] ASoC: Intel: AVS - Audio DSP for cAVS Pierre-Louis Bossart
2021-12-08 17:51   ` Mark Brown
2021-12-09  9:59   ` Cezary Rojewski
2021-12-24 13:06 ` Mark Brown
2022-01-06 13:39   ` Cezary Rojewski
2022-01-18  9:42     ` Cezary Rojewski
2022-01-25 13:25       ` Mark Brown
2022-01-28 17:00     ` Mark Brown
2022-01-30 19:15       ` Cezary Rojewski
2022-02-02 13:26         ` Amadeusz Sławiński
2022-02-02 16:08           ` Mark Brown
2022-02-02 14:41         ` Mark Brown
2022-02-07 13:42           ` Cezary Rojewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ef9c9b72-a86e-066a-8af4-b08252559840@intel.com \
    --to=cezary.rojewski@intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=amadeuszx.slawinski@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=cujomalainey@chromium.org \
    --cc=harshapriya.n@intel.com \
    --cc=hdegoede@redhat.com \
    --cc=lma@semihalf.com \
    --cc=peter.ujfalusi@linux.intel.com \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=rad@semihalf.com \
    --cc=ranjani.sridharan@linux.intel.com \
    --cc=tiwai@suse.com \
    --cc=upstream@semihalf.com \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).