From 60a9d0dfb40306630464528ff01867136b693d4c Mon Sep 17 00:00:00 2001 From: Zhu Yingjiang Date: Wed, 27 Mar 2019 16:47:57 +0800 Subject: [PATCH] ASoC:SOF:fix the NOCODEC and HDA mutually incompatible to make NOCODEC and HDA mutually incompatible, the DSP common control part registers are needed to be set for NOCODEC mode. At least INTCTL and PP_PPCTL are needed to be set, or else the DSP will not powerup during suspend/resume. Signed-off-by: Zhu Yingjiang --- sound/soc/sof/intel/hda-ctrl.c | 16 ++++++++++++++++ sound/soc/sof/intel/hda-dsp.c | 22 ++++++++++++++++++++++ sound/soc/sof/intel/hda.h | 2 ++ 3 files changed, 40 insertions(+) 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);