Repository navigation
[RFC] ASoC: SOF: Intel: hda: refine init/stop chip in hda_suspend/hda_resume - #965
zhuyingjiang wants to merge 4 commits into
Conversation
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>
plbossart
left a comment
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
thats seems wrong. You are changing the programming sequence here by resetting things without taking care of the clock gating. Why?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
@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.
|
@plbossart So this is request for comments, and are tested for APL/WHL with HDA/nocodec all 4 cases. |
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>
1a98909 to
eee6e43
Compare
|
@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. |
When kfence fails to initialize kfence pool, it frees the pool. But it does not reset memcg_data and PG_slab flag. Below is a BUG because of this. Let's fix it by resetting memcg_data and PG_slab flag before free. [ 0.089149] BUG: Bad page state in process swapper/0 pfn:3d8e06 [ 0.089149] page:ffffea46cf638180 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x3d8e06 [ 0.089150] memcg:ffffffff94a475d1 [ 0.089150] flags: 0x17ffffc0000200(slab|node=0|zone=2|lastcpupid=0x1fffff) [ 0.089151] raw: 0017ffffc0000200 ffffea46cf638188 ffffea46cf638188 0000000000000000 [ 0.089152] raw: 0000000000000000 0000000000000000 00000000ffffffff ffffffff94a475d1 [ 0.089152] page dumped because: page still charged to cgroup [ 0.089153] Modules linked in: [ 0.089153] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G B W 5.18.0-rc1+ thesofproject#965 [ 0.089154] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 [ 0.089154] Call Trace: [ 0.089155] <TASK> [ 0.089155] dump_stack_lvl+0x49/0x5f [ 0.089157] dump_stack+0x10/0x12 [ 0.089158] bad_page.cold+0x63/0x94 [ 0.089159] check_free_page_bad+0x66/0x70 [ 0.089160] __free_pages_ok+0x423/0x530 [ 0.089161] __free_pages_core+0x8e/0xa0 [ 0.089162] memblock_free_pages+0x10/0x12 [ 0.089164] memblock_free_late+0x8f/0xb9 [ 0.089165] kfence_init+0x68/0x92 [ 0.089166] start_kernel+0x789/0x992 [ 0.089167] x86_64_start_reservations+0x24/0x26 [ 0.089168] x86_64_start_kernel+0xa9/0xaf [ 0.089170] secondary_startup_64_no_verify+0xd5/0xdb [ 0.089171] </TASK> Link: https://lkml.kernel.org/r/YnPG3pQrqfcgOlVa@hyeyoo Fixes: 0ce20dd ("mm: add Kernel Electric-Fence infrastructure") Fixes: 8f0b364 ("mm: kfence: fix objcgs vector allocation") Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Reviewed-by: Marco Elver <elver@google.com> Reviewed-by: Muchun Song <songmuchun@bytedance.com> Cc: Alexander Potapenko <glider@google.com> Cc: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
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