diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 8662b422eb8074..f903ef720e52f9 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -421,6 +421,20 @@ static inline void hda_dsp_sdw_process_mic_privacy(struct snd_sof_dev *sdev) { } /* pre fw run operations */ int hda_dsp_pre_fw_run(struct snd_sof_dev *sdev) { + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + int ret; + + /* Power down DSP if left enabled to ensure a clean boot state. */ + if (hda_dsp_core_is_enabled(sdev, chip->host_managed_cores_mask)) { + dev_dbg(sdev->dev, "DSP core enabled, power down DSP first\n"); + + ret = chip->power_down_dsp(sdev); + if (ret < 0) + dev_warn(sdev->dev, + "%s: failed to power down already-enabled DSP\n", __func__); + } + /* disable clock gating and power gating */ return hda_dsp_ctrl_clock_power_gating(sdev, false); } diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 68cf68135d054a..af7c879cdd60e1 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -236,6 +236,17 @@ int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) } EXPORT_SYMBOL_NS(mtl_enable_interrupts, "SND_SOC_SOF_INTEL_MTL"); +static bool mtl_dsp_is_enabled(struct snd_sof_dev *sdev) +{ + int val; + + val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS); + if (val & MTL_HFDSSCS_CPA_MASK) + return true; + + return false; +} + /* pre fw run operations */ static int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) { @@ -249,6 +260,18 @@ static int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) u32 dsppwrsts; const struct sof_intel_dsp_desc *chip; + /* Power down the DSP if it is left enabled to ensure clean boot state */ + if (mtl_dsp_is_enabled(sdev)) { + dev_dbg(sdev->dev, "powering down DSP first\n"); + + ret = mtl_power_down_dsp(sdev); + if (ret < 0) { + dev_warn(sdev->dev, + "%s: failed to power down already-enabled DSP\n", __func__); + /* Continue anyway to attempt recovery */ + } + } + chip = get_chip_info(sdev->pdata); if (chip->hw_ip_version > SOF_INTEL_ACE_2_0) { dsppwrctl = PTL_HFPWRCTL2;