Skip to content
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

[RFC] ASoC: Add Multi CPU DAI support #1644

Closed
wants to merge 6 commits into from

Conversation

bardliao
Copy link
Collaborator

This is a rebase version of https://www.alsa-project.org/pipermail/alsa-devel/2018-June/137190.html

The original commit message is:

As discussed in [1], ASoC core supports multi codec DAIs
on a DAI link. However it does not do so for CPU DAIs.

So, add support for multi CPU DAIs on a DAI Link by adding
multi CPU DAI in Card instantiation, suspend and resume
functions, PCM ops, stream handling functions and DAPM.

[1]: https://www.spinics.net/lists/alsa-devel/msg71369.html

Thanks @ranj063 for the comments. I addressed some, but I need more
time or help from others for the other comments.

struct snd_soc_dai *codec_dai;
int i;

pinctrl_pm_select_sleep_state(cpu_dai->dev);
for_each_rtd_codec_dai(rtd, i, cpu_dai) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao typo here. For_each_cpu_dai?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank will update it.


if (cpu_dai->active)
pinctrl_pm_select_default_state(cpu_dai->dev);
for_each_rtd_codec_dai(rtd, i, cpu_dai) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like typo here as well? For each cpu dai?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Thanks.

@@ -491,6 +491,14 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
if (!rtd->codec_dais)
goto free_rtd;

/*
* for rtd->cpu_dais
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is not very helpful at all

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to be consistent with the existing code. ie

	/*
	 * for rtd->codec_dais
	 */

above.

