Skip to content

[RFC] ASoC: SOF: Intel: hda: refine init/stop chip in hda_suspend/hda_resume#965

Closed
zhuyingjiang wants to merge 4 commits intothesofproject:topic/sof-devfrom
zhuyingjiang:topic/sof-dev-refine-suspend-resume
Closed

[RFC] ASoC: SOF: Intel: hda: refine init/stop chip in hda_suspend/hda_resume#965
zhuyingjiang wants to merge 4 commits intothesofproject:topic/sof-devfrom
zhuyingjiang:topic/sof-dev-refine-suspend-resume

Conversation

@zhuyingjiang
Copy link

Define a SOF hda_dsp_ctrl_stop_chip and use this in hda_suspend, so the disable and clear HDA irq and stream irqs steps all called during the suspend. Codec and HDA link related registers are write if CONFIG_SND_SOC_SOF_HDA is true.
Use the SOF defined ppcap functions in hda_suspend/hda_resume.
Use hda_dsp_ctrl_init_chip as common code for hda_resume.
fix part of #777

Use the SOF defined ppcap functions for both HDA and
none-HDA in hda_suspend and hda_resume.

Signed-off-by: Zhu Yingjiang <yingjiang.zhu@linux.intel.com>
Add hda_dsp_ctrl_stop_chip, so stop hda irq and streams irq sequence
will be called by hda_suspend. Whether CONFIG_SND_SOC_SOF_HDA is
defined or not.
This function is used to disable the whole IRQ and I/Os.

Signed-off-by: Zhu Yingjiang <yingjiang.zhu@linux.intel.com>
The SOF defined hda_dsp_ctrl_stop_chip can handle both cases for
whether CONFIG_SND_SOC_SOF_HDA is defined. Disable the interrupts
for HDA controller and streams. If CONFIG_SND_SOC_SOF_HDA is
defined, also disable the CORB/RIRB, and stop i/o.

Signed-off-by: Zhu Yingjiang <yingjiang.zhu@linux.intel.com>
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.

I cannot approve this PR. While it's good to add clean-ups, it contains too many changes without justifications that seem very scary to merge. Please double-check your changes and make sure they don't change the programming sequences. If you do change the programming sequence, then you need an explanation for why it didn't work before.

0);
#endif
/* disable hda bus irq and streams */
hda_dsp_ctrl_stop_chip(sdev);
Copy link
Member

Choose a reason for hiding this comment

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

that's not an iso-feature change for the case where CONFIG_SND_SOC_SOF_HDA is not defined. You are doing a lot more and you'd need to explain a bit more the rationale for the changes.

Copy link
Author

Choose a reason for hiding this comment

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

@plbossart The added steps are :
1 disable interrupts in stream descriptor
2 disable SIE for all streams
3 clear stream status
4 clear WAKESTS
5 clear interrupt status register
So all these are disable interrupts and clear registers of the streams, these are needed when shutdown/suspend to D3. Even with no HDA codecs.
So the previous code less them, although it seems still no problem with the DSP power off and on.
The PR has been tested with APL/WHL with HDA/nocodec mode.

Copy link
Member

@plbossart plbossart May 22, 2019

Choose a reason for hiding this comment

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

That one I could live with, but I would need a separate PR that adds those steps with the existing code. Once it's proven there is no impact we can do the code optimization. Doing all the changes at once is too risky and difficult to bisect.

Copy link
Author

Choose a reason for hiding this comment

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

OK, #975 is the separate PR for this. I will modify the last commit and send a separate PR for the misc clock gating with init chip.

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* Reset stream-to-link mapping */
list_for_each_entry(hlink, &bus->hlink_list, list)
bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
Copy link
Member

Choose a reason for hiding this comment

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

thats seems wrong. You are changing the programming sequence here by resetting things without taking care of the clock gating. Why?

Copy link
Author

Choose a reason for hiding this comment

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

