summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/avs/ipc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-03-14 11:10:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-03-14 11:10:43 -0700
commitfe46a7dd189e25604716c03576d05ac8a5209743 (patch)
treede7572a9f41bb91e570dce1053283e56d1efdd94 /sound/soc/intel/avs/ipc.c
parent705c1da8fa4816fb0159b5602fef1df5946a3ee2 (diff)
parenta39d51ff1f52cd0b6fe7d379ac93bd8b4237d1b7 (diff)
downloadlinux-stable-fe46a7dd189e25604716c03576d05ac8a5209743.tar.gz
linux-stable-fe46a7dd189e25604716c03576d05ac8a5209743.tar.bz2
linux-stable-fe46a7dd189e25604716c03576d05ac8a5209743.zip
Merge tag 'sound-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This was a relatively calm development cycle. Most of changes are rather small device-specific fixes and enhancements. The only significant changes in ALSA core are code refactoring with the recent cleanup infrastructure, which should bring no functionality changes. Some highlights below: Core: - Lots of cleanups in ALSA core code with automatic kfree cleanup and locking guard macros - New ALSA core kunit test ASoC: - SoundWire support for AMD ACP 6.3 systems - Support for reporting version information for AVS firmware - Support DSPless mode for Intel Soundwire systems - Support for configuring CS35L56 amplifiers using EFI calibration data - Log which component is being operated on as part of power management trace events. - Support for Microchip SAM9x7, NXP i.MX95 and Qualcomm WCD939x HD- and USB-audio: - More Cirrus HD-audio codec support - TAS2781 HD-audio codec fixes - Scarlett2 mixer fixes Others: - Enhancement of virtio driver for audio control supports - Cleanups of legacy PM code with new macros - Firewire sound updates" * tag 'sound-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (307 commits) ALSA: usb-audio: Stop parsing channels bits when all channels are found. ALSA: hda/tas2781: remove unnecessary runtime_pm calls ALSA: hda/realtek - ALC236 fix volume mute & mic mute LED on some HP models ALSA: aaci: Delete unused variable in aaci_do_suspend ALSA: scarlett2: Fix Scarlett 4th Gen input gain range again ALSA: scarlett2: Fix Scarlett 4th Gen input gain range ALSA: scarlett2: Fix Scarlett 4th Gen autogain status values ALSA: scarlett2: Fix Scarlett 4th Gen 4i4 low-voltage detection ALSA: hda/tas2781: restore power state after system_resume ALSA: hda/tas2781: do not call pm_runtime_force_* in system_resume/suspend ALSA: hda/tas2781: do not reset cur_* values in runtime_suspend ALSA: hda/tas2781: add lock to system_suspend ALSA: hda/tas2781: use dev_dbg in system_resume ALSA: hda/realtek: fix ALC285 issues on HP Envy x360 laptops platform/x86: serial-multi-instantiate: Add support for CS35L54 and CS35L57 ALSA: hda: cs35l56: Add support for CS35L54 and CS35L57 ASoC: cs35l56: Add support for CS35L54 and CS35L57 ASoC: Intel: catpt: Carefully use PCI bitwise constants ALSA: hda: hda_component: Include sound/hda_codec.h ALSA: hda: hda_component: Add missing #include guards ...
Diffstat (limited to 'sound/soc/intel/avs/ipc.c')
-rw-r--r--sound/soc/intel/avs/ipc.c66
1 files changed, 21 insertions, 45 deletions
diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
index 65bfc83bd1f0..ad0e535b3c2e 100644
--- a/sound/soc/intel/avs/ipc.c
+++ b/sound/soc/intel/avs/ipc.c
@@ -301,10 +301,10 @@ void avs_dsp_process_response(struct avs_dev *adev, u64 header)
complete(&ipc->busy_completion);
}
-irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
+irqreturn_t avs_irq_handler(struct avs_dev *adev)
{
- struct avs_dev *adev = dev_id;
struct avs_ipc *ipc = adev->ipc;
+ const struct avs_spec *const spec = adev->spec;
u32 adspis, hipc_rsp, hipc_ack;
irqreturn_t ret = IRQ_NONE;
@@ -312,35 +312,35 @@ irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
if (adspis == UINT_MAX || !(adspis & AVS_ADSP_ADSPIS_IPC))
return ret;
- hipc_ack = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCIE);
- hipc_rsp = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
+ hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset);
+ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);
/* DSP acked host's request */
- if (hipc_ack & SKL_ADSP_HIPCIE_DONE) {
+ if (hipc_ack & spec->hipc->ack_done_mask) {
/*
* As an extra precaution, mask done interrupt. Code executed
* due to complete() found below does not assume any masking.
*/
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
AVS_ADSP_HIPCCTL_DONE, 0);
complete(&ipc->done_completion);
/* tell DSP it has our attention */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCIE,
- SKL_ADSP_HIPCIE_DONE,
- SKL_ADSP_HIPCIE_DONE);
+ snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset,
+ spec->hipc->ack_done_mask,
+ spec->hipc->ack_done_mask);
/* unmask done interrupt */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
AVS_ADSP_HIPCCTL_DONE,
AVS_ADSP_HIPCCTL_DONE);
ret = IRQ_HANDLED;
}
/* DSP sent new response to process */
- if (hipc_rsp & SKL_ADSP_HIPCT_BUSY) {
+ if (hipc_rsp & spec->hipc->rsp_busy_mask) {
/* mask busy interrupt */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
AVS_ADSP_HIPCCTL_BUSY, 0);
ret = IRQ_WAKE_THREAD;
@@ -349,40 +349,14 @@ irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
return ret;
}
-irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id)
-{
- struct avs_dev *adev = dev_id;
- union avs_reply_msg msg;
- u32 hipct, hipcte;
-
- hipct = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
- hipcte = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCTE);
-
- /* ensure DSP sent new response to process */
- if (!(hipct & SKL_ADSP_HIPCT_BUSY))
- return IRQ_NONE;
-
- msg.primary = hipct;
- msg.ext.val = hipcte;
- avs_dsp_process_response(adev, msg.val);
-
- /* tell DSP we accepted its message */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCT,
- SKL_ADSP_HIPCT_BUSY, SKL_ADSP_HIPCT_BUSY);
- /* unmask busy interrupt */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
- AVS_ADSP_HIPCCTL_BUSY, AVS_ADSP_HIPCCTL_BUSY);
-
- return IRQ_HANDLED;
-}
-
static bool avs_ipc_is_busy(struct avs_ipc *ipc)
{
struct avs_dev *adev = to_avs_dev(ipc->dev);
+ const struct avs_spec *const spec = adev->spec;
u32 hipc_rsp;
- hipc_rsp = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
- return hipc_rsp & SKL_ADSP_HIPCT_BUSY;
+ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);
+ return hipc_rsp & spec->hipc->rsp_busy_mask;
}
static int avs_ipc_wait_busy_completion(struct avs_ipc *ipc, int timeout)
@@ -440,9 +414,10 @@ static void avs_ipc_msg_init(struct avs_ipc *ipc, struct avs_ipc_msg *reply)
static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool read_fwregs)
{
+ const struct avs_spec *const spec = adev->spec;
u64 reg = ULONG_MAX;
- tx->header |= SKL_ADSP_HIPCI_BUSY;
+ tx->header |= spec->hipc->req_busy_mask;
if (read_fwregs)
reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW));
@@ -450,8 +425,8 @@ static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool r
if (tx->size)
memcpy_toio(avs_downlink_addr(adev), tx->data, tx->size);
- snd_hdac_adsp_writel(adev, SKL_ADSP_REG_HIPCIE, tx->header >> 32);
- snd_hdac_adsp_writel(adev, SKL_ADSP_REG_HIPCI, tx->header & UINT_MAX);
+ snd_hdac_adsp_writel(adev, spec->hipc->req_ext_offset, tx->header >> 32);
+ snd_hdac_adsp_writel(adev, spec->hipc->req_offset, tx->header & UINT_MAX);
}
static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request,
@@ -606,6 +581,7 @@ int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, cons
void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable)
{
+ const struct avs_spec *const spec = adev->spec;
u32 value, mask;
/*
@@ -617,7 +593,7 @@ void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable)
mask = AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY;
value = enable ? mask : 0;
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, mask, value);
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset, mask, value);
}
int avs_ipc_init(struct avs_ipc *ipc, struct device *dev)