-
Notifications
You must be signed in to change notification settings - Fork 132
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
load topology for each device #5209
base: topic/sof-dev
Are you sure you want to change the base?
load topology for each device #5209
Conversation
SOFCI TEST |
7eb5975
to
ffadfbb
Compare
ffadfbb
to
1deb725
Compare
1deb725
to
3264fc3
Compare
sound/soc/sof/topology.c
Outdated
ret = request_firmware(&fw, tplg_files[i].file, scomp->dev); | ||
if (ret < 0) { | ||
if (i == 0) { | ||
dev_dbg(scomp->dev,"Fail back to %s\n", tplg_name); |
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.
If it was a topology w/ DMIC then you have dropped the -2ch in a previous loop, you are not going to load the topology you supposed to be loading.
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.
Yes, you are right. I need to restore the original topology name.
sound/soc/sof/topology.c
Outdated
tplg_name = strremove(tplg_name, "-2ch"); | ||
} else if (strstr(file, "-4ch")) { | ||
tplg_device = "dmic-4ch"; | ||
tplg_name = strremove(tplg_name, "-4ch"); |
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 are you dropping the 2ch/4ch from the original name?
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.
Because I would like to load the topology without dmic. For example, sof-hda-generic-2ch.tplg -> sof-hda-generic.tplg or similar.
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 the tplg_name is used only for loading the fallback, legacy, monolithic topology, in which case the fragments are not loaded. On a machine which have DMIC, you will load the topology w/o DMIC
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 exactly, tplg_name topology will be also loaded if not all dai links are handled. For example, if the monolithic topology is sof-lnl-rt711-4ch
, then sof-lnl-rt711
and sof-lnl-dmic-4ch-id5
will be loaded
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.
right, but if something fails in between and we need to fallback to the monolithic topology then at line 2641 you will have sof-lnl-rt711.tplg
instead the correct monolithic sof-lnl-rt711-4ch.tplg
, or am I missing something?
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.
right, but if something fails in between and we need to fallback to the monolithic topology then at line 2641 you will have
sof-lnl-rt711.tplg
instead the correct monolithicsof-lnl-rt711-4ch.tplg
, or am I missing something?
Yeah, I will restore the tplg file name when it fails back to the monolithic topology, thanks.
sound/soc/sof/topology.c
Outdated
if (strstr(file, "hda-generic")) { | ||
tplg_device = "idisp"; | ||
} else { | ||
tplg_device = "sdca-hdmi"; |
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 HDMI audio using SDW link or HDMI audio using HDA link, but used with SDW machine?
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 the HDMI audio used with SDW codecs. I use different name for different codec interfaces is because that the existing topologies use different PCM id for different codec interfaces. For example, the HDMI PCM ids are 5,6,7 for SDW machines and 3,4,5 for HDA machines.
00-00: Jack Out (*) : : playback 1
00-01: Jack In (*) : : capture 1
00-02: Speaker (*) : : playback 1
00-03: Amp feedback (*) : : capture 1
00-04: Microphone (*) : : capture 1
00-05: HDMI1 (*) : : playback 1
00-06: HDMI2 (*) : : playback 1
00-07: HDMI3 (*) : : playback 1
00-31: Deepbuffer Jack Out (*) : : playback 1
00-00: HDA Analog (*) : : playback 1 : capture 1
00-03: HDMI1 (*) : : playback 1
00-04: HDMI2 (*) : : playback 1
00-05: HDMI3 (*) : : playback 1
00-06: DMIC Raw (*) : : capture 1
00-31: Deepbuffer HDA Analog (*) : : playback 1
sound/soc/sof/topology.c
Outdated
} else if (strstr(dai_link->name, "iDisp")) { | ||
tplg_dev = TPLG_DEVICE_HDMI; | ||
if (strstr(file, "hda-generic")) { | ||
tplg_device = "idisp"; |
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.
If I read the function right, this is not going to be used as the hda-generic will fall under load_default_tplg = true
, the HDA dai_link->name is not handled?
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.
load_default_tplg = true
means there are still some remaining pcms that are not loaded in the sparated topologies. And we need to load the renamed topology at line 2620.
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 can you load the idisp.tplg and the sof-hda-generic.tplg which also contains idisp definitions?
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 can you load the idisp.tplg and the sof-hda-generic.tplg which also contains idisp definitions?
No, so we need to make sure there is no idisp in sof-hda-generic.tplg.
sound/soc/sof/topology.c
Outdated
"sdca-%damp", dai_link->num_cpus); | ||
} else if (strstr(dai_link->name, "SmartMic")) { | ||
tplg_dev = TPLG_DEVICE_SDW_MIC; | ||
tplg_device = "sdca-mic"; |
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.
Here and for the other checks: we need to update this match list every time a new component got introduced to products and we have new tplg fragment?
Is it going to scale?
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 need to update this match list when a new dai links got introduced. Given that we didn't update dai links in our machine drivers. I think we will only update the match list occasionally.
sound/soc/sof/topology.c
Outdated
tplg_files[i].device, | ||
tplg_files[i].be_id); | ||
dev_dbg(scomp->dev, "Requesting %d %s\n", i, tplg_files[i].file); | ||
ret = request_firmware(&fw, tplg_files[i].file, scomp->dev); |
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.
the sof_create_ipc_file_profile()
will check if the firmware and the topology file (the monolithic one!) is in place.
The means that you always need to have the monolithic tplg and the split components installed, otherwise the profile is rejected and if not fallback IPC version is available then we will fail.
I have a feeling that this split tplg handling has to touch the fw-file-profile.c as well.
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.
Yeah, I am thinking this open, too. My idea is that we don't touch the monolithic topology. I.e. the monolithic topology will coexist with the split topologies. So that sof_create_ipc_file_profile() will still valid.
sound/soc/sof/topology.c
Outdated
"%s/sof-%s-%s-id%d.tplg", | ||
sof_pdata->tplg_filename_prefix, platform, | ||
tplg_files[i].device, | ||
tplg_files[i].be_id); |
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 clean documentation as commit message and comments to explain clearly the expected file naming and also an update to sof-docs must be done.
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.
Totally agree.
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.
have you thought about the documentation?
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 almost forget the document. I will do it next week.
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.
Sorry for the delay. @ujfalusi The sof-docs PR is thesofproject/sof-docs#507
6259f1d
to
78eed41
Compare
Topology PR: thesofproject/sof#9668. I would like to start with SDCA codecs only. SDCA is more urgent than others. If we can create dai links based on the supported SDCA functions, we don't need to use quirks for enabling/disabling specific dai links. |
95da27b
to
9641e65
Compare
9641e65
to
788e9bf
Compare
sound/soc/sof/topology.c
Outdated
@@ -2464,15 +2465,180 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = { | |||
.bytes_ext_ops_count = ARRAY_SIZE(sof_dspless_bytes_ext_ops), | |||
}; | |||
|
|||
#define MAX_TPLG_NUM 5 |
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.
Add TPLG_DEVICE_MAX at the end of the 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.
Yes, it would be better.
sound/soc/sof/topology.c
Outdated
|
||
static bool is_platform_support_separated_tplg(const char *platform) | ||
{ | ||
if (!strcmp(platform, "mtl") || !strcmp(platform, "lnl") || !strcmp(platform, "ptl")) |
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 not going to scale... You are already missing ARL...
I would allow this for SOF_IPC4, I guess you handle the case when the topology files are not split, so it should just fallback?
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 guess you want to exclude the sof-hda on top of platform, right?
if !ipc4 || hda -> false ?
But this includes I2S machines also... Not sure what rule you want to make here.
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.
My first thought is to only list the platforms that we already have the topology support. And "HDA" is one of the "platform" because we use sof-hda-generic.tplg for all platforms. Yeah, we can remove this check and fallback if the driver doesn't find the topology files.
sound/soc/sof/topology.c
Outdated
} else if (strstr(dai_link->name, "SmartAmp")) { | ||
tplg_dev = TPLG_DEVICE_SDW_AMP; | ||
tplg_device = devm_kasprintf(sdev->dev, GFP_KERNEL, | ||
"sdca-%damp", dai_link->num_cpus); |
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 there be multiple SmartAmp link? You only going to record the first one. The naming of the device is also interesting, it is postfixed with a number of CPU dais?
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 don't support multiple SmartAmp link in the machine driver. And, yes, postfixing with a number of CPU dais is intentional. We need to set NUM_SDW_AMP_LINKS in the topology.
sound/soc/sof/topology.c
Outdated
"%s/sof-%s-%s-id%d.tplg", | ||
sof_pdata->tplg_filename_prefix, platform, | ||
tplg_files[i].device, | ||
tplg_files[i].be_id); |
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.
have you thought about the documentation?
sound/soc/sof/topology.c
Outdated
TPLG_DEVICE_SDW_JACK, | ||
TPLG_DEVICE_SDW_AMP, | ||
TPLG_DEVICE_SDW_MIC, | ||
TPLG_DEVICE_HOST_DMIC, |
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 awkwardly named, I think you meant INTEL_DMIC (conencted to PCH-DMIC)?
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 will change it to TPLG_DEVICE_PCH_DMIC, thanks
sound/soc/sof/topology.c
Outdated
tplg_dev = TPLG_DEVICE_HOST_DMIC; | ||
} else if (strstr(dai_link->name, "iDisp")) { | ||
tplg_dev = TPLG_DEVICE_HDMI; | ||
tplg_device = "sdca-hdmi"; |
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 know that you have excluded generic HDA, but things might fall through the cracks and picks this as HDMI where the PCM device id range is not 5,6,7. Which I suppose this fragment will provide.
How this naming going to scale with display audio serviced by SDW?
I'm not sure how this can be handled, but if we let HDA generic into \this logic, it is going to fail.
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 added the be_id in the topology name, so that the PCM device id can be any number.
sound/soc/sof/topology.c
Outdated
goto legacy_tplg; | ||
} | ||
|
||
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n", |
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.
Please don't use 'error:' in new prints.
sound/soc/sof/topology.c
Outdated
return -ENOMEM; | ||
|
||
dev_dbg(scomp->dev, "Requesting %d %s\n", i, tplg_files[i].file); | ||
ret = request_firmware(&fw, tplg_files[i].file, scomp->dev); |
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.
firmware_request_nowarn() to handle the fallback in case the fragmented tplg is not present, but what will happen if you load two fragment thn the third is missing and try to load the monolithic over it?
I'm sure that this is going to happen.
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.
and the original name is altered, the -2/4ch is dropped, so we are not going to load the right tplg in some cases.
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.
firmware_request_nowarn() to handle the fallback in case the fragmented tplg is not present, but what will happen if you load two fragment thn the third is missing and try to load the monolithic over it?
It will return error if the second or later topology is not present. My idea is that if we can't find the first fragmented topology, it means we don't have the required version of topologies, then we need to fall back to use the original topology. However, if we find the first fragmented topology, it means we use the new version of topology, and there should be something wrong if we don't find any required fragmented topology.
and the original name is altered, the -2/4ch is dropped, so we are not going to load the right tplg in some cases.
I will restore the file name in this case.
sound/soc/sof/topology.c
Outdated
|
||
for (i = 0; i < tplg_num; i++) { | ||
tplg_files[i].file = devm_kasprintf(sdev->dev, GFP_KERNEL, | ||
"%s/sof-%s-%s-id%d.tplg", |
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.
Another question: can a sof-sdca-jack.tplg
work on all platforms, do we really need the mtl/lnl/ptl/arl/etc variants?
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.
Good questions. We set 'PLATFORM' in the topology, but we don't set any variables for SDW. So, I think we can remove the platform name for the SDW topologies. It will be easier to implement the topologies.
f5eb366
to
ec01782
Compare
f86b410
to
5a6f019
Compare
The sof-docs PR is thesofproject/sof-docs#507 and topology PR is thesofproject/sof#9668. @ujfalusi @ranj063 @lgirdwood Could you review? Thanks. |
5a6f019
to
ee0ee64
Compare
ee0ee64
to
c2253fe
Compare
c2253fe
to
779861b
Compare
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.
@bardliao, I will continue on Monday, sorry for the delay.
sound/soc/sof/topology.c
Outdated
}; | ||
|
||
/* The code is from https://stackoverflow.com/questions/47116974/remove-a-substring-from-a-string-in-c */ | ||
static char *strremove(char *str, const char *sub) |
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'm not sure if we want code from 'shady' places in kernel ;)
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.
On the second thought, the current PR only supports split topologies when all devices are covered by the split topologies. There is no needed to change the original tplg file name. And we don't need *strremove() in the commit.
sound/soc/sof/topology.c
Outdated
|
||
dev_dbg(scomp->dev, "loading topology:%s\n", file); | ||
|
||
ret = request_firmware(&fw, file, scomp->dev); | ||
tplg_name = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s", file); |
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.
is this needs to be resource managed?
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.
Fixed.
sound/soc/sof/topology.c
Outdated
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) | ||
goto legacy_tplg; | ||
|
||
ret = sscanf(sof_pdata->tplg_filename, "sof-%3s-*.tplg", platform); |
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.
So we must always have a monolithic topology present in filesystem? During probe we check for existence of the topology file in sof_test_topology_file() and we will fail if it is missing.
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.
Yes, we will create the monolithic topology. It is also for the old kernel that doesn't support split topologies.
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.
@bardliao I have a couple of fundamental problems with your solution.
- We start off as if there's only 1 topology file for each machine and then you come here in this function and decide thats not correct and then figure out what all sub-topologies to load. What does it mean "user will create topology for single device...". Its more like the user will create multiple generic mini topologies that are applicable across platforms isnt it?
- Secondly, this is very Soundwire-specific isnt it? Can we make it a bit more generic so that it applies to all machines, SDW, I2S, HDA etc? We can have a coarse-grained split based on DAI types i.e SDW/I2S/HDA + HDMI + DMIC and a fine-grained split for the first part based onthe disco table for the SDW bits. This way we can do this change in 2 steps, first the split by DAI types and then isolate the SDW disco-specific split as a second step so it makes it more intuitive for everyone to understand.
sound/soc/sof/topology.c
Outdated
const struct firmware *fw; | ||
bool load_default_tplg = false; | ||
unsigned long tplg_mask = 0; | ||
char platform[4]; |
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.
"tgl-h" needs 6 char space...
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 the PLATFORM name is "tgl" in the topology.
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.
right, but this is a generic code, you cannot assume that every vendor's every topology family will use three letters.
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.
no magic numbers like 4 please
sound/soc/sof/topology.c
Outdated
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) | ||
{ | ||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | ||
struct topology_file tplg_files[TPLG_DEVICE_MAX]; |
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 can ever have 1 instance providing a function? no two jack/amp/mic/dmic/hdmi ? only ever one from each?
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.
think about karaoke devices with multiple jacks/mics for 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.
The idea is to have a topology for a function. Like we have 3 hdmi pcms, but we only have 1 hdmi topology.
951be49
to
5e1ab39
Compare
5e1ab39
to
448deb3
Compare
sound/soc/sof/topology.c
Outdated
@@ -2321,7 +2322,7 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = { | |||
.link_unload = sof_link_unload, | |||
|
|||
/* completion - called at completion of firmware loading */ | |||
.complete = sof_complete, | |||
/* complete will be added in the last tplg ops */ |
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.
what do you mean by the last topology here?
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.
The latest tplg file that we load.
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 be a bit more outspoken with:
/*
completion - called at completion of firmware loading
It is going to be set to sof_complete before the last topology fragment is loaded
to finalize the topology loading.
*/
.complete = NULL,
sound/soc/sof/topology.c
Outdated
goto legacy_tplg; | ||
|
||
for (i = 0; i < tplg_num; i++) { | ||
dev_dbg(scomp->dev, "Requesting %d %s\n", i, tplg_files[i]); |
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 think it makes better sense to move this down below just before loading the topology
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.
Hmm, but I need to know which file are needed. We will not know the file name if the first tplg file is not in the device.
sound/soc/sof/topology.c
Outdated
if (ret < 0) { | ||
if (i == 0) { | ||
dev_dbg(scomp->dev, "Fail back to %s\n", file); | ||
kfree(tplg_files[i]); |
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 are we freeing this here, this function doesnt seem to allocate it?
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.
tplg_files[] are allocated in card_ops[i].get_tplg_files(). Moved after the out:
label and added a comment to describe where they are allocated.
sound/soc/sof/topology.c
Outdated
|
||
dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n", | ||
tplg_files[i], ret); | ||
kfree(tplg_files[i]); |
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.
same here
sound/soc/sof/topology.c
Outdated
kfree(tplg_files[i]); | ||
goto out; | ||
} | ||
kfree(tplg_files[i]); |
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.
and here
|
||
/* set complete = sof_complete if it is the last topology */ | ||
if (i == tplg_num - 1) | ||
sof_tplg_ops.complete = sof_complete; |
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 should we restrict complete to only the last sub topology? All we do there is update the IPC structures, set the pipeline widget etc. Can we make this independent for each sub-tooplogy?
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.
All controls/widgets are added in the sdev lists and they will be handled. We need to split them if we want to handle them separately. Consider the same *scomp is passed to the .complete ops, I don't know how to make it independent for each sub-tooplogy. And actually, I don't get the benefit of make it independently.
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.
instead of setting the complete op why not just simply call sof_complete() here after successfully loading the last topology?
sound/soc/sof/topology.c
Outdated
release_firmware(fw); | ||
|
||
if (ret < 0) { | ||
dev_err(scomp->dev, "tplg component load failed %d\n", ret); |
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.
the return value will be printed anyway, can we print the name of the topology that failed here?
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.
Yes, done
sound/soc/sof/topology.c
Outdated
} | ||
} | ||
/* Load topology successfully, goto out */ | ||
goto out; |
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 think this part below should be condensed into the loop. Start with tplg_num = 1. Set the tplg_files[0] = file to begin with. Then you can remove the whole block below.
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.
Good suggestion, done
sound/soc/sof/card-tplg-ops.c
Outdated
@@ -0,0 +1,120 @@ | |||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) |
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.
@bardliao an alternative thought. Can we move this to the machine driver? I think it makes sense for this code to coexist along with the machine info and dailinks there.
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 thought about it. However, the topology stuff is more like belong to component level instead of card level. Besides, we need the *sof_pdata
data to construct the tplg file name.
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.
you've got tplg file name is available also in struct snd_soc_acpi_mach. I dont think you really need sof_pdata for this
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 thought about it. However, the topology stuff is more like belong to component level instead of card level. Besides, we need the
*sof_pdata
data to construct the tplg file name.
I agree with topology stuff belonging to component but this has nothing to do with the topology stuff but rather the machine level stuff ie whether there's a mic, a speaker a dmic etc no?
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.
@ranj063 I moved the ops to sound/soc/intel/common/
, and set the ops in each acpi_mach that needs it. I don't set the ops in sof_sdw.c because I can't access the same acpi_mach pointer in sof_sdw.c and SOF driver. The acpi_mach data is copied to the platform device not the pointer.
@bardliao I still have some fundamental issues with this approach:
|
sound/soc/sof/topology.c
Outdated
|
||
if (ret < 0) { | ||
dev_err(scomp->dev, "tplg component load failed %d\n", ret); | ||
return ret; |
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 incomplete. With a monolithic topology, an error would make sure to remove any successfully objects during topology loading. But with your approach, you leave the sub-topologies loaded
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.
Added snd_soc_tplg_component_remove()
448deb3
to
7863612
Compare
IMHO, the whole topology stuff belongs to the component level instead of the card level. That's why it is in the SOF core.
Yes, my point is that we just put the widgets in different topology files, but they all belong to the same audio system. IOW, they all work together no matter where they are from. I.e. The outcome should be identical no matter we load a monolithic topology or some sub-topologies.
Yes, handled in the updated code. |
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.
@bardliao, I really like this version much better!
Few comments inside.
sound/soc/sof/topology.c
Outdated
@@ -2321,7 +2322,7 @@ static const struct snd_soc_tplg_ops sof_tplg_ops = { | |||
.link_unload = sof_link_unload, | |||
|
|||
/* completion - called at completion of firmware loading */ | |||
.complete = sof_complete, | |||
/* complete will be added in the last tplg ops */ |
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 be a bit more outspoken with:
/*
completion - called at completion of firmware loading
It is going to be set to sof_complete before the last topology fragment is loaded
to finalize the topology loading.
*/
.complete = NULL,
sound/soc/sof/topology.h
Outdated
struct card_tplg_ops { | ||
const char *card_name; | ||
int (*get_tplg_files)(struct snd_soc_component *scomp, const char *file, | ||
const char ***tplg_files); |
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.
The return value must be documented, it is far from obvious from this that it returns -ERRNO or the number of files placed in tplg_files array.
Is 0 valid return value?
sound/soc/sof/topology.c
Outdated
for (i = 0; i < ARRAY_SIZE(card_ops); i++) { | ||
if (!strcmp(scomp->card->name, card_ops[i].card_name)) { | ||
ret = card_ops[i].get_tplg_files(scomp, file, &tplg_files); | ||
if (ret < 0) |
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.
you can use the file_num
directly, but I would rename the *_num to *_cnt, for me the _num is more like pointing to a specific index and here we have count.
or num_files.
you can as well just get away with using the single num_files
or tplg_cnt
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 use tplg_cnt
and file_cnt
separately because the tplg_cnt
can be changed when we fail back to the original topology. And we need to free the file_cnt
number of tplg_files[]
sound/soc/sof/topology.c
Outdated
@@ -2476,6 +2476,10 @@ static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = { | |||
}; | |||
|
|||
static const struct card_tplg_ops card_ops[] = { | |||
{ | |||
.card_name = "sof-soundwire", |
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.
sof-soundwire
is kind of reserved as "INTEL"-sof-soundwire, right? Can we add comment to spell this out?
sound/soc/sof/card-tplg-ops.c
Outdated
|
||
#define SOF_INTEL_PLATFORM_NAME_MAX 4 | ||
|
||
int get_sof_sdw_tplg_files(struct snd_soc_component *scomp, const char *file, |
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.
add intel in the function name, we only handle SOF_INTEL_PLATFORM_NAME_MAX long platform names.
sound/soc/sof/card-tplg-ops.c
Outdated
TPLG_DEVICE_SDCA_JACK, | ||
TPLG_DEVICE_SDCA_AMP, | ||
TPLG_DEVICE_SDCA_MIC, | ||
TPLG_DEVICE_PCH_DMIC, |
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.
TPLG_DEVICE_INTEL_PCH_DMIC
or
TPLG_DEVICE_SOC_DMIC
sound/soc/sof/topology.h
Outdated
*/ | ||
|
||
#ifndef __SOUND_SOC_SOF_TOPOLOGY_H | ||
#define __SOUND_SOC_SOF_TOPOLOGY_H |
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 rather create card-tplg-ops.h
instead.
We might (might) be able to extend this to be used by the fw-file-profile.c and cut the reliance on the monolithic topology file even if we only expect to use a generic one.
But, but, I guess we can create a generic sof--sdca-full-card.tplg and use this single one for all sdca setups...?
Currently, we always use single topology file to describe the widgets. We could split the topology into several sub-topologies and the sub-topologies can be used across cards. Then we can reuse those sub-topologies in enabling new products. The sub-topoloy name varies between audio configs. Add a get_tplg_files ops to get those names dynamically. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
7863612
to
06dfb66
Compare
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.
@bardliao this looks a lot more intuitive. Thanks! Just a few more comments
if (ret != 1) | ||
return 0; | ||
|
||
pr_err("bard: %s plarform: %s\n", card->name, platform); |
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.
remove?
} else { | ||
/* The dai link is not supported by sperated tplg yet */ | ||
dev_dbg(card->dev, | ||
"dai_link %s is not supported by sperated tplg yet\n", |
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.
typo seperated both lines but do we need the dbg statement at all?
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.
Yes, it can remind us what dai links are still not supported by separated tplg.
sound/soc/sof/topology.c
Outdated
out: | ||
/* Free tplg_files[] which are allocated by card_ops[i].get_tplg_files() */ | ||
for (i = 0; i < file_cnt; i++) | ||
kfree(tplg_files[i]); |
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 still looks awkward to free here. Why not use devm to allocate memory in the get_tplg_files op so that when the machine driver is removed due to this error, it will get freed automatically?
pr_err("bard: %s plarform: %s\n", card->name, platform); | ||
|
||
for_each_card_prelinks(card, i, dai_link) { | ||
char *tplg_device; |
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.
maybe change this to tplg_device_name or tplg_dev_name so that people dont confused why there's a tplg_dev and tplg_device
|
||
ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform); | ||
if (ret != 1) | ||
return 0; |
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.
isnt this as error? If not, maybe you can change the return type of this function to uint so that it is explicit
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.
Yes, it is an error. Changed the return value and added a trace.
dev_dbg(card->dev, | ||
"dai_link %s is not supported by sperated tplg yet\n", | ||
dai_link->name); | ||
return 0; |
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.
should we return here or continue?
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 return 0 so that snd_sof_load_topology() will use the monolithic topology.
sound/soc/sof/topology.c
Outdated
ret = firmware_request_nowarn(&fw, tplg_files[i], scomp->dev); | ||
if (ret < 0) { | ||
if (i == 0 && file_cnt) { | ||
dev_dbg(scomp->dev, "Fail back to %s\n", file); |
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.
@bardliao you're assuming here that the monolithic topology file always exists which is true for the current platforms. But once we move to the split sub-topologies, we may not even have the monolithic topologies for future platforms right?
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.
No, I didn't assume that the monolithic topology file always exists. I tested the return value of request_firmware(&fw, file, scomp->dev);
and return error if request_firmware() failed. That is the same as current code.
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.
if you didnt assume there's a monolithic topology, what did you mean by fall back? and there's a typo in fallback
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.
It means we tried the sub-topologies but failed. Now we are trying the monolithic topology. But we will know if the monolithic topology exists after calling request_firmware()
/* | ||
* The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg | ||
* where <platform> is only required for the DMIC function as the nhlt blob | ||
* is platform depentent. |
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.
typo dependent
06dfb66
to
61fd30e
Compare
sound/soc/sof/topology.c
Outdated
tplg_cnt = sof_pdata->machine->get_tplg_files(scomp->card, sof_pdata->machine, | ||
sof_pdata->tplg_filename_prefix, | ||
&tplg_files); | ||
if (tplg_cnt < 0) |
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.
you need to free tplg_files in the error path
sound/soc/sof/topology.c
Outdated
} | ||
} else { | ||
if (i > 0) | ||
snd_soc_tplg_component_remove(scomp); |
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.
actually after thinking about it, I think you dont need to do this at all. All of the aub-topologies are associated with the same component, so if a failure happens during loading for any of the sub-topologies, the component remove will handle all of the previously successfully loaded objects automatically. Maybe you can just add that comment here for clarity
61fd30e
to
f0c60a5
Compare
A topology can be split into several sub-topologies. The sub-topologies can be used across cards. In other words, we can create multiple mini topologies and let driver select what it needs. However, the topology depends on the cards. Add a get_tplg_files ops allow cards have their own sub-topology file names. The commit add an empty ops first. Will add the first ops in the follow up commit. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Add sof_sdw_get_tplg_files ops to get sub-topology file names for the sod_sdw card. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
With the get_tplg_files ops, sub-topologies could be used and the defaule topology is not necessary in the file system. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The audio configs with multi-function SDCA codecs can use the sof_sdw_get_tplg_files ops to get sub-topologies dynamically. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The audio configs with multi-function SDCA codecs can use the sof_sdw_get_tplg_files ops to get sub-topologies dynamically. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The audio configs with multi-function SDCA codecs can use the sof_sdw_get_tplg_files ops to get sub-topologies dynamically. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The audio configs with multi-function SDCA codecs can use the sof_sdw_get_tplg_files ops to get sub-topologies dynamically. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
f0c60a5
to
cfb0e72
Compare
Get device information from dai links. load topology for each device.
This should not impact the existing devices.