Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 150
Simplify S0ix implementation #1481
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -339,13 +339,17 @@ static int hda_dsp_send_pm_gate_ipc(struct snd_sof_dev *sdev, u32 flags) | ||
| } | ||
| int hda_dsp_set_power_state(struct snd_sof_dev *sdev, | ||
| enum sof_d0_substate d0_substate) | ||
| enum sof_dsp_power_state state) | ||
| { | ||
| struct hdac_bus *bus = sof_to_bus(sdev); | ||
| u32 flags; | ||
| int ret; | ||
| u8 value; | ||
| /* Nothing to do for D3 */ | ||
| if (state == SOF_DSP_D3) | ||
| return 0; | ||
| /* Write to D0I3C after Command-In-Progress bit is cleared */ | ||
| ret = hda_dsp_wait_d0i3c_done(sdev); | ||
| if (ret < 0) { | ||
| @@ -354,7 +358,7 @@ int hda_dsp_set_power_state(struct snd_sof_dev *sdev, | ||
| } | ||
| /* Update D0I3C register */ | ||
| value = d0_substate == SOF_DSP_D0I3 ? SOF_HDA_VS_D0I3C_I3 : 0; | ||
| value = state == SOF_DSP_D0I3 ? SOF_HDA_VS_D0I3C_I3 : 0; | ||
| snd_hdac_chip_updateb(bus, VS_D0I3C, SOF_HDA_VS_D0I3C_I3, value); | ||
| /* Wait for cmd in progress to be cleared before exiting the function */ | ||
| @@ -367,7 +371,7 @@ int hda_dsp_set_power_state(struct snd_sof_dev *sdev, | ||
| dev_vdbg(bus->dev, "D0I3C updated, register = 0x%x\n", | ||
| snd_hdac_chip_readb(bus, VS_D0I3C)); | ||
| if (d0_substate == SOF_DSP_D0I0) | ||
| if (state == SOF_DSP_D0I0) | ||
| flags = HDA_PM_PPG;/* prevent power gating in D0 */ | ||
| else | ||
| flags = HDA_PM_NO_DMA_TRACE;/* disable DMA trace in D0I3*/ | ||
ranj063 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| @@ -428,6 +432,8 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) | ||
| return ret; | ||
| } | ||
| sdev->dsp_power_state = SOF_DSP_D3; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to set D3 in the core driver, make D0 and D3 be the more generic states? CollaboratorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it makes sense here because the core requests the state and here's where the actual assignement happens isnt it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
My point is that for platforms which don't have platform .suspend() ops, the dsp_power_state will not be changed then? CollaboratorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it will not and thats correct right? You never change the DSP state for those platforms. | ||
| return 0; | ||
| } | ||
| @@ -473,15 +479,26 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) | ||
| hda_dsp_ctrl_ppcap_enable(sdev, true); | ||
| hda_dsp_ctrl_ppcap_int_enable(sdev, true); | ||
| sdev->dsp_power_state = SOF_DSP_D0I0; | ||
| return 0; | ||
| } | ||
| int hda_dsp_resume(struct snd_sof_dev *sdev) | ||
| int hda_dsp_resume(struct snd_sof_dev *sdev, | ||
| enum sof_dsp_power_state state) | ||
| { | ||
| struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; | ||
| struct pci_dev *pci = to_pci_dev(sdev->dev); | ||
| int ret; | ||
| if (sdev->dsp_power_state == SOF_DSP_D0I3) { | ||
| /* set DSP power state */ | ||
| ret = hda_dsp_set_power_state(sdev, state); | ||
| if (ret < 0) | ||
| return ret; | ||
| sdev->dsp_power_state = state; | ||
| if (sdev->s0_suspend) { | ||
| /* restore L1SEN bit */ | ||
| if (hda->l1_support_changed) | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, | ||
| @@ -523,14 +540,22 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev) | ||
| return hda_suspend(sdev, true); | ||
| } | ||
| int hda_dsp_suspend(struct snd_sof_dev *sdev) | ||
| int hda_dsp_suspend(struct snd_sof_dev *sdev, | ||
| enum sof_dsp_power_state state) | ||
| { | ||
| struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; | ||
| struct hdac_bus *bus = sof_to_bus(sdev); | ||
| struct pci_dev *pci = to_pci_dev(sdev->dev); | ||
| int ret; | ||
| if (sdev->s0_suspend) { | ||
| if (state == SOF_DSP_D0I3) { | ||
| /* set DSP power state */ | ||
| ret = hda_dsp_set_power_state(sdev, state); | ||
| if (ret < 0) | ||
| return ret; | ||
| sdev->dsp_power_state = state; | ||
| /* enable L1SEN to make sure the system can enter S0Ix */ | ||
| hda->l1_support_changed = | ||
| snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -346,13 +346,14 @@ static int sof_pcm_trigger(struct snd_soc_component *component, | ||
| stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; | ||
| break; | ||
| case SNDRV_PCM_TRIGGER_RESUME: | ||
| if (spcm->stream[substream->stream].suspend_ignored) { | ||
| if (spcm->stream[substream->stream].d0i3_compatible && | ||
| sdev->D0i3_pipeline_count) { | ||
| /* | ||
| * this case will be triggered when INFO_RESUME is | ||
| * supported, no need to resume streams that remained | ||
| * enabled in D0ix. | ||
| * supported, no need to start pipelines that were kept | ||
| * running during suspend. | ||
| */ | ||
| spcm->stream[substream->stream].suspend_ignored = false; | ||
| sdev->D0i3_pipeline_count--; | ||
| return 0; | ||
| } | ||
| @@ -366,27 +367,26 @@ static int sof_pcm_trigger(struct snd_soc_component *component, | ||
| /* fallthrough */ | ||
| case SNDRV_PCM_TRIGGER_START: | ||
| if (spcm->stream[substream->stream].suspend_ignored) { | ||
| if (spcm->stream[substream->stream].d0i3_compatible && | ||
| sdev->D0i3_pipeline_count) { | ||
ranj063 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| /* | ||
| * This case will be triggered when INFO_RESUME is | ||
| * not supported, no need to re-start streams that | ||
| * remained enabled in D0ix. | ||
| * not supported, no need to re-start pipelines that | ||
| * were kept running during suspend. | ||
| */ | ||
| spcm->stream[substream->stream].suspend_ignored = false; | ||
| sdev->D0i3_pipeline_count--; | ||
| return 0; | ||
| } | ||
| stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; | ||
| break; | ||
| case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| if (sdev->s0_suspend && | ||
| spcm->stream[substream->stream].d0i3_compatible) { | ||
| /* | ||
| * trap the event, not sending trigger stop to | ||
| * prevent the FW pipelines from being stopped, | ||
| * and mark the flag to ignore the upcoming DAPM | ||
| * PM events. | ||
| */ | ||
| spcm->stream[substream->stream].suspend_ignored = true; | ||
| /* | ||
| * D0i3-compatible pipelines should be kept running | ||
| * when suspending to S0ix. | ||
| */ | ||
| if (spcm->stream[substream->stream].d0i3_compatible && | ||
| sdev->s0_suspend) { | ||
| sdev->D0i3_pipeline_count++; | ||
| return 0; | ||
| } | ||
| /* fallthrough */ | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.