/* prune the BE if it's no longer in our active list */
if (widget && widget_in_list(list, widget))
/*
* The BE is pruned only if none of the the cpu_dai
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate "the" in comment

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank will update it.

Copy link
Member

@plbossart plbossart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good @bardliao, see comments below

@@ -1149,6 +1154,9 @@ struct snd_soc_pcm_runtime {
struct snd_soc_dai **codec_dais;
unsigned int num_codecs;

struct snd_soc_dai **cpu_dais;
unsigned int num_cpu_dai;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why we need to keep 'codec_dai' now that we have 'codec_dais" and 'num_codecs'?

Also why do we need 'cpu_dai' as well as 'cpus_dais' and 'num_cpu_dai'

Looks like room for additional cleanups

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why we need to keep 'codec_dai' now that we have 'codec_dais" and 'num_codecs'?

Also why do we need 'cpu_dai' as well as 'cpus_dais' and 'num_cpu_dai'

Looks like room for additional cleanups

Indeed, we can send another patch to remove cpu_dai and codec_dai

if (cpu_dai->component->driver->non_legacy_dai_naming) {
unsigned int inv_dai_fmt;
for_each_rtd_cpu_dai(rtd, i, cpu_dai) {
if (cpu_dai->component->driver->non_legacy_dai_naming) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the 'legacy_dai_naming' and can it be removed now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the 'legacy_dai_naming' and can it be removed now?

@plbossart No, I don't think it can be removed now. Codec will be registered to cpu dai in CODEC <-> CODEC link, and we can use the non_legacy_dai_naming flag to know that is codec.

for_each_rtd_cpu_dai(rtd, i, cpu_dai) {
ret = snd_soc_dai_hw_params(cpu_dai, substream, params);
if (ret < 0)
goto interface_err;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to add the error handling here, the interface_err only deals with the codec case

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to add the error handling here, the interface_err only deals with the codec case

Yes, thanks @plbossart

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart Updated

if (widget && widget_in_list(list, widget))
do_prune = 0;
}
if (!do_prune)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will conflict with @lyakh 's work...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will conflict with @lyakh 's work...

Sorry, @plbossart @lyakh Could you describe it in more detail? Which PR will be affected?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao it's #1501 but I think it should be ok for you to proceed with your PR for now. I'm not sure what @plbossart's plan is, but as far as I understand, even after #1501 is fully reviewed and approved here, we'll first need to also get it reviewed on ALSA and virtualisation lists, so, it will take a while.

@@ -3038,7 +3172,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
out:
dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
(rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
cpu_dai->name);
(rtd->num_cpu_dai > 1) ? "multicpu" : rtd->cpu_dai->name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks really ugly, what cant' we use rtd->cpu_dais[0].name and completely remove the use of rtd->cpu_dai?

for_each_rtd_codec_dai(rtd, i, codec_dai) {
for_each_rtd_cpu_dai(rtd, j, cpu_dai) {
dapm_add_valid_dai_widget(card, rtd,
codec_dai, cpu_dai);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems odd. You will not have a connection between each CPU dai and each codec_dai

e,g. for Soundwire, you will connect ALH1.3 to RT1308.1.aif1 and ALH2.3 to RT1308.2.aif1

There will be no routing/link between e.g. ALH1.3 and RT1308.2.aif1

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems odd. You will not have a connection between each CPU dai and each codec_dai

e,g. for Soundwire, you will connect ALH1.3 to RT1308.1.aif1 and ALH2.3 to RT1308.2.aif1

There will be no routing/link between e.g. ALH1.3 and RT1308.2.aif1

Yes, it is what we are missing now. Thanks @plbossart

@plbossart
Copy link
Member

@morimoto if you have spare cycles your feedback on this PR would be more than appreciated.

@bardliao bardliao force-pushed the for-multi-cpu branch 5 times, most recently from fa4266b to 30cc579 Compare December 26, 2019 05:53
@bardliao bardliao force-pushed the for-multi-cpu branch 2 times, most recently from 8d64b21 to 4a4b971 Compare January 2, 2020 09:07
@bardliao
Copy link
Collaborator Author

bardliao commented Jan 6, 2020

@plbossart I compared and merged @morimoto 's version. Could you review it? I have two question.

  1. Do we need to support multi-cpu for FE? What is the scenario of multi-cpu on codec to codec dai link?

cpu_rate_max = min_not_zero(cpu_rate_max, cpu_stream->rate_max);
formats &= cpu_stream->formats;
cpu_rates = snd_pcm_rate_mask_intersect(cpu_stream->rates,
rates);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cpu_rates?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks @lyakh

if (widget && widget_in_list(list, widget))
do_prune = 0;
}
if (!do_prune)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao it's #1501 but I think it should be ok for you to proceed with your PR for now. I'm not sure what @plbossart's plan is, but as far as I understand, even after #1501 is fully reviewed and approved here, we'll first need to also get it reviewed on ALSA and virtualisation lists, so, it will take a while.

dapm_add_valid_dai_widget(card, rtd,
codec_dai,
rtd->cpu_dais[i]);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superfluous parentheses

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Thanks.

} else {
for_each_rtd_codec_dai(rtd, i, codec_dai) {
dapm_add_valid_dai_widget(card, rtd,
codec_dai, rtd->cpu_dais[0]);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Thanks.

@@ -62,6 +62,10 @@ int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
struct snd_dmaengine_dai_dma_data *dma_data;
int ret;

if (rtd->num_cpus > 1)
dev_warn(rtd->dev,
"%s doesn't support Multi CPU yet\n", __func__);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would actually happen in such a case? Would it still work at least with just one CPU codec? Shouldn't we return an error in this and similar cases instrad?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would actually happen in such a case? Would it still work at least with just one CPU codec? Shouldn't we return an error in this and similar cases instrad?

To be honest, I don't know how to test it. I should still work with one CPU. I don't want to return an error for now is because I want to know what will happen if these functions are invoked with multi cpus.

@plbossart
Copy link
Member

@bardliao I've lost track of the directions here, Mark Brown seemed to think this was a good patchset, are you going to update the PR, send the changes directly to alsa-devel? Let me know, thanks!

@bardliao
Copy link
Collaborator Author

@bardliao I've lost track of the directions here, Mark Brown seemed to think this was a good patchset, are you going to update the PR, send the changes directly to alsa-devel? Let me know, thanks!

@plbossart Yes, I will double check the comments and send a new version to alsa-devel after addressing all comments.

@bardliao bardliao force-pushed the for-multi-cpu branch 2 times, most recently from ce89c61 to 279476a Compare January 17, 2020 07:54
"ASoC: Neither/both cpu name/of_node are set for %s\n",
link->name);
return -EINVAL;
}

Copy link
Collaborator

@dbaluta dbaluta Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something is off here. Either the error message is wrong or the if condition is wrong. If none of cpu->name / cpu->of_node are set we won't hit the error message.

This is not a blocker for this PR as the issue was pre-existent. Will send an email to alsa-devel.

ASoC core supports multiple codec DAIs but supports only a CPU DAI.
To support multiple cpu DAIs, add cpu_dai and num_cpu_dai in
snd_soc_dai_link and snd_soc_pcm_runtime structures similar to
support for codec_dai. This is intended as a preparatory patch to
eventually support the unification of the Codec and CPU DAI.

Inline with multiple codec DAI approach, add support to allocate,
init, bind and probe multiple cpu_dai on init if driver specifies
that. Also add support to loop over multiple cpu_dai during
suspend and resume.

This is intended as a preparatory patch to eventually unify the CPU
and Codec DAI into DAI components.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
shreyasnc1 and others added 5 commits January 20, 2020 22:59
Add support in PCM operations to invoke multiple cpu dais as we do
for multiple codec dais. Also the symmetry calculations are updated to
reflect multiple cpu dais.

Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Adding a helper to connect widget for a specific cpu and codec dai
The helper will help dapm_connect_dai_link_widgets() to reduce indents.

Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
DAPM handles DAIs during soc_dapm_stream_event() and during addition
and creation of DAI widgets i.e., dapm_add_valid_dai_widget() and
dapm_connect_dai_link_widgets().

Extend these functions to handle multiple cpu dai.

Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Multi cpu is not supported by all functions yet. Add an error message
and return.

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Bard liao <yung-chuan.liao@linux.intel.com>
Now multi-cpu-dai is supported. We have the same resaon as
multi-codec-dai to skip CPUs which don't support the current stream.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
@plbossart
Copy link
Member

replaced by PR #1802

@plbossart plbossart closed this Feb 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants