summaryrefslogtreecommitdiff
path: root/sound/soc/intel/avs/dsp.c
diff options
context:
space:
mode:
authorCezary Rojewski <cezary.rojewski@intel.com>2022-05-16 12:11:09 +0200
committerMark Brown <broonie@kernel.org>2022-05-17 11:58:00 +0100
commit335c4cbd201d4b74942ff37e6c644d56b9247df3 (patch)
tree1fc8ebfeaa509abfa955b735d8fc38b24f29c144 /sound/soc/intel/avs/dsp.c
parent4b86115cb91a3d34ce7da87b734572ce6063babc (diff)
ASoC: Intel: avs: D0ix power state support
Audio DSP device supports D0 substates in form of D0ix, allowing for preserving more power even when device is still considered active (D0). When entered, certain domains which are not being currently used become power gated. Entering and leaving D0ix is a complex process and differs between firmware generations. Conditions that disallow D0i3 and require immediate D0i0 transition include but may not be limited to: IPC traffic, firmware tracing and SRAM I/O. To make D0ix toggling sane, delay D0i3 transition and refresh the timer each time an IPC is requested. Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://lore.kernel.org/r/20220516101116.190192-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/avs/dsp.c')
-rw-r--r--sound/soc/intel/avs/dsp.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c
index 3ff17bd22a5a..2f18b137ff42 100644
--- a/sound/soc/intel/avs/dsp.c
+++ b/sound/soc/intel/avs/dsp.c
@@ -152,6 +152,15 @@ static int avs_dsp_get_core(struct avs_dev *adev, u32 core_id)
adev->core_refs[core_id]++;
if (adev->core_refs[core_id] == 1) {
+ /*
+ * No cores other than main-core can be running for DSP
+ * to achieve d0ix. Conscious SET_D0IX IPC failure is permitted,
+ * simply d0ix power state will no longer be attempted.
+ */
+ ret = avs_dsp_disable_d0ix(adev);
+ if (ret && ret != -AVS_EIPC)
+ goto err_disable_d0ix;
+
ret = avs_dsp_enable(adev, mask);
if (ret)
goto err_enable_dsp;
@@ -160,6 +169,8 @@ static int avs_dsp_get_core(struct avs_dev *adev, u32 core_id)
return 0;
err_enable_dsp:
+ avs_dsp_enable_d0ix(adev);
+err_disable_d0ix:
adev->core_refs[core_id]--;
err:
dev_err(adev->dev, "get core %d failed: %d\n", core_id, ret);
@@ -185,6 +196,9 @@ static int avs_dsp_put_core(struct avs_dev *adev, u32 core_id)
ret = avs_dsp_disable(adev, mask);
if (ret)
goto err;
+
+ /* Match disable_d0ix in avs_dsp_get_core(). */
+ avs_dsp_enable_d0ix(adev);
}
return 0;