Commit eb73f6d6 authored by Mark Brown's avatar Mark Brown

ASoC/soundwire: revisit interrupt and lcount handling

Merge series from Bard Liao <yung-chuan.liao@linux.intel.com>:

The code in drivers/soundwire/intel_init.c is hardware-dependent and the
code does not apply to new generations starting with MeteorLake. Refactor
and clean-up the code to make this intel_init.c hardware-agnostic and
move all hardware-dependencies in the SOF driver using chip descriptors.
parents 57405d8b 5e2cbc4a
...@@ -125,30 +125,6 @@ static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx) ...@@ -125,30 +125,6 @@ static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
return 0; return 0;
} }
#define HDA_DSP_REG_ADSPIC2 (0x10)
#define HDA_DSP_REG_ADSPIS2 (0x14)
#define HDA_DSP_REG_ADSPIC2_SNDW BIT(5)
/**
* sdw_intel_enable_irq() - enable/disable Intel SoundWire IRQ
* @mmio_base: The mmio base of the control register
* @enable: true if enable
*/
void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable)
{
u32 val;
val = readl(mmio_base + HDA_DSP_REG_ADSPIC2);
if (enable)
val |= HDA_DSP_REG_ADSPIC2_SNDW;
else
val &= ~HDA_DSP_REG_ADSPIC2_SNDW;
writel(val, mmio_base + HDA_DSP_REG_ADSPIC2);
}
EXPORT_SYMBOL_NS(sdw_intel_enable_irq, SOUNDWIRE_INTEL_INIT);
irqreturn_t sdw_intel_thread(int irq, void *dev_id) irqreturn_t sdw_intel_thread(int irq, void *dev_id)
{ {
struct sdw_intel_ctx *ctx = dev_id; struct sdw_intel_ctx *ctx = dev_id;
...@@ -157,7 +133,6 @@ irqreturn_t sdw_intel_thread(int irq, void *dev_id) ...@@ -157,7 +133,6 @@ irqreturn_t sdw_intel_thread(int irq, void *dev_id)
list_for_each_entry(link, &ctx->link_list, list) list_for_each_entry(link, &ctx->link_list, list)
sdw_cdns_irq(irq, link->cdns); sdw_cdns_irq(irq, link->cdns);
sdw_intel_enable_irq(ctx->mmio_base, true);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT); EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
...@@ -297,24 +272,12 @@ sdw_intel_startup_controller(struct sdw_intel_ctx *ctx) ...@@ -297,24 +272,12 @@ sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
{ {
struct acpi_device *adev = acpi_fetch_acpi_dev(ctx->handle); struct acpi_device *adev = acpi_fetch_acpi_dev(ctx->handle);
struct sdw_intel_link_dev *ldev; struct sdw_intel_link_dev *ldev;
u32 caps;
u32 link_mask; u32 link_mask;
int i; int i;
if (!adev) if (!adev)
return -EINVAL; return -EINVAL;
/* Check SNDWLCAP.LCOUNT */
caps = ioread32(ctx->mmio_base + ctx->shim_base + SDW_SHIM_LCAP);
caps &= SDW_SHIM_LCAP_LCOUNT_MASK;
/* Check HW supported vs property value */
if (caps < ctx->count) {
dev_err(&adev->dev,
"BIOS master count is larger than hardware capabilities\n");
return -EINVAL;
}
if (!ctx->ldev) if (!ctx->ldev)
return -EINVAL; return -EINVAL;
......
...@@ -286,8 +286,6 @@ int sdw_intel_startup(struct sdw_intel_ctx *ctx); ...@@ -286,8 +286,6 @@ int sdw_intel_startup(struct sdw_intel_ctx *ctx);
void sdw_intel_exit(struct sdw_intel_ctx *ctx); void sdw_intel_exit(struct sdw_intel_ctx *ctx);
void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable);
irqreturn_t sdw_intel_thread(int irq, void *dev_id); irqreturn_t sdw_intel_thread(int irq, void *dev_id);
#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1) #define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1)
......
...@@ -457,6 +457,8 @@ const struct sof_intel_dsp_desc cnl_chip_info = { ...@@ -457,6 +457,8 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -490,6 +492,8 @@ const struct sof_intel_dsp_desc jsl_chip_info = { ...@@ -490,6 +492,8 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
...@@ -155,9 +155,27 @@ struct sdw_intel_ops sdw_callback = { ...@@ -155,9 +155,27 @@ struct sdw_intel_ops sdw_callback = {
.free_stream = sdw_free_stream, .free_stream = sdw_free_stream,
}; };
void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
{
struct sof_intel_hda_dev *hdev;
hdev = sdev->pdata->hw_pdata;
if (!hdev->sdw)
return;
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC2,
HDA_DSP_REG_ADSPIC2_SNDW,
enable ? HDA_DSP_REG_ADSPIC2_SNDW : 0);
}
void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
{ {
sdw_intel_enable_irq(sdev->bar[HDA_DSP_BAR], enable); const struct sof_intel_dsp_desc *chip;
chip = get_chip_info(sdev->pdata);
if (chip && chip->enable_sdw_irq)
chip->enable_sdw_irq(sdev, enable);
} }
static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev)
...@@ -220,10 +238,45 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) ...@@ -220,10 +238,45 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
return 0; return 0;
} }
int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hdev;
struct sdw_intel_ctx *ctx;
u32 caps;
hdev = sdev->pdata->hw_pdata;
ctx = hdev->sdw;
caps = snd_sof_dsp_read(sdev, HDA_DSP_BAR, ctx->shim_base + SDW_SHIM_LCAP);
caps &= SDW_SHIM_LCAP_LCOUNT_MASK;
/* Check HW supported vs property value */
if (caps < ctx->count) {
dev_err(sdev->dev,
"BIOS master count %d is larger than hardware capabilities %d\n",
ctx->count, caps);
return -EINVAL;
}
return 0;
}
static int hda_sdw_check_lcount(struct snd_sof_dev *sdev)
{
const struct sof_intel_dsp_desc *chip;
chip = get_chip_info(sdev->pdata);
if (chip && chip->read_sdw_lcount)
return chip->read_sdw_lcount(sdev);
return 0;
}
int hda_sdw_startup(struct snd_sof_dev *sdev) int hda_sdw_startup(struct snd_sof_dev *sdev)
{ {
struct sof_intel_hda_dev *hdev; struct sof_intel_hda_dev *hdev;
struct snd_sof_pdata *pdata = sdev->pdata; struct snd_sof_pdata *pdata = sdev->pdata;
int ret;
hdev = sdev->pdata->hw_pdata; hdev = sdev->pdata->hw_pdata;
...@@ -233,6 +286,10 @@ int hda_sdw_startup(struct snd_sof_dev *sdev) ...@@ -233,6 +286,10 @@ int hda_sdw_startup(struct snd_sof_dev *sdev)
if (pdata->machine && !pdata->machine->mach_params.link_mask) if (pdata->machine && !pdata->machine->mach_params.link_mask)
return 0; return 0;
ret = hda_sdw_check_lcount(sdev);
if (ret < 0)
return ret;
return sdw_intel_startup(hdev->sdw); return sdw_intel_startup(hdev->sdw);
} }
...@@ -887,6 +944,8 @@ static int hda_init_caps(struct snd_sof_dev *sdev) ...@@ -887,6 +944,8 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
return ret; return ret;
} }
hda_bus_ml_get_capabilities(bus);
/* scan SoundWire capabilities exposed by DSDT */ /* scan SoundWire capabilities exposed by DSDT */
ret = hda_sdw_acpi_scan(sdev); ret = hda_sdw_acpi_scan(sdev);
if (ret < 0) { if (ret < 0) {
...@@ -915,8 +974,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev) ...@@ -915,8 +974,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
skip_soundwire: skip_soundwire:
hda_bus_ml_get_capabilities(bus);
/* create codec instances */ /* create codec instances */
hda_codec_probe_bus(sdev); hda_codec_probe_bus(sdev);
......
...@@ -294,6 +294,7 @@ ...@@ -294,6 +294,7 @@
#define HDA_DSP_REG_ADSPIC2 (HDA_DSP_GEN_BASE + 0x10) #define HDA_DSP_REG_ADSPIC2 (HDA_DSP_GEN_BASE + 0x10)
#define HDA_DSP_REG_ADSPIS2 (HDA_DSP_GEN_BASE + 0x14) #define HDA_DSP_REG_ADSPIS2 (HDA_DSP_GEN_BASE + 0x14)
#define HDA_DSP_REG_ADSPIC2_SNDW BIT(5)
#define HDA_DSP_REG_ADSPIS2_SNDW BIT(5) #define HDA_DSP_REG_ADSPIS2_SNDW BIT(5)
/* Intel HD Audio Inter-Processor Communication Registers */ /* Intel HD Audio Inter-Processor Communication Registers */
...@@ -794,18 +795,29 @@ int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd); ...@@ -794,18 +795,29 @@ int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd);
*/ */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev);
int hda_sdw_startup(struct snd_sof_dev *sdev); int hda_sdw_startup(struct snd_sof_dev *sdev);
void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable);
void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable); void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable);
void hda_sdw_process_wakeen(struct snd_sof_dev *sdev); void hda_sdw_process_wakeen(struct snd_sof_dev *sdev);
bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev); bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev);
#else #else
static inline int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev)
{
return 0;
}
static inline int hda_sdw_startup(struct snd_sof_dev *sdev) static inline int hda_sdw_startup(struct snd_sof_dev *sdev)
{ {
return 0; return 0;
} }
static inline void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
{
}
static inline void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) static inline void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
{ {
} }
......
...@@ -181,6 +181,8 @@ const struct sof_intel_dsp_desc icl_chip_info = { ...@@ -181,6 +181,8 @@ const struct sof_intel_dsp_desc icl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
...@@ -134,111 +134,79 @@ static void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev) ...@@ -134,111 +134,79 @@ static void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev)
MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 0); MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 0);
} }
static int mtl_enable_interrupts(struct snd_sof_dev *sdev) static void mtl_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
{ {
u32 hfintipptr;
u32 irqinten;
u32 host_ipc;
u32 hipcie; u32 hipcie;
u32 mask;
u32 val;
int ret; int ret;
/* read Interrupt IP Pointer */ /* Enable/Disable SoundWire interrupt */
hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; mask = MTL_DSP_REG_HfSNDWIE_IE_MASK;
if (enable)
val = mask;
else
val = 0;
/* Enable Host IPC and SOUNDWIRE */ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, mask, val);
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr,
MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK,
MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK);
/* check if operation was successful */ /* check if operation was successful */
host_ipc = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK;
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten,
(irqinten & host_ipc) == host_ipc,
HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
if (ret < 0) {
dev_err(sdev->dev, "failed to enable Host IPC and/or SOUNDWIRE\n");
return ret;
}
/* Set Host IPC interrupt enable */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE,
MTL_DSP_REG_HfHIPCIE_IE_MASK, MTL_DSP_REG_HfHIPCIE_IE_MASK);
/* check if operation was successful */
host_ipc = MTL_DSP_REG_HfHIPCIE_IE_MASK;
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie,
(hipcie & host_ipc) == host_ipc,
HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
if (ret < 0) {
dev_err(sdev->dev, "failed to set Host IPC interrupt enable\n");
return ret;
}
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE,
MTL_DSP_REG_HfSNDWIE_IE_MASK, MTL_DSP_REG_HfSNDWIE_IE_MASK);
host_ipc = MTL_DSP_REG_HfSNDWIE_IE_MASK;
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie, ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie,
(hipcie & host_ipc) == host_ipc, (hipcie & mask) == val,
HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
if (ret < 0) if (ret < 0)
dev_err(sdev->dev, "failed to set SoundWire IPC interrupt enable\n"); dev_err(sdev->dev, "failed to set SoundWire IPC interrupt %s\n",
enable ? "enable" : "disable");
return ret;
} }
static int mtl_disable_interrupts(struct snd_sof_dev *sdev) static int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable)
{ {
u32 hfintipptr; u32 hfintipptr;
u32 irqinten; u32 irqinten;
u32 host_ipc;
u32 hipcie; u32 hipcie;
int ret1; u32 mask;
u32 val;
int ret; int ret;
/* read Interrupt IP Pointer */ /* read Interrupt IP Pointer */
hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK;
/* Disable Host IPC and SOUNDWIRE */ /* Enable/Disable Host IPC and SOUNDWIRE */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr, mask = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK;
MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK, 0); if (enable)
val = mask;
else
val = 0;
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr, mask, val);
/* check if operation was successful */ /* check if operation was successful */
host_ipc = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK;
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten, ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten,
(irqinten & host_ipc) == 0, (irqinten & mask) == val,
HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
/* Continue to disable other interrupts when error happens */ if (ret < 0) {
if (ret < 0) dev_err(sdev->dev, "failed to %s Host IPC and/or SOUNDWIRE\n",
dev_err(sdev->dev, "failed to disable Host IPC and SoundWire\n"); enable ? "enable" : "disable");
return ret;
}
/* Set Host IPC interrupt disable */ /* Enable/Disable Host IPC interrupt*/
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, mask = MTL_DSP_REG_HfHIPCIE_IE_MASK;
MTL_DSP_REG_HfHIPCIE_IE_MASK, 0); if (enable)
val = mask;
else
val = 0;
/* check if operation was successful */ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, mask, val);
host_ipc = MTL_DSP_REG_HfHIPCIE_IE_MASK;
ret1 = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie,
(hipcie & host_ipc) == 0,
HDA_DSP_REG_POLL_INTERVAL_US,
HDA_DSP_RESET_TIMEOUT_US);
if (ret1 < 0) {
dev_err(sdev->dev, "failed to set Host IPC interrupt disable\n");
if (!ret)
ret = ret1;
}
/* Set SoundWire IPC interrupt disable */ /* check if operation was successful */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie,
MTL_DSP_REG_HfSNDWIE_IE_MASK, 0); (hipcie & mask) == val,
host_ipc = MTL_DSP_REG_HfSNDWIE_IE_MASK; HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
ret1 = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie, if (ret < 0) {
(hipcie & host_ipc) == 0, dev_err(sdev->dev, "failed to set Host IPC interrupt %s\n",
HDA_DSP_REG_POLL_INTERVAL_US, enable ? "enable" : "disable");
HDA_DSP_RESET_TIMEOUT_US); return ret;
if (ret1 < 0) {
dev_err(sdev->dev, "failed to set SoundWire IPC interrupt disable\n");
if (!ret)
ret = ret1;
} }
return ret; return ret;
...@@ -473,7 +441,7 @@ static int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_bo ...@@ -473,7 +441,7 @@ static int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_bo
chip->ipc_ack_mask); chip->ipc_ack_mask);
/* step 4: enable interrupts */ /* step 4: enable interrupts */
ret = mtl_enable_interrupts(sdev); ret = mtl_enable_interrupts(sdev, true);
if (ret < 0) { if (ret < 0) {
if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
dev_err(sdev->dev, "%s: failed to enable interrupts\n", __func__); dev_err(sdev->dev, "%s: failed to enable interrupts\n", __func__);
...@@ -608,8 +576,9 @@ static void mtl_ipc_dump(struct snd_sof_dev *sdev) ...@@ -608,8 +576,9 @@ static void mtl_ipc_dump(struct snd_sof_dev *sdev)
static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev) static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev)
{ {
mtl_enable_sdw_irq(sdev, false);
mtl_disable_ipc_interrupts(sdev); mtl_disable_ipc_interrupts(sdev);
return mtl_disable_interrupts(sdev); return mtl_enable_interrupts(sdev, false);
} }
/* Meteorlake ops */ /* Meteorlake ops */
...@@ -685,6 +654,8 @@ const struct sof_intel_dsp_desc mtl_chip_info = { ...@@ -685,6 +654,8 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE_ACE, .sdw_shim_base = SDW_SHIM_BASE_ACE,
.sdw_alh_base = SDW_ALH_BASE_ACE, .sdw_alh_base = SDW_ALH_BASE_ACE,
.d0i3_offset = MTL_HDA_VS_D0I3C, .d0i3_offset = MTL_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = mtl_enable_sdw_irq,
.check_sdw_irq = mtl_dsp_check_sdw_irq, .check_sdw_irq = mtl_dsp_check_sdw_irq,
.check_ipc_irq = mtl_dsp_check_ipc_irq, .check_ipc_irq = mtl_dsp_check_ipc_irq,
.cl_init = mtl_dsp_cl_init, .cl_init = mtl_dsp_cl_init,
......
...@@ -185,6 +185,8 @@ struct sof_intel_dsp_desc { ...@@ -185,6 +185,8 @@ struct sof_intel_dsp_desc {
u32 d0i3_offset; u32 d0i3_offset;
u32 quirks; u32 quirks;
enum sof_intel_hw_ip_version hw_ip_version; enum sof_intel_hw_ip_version hw_ip_version;
int (*read_sdw_lcount)(struct snd_sof_dev *sdev);
void (*enable_sdw_irq)(struct snd_sof_dev *sdev, bool enable);
bool (*check_sdw_irq)(struct snd_sof_dev *sdev); bool (*check_sdw_irq)(struct snd_sof_dev *sdev);
bool (*check_ipc_irq)(struct snd_sof_dev *sdev); bool (*check_ipc_irq)(struct snd_sof_dev *sdev);
int (*power_down_dsp)(struct snd_sof_dev *sdev); int (*power_down_dsp)(struct snd_sof_dev *sdev);
......
...@@ -136,6 +136,8 @@ const struct sof_intel_dsp_desc tgl_chip_info = { ...@@ -136,6 +136,8 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -162,6 +164,8 @@ const struct sof_intel_dsp_desc tglh_chip_info = { ...@@ -162,6 +164,8 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -188,6 +192,8 @@ const struct sof_intel_dsp_desc ehl_chip_info = { ...@@ -188,6 +192,8 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -214,6 +220,8 @@ const struct sof_intel_dsp_desc adls_chip_info = { ...@@ -214,6 +220,8 @@ const struct sof_intel_dsp_desc adls_chip_info = {
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C, .d0i3_offset = SOF_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = hda_common_enable_sdw_irq,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment