sound/soc/sof/intel/mtl.c
Source file repositories/reference/linux-study-clean/sound/soc/sof/intel/mtl.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sof/intel/mtl.c- Extension
.c- Size
- 24186 bytes
- Lines
- 817
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/debugfs.hlinux/firmware.hlinux/string_choices.hsound/sof/ipc4/header.htrace/events/sof_intel.h../ipc4-priv.h../ops.hhda.hhda-ipc.h../sof-audio.hmtl.htelemetry.h
Detected Declarations
function mtl_ipc_host_donefunction mtl_ipc_dsp_donefunction mtl_dsp_check_ipc_irqfunction mtl_dsp_check_sdw_irqfunction mtl_ipc_send_msgfunction mtl_enable_ipc_interruptsfunction mtl_disable_ipc_interruptsfunction mtl_enable_sdw_irqfunction mtl_enable_interruptsfunction mtl_dsp_pre_fw_runfunction mtl_dsp_post_fw_runfunction mtl_dsp_dumpfunction mtl_dsp_primary_core_is_enabledfunction mtl_dsp_core_power_upfunction mtl_dsp_core_power_downfunction mtl_power_down_dspfunction mtl_dsp_cl_initfunction mtl_ipc_irq_threadfunction mtl_dsp_ipc_get_mailbox_offsetfunction mtl_dsp_ipc_get_window_offsetfunction mtl_ipc_dumpfunction mtl_dsp_disable_interruptsfunction mtl_dsp_core_getfunction mtl_dsp_core_putfunction sof_mtl_set_ops
Annotated Snippet
if (ret < 0) {
dev_err(sdev->dev, "could not startup SoundWire links\n");
return ret;
}
/* Check if IMR boot is usable */
if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) {
hdev->imrboot_supported = true;
debugfs_create_bool("skip_imr_boot",
0644, sdev->debugfs_root,
&hdev->skip_imr_boot);
}
}
hda_sdw_int_enable(sdev, true);
return 0;
}
static void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
{
char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
u32 fwsts;
u32 fwlec;
hda_dsp_get_state(sdev, level);
fwsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_STS);
fwlec = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_ERROR);
if (fwsts != 0xffffffff)
dev_err(sdev->dev, "Firmware state: %#x, status/error code: %#x\n",
fwsts, fwlec);
sof_ipc4_intel_dump_telemetry_state(sdev, flags);
}
static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev)
{
int val;
val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE);
if (val != U32_MAX && val & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK)
return true;
return false;
}
static int mtl_dsp_core_power_up(struct snd_sof_dev *sdev, int core)
{
unsigned int cpa;
u32 dspcxctl;
int ret;
/* Only the primary core can be powered up by the host */
if (core != SOF_DSP_PRIMARY_CORE || mtl_dsp_primary_core_is_enabled(sdev))
return 0;
/* Program the owner of the IP & shim registers (10: Host CPU) */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE,
MTL_DSP2CXCTL_PRIMARY_CORE_OSEL,
0x2 << MTL_DSP2CXCTL_PRIMARY_CORE_OSEL_SHIFT);
/* enable SPA bit */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE,
MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK,
MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK);
/* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */
usleep_range(1000, 1010);
/* poll with timeout to check if operation successful */
cpa = MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK;
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl,
(dspcxctl & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US,
HDA_DSP_RESET_TIMEOUT_US);
if (ret < 0) {
dev_err(sdev->dev, "%s: timeout on MTL_DSP2CXCTL_PRIMARY_CORE read\n",
__func__);
return ret;
}
/* set primary core mask and refcount to 1 */
sdev->enabled_cores_mask = BIT(SOF_DSP_PRIMARY_CORE);
sdev->dsp_core_ref_count[SOF_DSP_PRIMARY_CORE] = 1;
return 0;
}
static int mtl_dsp_core_power_down(struct snd_sof_dev *sdev, int core)
{
u32 dspcxctl;
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/firmware.h`, `linux/string_choices.h`, `sound/sof/ipc4/header.h`, `trace/events/sof_intel.h`, `../ipc4-priv.h`, `../ops.h`, `hda.h`.
- Detected declarations: `function mtl_ipc_host_done`, `function mtl_ipc_dsp_done`, `function mtl_dsp_check_ipc_irq`, `function mtl_dsp_check_sdw_irq`, `function mtl_ipc_send_msg`, `function mtl_enable_ipc_interrupts`, `function mtl_disable_ipc_interrupts`, `function mtl_enable_sdw_irq`, `function mtl_enable_interrupts`, `function mtl_dsp_pre_fw_run`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.