Within @lbetlej 's email:
"CGCTL.MISCBDCGE needs to be disabled during controller reset "
So hda_dsp_ctrl_misc_clock_gating are disabled before controller reset and enabled after that.
with regard to "Reset stream-to-link mapping", there is no need to disable CGCTL.MISCBDCGE before that and then enable after.
So there are 2 solution:
1). move "Reset stream-to-link mapping" into hda_dsp_ctrl_init_chip and before enable CGCTL.MISCBDCGE
2). don't need CGCTL.MISCBDCGE operations before and after "Reset stream-to-link mapping".
With testing 2) on APL/WHL with HDA mode, it seems there is no difference if don't do that.
@lbetlej do we need disable and enable CGCTL.MISCBDCGE for "Reset stream-to-link mapping"?which solution is right in your opinion?

Copy link
Member

Choose a reason for hiding this comment

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

@zhuyingjiang you are playing with fire here. The sequence has been used for several years, and it'll take architectural pointers and a lot more experimental evidence to convince me to change something which is not broken.

Copy link
Author

Choose a reason for hiding this comment

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

@zhuyingjiang you are playing with fire here. The sequence has been used for several years, and it'll take architectural pointers and a lot more experimental evidence to convince me to change something which is not broken.

@plbossart let me explain more here, the first attempt to change here is because the code difference with SST,
In SST the code is:
static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
{
struct hdac_ext_link hlink;
int ret;
skl_enable_miscbdcge(bus->dev, false);
ret = snd_hdac_bus_init_chip(bus, full_reset);
/
Reset stream-to-link mapping */
list_for_each_entry(hlink, &bus->hlink_list, list)
bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
skl_enable_miscbdcge(bus->dev, true);
return ret;
}

But in our code it is:

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* reset and start hda controller /
ret = hda_dsp_ctrl_init_chip(sdev, true);
==>hda_dsp_ctrl_misc_clock_gating(sdev, false);
==>hda_dsp_ctrl_link_reset
==>...
==>hda_dsp_ctrl_misc_clock_gating(sdev, true);
hda_dsp_ctrl_misc_clock_gating(sdev, false);
/
Reset stream-to-link mapping /
list_for_each_entry(hlink, &bus->hlink_list, list)
bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
hda_dsp_ctrl_misc_clock_gating(sdev, true);
/
enable ppcap interrupt */
snd_hdac_ext_bus_ppcap_enable(bus, true);
snd_hdac_ext_bus_ppcap_int_enable(bus, true);
#else

So in our code there will be disable and enable clock gating twice.

And a more important difference is in probe,
The SST skl_probe_work which called skl_init_chip still do the below steps:
/* Reset stream-to-link mapping */
list_for_each_entry(hlink, &bus->hlink_list, list)
bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);

but in our code, there is no such step in probe.

So in conclusion, I think the solution 1) I mentioned above may be better (move "Reset stream-to-link mapping" into hda_dsp_ctrl_init_chip and before enable CGCTL.MISCBDCGE inside. the programming sequence goes the same steps with SST),
and for 2) , it changed a little much and may leads to uncertain results.

I will change the PR according to solution 1) and request for comments.

@zhuyingjiang zhuyingjiang requested a review from lbetlej May 22, 2019 10:55
@zhuyingjiang
Copy link
Author

@plbossart So this is request for comments, and are tested for APL/WHL with HDA/nocodec all 4 cases.
Some are register programming sequences better have.(disable irq and clear registers for stream before shutdown)
Others are from @lbetlej 's email and compare to SST driver steps.

The SOF defined hda_dsp_ctrl_init_chip function can handle
both case whether CONFIG_SND_SOC_SOF_HDA is defined, so
make it common codes.
Move reset stream-to-link mapping into hda_dsp_ctrl_init_chip.
So only one misc clock gating disable/enable is needed.

Signed-off-by: Zhu Yingjiang <yingjiang.zhu@linux.intel.com>
@zhuyingjiang zhuyingjiang force-pushed the topic/sof-dev-refine-suspend-resume branch from 1a98909 to eee6e43 Compare May 23, 2019 07:56
@zhuyingjiang
Copy link
Author

@plbossart #975 is the separate PR for refine suspend with stop chip, and ppcap. I modified the last commit with solution 1) I mentioned above, and for RFC. Will submit it after #975 is merged.

@zhuyingjiang
Copy link
Author

Close this since this is separated as:
#975 for stop chip in suspend.
#1020 for init chip in resume.

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.

2 participants