Repository navigation
Conversation
|
The corresponding FW PR here: thesofproject/sof#4320, though it is backward compatible so the 2 PRs can be merged separately. @plbossart @ranj063 @kv2019i @bardliao please help to review. The change here might be invasive as I don't add a kconfig item to enable/disable this new IMR restore feature, we can discuss if making it configurable is needed. |
| #define SOF_IPC_INFO_LOCKS BIT(1) | ||
| #define SOF_IPC_INFO_LOCKSV BIT(2) | ||
| #define SOF_IPC_INFO_GDB BIT(3) | ||
| #define SOF_IPC_INFO_IMR_RESTORE BIT(4) |
There was a problem hiding this comment.
ABI change?
It is backward compatible, e.g. all FW/driver combination works, so I think we don't need ABI bump here:
old FW + old driver, no IMR restore.
old FW + new driver, no IMR restore.
new FW + old driver, driver FW purge IPC and re-downloading, no IMR restore.
new FW + new driver, IMR restore.
There was a problem hiding this comment.
@keyonjie Yes, but it's still extending the public interface so
"Increment MINOR version if you add backwards compatible features or
changes. PATCH should be reset to 0." applies. https://github.com/thesofproject/sof/blob/main/src/include/kernel/abi.h
There was a problem hiding this comment.
ment MINOR version if you add backwards compatible features or
changes. PATCH should be reset to 0.
OK, let me bump it to 3.19.0 then.
| * enabled before accessing the SoundWire SHIM registers | ||
| */ | ||
| if (!sdev->first_boot) | ||
| hda_sdw_process_wakeen(sdev); |
There was a problem hiding this comment.
lines 354..383 look like copy/paste. can we avoid this please? At the very least introduce helpers for SSP and SoundWire.
There was a problem hiding this comment.
lines 354..383 look like copy/paste. can we avoid this please? At the very least introduce helpers for SSP and SoundWire.
Um, I thought about this, then I didn't want to change the sequence (e.g. to move SSP/SDW to the last) to introduce unexpected risk and that's why you see this...
Since you are confirming the SSP/SDW can be moved to the very last, let me share that part to avoid copy/paste here.
There was a problem hiding this comment.
I am not confirming anything wrt SSP/SDW, you need to keep the same order as before, but call a helper. Having duplicated code and comments isn't good.
There was a problem hiding this comment.
I am not confirming anything wrt SSP/SDW, you need to keep the same order as before, but call a helper. Having duplicated code and comments isn't good.
got you.
| * is initialized successfully, which ensures power rails are | ||
| * enabled before accessing the SoundWire SHIM registers | ||
| */ | ||
| if (!sdev->first_boot) |
There was a problem hiding this comment.
what is the definition of 'first_boot' if we don't re-initialize the firmware?
There was a problem hiding this comment.
what is the definition of 'first_boot' if we don't re-initialize the firmware?
We are only not re-downloading the firmware, the first/second/... FW boot concept are kept intact?
There was a problem hiding this comment.
my point was: be careful and check for all usages of 'first boot'. In the past we would download and authenticate the firmware at every resume, now only at first boot. It's a legitimate question to revisit all usages of first_boot to make sure we don't forget about something.
There was a problem hiding this comment.
my point was: be careful and check for all usages of 'first boot'. In the past we would download and authenticate the firmware at every resume, now only at first boot. It's a legitimate question to revisit all usages of first_boot to make sure we don't forget about something.
Got you, let me list all of those usages below to relax us about that.
The first_boot is initialize to be 'true' and changed to 'false' once the probing succeed in core.c, all remain usages of 'first boot' is reading:
in hda-loader.c, 3 usages:
hda-loader.c:406, hda_sdw_process_waken() called for resuming boot, kept unchanged in my PR.
hda-loader.c:463, 487, hda_sdw_startup() called at post_fw_run() for first boot only, I think we don't need it for resuming case, even we don't re-download the FW, @bardliao @RanderWang @plbossart can you help to confirm this?
in loader.c, we basically use first_boot to decide if requesting firmware, creating debugfs and parsing fw_ready message is needed, we still don't need those (as previous) with the change here.
in pm.c:100, first_boot is used to check if sof_resume() should be performed, if the first_boot is true, it means the probing was not succeed so sof_resume() still no needed.
in trace.c:485, first_boot is used for creating trace related debugfs entries, we don't need create them for resuming boot, this is not changed.
$ grep first_boot sound/soc/sof/* -rn
sound/soc/sof/core.c:222: sdev->first_boot = false;
sound/soc/sof/core.c:270: sdev->first_boot = true;
sound/soc/sof/core.c:303: sdev->first_boot = true;
sound/soc/sof/intel/hda-loader.c:406: if (!sdev->first_boot)
sound/soc/sof/intel/hda-loader.c:463: if (sdev->first_boot) {
sound/soc/sof/intel/hda-loader.c:487: if (sdev->first_boot) {
sound/soc/sof/loader.c:66: if (sdev->first_boot) {
sound/soc/sof/loader.c:190: if (sdev->first_boot)
sound/soc/sof/loader.c:230: if (sdev->first_boot && elem->value)
sound/soc/sof/loader.c:495: if (!sdev->first_boot)
sound/soc/sof/loader.c:795: if (sdev->first_boot) {
sound/soc/sof/pm.c:100: if (sdev->first_boot)
sound/soc/sof/sof-priv.h:396: bool first_boot;
sound/soc/sof/trace.c:485: if (sdev->first_boot) {
| if ((sdev->fw_ready.flags & SOF_IPC_INFO_IMR_RESTORE) && | ||
| !sdev->first_boot) { | ||
| dev_info(sdev->dev, "info: IMR restore supported, booting from IMR directly\n"); | ||
| return hda_dsp_boot_imr(sdev); |
There was a problem hiding this comment.
what happens if we override this IMR_RESTORE configuration. Can we still go ahead and proceed with the default path?
This should be an opt-in solution IMHO. Changing the flows will mechanically lead to bugs, so by default users who upgrade the firmware should not see a change on how the DSP is managed.
There was a problem hiding this comment.
what happens if we override this IMR_RESTORE configuration. Can we still go ahead and proceed with the default path?
Yes, if the driver choose to re-downloading, even the IMR_RESTORE is declared support from the fw_ready, we will still go ahead with today's path.
This should be an opt-in solution IMHO. Changing the flows will mechanically lead to bugs, so by default users who upgrade the firmware should not see a change on how the DSP is managed.
Um, that's what I commented above, do you suggest a kconfig item or a module param here?
There was a problem hiding this comment.
@plbossart This can also fix issues, so not sure if this should be opt-in. If tests look good, we could just make this the default and offer an opt-out in case an issue is hit.
There was a problem hiding this comment.
@kv2019i yes, that's what I meant, opt-out/disable similar to pm_runtime or dynamic pipelines.
There was a problem hiding this comment.
So let me add a kconfig item and the check will be like this:
if ((sdev->fw_ready.flags & SOF_IPC_INFO_IMR_RESTORE) &&
!CONFIG_SND_SOC_SOF_DEBUG_DISABLE_IMR_RESTORE &&
!sdev->first_boot) {There was a problem hiding this comment.
@keyonjie @plbossart I'd vote for a module option. If this causes a regression, user can easily add a modprobe.d option, but having to roll out a custom kernel for a specific system is too difficult. And we have to too many Kconfig options. If there are many, we should have a quirk table in driver to make the default sane for most systems (as the module option is not scalable either).
There was a problem hiding this comment.
agree with @kv2019i we already have sof_debug quirks as a module parameter, let's add one bit to disable IMR reload.
| * is initialized successfully, which ensures power rails are | ||
| * enabled before accessing the SoundWire SHIM registers | ||
| */ | ||
| if (!sdev->first_boot) |
There was a problem hiding this comment.
On a similar note, when is the firmware preserved in IMR?
D3/S0 aka pm_runtime_suspend or RTD3?
D3/S3 aka system suspend/hibernate?
There was a problem hiding this comment.
On a similar note, when is the firmware preserved in IMR?
D3/S0 aka pm_runtime_suspend or RTD3?
D3/S3 aka system suspend/hibernate?
Per my understanding, it is preserved in case the DDR is with power, so yes for both D3/S0 and D3/S3.
I am not quite sure about the S4 (Suspend-to-Disk) case though, what do you think about that?
There was a problem hiding this comment.
That's for you to find out @keyonjie, and it goes back to my question on 'first-boot'. It's rather important to know when the IMR is preserved and when it's not.
There was a problem hiding this comment.
That's for you to find out @keyonjie, and it goes back to my question on 'first-boot'. It's rather important to know when the IMR is preserved and when it's not.
Since I can't find a platform that support S4 hibernation at my end, will try this later.
kv2019i
left a comment
There was a problem hiding this comment.
Excellent @keyonjie ! I do think we need to to bump the minor version and we'd need to come up some way to rename the flag name. Either make it generic (IMR is Intel specific) or use some vendor specific method to pass info (ext-manifest). I think this is generally useful indication, so maybe we can just rename the flag.
| #define SOF_IPC_INFO_LOCKS BIT(1) | ||
| #define SOF_IPC_INFO_LOCKSV BIT(2) | ||
| #define SOF_IPC_INFO_GDB BIT(3) | ||
| #define SOF_IPC_INFO_IMR_RESTORE BIT(4) |
There was a problem hiding this comment.
@keyonjie Yes, but it's still extending the public interface so
"Increment MINOR version if you add backwards compatible features or
changes. PATCH should be reset to 0." applies. https://github.com/thesofproject/sof/blob/main/src/include/kernel/abi.h
| if ((sdev->fw_ready.flags & SOF_IPC_INFO_IMR_RESTORE) && | ||
| !sdev->first_boot) { | ||
| dev_info(sdev->dev, "info: IMR restore supported, booting from IMR directly\n"); | ||
| return hda_dsp_boot_imr(sdev); |
There was a problem hiding this comment.
@plbossart This can also fix issues, so not sure if this should be opt-in. If tests look good, we could just make this the default and offer an opt-out in case an issue is hit.
| hda_dsp_ipc_int_enable(sdev); | ||
|
|
||
| /* | ||
| * When a SoundWire link is in clock stop state, a Slave |
There was a problem hiding this comment.
IIRC the standard vocabulary has been updated?
There was a problem hiding this comment.
IIRC the standard vocabulary has been updated?
Not quite sure if it has been updated for SDW part, @plbossart should I s/Slave/secondary ?
commented
Jun 15, 2021
|
@kv2019i @plbossart @lyakh updated with most comments addressed. |
left a comment
There was a problem hiding this comment.
Looks good now. Only thing left is for us to agree on the opt-out mechanism. Currently patch has none, @keyonjie has proposed Kconfig and now made inline comment that I'd prefer a module parameter.
|
|
||
| if ((sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) && | ||
| !sdev->first_boot) { | ||
| dev_info(sdev->dev, "info: IMR restore supported, booting from IMR directly\n"); |
There was a problem hiding this comment.
This will a very frequent and normal flow, so dev_info() is too verbose. Maybe dev_dbg() for this.
| if ((sdev->fw_ready.flags & SOF_IPC_INFO_IMR_RESTORE) && | ||
| !sdev->first_boot) { | ||
| dev_info(sdev->dev, "info: IMR restore supported, booting from IMR directly\n"); | ||
| return hda_dsp_boot_imr(sdev); |
There was a problem hiding this comment.
@keyonjie @plbossart I'd vote for a module option. If this causes a regression, user can easily add a modprobe.d option, but having to roll out a custom kernel for a specific system is too difficult. And we have to too many Kconfig options. If there are many, we should have a quirk table in driver to make the default sane for most systems (as the module option is not scalable either).
commented
Jun 15, 2021
|
Removed "[RFC]" as this is no longer a draft. |
commented
Jun 16, 2021
|
@kv2019i @plbossart module option added. |
commented
Jun 16, 2021
|
SOFCI TEST |
commented
Oct 13, 2021
|
SOFCI TEST |
1 similar comment
commented
Oct 13, 2021
|
SOFCI TEST |
commented
Oct 13, 2021
|
This need to go after FW PR thesofproject/sof#4386 |
| sdev->enabled_cores_mask |= chip->init_core_mask; | ||
| mask = sdev->enabled_cores_mask; | ||
| for_each_set_bit(j, &mask, SOF_MAX_DSP_NUM_CORES) | ||
| sdev->dsp_core_ref_count[j]++; |
There was a problem hiding this comment.
@keyonjie I was not able to understand the difference with the first boot where this code is used
/* step 1: power up corex */
ret = hda_dsp_enable_core(sdev, chip->host_managed_cores_mask);init_core_mask, enable_cores_mask, host_managed_cores_mask, that looks like a recipe for bugs.
There was a problem hiding this comment.
@keyonjie I was not able to understand the difference with the first boot where this code is used
/* step 1: power up corex */ ret = hda_dsp_enable_core(sdev, chip->host_managed_cores_mask);init_core_mask, enable_cores_mask, host_managed_cores_mask, that looks like a recipe for bugs.
It could be, but that is not introduced by this PR, no?
| int ret; | ||
|
|
||
| /* init for booting wait */ | ||
| init_waitqueue_head(&sdev->boot_wait); |
There was a problem hiding this comment.
this is not needed. In fact it should be removed from hda_dsp_cl_boot_firmware() as well. snd_sof_run_firmware() already does it
There was a problem hiding this comment.
this is not needed. In fact it should be removed from hda_dsp_cl_boot_firmware() as well. snd_sof_run_firmware() already does it
What you mentioned could be true, but that should belong to another PR? Here the PR is just following what the hda_dsp_cl_boot_firmware() does.
There was a problem hiding this comment.
no I think we should remove it from here. We can remoe it from hda_dsp_cl_boot_firmware() in another PR
| } | ||
|
|
||
| /* set enabled cores mask and increment ref count for cores in init_core_mask */ | ||
| sdev->enabled_cores_mask |= chip->init_core_mask; |
There was a problem hiding this comment.
@keyonjie paranoia check here: I hope you have checked that this is OK to do i.e just power up the init_core_mask. When we download the fw, we power up all cores and then power down ~init_core_mask cores.
There was a problem hiding this comment.
@keyonjie paranoia check here: I hope you have checked that this is OK to do i.e just power up the init_core_mask. When we download the fw, we power up all cores and then power down ~init_core_mask cores.
Yes, the CI test showed me that we actually don't need to power up other Cores not covered by init_core_mask.
There was a problem hiding this comment.
@keyonjie you should base your results on the hardware recommended sequences, not experimental results from a small set of devices in the CI pool. That really doesn't inspire confidence if I'm honest.
There was a problem hiding this comment.
@keyonjie you should base your results on the hardware recommended sequences, not experimental results from a small set of devices in the CI pool. That really doesn't inspire confidence if I'm honest.
That's a good point, I didn't find any hardware-recommended sequences mentioning that we have to power on all DSP cores at the booting, @ranj063 did you?
commented
Nov 24, 2021
|
@keyonjie could you please run a daily test with this PR? |
516422d to
01cee21
Compare
commented
Nov 26, 2021
|
@ranj063 @plbossart looks it doesn't build anymore with simple rebasing, will work on it later. |
commented
Dec 1, 2021
@keyonjie let us know when this is ready for review! |
584afd2 to
fb23c7c
Compare
commented
Dec 10, 2021
|
@ranj063 @plbossart ready for review now. |
|
@ranj063 @plbossart @lgirdwood to test IMR restore feature, we need to config CONFIG_CAVS_IMR_D3_PERSISTENT for each platforms intended to use that, the CI test report is here: you will see dmesg log "IMR restore supported, booting from IMR directly" which means IMR restore is used there. |
commented
Dec 10, 2021
|
@mengdonglin are we able to test with this config from Keyon after v2/v1.9.3 validation is complete ? |
| #define SOF_IPC_INFO_LOCKS BIT(1) | ||
| #define SOF_IPC_INFO_LOCKSV BIT(2) | ||
| #define SOF_IPC_INFO_GDB BIT(3) | ||
| #define SOF_IPC_INFO_D3_PERSISTENT BIT(4) |
There was a problem hiding this comment.
Can you also fix the typos in the commit message: "Add a bit to denote if the FW supports the IMR..." and Firmware in all small-case in the second line.
|
|
||
| #define HDA_CL_STREAM_FORMAT 0x40 | ||
|
|
||
| static void hda_set_ssps_slave(struct snd_sof_dev *sdev) |
There was a problem hiding this comment.
typos in commit message: "Move the SSP DAI's slave mode set function to the hda_set_ssps_slave() helper and the SDW wakeen interrupt enabling to the hda_sdw_wakeen_resume() helper"
|
|
||
| #define HDA_CL_STREAM_FORMAT 0x40 | ||
|
|
||
| static void hda_set_ssps_slave(struct snd_sof_dev *sdev) |
There was a problem hiding this comment.
maybe call this function hda_ssp_resume()? then it will avoid using "slave" and it will leave the door open to move other things into it
| } | ||
| } | ||
|
|
||
| static void hda_sdw_wakeen_resume(struct snd_sof_dev *sdev) |
There was a problem hiding this comment.
same here drop the wakeen from the function name
| int ret; | ||
|
|
||
| /* init for booting wait */ | ||
| init_waitqueue_head(&sdev->boot_wait); |
There was a problem hiding this comment.
no I think we should remove it from here. We can remoe it from hda_dsp_cl_boot_firmware() in another PR
| /* power up & unstall/run the cores to run the firmware */ | ||
| ret = hda_dsp_enable_core(sdev, chip->init_core_mask); | ||
| if (ret < 0) { | ||
| dev_err(sdev->dev, "error: dsp core start failed %d\n", ret); |
There was a problem hiding this comment.
yes, it could be superfluous, but aligns to all error prints in this file?
There was a problem hiding this comment.
no we're slowly moving away from the error prefix. so no new ones please
| return ret; | ||
| } | ||
|
|
||
| static int hda_dsp_boot_imr(struct snd_sof_dev *sdev) |
There was a problem hiding this comment.
you call it IMR restore support with no mention on it in the code anywhere. The code has only references to D3_PERSISTENT. Can we just stick to that in the commit messages as well so that reader don't get confused. Also I think PERSISTENT_D3 sounds more intuitive than D3_PERSISTENT. D3_PERSISTENT sounds like the D3 state will be persistent.
There was a problem hiding this comment.
acutally if I read back my own comment, both of them convey the same message. Maybe we should call it IMR_PERSISTENT_D3 or something similar to say whats persistent in D3
There was a problem hiding this comment.
Per my understanding, the IMR D3 persistency is our system behavior and should not be configurable, but either to use the IMR restoring feature or not is configurable.
Yes, the naming SOF_IPC_INFO_D3_PERSISTENT is somewhat confusing with respect to what I mentioned above, it should be SOF_IPC_INFO_IMR_RESTORE_SUPPORT, but since the naming is already quite long, and it needs to align to the existed FW side also, I would suggest keeping it at the moment and change it later from both side if needed.
Add a bit definition to the fw_ready message, to denote if the FW supports the IMR (Isolated Memory Region) restoring feature. If the bit is set, the driver can skip downloading the firmware again during system resume or runtime resume. Bump the ABI version to 3.19 to make it aligned with FW side. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Move the SSP slave mode set function to the hda_set_ssps_slave() helper and the SDW wakeen interrupt enabling to the hda_sdw_resume() helper, then these helpers can be shared to different callers later. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
9371cdd to
e6a20b5
Compare
If the firmware declares the IMR restore feature, we only need to do a simple powering up for resuming from the suspended state, no firmware re-downloading needed. Add a helper hda_dsp_boot_imr() for this simple DSP rebooting, and use it when it is available. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Add flag _IGNORE_D3_PERSISTENT to disable IMR restore feature to the sof_debug module parameter. The IMR restore feature will be enabled for all Intel cAVS platforms by default, but setting the flag _IGNORE_D3_PERSISTENT can help to disable the feature for debug purpose, to rule out any possible regression introduced by the change of not re-downloading firmware to the DSP at resuming from suspended state. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
e6a20b5 to
34992b3
Compare
commented
Dec 14, 2021
|
the latest feature test result here: https://sof-ci.sh.intel.com/#/result/planresultdetail/8877 |
| int ret, ret1, i; | ||
|
|
||
| if ((sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) && | ||
| !(sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) && |
There was a problem hiding this comment.
this patch has to be squashed with the previous one no? Because we'd enable it by default in the previous one and only disable it based on the module param in this one
There was a problem hiding this comment.
my design here is to enable it by default if the FW claims it supports the feature. So this subsequent module param is only adding an interface to disable using the FW feature on the host side, for debugging purposes only.
left a comment
There was a problem hiding this comment.
looks good @keyonjie. I'd like the lat 2 patches to still be squashed but I'll leave that for others to comment.
| SSP_SET_SLAVE, | ||
| SSP_SET_SLAVE); | ||
| } | ||
| hda_ssp_resume(sdev); |
There was a problem hiding this comment.
the commit message mentions a different name so that needs to be modified.
what was wrong with hda_set_ssps_slave()?
There was a problem hiding this comment.
this calls SSP_SET_SLAVE...
I am all for inclusive terms, but this has nothing to do with resume operations.
There was a problem hiding this comment.
this calls SSP_SET_SLAVE...
I am all for inclusive terms, but this has nothing to do with resume operations.
I think Ranjani means "what we need to perform to SSPs when resuming audio device (D3->D0)", like "_ssp_at_resume()". And, use the more generic _ssp_resume() will be friendly to add more SSP related reset/resume/init stuff into it in future when needed.
I am fine on both, just let me know the aligned one.
There was a problem hiding this comment.
just because we do set_slave doesnt mean we have to name the function that too no? Someday maybe set_slave will get renamed and we wont have to worry about the static function name having the word"slave" in it. But I agree resume is a bad name. This is the loader, so while it is also called during resume, thats not the only thing. Why not call is something lika hda_ssp_cl_init() and hda_sdw_cl_init()
There was a problem hiding this comment.
the acronym we came up with is CBP Codec BitClockProvider, so we can call this wrapper
hda_ssp_set_cbp()
if it also sets the fsync hda_ssp_set_cbp_cfp().
and no wrapper for SoundWire (see comment below) would be my preference.
There was a problem hiding this comment.
sound/soc/sof/intel/hda-loader.c: SSP_SET_SLAVE,
sound/soc/sof/intel/hda-loader.c: SSP_SET_SLAVE);
sound/soc/sof/intel/hda.h:#define SSP_SET_SLAVE (SSP_SET_SCLK_SLAVE | SSP_SET_SFRM_SLAVE)
This should be SSP_SET_CBP_CFP
| */ | ||
| if (!sdev->first_boot) | ||
| hda_sdw_process_wakeen(sdev); | ||
| hda_sdw_resume(sdev); |
There was a problem hiding this comment.
we could move the !sdev->first_boot inside the helper, no need to add a new definition that's rather misleading.
There was a problem hiding this comment.
we could move the !sdev->first_boot inside the helper, no need to add a new definition that's rather misleading.
checking sdev->first_boot inside hda_sdw_process_wakeen() sounds a bit odd to me, @plbossart do you really want that?
There was a problem hiding this comment.
I actually don't see a need for a new wrapper here, just use
if (!sdev->first_boot)
hda_sdw_process_wakeen(sdev);
twice...
There was a problem hiding this comment.
actually the imr stuff only happens after the first boot so the test is not needed ... really no need for a wrapper.
| */ | ||
| #define SOF_DBG_PRINT_ALL_DUMPS BIT(6) /* Print all ipc and dsp dumps */ | ||
| #define SOF_DBG_IGNORE_D3_PERSISTENT BIT(7) /* ignore the DSP D3 persistent capability | ||
| * and always do FW downloading at resume |
There was a problem hiding this comment.
and always download firmware upon D3 exit.
This simply series implement the IMR restoring feature from the Linux side.
It is verified on cAVS platforms.
After switching to IMR restoring, the resuming boot time is decreased significantly:
e.g.