From 8b66d7c58c11cf3b1a1cea738582367a96cdaaf8 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Tue, 5 Jan 2021 17:56:40 +0200 Subject: ASoC: SOF: add mutex to protect the dsp_power_state access There could be more than one thread read/write the dsp_power_state simultaneously (e.g. hda_dsp_d0i3_work and sof_ipc_tx_message), add a mutex power_state_access to make sure the access to it is mutually exclusive. Signed-off-by: Keyon Jie Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210105155640.3725238-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 1 + sound/soc/sof/ops.h | 11 ++++++++--- sound/soc/sof/sof-priv.h | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index adc7c37145d6..2b85ef5d6092 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -316,6 +316,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) INIT_LIST_HEAD(&sdev->route_list); spin_lock_init(&sdev->ipc_lock); spin_lock_init(&sdev->hw_lock); + mutex_init(&sdev->power_state_access); if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) INIT_WORK(&sdev->probe_work, sof_probe_work); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 95e748b36903..4c1f9daaa6e8 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -208,11 +208,16 @@ static inline int snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev, const struct sof_dsp_power_state *target_state) { + int ret = 0; + + mutex_lock(&sdev->power_state_access); + if (sof_ops(sdev)->set_power_state) - return sof_ops(sdev)->set_power_state(sdev, target_state); + ret = sof_ops(sdev)->set_power_state(sdev, target_state); - /* D0 substate is not supported, do nothing here. */ - return 0; + mutex_unlock(&sdev->power_state_access); + + return ret; } /* debug */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 68da8f797403..28d19fa30614 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -375,6 +375,8 @@ struct snd_sof_dev { /* current DSP power state */ struct sof_dsp_power_state dsp_power_state; + /* mutex to protect the dsp_power_state access */ + struct mutex power_state_access; /* Intended power target of system suspend */ enum sof_system_suspend_state system_suspend_target; -- cgit v1.2.3 From 7edb3051f11683640c38b93e183ef1676090a79b Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:14 +0200 Subject: ASoC: SOF: add .shutdown() callback to snd_sof_dsp_ops Add .shutdown() callback to the struct snd_sof_dsp_ops, for doing platform specific actions at shutdown. Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ops.h | 8 ++++++++ sound/soc/sof/sof-priv.h | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 4c1f9daaa6e8..f0c9ca8820d2 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -37,6 +37,14 @@ static inline int snd_sof_remove(struct snd_sof_dev *sdev) return 0; } +static inline int snd_sof_shutdown(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->shutdown) + return sof_ops(sdev)->shutdown(sdev); + + return 0; +} + /* control */ /* diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 28d19fa30614..682c4b6d01ef 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -98,9 +98,10 @@ struct snd_sof_pdata; */ struct snd_sof_dsp_ops { - /* probe and remove */ + /* probe/remove/shutdown */ int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */ int (*remove)(struct snd_sof_dev *sof_dev); /* optional */ + int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */ /* DSP core boot / reset */ int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */ @@ -462,6 +463,7 @@ struct snd_sof_dev { int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data); int snd_sof_device_remove(struct device *dev); +int snd_sof_device_shutdown(struct device *dev); int snd_sof_runtime_suspend(struct device *dev); int snd_sof_runtime_resume(struct device *dev); -- cgit v1.2.3 From daff7f1478e12cdee3e639c83c571cfd38bc5080 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:15 +0200 Subject: ASoC: SOF: add snd_sof_device_shutdown() helper for shutdown Add helper snd_sof_device_shutdown() to wrap the platform specific .shutdown callbacks for SOF platforms. Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 2b85ef5d6092..8d13eb13fe08 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -385,6 +385,14 @@ int snd_sof_device_remove(struct device *dev) } EXPORT_SYMBOL(snd_sof_device_remove); +int snd_sof_device_shutdown(struct device *dev) +{ + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + + return snd_sof_shutdown(sdev); +} +EXPORT_SYMBOL(snd_sof_device_shutdown); + MODULE_AUTHOR("Liam Girdwood"); MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core"); MODULE_LICENSE("Dual BSD/GPL"); -- cgit v1.2.3 From 3475b44c7601d6f2b4d96e731047ef73fd2f1eb2 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:16 +0200 Subject: ASoC: SOF: sof-pci-dev: add .shutdown() callback Add the .shutdown() callback to the sof-pci-dev driver, to help to handle shutting down specific tasks for SOF PCI platforms. Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-3-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-pci-dev.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 63b989e3ec40..5f53c3e76e6f 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -450,6 +450,11 @@ static void sof_pci_remove(struct pci_dev *pci) pci_release_regions(pci); } +static void sof_pci_shutdown(struct pci_dev *pci) +{ + snd_sof_device_shutdown(&pci->dev); +} + /* PCI IDs */ static const struct pci_device_id sof_pci_ids[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) @@ -523,6 +528,7 @@ static struct pci_driver snd_sof_pci_driver = { .id_table = sof_pci_ids, .probe = sof_pci_probe, .remove = sof_pci_remove, + .shutdown = sof_pci_shutdown, .driver = { .pm = &sof_pci_pm, }, -- cgit v1.2.3 From 44a4cfad8d78efcda9ec0dd97ceea38d8b602f24 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 13 Jan 2021 17:26:17 +0200 Subject: ASoC: SOF: Intel: tgl: do thorough remove at .shutdown() callback Invoke hda_dsp_remove() as the .shutdown() callback. This will help to perform shutdown of the DSP safely on TGL platforms before shutting down or rebooting the system. BugLink: https://github.com/thesofproject/linux/issues/2571 Signed-off-by: Keyon Jie Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210113152617.4048541-4-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/tgl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 2252ca38ff4b..419f05ba1920 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -22,9 +22,10 @@ static const struct snd_sof_debugfs_map tgl_dsp_debugfs[] = { /* Tigerlake ops */ const struct snd_sof_dsp_ops sof_tgl_ops = { - /* probe and remove */ + /* probe/remove/shutdown */ .probe = hda_dsp_probe, .remove = hda_dsp_remove, + .shutdown = hda_dsp_remove, /* Register IO */ .write = sof_io_write, -- cgit v1.2.3 From 39860fe070c97e62ae9e80addce40ce0b3c2b082 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 14 Jan 2021 13:55:58 +0200 Subject: ASoC: SOF: Intel: initial support to AlderLake-P Add PCI id for the AlderLake-P. Signed-off-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210114115558.52699-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-pci-dev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 5f53c3e76e6f..7757463bd81a 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -213,7 +213,7 @@ static const struct sof_dev_desc icl_desc = { }; #endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) || IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) static const struct sof_dev_desc tgl_desc = { .machines = snd_soc_acpi_intel_tgl_machines, .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, @@ -230,7 +230,9 @@ static const struct sof_dev_desc tgl_desc = { .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", .ops = &sof_tgl_ops, }; +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) static const struct sof_dev_desc tglh_desc = { .machines = snd_soc_acpi_intel_tgl_machines, .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, @@ -517,6 +519,8 @@ static const struct pci_device_id sof_pci_ids[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) { PCI_DEVICE(0x8086, 0x7ad0), .driver_data = (unsigned long)&adls_desc}, + { PCI_DEVICE(0x8086, 0x51c8), + .driver_data = (unsigned long)&tgl_desc}, #endif { 0, } }; -- cgit v1.2.3 From ab152afa2427bb3e4eea7c9f21c4393287838774 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2021 14:33:36 +0100 Subject: ASoC: SOF: intel: Simplify with dma_set_mask_and_coherent() ASoC Intel SOF driver still has explicit calls of dma_set_mask() and dma_set_coherent_mask(). Let's simplify with dma_set_mask_and_coherent(). Cc: Pierre-Louis Bossart Cc: Ranjani Sridharan Cc: Kai Vehmanen Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20210114133337.1039-3-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 509a9b256423..7e703ce22fcd 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -809,13 +809,9 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) sdev->mailbox_bar = HDA_DSP_BAR; /* allow 64bit DMA address if supported by H/W */ - if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(64))) { - dev_dbg(sdev->dev, "DMA mask is 64 bit\n"); - dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(64)); - } else { + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(64))) { dev_dbg(sdev->dev, "DMA mask is 32 bit\n"); - dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); - dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); + dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); } /* init streams */ -- cgit v1.2.3 From 89a400bdeb129dbc7e1c8ad2151cc8141a619709 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 26 Jan 2021 18:07:36 -0800 Subject: ASoC: SOF: Intel: hda: enable DMI L1 for D0i3-compatible streams DMI L1 entry is currently disabled whenever any capture stream is opened to prevent xruns during pause/release. But, in order to maximise power savings for the wake-on-voice usecase, DMI L1 entry should be enabled for D0i3-compatible capture streams. Introduce a new field, flags in struct sof_intel_hda_stream that stores whether a stream is dmi_l1_compatible. All playback streams, and D0i3-compatible capture streams are DMI L1 compatible. Reviewed-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210127020737.1088960-2-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-compress.c | 2 +- sound/soc/sof/intel/hda-loader.c | 2 +- sound/soc/sof/intel/hda-pcm.c | 16 +++++++++++++++- sound/soc/sof/intel/hda-stream.c | 38 ++++++++++++++++++++++---------------- sound/soc/sof/intel/hda-trace.c | 3 +-- sound/soc/sof/intel/hda.h | 6 +++++- 6 files changed, 45 insertions(+), 22 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-compress.c index 53c08034fa22..c6cf7b313934 100644 --- a/sound/soc/sof/intel/hda-compress.c +++ b/sound/soc/sof/intel/hda-compress.c @@ -25,7 +25,7 @@ int hda_probe_compr_assign(struct snd_sof_dev *sdev, { struct hdac_ext_stream *stream; - stream = hda_dsp_stream_get(sdev, cstream->direction); + stream = hda_dsp_stream_get(sdev, cstream->direction, 0); if (!stream) return -EBUSY; diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index ed773696b495..365a79fc7081 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -35,7 +35,7 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig struct pci_dev *pci = to_pci_dev(sdev->dev); int ret; - dsp_stream = hda_dsp_stream_get(sdev, direction); + dsp_stream = hda_dsp_stream_get(sdev, direction, 0); if (!dsp_stream) { dev_err(sdev->dev, "error: no stream available\n"); diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 5d35bb18660a..689934131a68 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -215,11 +215,25 @@ found: int hda_dsp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_component *scomp = sdev->component; struct hdac_ext_stream *dsp_stream; + struct snd_sof_pcm *spcm; int direction = substream->stream; + u32 flags = 0; + + spcm = snd_sof_find_spcm_dai(scomp, rtd); + if (!spcm) { + dev_err(sdev->dev, "error: can't find PCM with DAI ID %d\n", rtd->dai_link->id); + return -EINVAL; + } - dsp_stream = hda_dsp_stream_get(sdev, direction); + /* All playback and D0i3 compatible streams are DMI L1 capable */ + if (direction == SNDRV_PCM_STREAM_PLAYBACK || + spcm->stream[substream->stream].d0i3_compatible) + flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE; + dsp_stream = hda_dsp_stream_get(sdev, direction, flags); if (!dsp_stream) { dev_err(sdev->dev, "error: no stream available\n"); return -ENODEV; diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 0e09ede922c7..40a3993ae2cb 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -155,7 +155,7 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, /* get next unused stream */ struct hdac_ext_stream * -hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) +hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) { struct hdac_bus *bus = sof_to_bus(sdev); struct sof_intel_hda_stream *hda_stream; @@ -183,18 +183,22 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) spin_unlock_irq(&bus->reg_lock); /* stream found ? */ - if (!stream) + if (!stream) { dev_err(sdev->dev, "error: no free %s streams\n", direction == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture"); + return stream; + } + + hda_stream->flags = flags; /* - * Disable DMI Link L1 entry when capture stream is opened. + * Prevent DMI Link L1 entry for streams that don't support it. * Workaround to address a known issue with host DMA that results * in xruns during pause/release in capture scenarios. */ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) - if (stream && direction == SNDRV_PCM_STREAM_CAPTURE) + if (stream && !(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, HDA_VS_INTEL_EM2_L1SEN, 0); @@ -206,37 +210,39 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) { struct hdac_bus *bus = sof_to_bus(sdev); + struct sof_intel_hda_stream *hda_stream; + struct hdac_ext_stream *stream; struct hdac_stream *s; - bool active_capture_stream = false; + bool dmi_l1_enable = true; bool found = false; spin_lock_irq(&bus->reg_lock); /* - * close stream matching the stream tag - * and check if there are any open capture streams. + * close stream matching the stream tag and check if there are any open streams + * that are DMI L1 incompatible. */ list_for_each_entry(s, &bus->stream_list, list) { + stream = stream_to_hdac_ext_stream(s); + hda_stream = container_of(stream, struct sof_intel_hda_stream, hda_stream); + if (!s->opened) continue; if (s->direction == direction && s->stream_tag == stream_tag) { s->opened = false; found = true; - } else if (s->direction == SNDRV_PCM_STREAM_CAPTURE) { - active_capture_stream = true; + } else if (!(hda_stream->flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) { + dmi_l1_enable = false; } } spin_unlock_irq(&bus->reg_lock); - /* Enable DMI L1 entry if there are no capture streams open */ - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) - if (!active_capture_stream) - snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, - HDA_VS_INTEL_EM2, - HDA_VS_INTEL_EM2_L1SEN, - HDA_VS_INTEL_EM2_L1SEN); + /* Enable DMI L1 if permitted */ + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1) && dmi_l1_enable) + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, + HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN); if (!found) { dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag); diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index 1eb746d5adeb..ca869038e909 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -42,8 +42,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; int ret; - hda->dtrace_stream = hda_dsp_stream_get(sdev, - SNDRV_PCM_STREAM_CAPTURE); + hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, 0); if (!hda->dtrace_stream) { dev_err(sdev->dev, diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 9ec8ae0fd649..8e9b94bf0333 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -402,6 +402,9 @@ struct sof_intel_dsp_bdl { #define SOF_HDA_PLAYBACK 0 #define SOF_HDA_CAPTURE 1 +/* stream flags */ +#define SOF_HDA_STREAM_DMI_L1_COMPATIBLE 1 + /* * Time in ms for opportunistic D0I3 entry delay. * This has been deliberately chosen to be long to avoid race conditions. @@ -471,6 +474,7 @@ struct sof_intel_hda_stream { struct hdac_ext_stream hda_stream; struct sof_intel_stream stream; int host_reserved; /* reserve host DMA channel */ + u32 flags; }; #define hstream_to_sof_hda_stream(hstream) \ @@ -562,7 +566,7 @@ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev); bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev); struct hdac_ext_stream * - hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction); + hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags); int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag); int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream, -- cgit v1.2.3 From 6e0210763024ac43c5716dc873065ce5069edbf0 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 26 Jan 2021 18:07:37 -0800 Subject: ASoC: SOF: Intel: hda: Enable DMI L1 for trace Enabling DMI L1 for capture streams could result in xruns during pause/release. As pause/release is not a valid scenario for trace, we can safely enable DMI L1 for it. Reviewed-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210127020737.1088960-3-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index ca869038e909..81d76d3debc6 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -42,7 +42,8 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; int ret; - hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, 0); + hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, + SOF_HDA_STREAM_DMI_L1_COMPATIBLE); if (!hda->dtrace_stream) { dev_err(sdev->dev, -- cgit v1.2.3 From f6c246eacb62977dea5c9c65ac6fb4921cad5bcd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:46 +0200 Subject: 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(-) (limited to 'sound/soc/sof') 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 @@ err: 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, -- cgit v1.2.3 From cedd502d18b5b7a913fa13fa18a037cc51b1798d Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:47 +0200 Subject: 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(-) (limited to 'sound/soc/sof') 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, -- cgit v1.2.3 From 42077f08b3f1ba891dca1f8f479810f16b7d6cbd Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:48 +0200 Subject: 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(-) (limited to 'sound/soc/sof') 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 @@ 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; -- cgit v1.2.3 From 30876e2a06f35b525dc71f94dfc3c6f329e55a28 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:49 +0200 Subject: 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(-) (limited to 'sound/soc/sof') 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; -- cgit v1.2.3 From 92c6ec606cd12c16091b70442da536bdeddb1f7f Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 28 Jan 2021 11:38:50 +0200 Subject: 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(-) (limited to 'sound/soc/sof') 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, -- cgit v1.2.3 From a8f50cd9be7cc4c57f29c1390568225ebee90eda Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Mon, 8 Feb 2021 17:21:45 -0600 Subject: ASoC: SOF: add missing pm debug Type is not part of debugging parse code. Add it so unknown types don't show up while debugging Reviewed-by: Ranjani Sridharan Signed-off-by: Curtis Malainey Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index fc13bb06dbf3..1bc3d6282f16 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -106,6 +106,8 @@ static void ipc_log_header(struct device *dev, u8 *text, u32 cmd) str2 = "CLK_REQ"; break; case SOF_IPC_PM_CORE_ENABLE: str2 = "CORE_ENABLE"; break; + case SOF_IPC_PM_GATE: + str2 = "GATE"; break; default: str2 = "unknown type"; break; } -- cgit v1.2.3 From ce1f55bac5534aa518e26b94728173ee45f91a8c Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Mon, 8 Feb 2021 17:21:46 -0600 Subject: ASoC: SOF: fix string format for errors These are negative error return values, printing them as hex is annoying and not beneficial. Switch back to signed type to make error lookup simpler. Reviewed-by: Kai Vehmanen Reviewed-by: Daniel Baluta Reviewed-by: Guennadi Liakhovetski Signed-off-by: Curtis Malainey Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-compress.c | 2 +- sound/soc/sof/intel/hda-dsp.c | 2 +- sound/soc/sof/intel/hda-loader.c | 6 +++--- sound/soc/sof/intel/hda-pcm.c | 2 +- sound/soc/sof/intel/hda-trace.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-compress.c index c6cf7b313934..fe2f3f7d236b 100644 --- a/sound/soc/sof/intel/hda-compress.c +++ b/sound/soc/sof/intel/hda-compress.c @@ -82,7 +82,7 @@ int hda_probe_compr_set_params(struct snd_sof_dev *sdev, ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); if (ret < 0) { - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); return ret; } diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index e92e9750b720..72c0b8e9a196 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -732,7 +732,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev) ret = snd_hdac_ext_bus_link_power_up(hlink); if (ret < 0) { dev_dbg(sdev->dev, - "error %x in %s: failed to power up links", + "error %d in %s: failed to power up links", ret, __func__); return ret; } diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index d744952f6954..fc25ee8f68dc 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -47,7 +47,7 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig /* allocate DMA buffer */ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, &pci->dev, size, dmab); if (ret < 0) { - dev_err(sdev->dev, "error: memory alloc failed: %x\n", ret); + dev_err(sdev->dev, "error: memory alloc failed: %d\n", ret); goto error; } @@ -58,13 +58,13 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig if (direction == SNDRV_PCM_STREAM_CAPTURE) { ret = hda_dsp_iccmax_stream_hw_params(sdev, dsp_stream, dmab, NULL); if (ret < 0) { - dev_err(sdev->dev, "error: iccmax stream prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: iccmax stream prepare failed: %d\n", ret); goto error; } } else { ret = hda_dsp_stream_hw_params(sdev, dsp_stream, dmab, NULL); if (ret < 0) { - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); goto error; } hda_dsp_stream_spib_config(sdev, dsp_stream, HDA_DSP_SPIB_ENABLE, size); diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 689934131a68..df00db8369c7 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -111,7 +111,7 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev, ret = hda_dsp_stream_hw_params(sdev, stream, dmab, params); if (ret < 0) { - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); return ret; } diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index 81d76d3debc6..29e3da3c63db 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -32,7 +32,7 @@ static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev) ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); if (ret < 0) - dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); return ret; } @@ -59,7 +59,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) */ ret = hda_dsp_trace_prepare(sdev); if (ret < 0) { - dev_err(sdev->dev, "error: hdac trace init failed: %x\n", ret); + dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret); hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, *stream_tag); hda->dtrace_stream = NULL; *stream_tag = 0; -- cgit v1.2.3 From 3be46fa21088740ae5790d84b882e5a3c98fce41 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 8 Feb 2021 17:21:47 -0600 Subject: ASoC: SOF: remove unused functions hda_dsp_dump_skl() is never used and hda_dsp_get_status_skl() is only called from that function. Remove both functions. Reviewed-by: Ranjani Sridharan Reviewed-by: Keyon Jie Signed-off-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 50 ----------------------------------------------- sound/soc/sof/intel/hda.h | 1 - 2 files changed, 51 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 447163494b05..57853ef89cd1 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -317,26 +317,6 @@ static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { {HDA_DSP_ROM_NULL_FW_ENTRY, "error: null FW entry point"}, }; -static void hda_dsp_get_status_skl(struct snd_sof_dev *sdev) -{ - u32 status; - int i; - - status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_ADSP_FW_STATUS_SKL); - - for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) { - if (status == hda_dsp_rom_msg[i].code) { - dev_err(sdev->dev, "%s - code %8.8x\n", - hda_dsp_rom_msg[i].msg, status); - return; - } - } - - /* not for us, must be generic sof message */ - dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); -} - static void hda_dsp_get_status(struct snd_sof_dev *sdev) { u32 status; @@ -385,36 +365,6 @@ static void hda_dsp_get_registers(struct snd_sof_dev *sdev, stack_words * sizeof(u32)); } -void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags) -{ - struct sof_ipc_dsp_oops_xtensa xoops; - struct sof_ipc_panic_info panic_info; - u32 stack[HDA_DSP_STACK_DUMP_SIZE]; - u32 status, panic; - - /* try APL specific status message types first */ - hda_dsp_get_status_skl(sdev); - - /* now try generic SOF status messages */ - status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_ADSP_ERROR_CODE_SKL); - - /*TODO: Check: there is no define in spec, but it is used in the code*/ - panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_ADSP_ERROR_CODE_SKL + 0x4); - - if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) { - hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, - HDA_DSP_STACK_DUMP_SIZE); - snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, - stack, HDA_DSP_STACK_DUMP_SIZE); - } else { - dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", - status, panic); - hda_dsp_get_status_skl(sdev); - } -} - /* dump the first 8 dwords representing the extended ROM status */ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev, u32 flags) { diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 8e39d1e16178..d979411b4041 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -517,7 +517,6 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_idle(struct snd_sof_dev *sdev); int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); -void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); void hda_ipc_dump(struct snd_sof_dev *sdev); void hda_ipc_irq_dump(struct snd_sof_dev *sdev); -- cgit v1.2.3 From f1bb023525fd654121f18f6e2587eeee84c9db04 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 8 Feb 2021 17:21:48 -0600 Subject: ASoC: SOF: HDA: (cosmetic) simplify hda_dsp_d0i3_work() Simplify hda_dsp_d0i3_work() by returning immediately from it if D0i3 cannot be set. Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Keyon Jie Signed-off-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208232149.58899-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 72c0b8e9a196..5788fe356960 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -934,19 +934,15 @@ void hda_dsp_d0i3_work(struct work_struct *work) d0i3_work.work); struct hdac_bus *bus = &hdev->hbus.core; struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev); - struct sof_dsp_power_state target_state; + struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D0, + .substate = SOF_HDA_DSP_PM_D0I3, + }; int ret; - target_state.state = SOF_DSP_PM_D0; - /* DSP can enter D0I3 iff only D0I3-compatible streams are active */ - if (snd_sof_dsp_only_d0i3_compatible_stream_active(sdev)) - target_state.substate = SOF_HDA_DSP_PM_D0I3; - else - target_state.substate = SOF_HDA_DSP_PM_D0I0; - - /* remain in D0I0 */ - if (target_state.substate == SOF_HDA_DSP_PM_D0I0) + if (!snd_sof_dsp_only_d0i3_compatible_stream_active(sdev)) + /* remain in D0I0 */ return; /* This can fail but error cannot be propagated */ -- cgit v1.2.3 From 6f5d506d7ff1d9b1ffac0130f2958b9da41175f4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:33 -0600 Subject: ASoC: SOF: Intel: SoundWire: refine ACPI match We have existing platforms where the wrong machine is selected. We need to make sure the number of devices reported on a link matches what we expect for a link descriptor. This helps avoid using the TGL-RVP configuration for an HP platform or vice-versa, depending on the order in which they are inserted in the table. Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210208233336.59449-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 59 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 447163494b05..db868376039a 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1071,32 +1071,63 @@ static bool link_slaves_found(struct snd_sof_dev *sdev, struct sdw_intel_slave_id *ids = sdw->ids; int num_slaves = sdw->num_slaves; unsigned int part_id, link_id, unique_id, mfg_id; - int i, j; + int i, j, k; for (i = 0; i < link->num_adr; i++) { u64 adr = link->adr_d[i].adr; + int reported_part_count = 0; mfg_id = SDW_MFG_ID(adr); part_id = SDW_PART_ID(adr); link_id = SDW_DISCO_LINK_ID(adr); + + for (j = 0; j < num_slaves; j++) { + /* find out how many identical parts were reported on that link */ + if (ids[j].link_id == link_id && + ids[j].id.part_id == part_id && + ids[j].id.mfg_id == mfg_id) + reported_part_count++; + } + for (j = 0; j < num_slaves; j++) { + int expected_part_count = 0; + if (ids[j].link_id != link_id || ids[j].id.part_id != part_id || ids[j].id.mfg_id != mfg_id) continue; - /* - * we have to check unique id - * if there is more than one - * Slave on the link - */ - unique_id = SDW_UNIQUE_ID(adr); - if (link->num_adr == 1 || - ids[j].id.unique_id == SDW_IGNORED_UNIQUE_ID || - ids[j].id.unique_id == unique_id) { - dev_dbg(bus->dev, - "found %x at link %d\n", - part_id, link_id); - break; + + /* find out how many identical parts are expected */ + for (k = 0; k < link->num_adr; k++) { + u64 adr2 = link->adr_d[i].adr; + unsigned int part_id2, link_id2, mfg_id2; + + mfg_id2 = SDW_MFG_ID(adr2); + part_id2 = SDW_PART_ID(adr2); + link_id2 = SDW_DISCO_LINK_ID(adr2); + + if (link_id2 == link_id && + part_id2 == part_id && + mfg_id2 == mfg_id) + expected_part_count++; + } + + if (reported_part_count == expected_part_count) { + /* + * we have to check unique id + * if there is more than one + * Slave on the link + */ + unique_id = SDW_UNIQUE_ID(adr); + if (reported_part_count == 1 || + ids[j].id.unique_id == unique_id) { + dev_dbg(bus->dev, "found %x at link %d\n", + part_id, link_id); + break; + } + } else { + dev_dbg(bus->dev, "part %x reported %d expected %d on link %d, skipping\n", + part_id, reported_part_count, expected_part_count, link_id); } } if (j == num_slaves) { -- cgit v1.2.3 From 7aecf59770920cce5ff6e94b3809574364178126 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:34 -0600 Subject: ASoC: SOF: Intel: detect DMIC number in SoundWire mixed config The pinmux allows for 2 SoundWire links to be enabled along with DMICs. This was the default configuration on the TGL-RVP. One issue with this configuration is that we don't have a means to automatically detect how many DMICs are used, which in turn requires the user to manually rename the topology file required on a platform. This was borderline acceptable for Intel RVPs, but now that this configuration is present in HP devices we need to automate the process. This patch makes use of the NHLT information and will pass the DMIC number to the machine driver as a parameter. A follow-up patch will expose the DMIC number to userspace/UCM with the configuration strings. The Google devices do make use of DMICs instead of SoundWire link 2 and 3, but their topology is unique enough that they do not need any NHTL support or topology renaming. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 133 +++++++++++++++++++++++++++++----------------- 1 file changed, 85 insertions(+), 48 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index db868376039a..7ae2c2c451ef 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -285,11 +285,13 @@ static char *hda_model; module_param(hda_model, charp, 0444); MODULE_PARM_DESC(hda_model, "Use the given HDA board model."); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) static int hda_dmic_num = -1; module_param_named(dmic_num, hda_dmic_num, int, 0444); MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number"); +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI); module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444); MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver"); @@ -555,7 +557,7 @@ static int hda_init(struct snd_sof_dev *sdev) return ret; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) static int check_nhlt_dmic(struct snd_sof_dev *sdev) { @@ -598,6 +600,53 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev, return tplg_filename; } +static int dmic_topology_fixup(struct snd_sof_dev *sdev, + const char **tplg_filename, + const char *idisp_str, + int *dmic_found) +{ + const char *default_tplg_filename = *tplg_filename; + const char *fixed_tplg_filename; + const char *dmic_str; + int dmic_num; + + /* first check NHLT for DMICs */ + dmic_num = check_nhlt_dmic(sdev); + + /* allow for module parameter override */ + if (hda_dmic_num != -1) + dmic_num = hda_dmic_num; + + switch (dmic_num) { + case 1: + dmic_str = "-1ch"; + break; + case 2: + dmic_str = "-2ch"; + break; + case 3: + dmic_str = "-3ch"; + break; + case 4: + dmic_str = "-4ch"; + break; + default: + dmic_num = 0; + dmic_str = ""; + break; + } + + fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename, + idisp_str, dmic_str); + if (!fixed_tplg_filename) + return -ENOMEM; + + dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num); + *dmic_found = dmic_num; + *tplg_filename = fixed_tplg_filename; + + return 0; +} #endif static int hda_init_caps(struct snd_sof_dev *sdev) @@ -963,9 +1012,9 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) struct snd_sof_pdata *pdata = sdev->pdata; const char *tplg_filename; const char *idisp_str; - const char *dmic_str; int dmic_num = 0; int codec_num = 0; + int ret; int i; /* codec detection */ @@ -990,10 +1039,6 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) if (!pdata->machine && codec_num <= 2) { hda_mach = snd_soc_acpi_intel_hda_machines; - /* topology: use the info from hda_machines */ - pdata->tplg_filename = - hda_mach->sof_tplg_filename; - dev_info(bus->dev, "using HDA machine driver %s now\n", hda_mach->drv_name); @@ -1002,42 +1047,13 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) else idisp_str = ""; - /* first check NHLT for DMICs */ - dmic_num = check_nhlt_dmic(sdev); - - /* allow for module parameter override */ - if (hda_dmic_num != -1) - dmic_num = hda_dmic_num; - - switch (dmic_num) { - case 1: - dmic_str = "-1ch"; - break; - case 2: - dmic_str = "-2ch"; - break; - case 3: - dmic_str = "-3ch"; - break; - case 4: - dmic_str = "-4ch"; - break; - default: - dmic_num = 0; - dmic_str = ""; - break; - } - - tplg_filename = pdata->tplg_filename; - tplg_filename = fixup_tplg_name(sdev, tplg_filename, - idisp_str, dmic_str); - if (!tplg_filename) - return -EINVAL; - - dev_info(bus->dev, - "DMICs detected in NHLT tables: %d\n", - dmic_num); + /* topology: use the info from hda_machines */ + tplg_filename = hda_mach->sof_tplg_filename; + ret = dmic_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num); + if (ret < 0) + return ret; + hda_mach->mach_params.dmic_num = dmic_num; pdata->machine = hda_mach; pdata->tplg_filename = tplg_filename; } @@ -1049,7 +1065,6 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev) &pdata->machine->mach_params; mach_params->codec_mask = bus->codec_mask; mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi; - mach_params->dmic_num = dmic_num; } return 0; @@ -1144,7 +1159,6 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *pdata = sdev->pdata; const struct snd_soc_acpi_link_adr *link; - struct hdac_bus *bus = sof_to_bus(sdev); struct snd_soc_acpi_mach *mach; struct sof_intel_hda_dev *hdev; u32 link_mask; @@ -1192,10 +1206,8 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) break; } if (mach && mach->link_mask) { - dev_dbg(bus->dev, - "SoundWire machine driver %s topology %s\n", - mach->drv_name, - mach->sof_tplg_filename); + int dmic_num = 0; + pdata->machine = mach; mach->mach_params.links = mach->links; mach->mach_params.link_mask = mach->link_mask; @@ -1205,6 +1217,31 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) else pdata->fw_filename = pdata->desc->default_fw_filename; pdata->tplg_filename = mach->sof_tplg_filename; + + /* + * DMICs use up to 4 pins and are typically pin-muxed with SoundWire + * link 2 and 3, thus we only try to enable dmics if all conditions + * are true: + * a) link 2 and 3 are not used by SoundWire + * b) the NHLT table reports the presence of microphones + */ + if (!(mach->link_mask & GENMASK(3, 2))) { + const char *tplg_filename = mach->sof_tplg_filename; + int ret; + + ret = dmic_topology_fixup(sdev, &tplg_filename, "", &dmic_num); + + if (ret < 0) + return ret; + + pdata->tplg_filename = tplg_filename; + } + mach->mach_params.dmic_num = dmic_num; + + dev_dbg(sdev->dev, + "SoundWire machine driver %s topology %s\n", + mach->drv_name, + pdata->tplg_filename); } else { dev_info(sdev->dev, "No SoundWire machine driver found\n"); -- cgit v1.2.3 From b9088535e1021f11500f8417598b6af1f381f7dc Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 8 Feb 2021 17:33:35 -0600 Subject: ASoC: SOF: Intel: HDA: don't keep a temporary variable fixup_tplg_name() doesn't need to keep the string, allocated for filename - it's temporary. Reviewed-by: Kai Vehmanen Signed-off-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210208233336.59449-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7ae2c2c451ef..bd1cbef90278 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -581,22 +581,22 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev, const char *dmic_str) { const char *tplg_filename = NULL; - char *filename; - char *split_ext; + char *filename, *tmp; + const char *split_ext; - filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); + filename = kstrdup(sof_tplg_filename, GFP_KERNEL); if (!filename) return NULL; /* this assumes a .tplg extension */ - split_ext = strsep(&filename, "."); - if (split_ext) { + tmp = filename; + split_ext = strsep(&tmp, "."); + if (split_ext) tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s%s.tplg", split_ext, idisp_str, dmic_str); - if (!tplg_filename) - return NULL; - } + kfree(filename); + return tplg_filename; } -- cgit v1.2.3 From 026370cb5bd7ef7999bc4379ab89ffd7a73874f2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:36 -0600 Subject: ASoC: SOF: Intel: hda: add dev_dbg() when DMIC number is overridden It's useful for debug and system integration to show cases where we ignore the number of microphones reported by NHLT. Suggested-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index bd1cbef90278..0251bf83d0fe 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -614,8 +614,12 @@ static int dmic_topology_fixup(struct snd_sof_dev *sdev, dmic_num = check_nhlt_dmic(sdev); /* allow for module parameter override */ - if (hda_dmic_num != -1) + if (hda_dmic_num != -1) { + dev_dbg(sdev->dev, + "overriding DMICs detected in NHLT tables %d by kernel param %d\n", + dmic_num, hda_dmic_num); dmic_num = hda_dmic_num; + } switch (dmic_num) { case 1: -- cgit v1.2.3 From 271d9373db1c76f239fe3124e552b6b58b2af984 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 10 Feb 2021 12:52:37 +0200 Subject: ASoC: SOF: fix runtime pm usage mismatch after probe errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With current delayed probe implementation, sof_probe_complete is not called in case of errors. And as this function is responsible for decrementing runtime pm usage counter, this will result in following problem: - probe driver in conditions where probe will fail (to force the condition on Intel SOF systems, set "snd_sof_intel_hda_common.codec_mask=0") - unload driver (runtime-pm usage_count is leaked) - fix the issue by installing missing fw, modifying module parameters, etc actions - try to load driver again -> success, probe ok -> device never enters runtime suspend Fix the issue by storing result of delayed probe to a state variable and providing new snd_sof_device_probe_completed() to be queried from SOF PCI/ACPI/OF drivers. If probe never completed successfully, runtime PM was not set up and thus at remove(), we should not increment usage count anymore. Signed-off-by: Kai Vehmanen Reviewed-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Link: https://lore.kernel.org/r/20210210105237.2179273-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 10 ++++++++++ sound/soc/sof/sof-pci-dev.c | 3 ++- sound/soc/sof/sof-priv.h | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 8d13eb13fe08..6d8f7d9fd192 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -246,6 +246,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) if (plat_data->sof_probe_complete) plat_data->sof_probe_complete(sdev->dev); + sdev->probe_completed = true; + return 0; fw_trace_err: @@ -340,6 +342,14 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) } EXPORT_SYMBOL(snd_sof_device_probe); +bool snd_sof_device_probe_completed(struct device *dev) +{ + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + + return sdev->probe_completed; +} +EXPORT_SYMBOL(snd_sof_device_probe_completed); + int snd_sof_device_remove(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev); diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 388772f9c4d2..84990cc8aa7d 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -447,7 +447,8 @@ static void sof_pci_remove(struct pci_dev *pci) snd_sof_device_remove(&pci->dev); /* follow recommendation in pci-driver.c to increment usage counter */ - if (!(sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME)) + if (snd_sof_device_probe_completed(&pci->dev) && + !(sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME)) pm_runtime_get_noresume(&pci->dev); /* release pci regions and disable device */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 682c4b6d01ef..ad0d7ba2708c 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -389,6 +389,7 @@ struct snd_sof_dev { /* work queue in case the probe is implemented in two steps */ struct work_struct probe_work; + bool probe_completed; /* DSP HW differentiation */ struct snd_sof_pdata *pdata; @@ -464,6 +465,7 @@ struct snd_sof_dev { int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data); int snd_sof_device_remove(struct device *dev); int snd_sof_device_shutdown(struct device *dev); +bool snd_sof_device_probe_completed(struct device *dev); int snd_sof_runtime_suspend(struct device *dev); int snd_sof_runtime_resume(struct device *dev); -- cgit v1.2.3 From 53129e66e4b716ea7cffa4477a96ccb48f78e7ac Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 11 Feb 2021 19:24:40 +0200 Subject: ASoC: SOF: relax ABI checks and avoid unnecessary warnings With recent SOF 1.7 pre-releases, kernel has been emitting following warnings at probe: [10006.645216] sof-audio-pci 0000:00:1f.3: warn: FW ABI is more recent than kernel [10006.652137] sof-audio-pci 0000:00:1f.3: warn: topology ABI is more recent than kernel The warnings are emitted due to increase of the patch-level in firmware mainline (to 3.17.1). But the patch level should not be considered even in the strict ABI check, so modify the kernel side logic that makes the check and only consider the major.minor components. BugLink: https://github.com/thesofproject/linux/issues/2647 Signed-off-by: Kai Vehmanen Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20210211172440.2371447-1-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc.c | 2 +- sound/soc/sof/topology.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sof') diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 1bc3d6282f16..c2d07b783f60 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -798,7 +798,7 @@ int snd_sof_ipc_valid(struct snd_sof_dev *sdev) return -EINVAL; } - if (v->abi_version > SOF_ABI_VERSION) { + if (SOF_ABI_VERSION_MINOR(v->abi_version) > SOF_ABI_MINOR) { if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { dev_warn(sdev->dev, "warn: FW ABI is more recent than kernel\n"); } else { diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index d6e1f33eb1e9..10f99620eb31 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -3658,7 +3658,7 @@ static int sof_manifest(struct snd_soc_component *scomp, int index, return -EINVAL; } - if (abi_version > SOF_ABI_VERSION) { + if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n"); } else { -- cgit v1.2.3