-
Notifications
You must be signed in to change notification settings - Fork 349
[REVIEW ONLY] topology 2.0 #3183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Topology 2.0 file format is an extension of the ALSA configuration language. It uses the same basic syntax of "key-value pairs" of the language but adds features, required to be able to define complex objects by re-using definitions of component objects with different attributes. This replaces the SOF m4 topology macro library. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
|
Forgot to add yesterday: a list of new ALSA configuration keywords (might be missing some) |
lgirdwood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make the changes and share a pipeline like
Host0 --> buffer0 --> volume0 --> buffer1 --> SSP0
We will need to have a global attributes and per widget/component/section attributes that should be prefixed to avoid collisions.
| # adding ".optional" or ".mandatory" to the array name | ||
|
|
||
| DefineType.format { | ||
| enum [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we name space this and use the "" here. e.g.
DefineType."pcm.format" {
Since "format" can be used for multiple items.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a type definition, not an attribute declaration. PCM and DAI formats are the same, aren't they?
| ] | ||
| } | ||
|
|
||
| DefineType.time_domain { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto "pipeline.time_domain"
|
|
||
| DefineType.time_domain { | ||
| enum [ | ||
| "dma" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use the # here to comment each field. i.e.
"dma" #pipeline is scheduled via DMA interrupts
| type array.tuple | ||
| } | ||
|
|
||
| DefineAttribute.format { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This overlaps with DefineType. I much rather reduce the number of new keywords so
DefineAttribute."pcm.format" {
type enum
values [
s16le
s24le
[
default s16le
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but we will have several attributes of type "format." Without defining the type "format" we'll have to repeat the same enum every time. Even worse with much longer enums like widget types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be global and in a global pcm.conf header. PCM format will be used in lots of places so why would we have to repeat. Can you provide an example ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lgirdwood Even in minimal examples we have two formats: a pipeline format and a DAI format, so we need at least two attributes of type "format" - see pipeline_format and dai_format in this PR
| ] | ||
| } | ||
|
|
||
| DefineAttribute.tokens { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont need to define tokens - it's low level implementation detail only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a "tokens" attribute for cases where higher level configuration files (e.g. machine level) pass their specific token arrays to lower level configuration files (pipelines). This is currently used for example to define pipelines:
dnl W_PIPELINE(stream, period, priority, core, initiator, platform)
^^^^^^^^
define(`W_PIPELINE',
...
`SectionWidget."'N_PIPELINE($1)`" {'
...
` data ['
` "'N_PIPELINE($1)`_data"'
` "'$6`"'
^^^^^^
` ]'
`}')
which then is called as
W_PIPELINE(N_DAI_OUT, SCHEDULE_PERIOD, SCHEDULE_PRIORITY, SCHEDULE_CORE, SCHEDULE_TIME_DOMAIN, pipe_dai_schedule_plat)
^^^^^^^^^^^^^^^^^^^^^^
and pipe_dai_schedule_plat is an array of tokens, defined in bxt.m4 or similar. So far I don't have a good idea how to avoid such token array passing. The only thing we can make easier is make arrays of word- and string-tokens a built-in type, without this defining them directly as a structure of an array of string tokens and an array of word tokens becomes really painful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we are not using SectionWidget or token array directly - we abstract all tokens with Attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lgirdwood we do that where possible, yes. E.g. for volume, where it's known in advance which tokens must be supplied. But here it can be any tokens that the respective platform decides to apply. So I don't see how we can replace them with fixed attributes?
|
|
||
| # A buffer block, most attributes inherited from "Widget" | ||
| DefineWidget."buffer" { | ||
| attributes [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make these attribute mandatory and optional in the widget definition. Some widgets will only have mandatory but some will have both e.g. for buffer "size" is mandatory but "ignore_underrun" is optional and false by default.
| "siggen" | ||
| "src" | ||
| ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont need this, it's low level and encoded in the CC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't we add new widget types from time to time? Do we really want to patch the compiler every time we do that?
| default_hw_conf_id $id | ||
|
|
||
| # FIXME we need concatenation | ||
| hw_configs [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to concat this ?
hw_configs [
config1
config2
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
those aren't multiple configurations, that's just one configuration, generated by concatenating those two strings:
`SectionBE."'$4`" {'
...
` hw_configs ['
` "'$1$2`"'
` ]'
| } | ||
|
|
||
| # SectionHWConfig | ||
| DefineHWConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefineHWConfig."hw_cfg.ssp" etc would support per DAI type configs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand correctly what you mean. This is dai.conf, so this is a generic definition of a SectionHWConfig component. "hw_cfg." seems to be unneeded - it just repeats DefineHWConfig. As for "ssp" - that would mean, that we have to instantiate SectionHWConfig components in machine configuration files. In fact this is exactly what my latest version does. But then we also have to define them per DAI type - as you say. What do we gain that way? So far we don't seem to have to do that? But that can be done, I think, let's see if we need it.
| @@ -0,0 +1,80 @@ | |||
| # Instantiate a subtree - all the pipelines, connected to one DAI | |||
| subtree { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect the machine file to contain
DeclarePipeline."pipe-name1" {
}
DeclarePipeline."pipe-name2" {
}
DeclareDAI."dai-name1" {
}
It should be representing the same data as contained in the machine M4 today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Declare" in your code above means instantiation? I use "new." for it now. But yes, that's also what I do.
As far as I understand, the whole DSP audio topology can be divided into "DAI groups." I.e. each DAI can have a group of pipelines associated with it, but different DAIs never link. This seems to be what I see in most pipelines ATM but in fact I suspect this isn't a general rule? There can be some pass-through paths from a DMIC to a playback DAI, right? Do we have any such examples or any other examples, where different DAIs link together?
Currently in my notation a "subtree" is such an isolated part of the topology graph and it can include several pipelines, but only one DAI. The difference to the current m4 situation, where machine files just contain collections of pipelines, DAIs, backends, etc. is, that to make that approach work our m4 files make a heavy use of string-matching, i.e. concatenation. That's how DAIs, their configurations, graphs and pipelines are matched. To avoid that and to make explicit separation of graph parts I use "subtrees." E.g. each such subtree defines global parameters like dai_format etc. Without separating subtrees this would be impossible.
@lgirdwood you want SSP over HDA? I now have exactly that example, but with HDA because their configuration is easier, it doesn't include capture and some other extensions. |
|
@lyakh a short introduction and context for this PR would be useful to have a better feel of why we are doing topology 2.0 |
That's precisely what I recommended we avoid last week! |
@plbossart yes, this is testing so far, but at least an example graph of the kind you're thinking about would be helpful. You mentioned, that sof-byt-codec.m4 was a good example, which defines the topology as where |
@dbaluta this is a rather early stage yet: we still haven't quite converged even on a prototype of a language definition and I'm just starting very tentative coding. The reason to try and replace the present SOF m4 topology library is the inconvenience of dealing with parameters. It's very difficult or impossible to verify macro parameters, which makes their use very error-prone. We want to fix those issues, make working with topology files more natural and add further compile-time topology checks. For this we propose to extend the present ALSA configuration language by adding primitives, that will allow us to define topology components and then to use those definitions to build specific topologies - similar to how this is done now with m4. |
Can you link in your bug/pr for reference here to remind me. I cant remember if this was to resolve some driver issues (sorry not tracking these atm). |
@lyakh thanks for explanation. Make sure this is also present in commit messages / PR description. |
|
There is a problem with this proposal: in ALSA configuration language '.' is used to describe parent-child relationships. And in this PR constructs like "DefineWidget.pipeline" or "new.widget.pcm" don't really describe such relationships. Moreover, in a fragment like the "pipeline" widget will have 2 children: "format" and "new" which doesn't seem to make good sense. |
| @@ -0,0 +1,162 @@ | |||
| # "DefineTemplate" doesn't seem to be needed | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyakh I think we should have DefineTemplate{}. Ideally we should have DefineTemplate{} follow all Define*{} for that kind. For example, DefineMixerControl{} should have a DefineTemplate.mixercontrol{}, with default values so that we can instantiate a mixercontrol with that template and modfied attributes (if needed) easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
A new pull request was probably in order anyway, but now you have to do it because the base branch "master" is gone. |
This is a very early proposal of what Topology v2.0 files could eventually look like. For review and commenting only for now.