From c4cee2684831f5ca67be730136aa334c4dd1afa9 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 17 Jan 2019 09:57:29 -0800 Subject: [PATCH 1/2] ASoC: SOF: add field to keep track of cores enabled in SMP Add a field "enabled_cores_mask" to keep track of the cores that are enabled in SMP and update it during topology loading/unloading. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/sof-priv.h | 1 + sound/soc/sof/topology.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 1bd9db4005fcf9..dad43559ec589a 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -392,6 +392,7 @@ struct snd_sof_dev { struct list_head dai_list; struct list_head route_list; struct snd_soc_component *component; + u32 enabled_cores_mask; /* keep track of enabled cores */ /* FW configuration */ struct sof_ipc_dma_buffer_data *info_buffer; diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index e163138088e68f..c2192e1aa99430 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1110,12 +1110,15 @@ int sof_load_pipeline_ipc(struct snd_sof_dev *sdev, return ret; } + /* update enabled cores mask */ + sdev->enabled_cores_mask |= 1 << pipeline->core; + /* * Now notify DSP that the core that this pipeline is scheduled on * has been powered up */ memset(&pm_core_config, 0, sizeof(pm_core_config)); - pm_core_config.enable_mask = 1 << pipeline->core; + pm_core_config.enable_mask = sdev->enabled_cores_mask; /* configure CORE_ENABLE ipc message */ pm_core_config.hdr.size = sizeof(pm_core_config); @@ -1842,6 +1845,10 @@ static int sof_widget_unload(struct snd_soc_component *scomp, if (ret < 0) dev_err(sdev->dev, "error: powering down pipeline schedule core %d\n", pipeline->core); + + /* update enabled cores mask */ + sdev->enabled_cores_mask &= ~(1 << pipeline->core); + break; case snd_soc_dapm_pga: From e0272e7227a0858bc8bb808bb7453a35255a6bef Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Fri, 8 Feb 2019 18:11:09 -0800 Subject: [PATCH 2/2] ASoC: SOF: add init_core_mask to struct sof_intel_dsp_desc Add a init_core_mask member to sof_intel_dsp_desc and set the value for SKL+ platforms. This will be used to specify which cores are enabled after fw boot is complete. Also make snd_sof_dsp_run() op return the init_core_mask. SKL- platforms with single core DSP's just return 1. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/intel/bdw.c | 3 ++- sound/soc/sof/intel/byt.c | 3 ++- sound/soc/sof/intel/cnl.c | 1 + sound/soc/sof/intel/hda-loader.c | 11 +++++++++-- sound/soc/sof/intel/hsw.c | 3 ++- sound/soc/sof/intel/shim.h | 1 + sound/soc/sof/intel/skl.c | 1 + sound/soc/sof/loader.c | 6 ++++++ sound/soc/sof/ops.h | 5 +++++ 10 files changed, 30 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 1c040b600891d3..692f0e06652f2f 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -101,6 +101,7 @@ EXPORT_SYMBOL(sof_apl_ops); const struct sof_intel_dsp_desc apl_chip_info = { /* Apollolake */ .cores_num = 2, + .init_core_mask = 1, .cores_mask = HDA_DSP_CORE_MASK(0) | HDA_DSP_CORE_MASK(1), .ipc_req = HDA_DSP_REG_HIPCI, .ipc_req_mask = HDA_DSP_REG_HIPCI_BUSY, diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 7d5fa9387b39c9..fbaa170fc5e14a 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -84,7 +84,8 @@ static int bdw_run(struct snd_sof_dev *sdev) snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR, SHIM_CSR_STALL, 0x0); - return 0; + /* return init core mask */ + return 1; } static int bdw_reset(struct snd_sof_dev *sdev) diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 34ad7536bdc806..8baf98764488b2 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -463,7 +463,8 @@ static int byt_run(struct snd_sof_dev *sdev) return -ENODEV; } - return 0; + /* return init core mask */ + return 1; } static int byt_reset(struct snd_sof_dev *sdev) diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index ae080b865bccc8..626f3d49bf8c36 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -256,6 +256,7 @@ EXPORT_SYMBOL(sof_cnl_ops); const struct sof_intel_dsp_desc cnl_chip_info = { /* Cannonlake */ .cores_num = 4, + .init_core_mask = 1, .cores_mask = HDA_DSP_CORE_MASK(0) | HDA_DSP_CORE_MASK(1) | HDA_DSP_CORE_MASK(2) | diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 6a5e07df411655..9362771ee0d0a9 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -248,10 +248,14 @@ static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream) int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) { struct snd_sof_pdata *plat_data = sdev->pdata; + const struct sof_dev_desc *desc = plat_data->desc; + const struct sof_intel_dsp_desc *chip_info; struct hdac_ext_stream *stream; struct firmware stripped_firmware; int ret, ret1, tag, i; + chip_info = (struct sof_intel_dsp_desc *)desc->chip_info; + stripped_firmware.data = plat_data->fw->data; stripped_firmware.size = plat_data->fw->size; @@ -329,9 +333,12 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) ret = ret1; } - /* return if both copying fw and stream clean up are successful */ + /* + * return master core id if both fw copy + * and stream clean up are successful + */ if (!ret) - return ret; + return chip_info->init_core_mask; /* dump dsp registers and disable DSP upon error */ err: diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index 95807406eeb866..8295b4b02dd41c 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -84,7 +84,8 @@ static int hsw_run(struct snd_sof_dev *sdev) snd_sof_dsp_update_bits_unlocked(sdev, HSW_DSP_BAR, SHIM_CSR, SHIM_CSR_STALL, 0x0); - return 0; //TODO: Fix return value + /* return init core mask */ + return 1; } static int hsw_reset(struct snd_sof_dev *sdev) diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h index 1a92b155af24c7..63fc9b7499a09b 100644 --- a/sound/soc/sof/intel/shim.h +++ b/sound/soc/sof/intel/shim.h @@ -155,6 +155,7 @@ struct sof_intel_dsp_desc { int cores_num; int cores_mask; + int init_core_mask; /* cores available after fw boot */ int ipc_req; int ipc_req_mask; int ipc_ack; diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index f8409c26b748c5..fd3d187f9face5 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -94,6 +94,7 @@ EXPORT_SYMBOL(sof_skl_ops); const struct sof_intel_dsp_desc skl_chip_info = { /* Apollolake */ .cores_num = 2, + .init_core_mask = 1, .cores_mask = HDA_DSP_CORE_MASK(0) | HDA_DSP_CORE_MASK(1), .ipc_req = HDA_DSP_REG_HIPCI, .ipc_req_mask = HDA_DSP_REG_HIPCI_BUSY, diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index f996082fa656aa..230fb696e8fb1f 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -301,6 +301,7 @@ 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); sdev->boot_complete = false; @@ -333,6 +334,8 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) return ret; } + init_core_mask = ret; + /* now wait for the DSP to boot */ ret = wait_event_timeout(sdev->boot_wait, sdev->boot_complete, msecs_to_jiffies(sdev->boot_timeout)); @@ -352,6 +355,9 @@ 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 c6374f0210e987..b070ad34e17c62 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -40,6 +40,11 @@ static inline int snd_sof_remove(struct snd_sof_dev *sdev) } /* control */ + +/* + * snd_sof_dsp_run returns the core mask of the cores that are available + * after successful fw boot + */ static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev) { if (sof_ops(sdev)->run)