-
Notifications
You must be signed in to change notification settings - Fork 140
ASoC: SOF: refine suspend_ignored flag #1524
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
Conversation
Yes, it came from yours, sorry about missing your authorship here as I split it from the big local change here, correcting it now.
Yes, your 2nd commit goes further, but I want it to go even further when with S0 D0I3 support enabled, all these are already done on my side, I am refining remained local changes(there might be 5~8 commits) and will submit them soon. |
@keyonjie dont worry about authorship. not a big deal, we're the same team. lets put all patches in one PR. It will be hard to see the entire picture if you split them up. |
|
@ranj063 @plbossart OK, I will submit S0 D0i3 support commits here together. |
|
@ranj063 @plbossart S0 D0I3 is implemented now, please help review. |
sound/soc/sof/sof-priv.h
Outdated
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.
@keyonjie this patch is just difficult to understand "ASoC: SOF: refine DSP power states". Care to break it down?
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.
sure, let me move these macro definitions to a separated patch.
sound/soc/sof/sof-priv.h
Outdated
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 comment makes no sense. Is the DSP in D0 or D3?
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 like this?
/* 1 -- dsp is in D0, 0 -- dsp is in D3 */
sound/soc/sof/sof-priv.h
Outdated
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 am not a big fan of bit masks for dsp state. Its not like you could have 2 bits set at the same time. Enum is a lot more intuitive.
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.
Plus don't invent new definitions. I3 does not exist, it's D0i3.
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 @plbossart let me do this in another way in the coming update version.
sound/soc/sof/pm.c
Outdated
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 you should move this to snd_sof_dsp_suspend() as well.
sound/soc/sof/topology.c
Outdated
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 dont change this. let it be 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.
oops, I don't know why I changed this, fix it now.
sound/soc/sof/pm.c
Outdated
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. should be moved to snd_sof_dsp_resume()
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, actually.
sound/soc/sof/intel/hda.c
Outdated
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.
@keyonjie this looks incorrect. Typically when you remove the SOF device, you resume it and bring it back to full power. So the DSP cant be in D3.
Besides reset is hardly intuitive to convey the message that the DSP is in D3. please change the 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.
@keyonjie this looks incorrect. Typically when you remove the SOF device, you resume it and bring it back to full power. So the DSP cant be in D3.
Really? Why we need to keep it in full power if it is not used?
Besides reset is hardly intuitive to convey the message that the DSP is in D3. please change the name.
@ranj063 what name do you suggest to use? My understanding "reset to xxx state" is quite common?
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.
@keyonjie I dont know in my opinion, the mutex isnt required, so just set the power state directly here and remove the init/reset functions
sound/soc/sof/intel/hda.h
Outdated
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 am also not able to fully appreciate the need for this mutex, at least just yet while reviewing only the second patch of the series. We only set the power states during suspend/resume and they can never overlap
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.
they could be set in IPC sending and PCM open/close also in the subsequent patches.
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.
@keyonjie that was my other comment, why do we need to do it in PCM open/close, can we not do it just when we send the IPC?
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.
@keyonjie This is not a simple lock. In the comment this indicates the lock protects "dsp_power_state", but reading the code, the lock actually covers DSP power state as well. E.g. if you change the DSP power state, you need to hold this lock. Do we really need, or is a lock protecting just the dsp_power_state enough (and if yes, do we need a lock at all)?
sound/soc/sof/intel/hda-pcm.c
Outdated
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.
@keyonjie which "SOF specific information" do you need easy access to. Neither the patch nor the commit message make it clear
sound/soc/sof/intel/hda-dsp.c
Outdated
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.
"delay D0i3" you mean D0i3 in S0?
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, let me change the comment.
sound/soc/sof/intel/hda-pcm.c
Outdated
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.
Do you really need this here? You can do this after IPC TX 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.
Here is PCM open, Do you mean doing it after trigger start IPC, in pcm_trigger?
sound/soc/sof/intel/hda.c
Outdated
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.
don't you also need to cancel this work during system suspend?
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 mean D0I3 suspend? that is already covered by hda_dsp_suspend()->hda_dsp_set_power_state() here:
case SOF_DSP_STATE_D0I3:
/* First Cancel any pending attempt to put DSP to D0i3 */
cancel_delayed_work_sync(&hda->d0i3_work);
/* disable DMA trace for no delay D0I3 */
ret = hda_dsp_set_d0i3(sdev, HDA_PM_NO_DMA_TRACE);
sound/soc/sof/intel/hda-dsp.c
Outdated
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.
There's too much in common between set D0i0 and set_D0i3. I think we can unify these 2 functions.
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.
um, 3 biggest differences that why I split them, the 1st is that we only need delayed work for set D0I3(not for set D0I0), the 2nd one is that we need opposite sequence of IPC sending and register setting, and the 3rd one is that we need vary POWER_GATE IPC flags for D0I3 only.
sound/soc/sof/intel/hda-dsp.c
Outdated
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 change really necessary? You'd always send the pm_date_ipc before the DSp is put in D0i3, isnt 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.
It is needed, without this x_nopm() helpers, it will wake up the DSP to D0I0 before sending the pm_gate_ipc.
|
WoW, looks this will become another 200+ comments PR easily, if I reply them one by one, :). I prefer to update to a new version firstly next week when I am back to Shanghai. |
I don't mean to sound rude but if you have 200+ comments you probably need to recheck this PR on your own and resubmit when it's mature. |
That's true, thanks for reminding. |
|
@plbossart @ranj063 Happy thanks giving day! I think I addressed most of the comments in the updated version, hope you like this version. I talked with @RanderWang and realize that we might need to change to put Audio DSP to D0I3 for runtime suspend, but I think there is no conflict with what I implemented here, though it might be possible to combine these 2 scenarios with change in ASoC PCM handling(I did this try at the very beginning of my start of the D0Ix task in #1154), some people might not like this solution as it change the component device RT PM logic in soc-dpcm.c when most of their platform actually don't need that extra logic. |
sound/soc/sof/intel/hda-dsp.c
Outdated
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.
@keyonjie I'm going to leave a long comment about the changes in this commit.
-
The checks for power state inside the set_D0i0/set_D0i3 are a bit of an overkill. In reality, there are only 2 options: enter D0i3 or exit D0i3. Entering is always from D0, you'd never really see the case where you're trying to enter D0i3 from D3. Likewise, exiting D0i3 is only possible if you're already in D0i3. Otherwise, it would be a system resume or a runtime resume.
-
I still do not appreciate the mutex. The commands to enter/exit D0i3 are already protected by waiting for the CIP timeout. Do we really need a mutex for just setting the hda->dsp_power_state? This is not really a register write. Maybe @kv2019i and @plbossart can correct me if I am wrong
-
The bit masks for the power states are also not pretty. There are 3 states, why cant we just simply use an enum instead of setting a D0 bit along with I3 bit? Makes it a lot easier to understand
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.
@keyonjie I'm going to leave a long comment about the changes in this commit.
- The checks for power state inside the set_D0i0/set_D0i3 are a bit of an overkill. In reality, there are only 2 options: enter D0i3 or exit D0i3. Entering is always from D0, you'd never really see the case where you're trying to enter D0i3 from D3. Likewise, exiting D0i3 is only possible if you're already in D0i3. Otherwise, it would be a system resume or a runtime resume.
That's true, but since the enum dsp_power_state can have the D3 value, we only implement the helpers here, we can't make sure the caller will use it correctly always?
Safe check is a compromise, some scenarios might never happen(e.g. D3->D0I3 entry, D3->D0I3 exit), some might happen via error used(e.g. D0I3->D0I3 entry, D0->D0I3 exit).
I preferred to add these check here to avoid critical errors happen or disordering the state(e.g. if we do try doing D3->D0I3), but I am fine if both you and @plbossart think we should remove the D3 check.
- I still do not appreciate the mutex. The commands to enter/exit D0i3 are already protected by waiting for the CIP timeout. Do we really need a mutex for just setting the hda->dsp_power_state? This is not really a register write. Maybe @kv2019i and @plbossart can correct me if I am wrong
I introduced the mutex as I think we could have race in setting and getting this dsp_power_state, especially considering that the hda_dsp_set_d0i3() could be a delayed work which could run in another thread.
- The bit masks for the power states are also not pretty. There are 3 states, why cant we just simply use an enum instead of setting a D0 bit along with I3 bit? Makes it a lot easier to understand
The key point here is that sometimes the caller(e.g. after a normal IPC sent) actually don't know which state it should put the DSP to, I introduce a command SOF_DSP_STATE_SET_AUTO here for these scenarios. So the rule here is only using command when calling hda_dsp_set_power_state(), and leave the DSP state change decision to the dsp state management logic(inside hda-dsp.c) only.
enum sof_dsp_state {
SOF_DSP_STATE_D3 = 0,
SOF_DSP_STATE_D0 = SOF_DSP_STATE_BIT_D0,
SOF_DSP_STATE_D0I3 = SOF_DSP_STATE_BIT_D0 | SOF_DSP_STATE_BIT_I3,
};
enum sof_dsp_state_cmd {
SOF_DSP_STATE_SET_D3 = SOF_DSP_STATE_D3,
SOF_DSP_STATE_SET_D0 = SOF_DSP_STATE_D0,
SOF_DSP_STATE_SET_D0I3 = SOF_DSP_STATE_D0I3,
SOF_DSP_STATE_SET_AUTO = SOF_DSP_STATE_BIT_UPDATE,
};
plbossart
left a comment
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.
sound/soc/sof/pm.c
Outdated
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 direction is not quite right.
It turns out that for SoundWire we do have to keep the DSP powered if we want to avoid complete re-enumeration when exiting clock stop. This could happen in the complete absence of 'D0i3 compatible' streams.
this is really missing an idle loop detection that is based on
a) D0i3-compatible streams being opened
b) no IPC for a while
c) the state of child devices, e.g. if a SoundWire master remains 'active' preventing pm_runtime entry.
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.
@plbossart I didnt quite understand this ask. The change here only really affects system suspend when there are D0i3-compatible streams running in the DSP. Are you saying that we also need to account for the fact that the SDW master could be active?
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 I am saying is that while doing a system suspend, the device may already be in D0i3 and remain there (S0 target) or move to D3 (S3 target).
The use of refcounts would be quite misleading here, it's only one of the reasons why the device might remain in D0i3.
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.
@plbossart agreed wrt the WoV usecase this is the only reason that the DSP would remain in D0i3. Maybe we're missing the line of sight for the other possible indicators for this. Can we possibly think of adding this in a separate PR?
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.
well no. You remove a criterion to replace it by a refcount, we are not going to modify this again later to come back to another criterion. We need to respect the time of reviewers...
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.
Hi @plbossart @ranj063 so the state machine could be updated like this:
/*
* Audio DSP states may transform as below:+
*
* +---------------------+ runtime resume
* | <---------------------+
* +------------> | runtime suspend |
* | | D0(active) +----------------+ |
* | | +------------+ | |
* | +----+ | D0I3 | | |
* | | +-------^----+----^-- + compatible| | |
* | | | | | stream | | |
* |resume | | | | opened | | |
* | from | D3 | | | only | | |
* | D3 |suspend | | | | | |
* | | | | |The last | | |
* | | | | |opened D0i3 | | |
* | | | | |compatible | | |
* | | | | |stream closed | | |
* +-+-------v-------+ | | | +---v---v----+---+
* | | | | +------------+ |
* | D3 (suspended) | | | D0I3 suspend | D0I3 |
* | | | +-----------------> +---+
* | | +----------------------+ | |
* +-------^---------+ resume from +----------------+ |
* | D0I3 suspend |
* | D3 suspend |
* +----------------------------------------------------------+
*
* d0i3_suspend = s0_suspend && D0I3 stream opened,
* D3 suspend = !d0i3_suspend,
*/
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.
@keyonjie are you saying that you'd never enter D3 during runtime suspend then>?
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, @ranj063 enter to D0I3 only for runtime suspend, if the platform doesn't support D0I3, the power gating will still work when it is not used, for power saving.
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.
NAK, runtime suspend and D0i3 are mutually incompatible.
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.
@plbossart can you help guide how the state machine should look like in your brain?
kv2019i
left a comment
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.
Late to the review, but a few specific comments (on new locks and refcounts), please see inline.
sound/soc/sof/pm.c
Outdated
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.
Hey, I wasn't on the review list, so I'm a bit late to this. I'm not thrilled about adding a refcount, especially as the places in code where it is incremented and decremented, have a lot of additional conditional logic of their own. When/if something goes wrong, it seems painful to debug where the refcount went wrong. With old snd_sof_dsp_d0i3_on_suspend(), you at least have a single place to check which stream is in unexpected state. And a place to add new logic that can keep DSP at D0i3.
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.
Hey, I wasn't on the review list, so I'm a bit late to this. I'm not thrilled about adding a refcount, especially as the places in code where it is incremented and decremented, have a lot of additional conditional logic of their own. When/if something goes wrong, it seems painful to debug where the refcount went wrong. With old snd_sof_dsp_d0i3_on_suspend(), you at least have a single place to check which stream is in unexpected state. And a place to add new logic that can keep DSP at D0i3.
Yes, @plbossart also mentioned about this, my opinion is that if the criteria we can foresee is only that "the count of D0I3 compatible streams being suspend > 0", I agree with @ranj063 that using this simple refcount is fine, but if we can foresee that we need to add some other criteria (e.g. for SDW) for D0I3 entry, yes, I agree with you and @plbossart here.
sound/soc/sof/intel/hda.h
Outdated
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.
@keyonjie This is not a simple lock. In the comment this indicates the lock protects "dsp_power_state", but reading the code, the lock actually covers DSP power state as well. E.g. if you change the DSP power state, you need to hold this lock. Do we really need, or is a lock protecting just the dsp_power_state enough (and if yes, do we need a lock at all)?
Yes, the intention is to protect the whold DSP power state change process. |
Thanks for review @kv2019i, it comes in time we are still in discussion and I just get myself free from other higher priority issues. |
Refine the DSP power states to prepare for adding S0 D0I3 support: 1. use bit masks for states and state set command definition. 2. move DSP state from struct snd_sof_dev to struct sof_intel_hda_dev. 3. add mutex to protect the DSP power state access. 4. specify the target power state for platform suspend. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Switch to pass snd_sof_pcm_stream to snd_sof_pcm_platform_open/close, with which we can retrieve sof specific information easier. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
To add D0I3 at S0 support, we add counts to count the opened stream and d0i3 compatible stream, when only d0i3 compatible streams are opened, we will try to put audio DSP to D0I3 low power state. To avoid frequent switching between D0 and D0I3, add a delayed work to perform the D0->D0I3 switching task. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
For most of the messages, we are using sof_ipc_tx_message() to transmit them to FW, add PM handling to make sure the transmitting will happen on D0 state. For some compact IPC messages, we can transmit them at either D0 or D0I3 state, create a new helper sof_ipc_tx_message_nopm() to handle this kind of IPC transmission. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
The PM_GATE IPC is compact one and we don't need mailbox access during transmitting it to FW, switch to use nopm mode for it. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
|
@plbossart @ranj063 @kv2019i the PR is updated with removing adding the d0i3_suspend_cnt(and keep using the helper snd_sof_dsp_d0i3_on_suspend() which can be extended for SDW later), I keep the usage of the mutex to protect the DSP power state access and the state changing itself as the state change can take long time during the delayed_work, e.g. if we forget to cancel the delayed work before trying to clear/reset the state, this mutex will help to reject this kind of operation. |
@keyonjie I am not going to review 2 PRs for the same things. Please work with @ranj063 and suggest a common solution. |
|
#1631 will be the replacement for this, closing this one. |
ASoC: SOF: refine suspend_ignored flag
Move the flag from snd_sof_pcm_stream to snd_sof_dev, use count to store
the number of d0i3 compatible streams being suspended, and then we don't
need the helper snd_sof_dsp_d0i3_on_suspend() anymore.