diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2023-04-04 12:21:09 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2023-04-04 12:42:37 +0100 |
commit | 9fc6786f549c4d71e55bd646ffb4814933286072 (patch) | |
tree | ccb4ba2598f5eaa42473cbe80084bcc5db340614 /sound/soc/sof/intel/hda-dsp.c | |
parent | 1f7b5d52be130e16fda60be446b30136698738c6 (diff) |
ASoC: SOF: Intel: hda: make DSPless mode work with DSP disabled in BIOS
When the DSP is disabled in the BIOS, the DSP_BAR and PP_BAR cannot be
accessed.
One possible objection noted in initial reviews is that this patch
adds a number of branches. However the number of branches is actually
limited in probe/suspend/resume routines mostly, so there isn't really
a degradation in terms of readability and maintainability. Adding yet
another level of abstraction/ops/callbacks would increase complexity
and not really help in terms of code reuse or readability and
maintainability. A split between controller and DSP driver would be
even more invasive.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230404092115.27949-7-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/intel/hda-dsp.c')
-rw-r--r-- | sound/soc/sof/intel/hda-dsp.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index c9231aeacc53..23c05e6f424a 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -321,6 +321,9 @@ void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_intel_dsp_desc *chip = hda->desc; + if (sdev->dspless_mode_selected) + return; + /* enable IPC DONE and BUSY interrupts */ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY, @@ -336,6 +339,9 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_intel_dsp_desc *chip = hda->desc; + if (sdev->dspless_mode_selected) + return; + /* disable IPC interrupt */ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC, HDA_DSP_ADSPIC_IPC, 0); @@ -681,6 +687,9 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) /* power down all hda links */ hda_bus_ml_suspend(bus); + if (sdev->dspless_mode_selected) + goto skip_dsp; + ret = chip->power_down_dsp(sdev); if (ret < 0) { dev_err(sdev->dev, "failed to power down DSP during suspend\n"); @@ -694,6 +703,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) /* disable ppcap interrupt */ hda_dsp_ctrl_ppcap_enable(sdev, false); hda_dsp_ctrl_ppcap_int_enable(sdev, false); +skip_dsp: /* disable hda bus irq and streams */ hda_dsp_ctrl_stop_chip(sdev); @@ -744,9 +754,11 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) hda_codec_jack_check(sdev); } - /* enable ppcap interrupt */ - hda_dsp_ctrl_ppcap_enable(sdev, true); - hda_dsp_ctrl_ppcap_int_enable(sdev, true); + if (!sdev->dspless_mode_selected) { + /* enable ppcap interrupt */ + hda_dsp_ctrl_ppcap_enable(sdev, true); + hda_dsp_ctrl_ppcap_int_enable(sdev, true); + } cleanup: /* display codec can powered off after controller init */ @@ -843,8 +855,10 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev) }; int ret; - /* cancel any attempt for DSP D0I3 */ - cancel_delayed_work_sync(&hda->d0i3_work); + if (!sdev->dspless_mode_selected) { + /* cancel any attempt for DSP D0I3 */ + cancel_delayed_work_sync(&hda->d0i3_work); + } /* stop hda controller and power dsp off */ ret = hda_suspend(sdev, true); @@ -866,8 +880,10 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) }; int ret; - /* cancel any attempt for DSP D0I3 */ - cancel_delayed_work_sync(&hda->d0i3_work); + if (!sdev->dspless_mode_selected) { + /* cancel any attempt for DSP D0I3 */ + cancel_delayed_work_sync(&hda->d0i3_work); + } if (target_state == SOF_DSP_PM_D0) { /* Set DSP power state */ |