From f6c246eacb62977dea5c9c65ac6fb4921cad5bcd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:46 +0200 Subject: [PATCH 1/5] ASoC: SOF: Intel: hda: use snd_sof_dsp_core_power_up/down API To implement common logic in SOF core, core power up/down flows should use common SOF API and not directly use low-level platform specific helper functions. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 2 +- sound/soc/sof/intel/hda-loader.c | 2 +- sound/soc/sof/intel/hda.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 2b001151fe37..4fe4175179d4 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -624,7 +624,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) #endif /* power down DSP */ - ret = hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); + ret = snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask); if (ret < 0) { dev_err(sdev->dev, "error: failed to power down core during suspend\n"); diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 365a79fc7081..4b2ab351e2cc 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -183,7 +183,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) flags |= SOF_DBG_DUMP_FORCE_ERR_LEVEL; hda_dsp_dump(sdev, flags); - hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); + snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask); return ret; } diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7e703ce22fcd..d57d484a42d1 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -928,7 +928,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) /* disable cores */ if (chip) - hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); + snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask); /* disable DSP */ snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, From cedd502d18b5b7a913fa13fa18a037cc51b1798d Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:47 +0200 Subject: [PATCH 2/5] ASoC: SOF: Intel: hda-loader: keep init cores alive init_core_mask should be the available cores mask after fw boot. So we should keep not core 0 but init cores alive. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-3-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 4b2ab351e2cc..07b73fe3c5e5 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -147,8 +147,9 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) chip->ipc_ack_mask, chip->ipc_ack_mask); - /* step 5: power down corex */ - ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & ~(BIT(0))); + /* step 5: power down cores that are no longer needed */ + ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & + ~(chip->init_core_mask)); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, From 42077f08b3f1ba891dca1f8f479810f16b7d6cbd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:48 +0200 Subject: [PATCH 3/5] ASoC: SOF: update dsp core power status in common APIs Only manage enabled_cores_mask in common snd_sof_dsp_core_power_up/down APIs to ensure it stays in sync with actual DSP core state. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-4-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/loader.c | 6 ------ sound/soc/sof/ops.h | 22 ++++++++++++++++------ sound/soc/sof/pm.c | 1 - sound/soc/sof/topology.c | 8 -------- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index 08a17abb63ff..4ade55bf6d75 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -811,7 +811,6 @@ EXPORT_SYMBOL(snd_sof_load_firmware); int snd_sof_run_firmware(struct snd_sof_dev *sdev) { int ret; - int init_core_mask; init_waitqueue_head(&sdev->boot_wait); @@ -843,8 +842,6 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) return ret; } - init_core_mask = ret; - /* * now wait for the DSP to boot. There are 3 possible outcomes: * 1. Boot wait times out indicating FW boot failure. @@ -874,9 +871,6 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) return ret; } - /* fw boot is complete. Update the active cores mask */ - sdev->enabled_cores_mask = init_core_mask; - return 0; } EXPORT_SYMBOL(snd_sof_run_firmware); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index f0c9ca8820d2..2e9a8da53d57 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -76,19 +76,29 @@ static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev) static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) { - if (sof_ops(sdev)->core_power_up) - return sof_ops(sdev)->core_power_up(sdev, core_mask); + int ret = 0; - return 0; + if (sof_ops(sdev)->core_power_up) { + ret = sof_ops(sdev)->core_power_up(sdev, core_mask); + if (!ret) + sdev->enabled_cores_mask |= core_mask; + } + + return ret; } static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask) { - if (sof_ops(sdev)->core_power_down) - return sof_ops(sdev)->core_power_down(sdev, core_mask); + int ret = 0; - return 0; + if (sof_ops(sdev)->core_power_down) { + ret = sof_ops(sdev)->core_power_down(sdev, core_mask); + if (!ret) + sdev->enabled_cores_mask &= ~core_mask; + } + + return ret; } /* pre/post fw load */ diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index c83fb6255961..fd265803f7bc 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -256,7 +256,6 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) /* reset FW state */ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED; - sdev->enabled_cores_mask = 0; return ret; } diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b6b32a7a91f8..b69f493b5faa 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1352,10 +1352,6 @@ static int sof_core_enable(struct snd_sof_dev *sdev, int core) core, ret); goto err; } - - /* update enabled cores mask */ - sdev->enabled_cores_mask |= BIT(core); - return ret; err: /* power down core if it is host managed and return the original error if this fails too */ @@ -2603,10 +2599,6 @@ static int sof_widget_unload(struct snd_soc_component *scomp, if (ret < 0) dev_err(scomp->dev, "error: powering down pipeline schedule core %d\n", pipeline->core); - - /* update enabled cores mask */ - sdev->enabled_cores_mask &= ~(1 << pipeline->core); - break; default: break; From 30876e2a06f35b525dc71f94dfc3c6f329e55a28 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:49 +0200 Subject: [PATCH 4/5] ASoC: SOF: Filter out unneeded core power up/downs Exclude cores that are already powered on/off correctly. This allows to simplify dsp_power_up/down() implementations and avoid unexpected error. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-5-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ops.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 2e9a8da53d57..5099ad03df72 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -78,7 +78,8 @@ static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev, { int ret = 0; - if (sof_ops(sdev)->core_power_up) { + core_mask &= ~sdev->enabled_cores_mask; + if (sof_ops(sdev)->core_power_up && core_mask) { ret = sof_ops(sdev)->core_power_up(sdev, core_mask); if (!ret) sdev->enabled_cores_mask |= core_mask; @@ -92,7 +93,8 @@ static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, { int ret = 0; - if (sof_ops(sdev)->core_power_down) { + core_mask &= sdev->enabled_cores_mask; + if (sof_ops(sdev)->core_power_down && core_mask) { ret = sof_ops(sdev)->core_power_down(sdev, core_mask); if (!ret) sdev->enabled_cores_mask &= ~core_mask; From 92c6ec606cd12c16091b70442da536bdeddb1f7f Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:50 +0200 Subject: [PATCH 5/5] ASoC: SOF: intel: hda-loader: use snd_sof_dsp_core_power_down/up APIs To manage enabled_cores_mask flag, we should always use snd_sof_dsp_ core_power_down/up APIs to power up/down dsp cores. The APIs do a little bit more than the original functions, but it is harmless. Suggested-by: Ranjani Sridharan Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210128093850.1041387-6-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 07b73fe3c5e5..d744952f6954 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -93,7 +93,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) int i; /* step 1: power up corex */ - ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask); + ret = snd_sof_dsp_core_power_up(sdev, chip->host_managed_cores_mask); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); @@ -148,8 +148,8 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) chip->ipc_ack_mask); /* step 5: power down cores that are no longer needed */ - ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & - ~(chip->init_core_mask)); + ret = snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask & + ~(chip->init_core_mask)); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev,