diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c index cda8c6c6e85920..2c3645736e1f76 100644 --- a/sound/soc/sof/intel/hda-ctrl.c +++ b/sound/soc/sof/intel/hda-ctrl.c @@ -109,6 +109,22 @@ int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev) return 0; } +void hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev *sdev, bool enable) +{ + u32 val = enable ? SOF_HDA_PPCTL_GPROCEN : 0; + + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, + SOF_HDA_PPCTL_GPROCEN, val); +} + +void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable) +{ + u32 val = enable ? SOF_HDA_PPCTL_PIE : 0; + + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, + SOF_HDA_PPCTL_PIE, val); +} + void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable) { u32 val = enable ? PCI_CGCTL_MISCBDCGE_MASK : 0; diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index c50dcc135e3871..daec2d880ed31e 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -309,6 +309,15 @@ static int hda_suspend(struct snd_sof_dev *sdev, int state) /* disable hda bus irq and i/o */ snd_hdac_bus_stop_chip(bus); +#else + /* disable ppcap interrupt */ + hda_dsp_ctrl_ppcap_enable(sdev, false); + hda_dsp_ctrl_ppcap_int_enable(sdev, false); + + /* disable hda bus irq */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, + SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, + 0); #endif /* disable LP retention mode */ @@ -362,6 +371,8 @@ static int hda_resume(struct snd_sof_dev *sdev) snd_hdac_ext_bus_ppcap_int_enable(bus, true); #else + hda_dsp_ctrl_misc_clock_gating(sdev, false); + /* reset controller */ ret = hda_dsp_ctrl_link_reset(sdev, true); if (ret < 0) { @@ -377,6 +388,17 @@ static int hda_resume(struct snd_sof_dev *sdev) "error: failed to ready controller during resume\n"); return ret; } + + /* enable hda bus irq */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, + SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, + SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN); + + hda_dsp_ctrl_misc_clock_gating(sdev, true); + + /* enable ppcap interrupt */ + hda_dsp_ctrl_ppcap_enable(sdev, true); + hda_dsp_ctrl_ppcap_int_enable(sdev, true); #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 6e1caf8331ae45..ebb97a59b59e85 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -488,6 +488,8 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev); * HDA Controller Operations. */ int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev); +void hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev *sdev, bool enable); +void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable); int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev, bool reset); void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable); int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable);