diff options
-rw-r--r-- | drivers/soundwire/intel_ace2x.c | 7 | ||||
-rw-r--r-- | include/sound/hda-mlink.h | 4 | ||||
-rw-r--r-- | sound/soc/codecs/es8323.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/rt721-sdca.c | 8 | ||||
-rw-r--r-- | sound/soc/codecs/rt722-sdca.c | 8 | ||||
-rw-r--r-- | sound/soc/intel/Kconfig | 3 | ||||
-rw-r--r-- | sound/soc/intel/avs/pcm.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/boards/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/intel/common/Makefile | 3 | ||||
-rw-r--r-- | sound/soc/intel/common/sst-dsp-priv.h | 101 | ||||
-rw-r--r-- | sound/soc/intel/common/sst-dsp.c | 250 | ||||
-rw-r--r-- | sound/soc/intel/common/sst-dsp.h | 61 | ||||
-rw-r--r-- | sound/soc/intel/common/sst-ipc.c | 294 | ||||
-rw-r--r-- | sound/soc/intel/common/sst-ipc.h | 86 | ||||
-rw-r--r-- | sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 5 | ||||
-rw-r--r-- | sound/soc/qcom/sm8250.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-dsp.c | 5 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-mlink.c | 18 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.c | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/lnl.c | 10 |
20 files changed, 39 insertions, 835 deletions
diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index fff312c6968d..3084f0ac7159 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -175,6 +175,9 @@ static int intel_link_power_up(struct sdw_intel *sdw) __func__, ret); goto out; } + + hdac_bus_eml_enable_interrupt_unlocked(sdw->link_res->hbus, true, + AZX_REG_ML_LEPTR_ID_SDW, true); } *shim_mask |= BIT(link_id); @@ -201,6 +204,10 @@ static int intel_link_power_down(struct sdw_intel *sdw) *shim_mask &= ~BIT(link_id); + if (!*shim_mask) + hdac_bus_eml_enable_interrupt_unlocked(sdw->link_res->hbus, true, + AZX_REG_ML_LEPTR_ID_SDW, false); + ret = hdac_bus_eml_sdw_power_down_unlocked(sdw->link_res->hbus, link_id); if (ret < 0) { dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_power_down failed: %d\n", diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h index 9ced94686ce3..6774f4b9e5fc 100644 --- a/include/sound/hda-mlink.h +++ b/include/sound/hda-mlink.h @@ -15,6 +15,7 @@ int hda_bus_ml_init(struct hdac_bus *bus); void hda_bus_ml_free(struct hdac_bus *bus); int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid); +void hdac_bus_eml_enable_interrupt_unlocked(struct hdac_bus *bus, bool alt, int elid, bool enable); void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable); bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid); @@ -72,6 +73,9 @@ static inline int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) { return 0; } static inline void +hdac_bus_eml_enable_interrupt_unlocked(struct hdac_bus *bus, bool alt, int elid, bool enable) { } + +static inline void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable) { } static inline bool diff --git a/sound/soc/codecs/es8323.c b/sound/soc/codecs/es8323.c index c09bd92b2ed3..6f4fa36ea34d 100644 --- a/sound/soc/codecs/es8323.c +++ b/sound/soc/codecs/es8323.c @@ -743,7 +743,7 @@ static int es8323_i2c_probe(struct i2c_client *i2c_client) struct device *dev = &i2c_client->dev; es8323 = devm_kzalloc(dev, sizeof(*es8323), GFP_KERNEL); - if (IS_ERR(es8323)) + if (!es8323) return -ENOMEM; i2c_set_clientdata(i2c_client, es8323); diff --git a/sound/soc/codecs/rt721-sdca.c b/sound/soc/codecs/rt721-sdca.c index 201cb667c8c1..bdd160b80b64 100644 --- a/sound/soc/codecs/rt721-sdca.c +++ b/sound/soc/codecs/rt721-sdca.c @@ -611,12 +611,8 @@ static int rt721_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol, if (!adc_vol_flag) /* boost gain */ ctl = regvalue / boost_step; - else { /* ADC gain */ - if (adc_vol_flag) - ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset); - else - ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset); - } + else /* ADC gain */ + ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset); ucontrol->value.integer.value[i] = ctl; } diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c index e5bd9ef812de..f9f7512ca360 100644 --- a/sound/soc/codecs/rt722-sdca.c +++ b/sound/soc/codecs/rt722-sdca.c @@ -607,12 +607,8 @@ static int rt722_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol, if (!adc_vol_flag) /* boost gain */ ctl = regvalue / boost_step; - else { /* ADC gain */ - if (adc_vol_flag) - ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset); - else - ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset); - } + else /* ADC gain */ + ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset); ucontrol->value.integer.value[i] = ctl; } diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index a32fb0a8d7d7..5bb7047c170f 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -15,9 +15,6 @@ config SND_SOC_INTEL_SST_TOPLEVEL if SND_SOC_INTEL_SST_TOPLEVEL -config SND_SOC_INTEL_SST - tristate - config SND_SOC_INTEL_CATPT tristate "Haswell and Broadwell" depends on ACPI || COMPILE_TEST diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index afc0fc74cf94..b37b6eeaf86a 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -490,7 +490,7 @@ static int avs_pcm_hw_constraints_init(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS, SNDRV_PCM_HW_PARAM_RATE, -1); - return ret; + return 0; } static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index cc10ae58b0c7..9b80b19bb8d0 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -519,6 +519,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT712_SDCA_DMIC_SDW select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW + select SND_SOC_RT721_SDCA_SDW select SND_SOC_RT722_SDCA_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile index 91e146e2487d..da551144ec0f 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -snd-soc-sst-dsp-y := sst-dsp.o -snd-soc-sst-ipc-y := sst-ipc.o snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \ soc-acpi-intel-hsw-bdw-match.o \ soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ @@ -18,5 +16,4 @@ snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-matc snd-soc-acpi-intel-match-y += soc-acpi-intel-ssp-common.o -obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h deleted file mode 100644 index de32bb9afccb..000000000000 --- a/sound/soc/intel/common/sst-dsp-priv.h +++ /dev/null @@ -1,101 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel Smart Sound Technology - * - * Copyright (C) 2013, Intel Corporation - */ - -#ifndef __SOUND_SOC_SST_DSP_PRIV_H -#define __SOUND_SOC_SST_DSP_PRIV_H - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/firmware.h> - -#include "../skylake/skl-sst-dsp.h" - -/* - * DSP Operations exported by platform Audio DSP driver. - */ -struct sst_ops { - /* Shim IO */ - void (*write)(void __iomem *addr, u32 offset, u32 value); - u32 (*read)(void __iomem *addr, u32 offset); - - /* IRQ handlers */ - irqreturn_t (*irq_handler)(int irq, void *context); - - /* SST init and free */ - int (*init)(struct sst_dsp *sst); - void (*free)(struct sst_dsp *sst); -}; - -/* - * Audio DSP memory offsets and addresses. - */ -struct sst_addr { - u32 sram0_base; - u32 sram1_base; - u32 w0_stat_sz; - u32 w0_up_sz; - void __iomem *lpe; - void __iomem *shim; -}; - -/* - * Audio DSP Mailbox configuration. - */ -struct sst_mailbox { - void __iomem *in_base; - void __iomem *out_base; - size_t in_size; - size_t out_size; -}; - -/* - * Generic SST Shim Interface. - */ -struct sst_dsp { - - /* Shared for all platforms */ - - /* runtime */ - struct sst_dsp_device *sst_dev; - spinlock_t spinlock; /* IPC locking */ - struct mutex mutex; /* DSP FW lock */ - struct device *dev; - void *thread_context; - int irq; - u32 id; - - /* operations */ - struct sst_ops *ops; - - /* debug FS */ - struct dentry *debugfs_root; - - /* base addresses */ - struct sst_addr addr; - - /* mailbox */ - struct sst_mailbox mailbox; - - /* SST FW files loaded and their modules */ - struct list_head module_list; - - /* SKL data */ - - const char *fw_name; - - /* To allocate CL dma buffers */ - struct skl_dsp_loader_ops dsp_ops; - struct skl_dsp_fw_ops fw_ops; - int sst_state; - struct skl_cl_dev cl_dev; - u32 intr_status; - const struct firmware *fw; - struct snd_dma_buffer dmab; -}; - -#endif diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c deleted file mode 100644 index cdd2f7cf50ae..000000000000 --- a/sound/soc/intel/common/sst-dsp.c +++ /dev/null @@ -1,250 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Smart Sound Technology (SST) DSP Core Driver - * - * Copyright (C) 2013, Intel Corporation - */ - -#include <linux/slab.h> -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/io-64-nonatomic-lo-hi.h> -#include <linux/delay.h> - -#include "sst-dsp.h" -#include "sst-dsp-priv.h" - -#define CREATE_TRACE_POINTS -#include <trace/events/intel-sst.h> - -/* Internal generic low-level SST IO functions - can be overidden */ -void sst_shim32_write(void __iomem *addr, u32 offset, u32 value) -{ - writel(value, addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_write); - -u32 sst_shim32_read(void __iomem *addr, u32 offset) -{ - return readl(addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_read); - -void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value) -{ - writeq(value, addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_write64); - -u64 sst_shim32_read64(void __iomem *addr, u32 offset) -{ - return readq(addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_read64); - -/* Public API */ -void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value) -{ - unsigned long flags; - - spin_lock_irqsave(&sst->spinlock, flags); - sst->ops->write(sst->addr.shim, offset, value); - spin_unlock_irqrestore(&sst->spinlock, flags); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_write); - -u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset) -{ - unsigned long flags; - u32 val; - - spin_lock_irqsave(&sst->spinlock, flags); - val = sst->ops->read(sst->addr.shim, offset); - spin_unlock_irqrestore(&sst->spinlock, flags); - - return val; -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_read); - -void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value) -{ - sst->ops->write(sst->addr.shim, offset, value); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_write_unlocked); - -u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset) -{ - return sst->ops->read(sst->addr.shim, offset); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_read_unlocked); - -int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - bool change; - unsigned int old, new; - u32 ret; - - ret = sst_dsp_shim_read_unlocked(sst, offset); - - old = ret; - new = (old & (~mask)) | (value & mask); - - change = (old != new); - if (change) - sst_dsp_shim_write_unlocked(sst, offset, new); - - return change; -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_unlocked); - -/* This is for registers bits with attribute RWC */ -void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - unsigned int old, new; - u32 ret; - - ret = sst_dsp_shim_read_unlocked(sst, offset); - - old = ret; - new = (old & (~mask)) | (value & mask); - - sst_dsp_shim_write_unlocked(sst, offset, new); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced_unlocked); - -int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - unsigned long flags; - bool change; - - spin_lock_irqsave(&sst->spinlock, flags); - change = sst_dsp_shim_update_bits_unlocked(sst, offset, mask, value); - spin_unlock_irqrestore(&sst->spinlock, flags); - return change; -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits); - -/* This is for registers bits with attribute RWC */ -void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - unsigned long flags; - - spin_lock_irqsave(&sst->spinlock, flags); - sst_dsp_shim_update_bits_forced_unlocked(sst, offset, mask, value); - spin_unlock_irqrestore(&sst->spinlock, flags); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced); - -int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, - u32 target, u32 time, char *operation) -{ - u32 reg; - unsigned long timeout; - int k = 0, s = 500; - - /* - * split the loop into sleeps of varying resolution. more accurately, - * the range of wakeups are: - * Phase 1(first 5ms): min sleep 0.5ms; max sleep 1ms. - * Phase 2:( 5ms to 10ms) : min sleep 0.5ms; max sleep 10ms - * (usleep_range (500, 1000) and usleep_range(5000, 10000) are - * both possible in this phase depending on whether k > 10 or not). - * Phase 3: (beyond 10 ms) min sleep 5ms; max sleep 10ms. - */ - - timeout = jiffies + msecs_to_jiffies(time); - while ((((reg = sst_dsp_shim_read_unlocked(ctx, offset)) & mask) != target) - && time_before(jiffies, timeout)) { - k++; - if (k > 10) - s = 5000; - - usleep_range(s, 2*s); - } - - if ((reg & mask) == target) { - dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n", - reg, operation); - - return 0; - } - - dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s timedout\n", - reg, operation); - return -ETIME; -} -EXPORT_SYMBOL_GPL(sst_dsp_register_poll); - -int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, size_t inbox_size, - u32 outbox_offset, size_t outbox_size) -{ - sst->mailbox.in_base = sst->addr.lpe + inbox_offset; - sst->mailbox.out_base = sst->addr.lpe + outbox_offset; - sst->mailbox.in_size = inbox_size; - sst->mailbox.out_size = outbox_size; - return 0; -} -EXPORT_SYMBOL_GPL(sst_dsp_mailbox_init); - -void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_outbox_write(bytes); - - memcpy_toio(sst->mailbox.out_base, message, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_outbox_wdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_outbox_write); - -void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_outbox_read(bytes); - - memcpy_fromio(message, sst->mailbox.out_base, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_outbox_rdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_outbox_read); - -void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_inbox_write(bytes); - - memcpy_toio(sst->mailbox.in_base, message, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_inbox_wdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_inbox_write); - -void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_inbox_read(bytes); - - memcpy_fromio(message, sst->mailbox.in_base, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_inbox_rdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood"); -MODULE_DESCRIPTION("Intel SST Core"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h deleted file mode 100644 index 998b1a052281..000000000000 --- a/sound/soc/intel/common/sst-dsp.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel Smart Sound Technology (SST) Core - * - * Copyright (C) 2013, Intel Corporation - */ - -#ifndef __SOUND_SOC_SST_DSP_H -#define __SOUND_SOC_SST_DSP_H - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/interrupt.h> - -struct sst_dsp; - -/* - * SST Device. - * - * This structure is populated by the SST core driver. - */ -struct sst_dsp_device { - /* Mandatory fields */ - struct sst_ops *ops; - irqreturn_t (*thread)(int irq, void *context); - void *thread_context; -}; - -/* SHIM Read / Write */ -void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value); -u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset); -int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); -void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); - -/* SHIM Read / Write Unlocked for callers already holding sst lock */ -void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value); -u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset); -int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); -void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); - -/* Internal generic low-level SST IO functions - can be overidden */ -void sst_shim32_write(void __iomem *addr, u32 offset, u32 value); -u32 sst_shim32_read(void __iomem *addr, u32 offset); -void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value); -u64 sst_shim32_read64(void __iomem *addr, u32 offset); - -/* Mailbox management */ -int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, - size_t inbox_size, u32 outbox_offset, size_t outbox_size); -void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes); -void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes); -void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes); -void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes); -int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, - u32 target, u32 time, char *operation); - -#endif diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c deleted file mode 100644 index 6b2c83f9f010..000000000000 --- a/sound/soc/intel/common/sst-ipc.c +++ /dev/null @@ -1,294 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel SST generic IPC Support - * - * Copyright (C) 2015, Intel Corporation - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/spinlock.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <linux/workqueue.h> -#include <linux/sched.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <sound/asound.h> - -#include "sst-dsp.h" -#include "sst-dsp-priv.h" -#include "sst-ipc.h" - -/* IPC message timeout (msecs) */ -#define IPC_TIMEOUT_MSECS 300 - -#define IPC_EMPTY_LIST_SIZE 8 - -/* locks held by caller */ -static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc) -{ - struct ipc_message *msg = NULL; - - if (!list_empty(&ipc->empty_list)) { - msg = list_first_entry(&ipc->empty_list, struct ipc_message, - list); - list_del(&msg->list); - } - - return msg; -} - -static int tx_wait_done(struct sst_generic_ipc *ipc, - struct ipc_message *msg, struct sst_ipc_message *reply) -{ - unsigned long flags; - int ret; - - /* wait for DSP completion (in all cases atm inc pending) */ - ret = wait_event_timeout(msg->waitq, msg->complete, - msecs_to_jiffies(IPC_TIMEOUT_MSECS)); - - spin_lock_irqsave(&ipc->dsp->spinlock, flags); - if (ret == 0) { - if (ipc->ops.shim_dbg != NULL) - ipc->ops.shim_dbg(ipc, "message timeout"); - - list_del(&msg->list); - ret = -ETIMEDOUT; - } else { - - /* copy the data returned from DSP */ - if (reply) { - reply->header = msg->rx.header; - if (reply->data) - memcpy(reply->data, msg->rx.data, msg->rx.size); - } - ret = msg->errno; - } - - list_add_tail(&msg->list, &ipc->empty_list); - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); - return ret; -} - -static int ipc_tx_message(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, - struct sst_ipc_message *reply, int wait) -{ - struct ipc_message *msg; - unsigned long flags; - - spin_lock_irqsave(&ipc->dsp->spinlock, flags); - - msg = msg_get_empty(ipc); - if (msg == NULL) { - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); - return -EBUSY; - } - - msg->tx.header = request.header; - msg->tx.size = request.size; - msg->rx.header = 0; - msg->rx.size = reply ? reply->size : 0; - msg->wait = wait; - msg->errno = 0; - msg->pending = false; - msg->complete = false; - - if ((request.size) && (ipc->ops.tx_data_copy != NULL)) - ipc->ops.tx_data_copy(msg, request.data, request.size); - - list_add_tail(&msg->list, &ipc->tx_list); - schedule_work(&ipc->kwork); - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); - - if (wait) - return tx_wait_done(ipc, msg, reply); - else - return 0; -} - -static int msg_empty_list_init(struct sst_generic_ipc *ipc) -{ - int i; - - ipc->msg = kcalloc(IPC_EMPTY_LIST_SIZE, sizeof(struct ipc_message), - GFP_KERNEL); - if (ipc->msg == NULL) - return -ENOMEM; - - for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { - ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); - if (ipc->msg[i].tx.data == NULL) - goto free_mem; - - ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); - if (ipc->msg[i].rx.data == NULL) { - kfree(ipc->msg[i].tx.data); - goto free_mem; - } - - init_waitqueue_head(&ipc->msg[i].waitq); - list_add(&ipc->msg[i].list, &ipc->empty_list); - } - - return 0; - -free_mem: - while (i > 0) { - kfree(ipc->msg[i-1].tx.data); - kfree(ipc->msg[i-1].rx.data); - --i; - } - kfree(ipc->msg); - - return -ENOMEM; -} - -static void ipc_tx_msgs(struct work_struct *work) -{ - struct sst_generic_ipc *ipc = - container_of(work, struct sst_generic_ipc, kwork); - struct ipc_message *msg; - - spin_lock_irq(&ipc->dsp->spinlock); - - while (!list_empty(&ipc->tx_list) && !ipc->pending) { - /* if the DSP is busy, we will TX messages after IRQ. - * also postpone if we are in the middle of processing - * completion irq - */ - if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) { - dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n"); - break; - } - - msg = list_first_entry(&ipc->tx_list, struct ipc_message, list); - list_move(&msg->list, &ipc->rx_list); - - if (ipc->ops.tx_msg != NULL) - ipc->ops.tx_msg(ipc, msg); - } - - spin_unlock_irq(&ipc->dsp->spinlock); -} - -int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply) -{ - int ret; - - /* - * DSP maybe in lower power active state, so - * check if the DSP supports DSP lp On method - * if so invoke that before sending IPC - */ - if (ipc->ops.check_dsp_lp_on) - if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) - return -EIO; - - ret = ipc_tx_message(ipc, request, reply, 1); - - if (ipc->ops.check_dsp_lp_on) - if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) - return -EIO; - - return ret; -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); - -int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request) -{ - return ipc_tx_message(ipc, request, NULL, 0); -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); - -int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply) -{ - return ipc_tx_message(ipc, request, reply, 1); -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); - -struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, - u64 header) -{ - struct ipc_message *msg; - u64 mask; - - if (ipc->ops.reply_msg_match != NULL) - header = ipc->ops.reply_msg_match(header, &mask); - else - mask = (u64)-1; - - if (list_empty(&ipc->rx_list)) { - dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n", - header); - return NULL; - } - - list_for_each_entry(msg, &ipc->rx_list, list) { - if ((msg->tx.header & mask) == header) - return msg; - } - - return NULL; -} -EXPORT_SYMBOL_GPL(sst_ipc_reply_find_msg); - -/* locks held by caller */ -void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, - struct ipc_message *msg) -{ - msg->complete = true; - - if (!msg->wait) - list_add_tail(&msg->list, &ipc->empty_list); - else - wake_up(&msg->waitq); -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete); - -int sst_ipc_init(struct sst_generic_ipc *ipc) -{ - int ret; - - INIT_LIST_HEAD(&ipc->tx_list); - INIT_LIST_HEAD(&ipc->rx_list); - INIT_LIST_HEAD(&ipc->empty_list); - init_waitqueue_head(&ipc->wait_txq); - - ret = msg_empty_list_init(ipc); - if (ret < 0) - return -ENOMEM; - - INIT_WORK(&ipc->kwork, ipc_tx_msgs); - return 0; -} -EXPORT_SYMBOL_GPL(sst_ipc_init); - -void sst_ipc_fini(struct sst_generic_ipc *ipc) -{ - int i; - - cancel_work_sync(&ipc->kwork); - - if (ipc->msg) { - for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { - kfree(ipc->msg[i].tx.data); - kfree(ipc->msg[i].rx.data); - } - kfree(ipc->msg); - } -} -EXPORT_SYMBOL_GPL(sst_ipc_fini); - -/* Module information */ -MODULE_AUTHOR("Jin Yao"); -MODULE_DESCRIPTION("Intel SST IPC generic"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h deleted file mode 100644 index 86d44ceadc92..000000000000 --- a/sound/soc/intel/common/sst-ipc.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel SST generic IPC Support - * - * Copyright (C) 2015, Intel Corporation - */ - -#ifndef __SST_GENERIC_IPC_H -#define __SST_GENERIC_IPC_H - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/wait.h> -#include <linux/list.h> -#include <linux/workqueue.h> -#include <linux/sched.h> - -struct sst_ipc_message { - u64 header; - void *data; - size_t size; -}; - -struct ipc_message { - struct list_head list; - struct sst_ipc_message tx; - struct sst_ipc_message rx; - - wait_queue_head_t waitq; - bool pending; - bool complete; - bool wait; - int errno; -}; - -struct sst_generic_ipc; -struct sst_dsp; - -struct sst_plat_ipc_ops { - void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); - void (*shim_dbg)(struct sst_generic_ipc *, const char *); - void (*tx_data_copy)(struct ipc_message *, char *, size_t); - u64 (*reply_msg_match)(u64 header, u64 *mask); - bool (*is_dsp_busy)(struct sst_dsp *dsp); - int (*check_dsp_lp_on)(struct sst_dsp *dsp, bool state); -}; - -/* SST generic IPC data */ -struct sst_generic_ipc { - struct device *dev; - struct sst_dsp *dsp; - - /* IPC messaging */ - struct list_head tx_list; - struct list_head rx_list; - struct list_head empty_list; - wait_queue_head_t wait_txq; - struct task_struct *tx_thread; - struct work_struct kwork; - bool pending; - struct ipc_message *msg; - int tx_data_max_size; - int rx_data_max_size; - - struct sst_plat_ipc_ops ops; -}; - -int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply); - -int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request); - -int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply); - -struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, - u64 header); - -void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, - struct ipc_message *msg); - -int sst_ipc_init(struct sst_generic_ipc *ipc); -void sst_ipc_fini(struct sst_generic_ipc *ipc); - -#endif diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c index 2a48f5fd6826..69a091dad88d 100644 --- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c +++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c @@ -2422,7 +2422,6 @@ static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream, unsigned int channels = params_channels(params); snd_pcm_format_t format = params_format(params); int width = snd_pcm_format_physical_width(format); - int ret; if (!is_valid_etdm_dai(dai->id)) return -EINVAL; @@ -2450,9 +2449,7 @@ static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream, etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN; } - ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id); - - return ret; + return mtk_dai_etdm_configure(afe, rate, channels, width, dai->id); } static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai, diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 19adadedc88a..91e9bba192c0 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -78,7 +78,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream) return qcom_snd_sdw_startup(substream); } -static void sm2450_snd_shutdown(struct snd_pcm_substream *substream) +static void sm8250_snd_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -123,7 +123,7 @@ static int sm8250_snd_hw_free(struct snd_pcm_substream *substream) static const struct snd_soc_ops sm8250_be_ops = { .startup = sm8250_snd_startup, - .shutdown = sm2450_snd_shutdown, + .shutdown = sm8250_snd_shutdown, .hw_params = sm8250_snd_hw_params, .hw_free = sm8250_snd_hw_free, .prepare = sm8250_snd_prepare, diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 4c88522d4048..6028a80418bb 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -858,7 +858,6 @@ skip_dsp: static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) { - const struct sof_intel_dsp_desc *chip; int ret; /* display codec must be powered before link reset */ @@ -891,10 +890,6 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) hda_dsp_ctrl_ppcap_int_enable(sdev, true); } - chip = get_chip_info(sdev->pdata); - if (chip && chip->hw_ip_version >= SOF_INTEL_ACE_2_0) - hda_sdw_int_enable(sdev, true); - cleanup: /* display codec can powered off after controller init */ hda_codec_i915_display_power(sdev, false); diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c index 9a3559c78b62..46f89d6d06f8 100644 --- a/sound/soc/sof/intel/hda-mlink.c +++ b/sound/soc/sof/intel/hda-mlink.c @@ -481,6 +481,24 @@ int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) } EXPORT_SYMBOL_NS(hdac_bus_eml_get_count, SND_SOC_SOF_HDA_MLINK); +void hdac_bus_eml_enable_interrupt_unlocked(struct hdac_bus *bus, bool alt, int elid, bool enable) +{ + struct hdac_ext2_link *h2link; + struct hdac_ext_link *hlink; + + h2link = find_ext2_link(bus, alt, elid); + if (!h2link) + return; + + if (!h2link->intc) + return; + + hlink = &h2link->hext_link; + + hdaml_link_enable_interrupt(hlink->ml_addr + AZX_REG_ML_LCTL, enable); +} +EXPORT_SYMBOL_NS(hdac_bus_eml_enable_interrupt_unlocked, SND_SOC_SOF_HDA_MLINK); + void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable) { struct hdac_ext2_link *h2link; diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 70fc08c8fc99..e4cb4ffc7270 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -866,8 +866,6 @@ skip_dsp_setup: dev_err(sdev->dev, "could not startup SoundWire links\n"); goto disable_pp_cap; } - - hda_sdw_int_enable(sdev, true); } init_waitqueue_head(&hdev->waitq); diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c index 3d5a1f8b17e5..e3c4b4a0d705 100644 --- a/sound/soc/sof/intel/lnl.c +++ b/sound/soc/sof/intel/lnl.c @@ -192,16 +192,8 @@ static bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) return hdac_bus_eml_check_interrupt(bus, true, AZX_REG_ML_LEPTR_ID_SDW); } -static void lnl_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) -{ - struct hdac_bus *bus = sof_to_bus(sdev); - - hdac_bus_eml_enable_interrupt(bus, true, AZX_REG_ML_LEPTR_ID_SDW, enable); -} - static int lnl_dsp_disable_interrupts(struct snd_sof_dev *sdev) { - lnl_enable_sdw_irq(sdev, false); mtl_disable_ipc_interrupts(sdev); return mtl_enable_interrupts(sdev, false); } @@ -237,7 +229,6 @@ const struct sof_intel_dsp_desc lnl_chip_info = { .ssp_count = MTL_SSP_COUNT, .d0i3_offset = MTL_HDA_VS_D0I3C, .read_sdw_lcount = hda_sdw_check_lcount_ext, - .enable_sdw_irq = lnl_enable_sdw_irq, .check_sdw_irq = lnl_dsp_check_sdw_irq, .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, .sdw_process_wakeen = hda_sdw_process_wakeen_common, @@ -262,7 +253,6 @@ const struct sof_intel_dsp_desc ptl_chip_info = { .ssp_count = MTL_SSP_COUNT, .d0i3_offset = MTL_HDA_VS_D0I3C, .read_sdw_lcount = hda_sdw_check_lcount_ext, - .enable_sdw_irq = lnl_enable_sdw_irq, .check_sdw_irq = lnl_dsp_check_sdw_irq, .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, .check_ipc_irq = mtl_dsp_check_ipc_irq, |