162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license. When using or 462306a36Sopenharmony_ci * redistributing this file, you may do so under either license. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright(c) 2018 Intel Corporation. All rights reserved. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifndef __SOUND_SOC_SOF_PRIV_H 1262306a36Sopenharmony_ci#define __SOUND_SOC_SOF_PRIV_H 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/device.h> 1562306a36Sopenharmony_ci#include <sound/hdaudio.h> 1662306a36Sopenharmony_ci#include <sound/sof.h> 1762306a36Sopenharmony_ci#include <sound/sof/info.h> 1862306a36Sopenharmony_ci#include <sound/sof/pm.h> 1962306a36Sopenharmony_ci#include <sound/sof/trace.h> 2062306a36Sopenharmony_ci#include <uapi/sound/sof/fw.h> 2162306a36Sopenharmony_ci#include <sound/sof/ext_manifest.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct snd_sof_pcm_stream; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* Flag definitions used in sof_core_debug (sof_debug module parameter) */ 2662306a36Sopenharmony_ci#define SOF_DBG_ENABLE_TRACE BIT(0) 2762306a36Sopenharmony_ci#define SOF_DBG_RETAIN_CTX BIT(1) /* prevent DSP D3 on FW exception */ 2862306a36Sopenharmony_ci#define SOF_DBG_VERIFY_TPLG BIT(2) /* verify topology during load */ 2962306a36Sopenharmony_ci#define SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE BIT(3) /* 0: use topology token 3062306a36Sopenharmony_ci * 1: override topology 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci#define SOF_DBG_DYNAMIC_PIPELINES_ENABLE BIT(4) /* 0: use static pipelines 3362306a36Sopenharmony_ci * 1: use dynamic pipelines 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci#define SOF_DBG_DISABLE_MULTICORE BIT(5) /* schedule all pipelines/widgets 3662306a36Sopenharmony_ci * on primary core 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci#define SOF_DBG_PRINT_ALL_DUMPS BIT(6) /* Print all ipc and dsp dumps */ 3962306a36Sopenharmony_ci#define SOF_DBG_IGNORE_D3_PERSISTENT BIT(7) /* ignore the DSP D3 persistent capability 4062306a36Sopenharmony_ci * and always download firmware upon D3 exit 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci#define SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS BIT(8) /* print DMA position updates 4362306a36Sopenharmony_ci * in dmesg logs 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_ci#define SOF_DBG_PRINT_IPC_SUCCESS_LOGS BIT(9) /* print IPC success 4662306a36Sopenharmony_ci * in dmesg logs 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci#define SOF_DBG_FORCE_NOCODEC BIT(10) /* ignore all codec-related 4962306a36Sopenharmony_ci * configurations 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_ci#define SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD BIT(11) /* On top of the IPC message header 5262306a36Sopenharmony_ci * dump the message payload also 5362306a36Sopenharmony_ci */ 5462306a36Sopenharmony_ci#define SOF_DBG_DSPLESS_MODE BIT(15) /* Do not initialize and use the DSP */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* Flag definitions used for controlling the DSP dump behavior */ 5762306a36Sopenharmony_ci#define SOF_DBG_DUMP_REGS BIT(0) 5862306a36Sopenharmony_ci#define SOF_DBG_DUMP_MBOX BIT(1) 5962306a36Sopenharmony_ci#define SOF_DBG_DUMP_TEXT BIT(2) 6062306a36Sopenharmony_ci#define SOF_DBG_DUMP_PCI BIT(3) 6162306a36Sopenharmony_ci/* Output this dump (at the DEBUG level) only when SOF_DBG_PRINT_ALL_DUMPS is set */ 6262306a36Sopenharmony_ci#define SOF_DBG_DUMP_OPTIONAL BIT(4) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* global debug state set by SOF_DBG_ flags */ 6562306a36Sopenharmony_cibool sof_debug_check_flag(int mask); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* max BARs mmaped devices can use */ 6862306a36Sopenharmony_ci#define SND_SOF_BARS 8 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* time in ms for runtime suspend delay */ 7162306a36Sopenharmony_ci#define SND_SOF_SUSPEND_DELAY_MS 2000 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* DMA buffer size for trace */ 7462306a36Sopenharmony_ci#define DMA_BUF_SIZE_FOR_TRACE (PAGE_SIZE * 16) 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define SOF_IPC_DSP_REPLY 0 7762306a36Sopenharmony_ci#define SOF_IPC_HOST_REPLY 1 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* convenience constructor for DAI driver streams */ 8062306a36Sopenharmony_ci#define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt) \ 8162306a36Sopenharmony_ci {.stream_name = sname, .channels_min = scmin, .channels_max = scmax, \ 8262306a36Sopenharmony_ci .rates = srates, .formats = sfmt} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#define SOF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ 8562306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* So far the primary core on all DSPs has ID 0 */ 8862306a36Sopenharmony_ci#define SOF_DSP_PRIMARY_CORE 0 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* max number of DSP cores */ 9162306a36Sopenharmony_ci#define SOF_MAX_DSP_NUM_CORES 8 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistruct sof_dsp_power_state { 9462306a36Sopenharmony_ci u32 state; 9562306a36Sopenharmony_ci u32 substate; /* platform-specific */ 9662306a36Sopenharmony_ci}; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/* System suspend target state */ 9962306a36Sopenharmony_cienum sof_system_suspend_state { 10062306a36Sopenharmony_ci SOF_SUSPEND_NONE = 0, 10162306a36Sopenharmony_ci SOF_SUSPEND_S0IX, 10262306a36Sopenharmony_ci SOF_SUSPEND_S3, 10362306a36Sopenharmony_ci SOF_SUSPEND_S4, 10462306a36Sopenharmony_ci SOF_SUSPEND_S5, 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cienum sof_dfsentry_type { 10862306a36Sopenharmony_ci SOF_DFSENTRY_TYPE_IOMEM = 0, 10962306a36Sopenharmony_ci SOF_DFSENTRY_TYPE_BUF, 11062306a36Sopenharmony_ci}; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cienum sof_debugfs_access_type { 11362306a36Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS = 0, 11462306a36Sopenharmony_ci SOF_DEBUGFS_ACCESS_D0_ONLY, 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistruct sof_compr_stream { 11862306a36Sopenharmony_ci u64 copied_total; 11962306a36Sopenharmony_ci u32 sampling_rate; 12062306a36Sopenharmony_ci u16 channels; 12162306a36Sopenharmony_ci u16 sample_container_bytes; 12262306a36Sopenharmony_ci size_t posn_offset; 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistruct snd_sof_dev; 12662306a36Sopenharmony_cistruct snd_sof_ipc_msg; 12762306a36Sopenharmony_cistruct snd_sof_ipc; 12862306a36Sopenharmony_cistruct snd_sof_debugfs_map; 12962306a36Sopenharmony_cistruct snd_soc_tplg_ops; 13062306a36Sopenharmony_cistruct snd_soc_component; 13162306a36Sopenharmony_cistruct snd_sof_pdata; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci/** 13462306a36Sopenharmony_ci * struct snd_sof_platform_stream_params - platform dependent stream parameters 13562306a36Sopenharmony_ci * @stream_tag: Stream tag to use 13662306a36Sopenharmony_ci * @use_phy_addr: Use the provided @phy_addr for configuration 13762306a36Sopenharmony_ci * @phy_addr: Platform dependent address to be used, if @use_phy_addr 13862306a36Sopenharmony_ci * is true 13962306a36Sopenharmony_ci * @no_ipc_position: Disable position update IPC from firmware 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_cistruct snd_sof_platform_stream_params { 14262306a36Sopenharmony_ci u16 stream_tag; 14362306a36Sopenharmony_ci bool use_phy_address; 14462306a36Sopenharmony_ci u32 phy_addr; 14562306a36Sopenharmony_ci bool no_ipc_position; 14662306a36Sopenharmony_ci bool cont_update_posn; 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/** 15062306a36Sopenharmony_ci * struct sof_firmware - Container struct for SOF firmware 15162306a36Sopenharmony_ci * @fw: Pointer to the firmware 15262306a36Sopenharmony_ci * @payload_offset: Offset of the data within the loaded firmware image to be 15362306a36Sopenharmony_ci * loaded to the DSP (skipping for example ext_manifest section) 15462306a36Sopenharmony_ci */ 15562306a36Sopenharmony_cistruct sof_firmware { 15662306a36Sopenharmony_ci const struct firmware *fw; 15762306a36Sopenharmony_ci u32 payload_offset; 15862306a36Sopenharmony_ci}; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci/* 16162306a36Sopenharmony_ci * SOF DSP HW abstraction operations. 16262306a36Sopenharmony_ci * Used to abstract DSP HW architecture and any IO busses between host CPU 16362306a36Sopenharmony_ci * and DSP device(s). 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_cistruct snd_sof_dsp_ops { 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci /* probe/remove/shutdown */ 16862306a36Sopenharmony_ci int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */ 16962306a36Sopenharmony_ci int (*remove)(struct snd_sof_dev *sof_dev); /* optional */ 17062306a36Sopenharmony_ci int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */ 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* DSP core boot / reset */ 17362306a36Sopenharmony_ci int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */ 17462306a36Sopenharmony_ci int (*stall)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */ 17562306a36Sopenharmony_ci int (*reset)(struct snd_sof_dev *sof_dev); /* optional */ 17662306a36Sopenharmony_ci int (*core_get)(struct snd_sof_dev *sof_dev, int core); /* optional */ 17762306a36Sopenharmony_ci int (*core_put)(struct snd_sof_dev *sof_dev, int core); /* optional */ 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci /* 18062306a36Sopenharmony_ci * Register IO: only used by respective drivers themselves, 18162306a36Sopenharmony_ci * TODO: consider removing these operations and calling respective 18262306a36Sopenharmony_ci * implementations directly 18362306a36Sopenharmony_ci */ 18462306a36Sopenharmony_ci void (*write8)(struct snd_sof_dev *sof_dev, void __iomem *addr, 18562306a36Sopenharmony_ci u8 value); /* optional */ 18662306a36Sopenharmony_ci u8 (*read8)(struct snd_sof_dev *sof_dev, 18762306a36Sopenharmony_ci void __iomem *addr); /* optional */ 18862306a36Sopenharmony_ci void (*write)(struct snd_sof_dev *sof_dev, void __iomem *addr, 18962306a36Sopenharmony_ci u32 value); /* optional */ 19062306a36Sopenharmony_ci u32 (*read)(struct snd_sof_dev *sof_dev, 19162306a36Sopenharmony_ci void __iomem *addr); /* optional */ 19262306a36Sopenharmony_ci void (*write64)(struct snd_sof_dev *sof_dev, void __iomem *addr, 19362306a36Sopenharmony_ci u64 value); /* optional */ 19462306a36Sopenharmony_ci u64 (*read64)(struct snd_sof_dev *sof_dev, 19562306a36Sopenharmony_ci void __iomem *addr); /* optional */ 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci /* memcpy IO */ 19862306a36Sopenharmony_ci int (*block_read)(struct snd_sof_dev *sof_dev, 19962306a36Sopenharmony_ci enum snd_sof_fw_blk_type type, u32 offset, 20062306a36Sopenharmony_ci void *dest, size_t size); /* mandatory */ 20162306a36Sopenharmony_ci int (*block_write)(struct snd_sof_dev *sof_dev, 20262306a36Sopenharmony_ci enum snd_sof_fw_blk_type type, u32 offset, 20362306a36Sopenharmony_ci void *src, size_t size); /* mandatory */ 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci /* Mailbox IO */ 20662306a36Sopenharmony_ci void (*mailbox_read)(struct snd_sof_dev *sof_dev, 20762306a36Sopenharmony_ci u32 offset, void *dest, 20862306a36Sopenharmony_ci size_t size); /* optional */ 20962306a36Sopenharmony_ci void (*mailbox_write)(struct snd_sof_dev *sof_dev, 21062306a36Sopenharmony_ci u32 offset, void *src, 21162306a36Sopenharmony_ci size_t size); /* optional */ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci /* doorbell */ 21462306a36Sopenharmony_ci irqreturn_t (*irq_handler)(int irq, void *context); /* optional */ 21562306a36Sopenharmony_ci irqreturn_t (*irq_thread)(int irq, void *context); /* optional */ 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* ipc */ 21862306a36Sopenharmony_ci int (*send_msg)(struct snd_sof_dev *sof_dev, 21962306a36Sopenharmony_ci struct snd_sof_ipc_msg *msg); /* mandatory */ 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* FW loading */ 22262306a36Sopenharmony_ci int (*load_firmware)(struct snd_sof_dev *sof_dev); /* mandatory */ 22362306a36Sopenharmony_ci int (*load_module)(struct snd_sof_dev *sof_dev, 22462306a36Sopenharmony_ci struct snd_sof_mod_hdr *hdr); /* optional */ 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci /* connect pcm substream to a host stream */ 22762306a36Sopenharmony_ci int (*pcm_open)(struct snd_sof_dev *sdev, 22862306a36Sopenharmony_ci struct snd_pcm_substream *substream); /* optional */ 22962306a36Sopenharmony_ci /* disconnect pcm substream to a host stream */ 23062306a36Sopenharmony_ci int (*pcm_close)(struct snd_sof_dev *sdev, 23162306a36Sopenharmony_ci struct snd_pcm_substream *substream); /* optional */ 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci /* host stream hw params */ 23462306a36Sopenharmony_ci int (*pcm_hw_params)(struct snd_sof_dev *sdev, 23562306a36Sopenharmony_ci struct snd_pcm_substream *substream, 23662306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 23762306a36Sopenharmony_ci struct snd_sof_platform_stream_params *platform_params); /* optional */ 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci /* host stream hw_free */ 24062306a36Sopenharmony_ci int (*pcm_hw_free)(struct snd_sof_dev *sdev, 24162306a36Sopenharmony_ci struct snd_pcm_substream *substream); /* optional */ 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci /* host stream trigger */ 24462306a36Sopenharmony_ci int (*pcm_trigger)(struct snd_sof_dev *sdev, 24562306a36Sopenharmony_ci struct snd_pcm_substream *substream, 24662306a36Sopenharmony_ci int cmd); /* optional */ 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci /* host stream pointer */ 24962306a36Sopenharmony_ci snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev, 25062306a36Sopenharmony_ci struct snd_pcm_substream *substream); /* optional */ 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci /* pcm ack */ 25362306a36Sopenharmony_ci int (*pcm_ack)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); /* optional */ 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci /* 25662306a36Sopenharmony_ci * optional callback to retrieve the link DMA position for the substream 25762306a36Sopenharmony_ci * when the position is not reported in the shared SRAM windows but 25862306a36Sopenharmony_ci * instead from a host-accessible hardware counter. 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci u64 (*get_stream_position)(struct snd_sof_dev *sdev, 26162306a36Sopenharmony_ci struct snd_soc_component *component, 26262306a36Sopenharmony_ci struct snd_pcm_substream *substream); /* optional */ 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci /* host read DSP stream data */ 26562306a36Sopenharmony_ci int (*ipc_msg_data)(struct snd_sof_dev *sdev, 26662306a36Sopenharmony_ci struct snd_sof_pcm_stream *sps, 26762306a36Sopenharmony_ci void *p, size_t sz); /* mandatory */ 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* host side configuration of the stream's data offset in stream mailbox area */ 27062306a36Sopenharmony_ci int (*set_stream_data_offset)(struct snd_sof_dev *sdev, 27162306a36Sopenharmony_ci struct snd_sof_pcm_stream *sps, 27262306a36Sopenharmony_ci size_t posn_offset); /* optional */ 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /* pre/post firmware run */ 27562306a36Sopenharmony_ci int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ 27662306a36Sopenharmony_ci int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci /* parse platform specific extended manifest, optional */ 27962306a36Sopenharmony_ci int (*parse_platform_ext_manifest)(struct snd_sof_dev *sof_dev, 28062306a36Sopenharmony_ci const struct sof_ext_man_elem_header *hdr); 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci /* DSP PM */ 28362306a36Sopenharmony_ci int (*suspend)(struct snd_sof_dev *sof_dev, 28462306a36Sopenharmony_ci u32 target_state); /* optional */ 28562306a36Sopenharmony_ci int (*resume)(struct snd_sof_dev *sof_dev); /* optional */ 28662306a36Sopenharmony_ci int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */ 28762306a36Sopenharmony_ci int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */ 28862306a36Sopenharmony_ci int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */ 28962306a36Sopenharmony_ci int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */ 29062306a36Sopenharmony_ci int (*set_power_state)(struct snd_sof_dev *sdev, 29162306a36Sopenharmony_ci const struct sof_dsp_power_state *target_state); /* optional */ 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci /* DSP clocking */ 29462306a36Sopenharmony_ci int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */ 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci /* debug */ 29762306a36Sopenharmony_ci const struct snd_sof_debugfs_map *debug_map; /* optional */ 29862306a36Sopenharmony_ci int debug_map_count; /* optional */ 29962306a36Sopenharmony_ci void (*dbg_dump)(struct snd_sof_dev *sof_dev, 30062306a36Sopenharmony_ci u32 flags); /* optional */ 30162306a36Sopenharmony_ci void (*ipc_dump)(struct snd_sof_dev *sof_dev); /* optional */ 30262306a36Sopenharmony_ci int (*debugfs_add_region_item)(struct snd_sof_dev *sdev, 30362306a36Sopenharmony_ci enum snd_sof_fw_blk_type blk_type, u32 offset, 30462306a36Sopenharmony_ci size_t size, const char *name, 30562306a36Sopenharmony_ci enum sof_debugfs_access_type access_type); /* optional */ 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci /* host DMA trace (IPC3) */ 30862306a36Sopenharmony_ci int (*trace_init)(struct snd_sof_dev *sdev, 30962306a36Sopenharmony_ci struct snd_dma_buffer *dmatb, 31062306a36Sopenharmony_ci struct sof_ipc_dma_trace_params_ext *dtrace_params); /* optional */ 31162306a36Sopenharmony_ci int (*trace_release)(struct snd_sof_dev *sdev); /* optional */ 31262306a36Sopenharmony_ci int (*trace_trigger)(struct snd_sof_dev *sdev, 31362306a36Sopenharmony_ci int cmd); /* optional */ 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* misc */ 31662306a36Sopenharmony_ci int (*get_bar_index)(struct snd_sof_dev *sdev, 31762306a36Sopenharmony_ci u32 type); /* optional */ 31862306a36Sopenharmony_ci int (*get_mailbox_offset)(struct snd_sof_dev *sdev);/* mandatory for common loader code */ 31962306a36Sopenharmony_ci int (*get_window_offset)(struct snd_sof_dev *sdev, 32062306a36Sopenharmony_ci u32 id);/* mandatory for common loader code */ 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci /* machine driver ops */ 32362306a36Sopenharmony_ci int (*machine_register)(struct snd_sof_dev *sdev, 32462306a36Sopenharmony_ci void *pdata); /* optional */ 32562306a36Sopenharmony_ci void (*machine_unregister)(struct snd_sof_dev *sdev, 32662306a36Sopenharmony_ci void *pdata); /* optional */ 32762306a36Sopenharmony_ci struct snd_soc_acpi_mach * (*machine_select)(struct snd_sof_dev *sdev); /* optional */ 32862306a36Sopenharmony_ci void (*set_mach_params)(struct snd_soc_acpi_mach *mach, 32962306a36Sopenharmony_ci struct snd_sof_dev *sdev); /* optional */ 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci /* IPC client ops */ 33262306a36Sopenharmony_ci int (*register_ipc_clients)(struct snd_sof_dev *sdev); /* optional */ 33362306a36Sopenharmony_ci void (*unregister_ipc_clients)(struct snd_sof_dev *sdev); /* optional */ 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci /* DAI ops */ 33662306a36Sopenharmony_ci struct snd_soc_dai_driver *drv; 33762306a36Sopenharmony_ci int num_drv; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci /* ALSA HW info flags, will be stored in snd_pcm_runtime.hw.info */ 34062306a36Sopenharmony_ci u32 hw_info; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci const struct dsp_arch_ops *dsp_arch_ops; 34362306a36Sopenharmony_ci}; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci/* DSP architecture specific callbacks for oops and stack dumps */ 34662306a36Sopenharmony_cistruct dsp_arch_ops { 34762306a36Sopenharmony_ci void (*dsp_oops)(struct snd_sof_dev *sdev, const char *level, void *oops); 34862306a36Sopenharmony_ci void (*dsp_stack)(struct snd_sof_dev *sdev, const char *level, void *oops, 34962306a36Sopenharmony_ci u32 *stack, u32 stack_words); 35062306a36Sopenharmony_ci}; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci#define sof_dsp_arch_ops(sdev) ((sdev)->pdata->desc->ops->dsp_arch_ops) 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* FS entry for debug files that can expose DSP memories, registers */ 35562306a36Sopenharmony_cistruct snd_sof_dfsentry { 35662306a36Sopenharmony_ci size_t size; 35762306a36Sopenharmony_ci size_t buf_data_size; /* length of buffered data for file read operation */ 35862306a36Sopenharmony_ci enum sof_dfsentry_type type; 35962306a36Sopenharmony_ci /* 36062306a36Sopenharmony_ci * access_type specifies if the 36162306a36Sopenharmony_ci * memory -> DSP resource (memory, register etc) is always accessible 36262306a36Sopenharmony_ci * or if it is accessible only when the DSP is in D0. 36362306a36Sopenharmony_ci */ 36462306a36Sopenharmony_ci enum sof_debugfs_access_type access_type; 36562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) 36662306a36Sopenharmony_ci char *cache_buf; /* buffer to cache the contents of debugfs memory */ 36762306a36Sopenharmony_ci#endif 36862306a36Sopenharmony_ci struct snd_sof_dev *sdev; 36962306a36Sopenharmony_ci struct list_head list; /* list in sdev dfsentry list */ 37062306a36Sopenharmony_ci union { 37162306a36Sopenharmony_ci void __iomem *io_mem; 37262306a36Sopenharmony_ci void *buf; 37362306a36Sopenharmony_ci }; 37462306a36Sopenharmony_ci}; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci/* Debug mapping for any DSP memory or registers that can used for debug */ 37762306a36Sopenharmony_cistruct snd_sof_debugfs_map { 37862306a36Sopenharmony_ci const char *name; 37962306a36Sopenharmony_ci u32 bar; 38062306a36Sopenharmony_ci u32 offset; 38162306a36Sopenharmony_ci u32 size; 38262306a36Sopenharmony_ci /* 38362306a36Sopenharmony_ci * access_type specifies if the memory is always accessible 38462306a36Sopenharmony_ci * or if it is accessible only when the DSP is in D0. 38562306a36Sopenharmony_ci */ 38662306a36Sopenharmony_ci enum sof_debugfs_access_type access_type; 38762306a36Sopenharmony_ci}; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci/* mailbox descriptor, used for host <-> DSP IPC */ 39062306a36Sopenharmony_cistruct snd_sof_mailbox { 39162306a36Sopenharmony_ci u32 offset; 39262306a36Sopenharmony_ci size_t size; 39362306a36Sopenharmony_ci}; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci/* IPC message descriptor for host <-> DSP IO */ 39662306a36Sopenharmony_cistruct snd_sof_ipc_msg { 39762306a36Sopenharmony_ci /* message data */ 39862306a36Sopenharmony_ci void *msg_data; 39962306a36Sopenharmony_ci void *reply_data; 40062306a36Sopenharmony_ci size_t msg_size; 40162306a36Sopenharmony_ci size_t reply_size; 40262306a36Sopenharmony_ci int reply_error; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci /* notification, firmware initiated messages */ 40562306a36Sopenharmony_ci void *rx_data; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci wait_queue_head_t waitq; 40862306a36Sopenharmony_ci bool ipc_complete; 40962306a36Sopenharmony_ci}; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci/** 41262306a36Sopenharmony_ci * struct sof_ipc_fw_tracing_ops - IPC-specific firmware tracing ops 41362306a36Sopenharmony_ci * @init: Function pointer for initialization of the tracing 41462306a36Sopenharmony_ci * @free: Optional function pointer for freeing of the tracing 41562306a36Sopenharmony_ci * @fw_crashed: Optional function pointer to notify the tracing of a firmware crash 41662306a36Sopenharmony_ci * @suspend: Function pointer for system/runtime suspend 41762306a36Sopenharmony_ci * @resume: Function pointer for system/runtime resume 41862306a36Sopenharmony_ci */ 41962306a36Sopenharmony_cistruct sof_ipc_fw_tracing_ops { 42062306a36Sopenharmony_ci int (*init)(struct snd_sof_dev *sdev); 42162306a36Sopenharmony_ci void (*free)(struct snd_sof_dev *sdev); 42262306a36Sopenharmony_ci void (*fw_crashed)(struct snd_sof_dev *sdev); 42362306a36Sopenharmony_ci void (*suspend)(struct snd_sof_dev *sdev, pm_message_t pm_state); 42462306a36Sopenharmony_ci int (*resume)(struct snd_sof_dev *sdev); 42562306a36Sopenharmony_ci}; 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci/** 42862306a36Sopenharmony_ci * struct sof_ipc_pm_ops - IPC-specific PM ops 42962306a36Sopenharmony_ci * @ctx_save: Optional function pointer for context save 43062306a36Sopenharmony_ci * @ctx_restore: Optional function pointer for context restore 43162306a36Sopenharmony_ci * @set_core_state: Optional function pointer for turning on/off a DSP core 43262306a36Sopenharmony_ci * @set_pm_gate: Optional function pointer for pm gate settings 43362306a36Sopenharmony_ci */ 43462306a36Sopenharmony_cistruct sof_ipc_pm_ops { 43562306a36Sopenharmony_ci int (*ctx_save)(struct snd_sof_dev *sdev); 43662306a36Sopenharmony_ci int (*ctx_restore)(struct snd_sof_dev *sdev); 43762306a36Sopenharmony_ci int (*set_core_state)(struct snd_sof_dev *sdev, int core_idx, bool on); 43862306a36Sopenharmony_ci int (*set_pm_gate)(struct snd_sof_dev *sdev, u32 flags); 43962306a36Sopenharmony_ci}; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci/** 44262306a36Sopenharmony_ci * struct sof_ipc_fw_loader_ops - IPC/FW-specific loader ops 44362306a36Sopenharmony_ci * @validate: Function pointer for validating the firmware image 44462306a36Sopenharmony_ci * @parse_ext_manifest: Function pointer for parsing the manifest of the firmware 44562306a36Sopenharmony_ci * @load_fw_to_dsp: Optional function pointer for loading the firmware to the 44662306a36Sopenharmony_ci * DSP. 44762306a36Sopenharmony_ci * The function implements generic, hardware independent way 44862306a36Sopenharmony_ci * of loading the initial firmware and its modules (if any). 44962306a36Sopenharmony_ci */ 45062306a36Sopenharmony_cistruct sof_ipc_fw_loader_ops { 45162306a36Sopenharmony_ci int (*validate)(struct snd_sof_dev *sdev); 45262306a36Sopenharmony_ci size_t (*parse_ext_manifest)(struct snd_sof_dev *sdev); 45362306a36Sopenharmony_ci int (*load_fw_to_dsp)(struct snd_sof_dev *sdev); 45462306a36Sopenharmony_ci}; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistruct sof_ipc_tplg_ops; 45762306a36Sopenharmony_cistruct sof_ipc_pcm_ops; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci/** 46062306a36Sopenharmony_ci * struct sof_ipc_ops - IPC-specific ops 46162306a36Sopenharmony_ci * @tplg: Pointer to IPC-specific topology ops 46262306a36Sopenharmony_ci * @pm: Pointer to PM ops 46362306a36Sopenharmony_ci * @pcm: Pointer to PCM ops 46462306a36Sopenharmony_ci * @fw_loader: Pointer to Firmware Loader ops 46562306a36Sopenharmony_ci * @fw_tracing: Optional pointer to Firmware tracing ops 46662306a36Sopenharmony_ci * 46762306a36Sopenharmony_ci * @init: Optional pointer for IPC related initialization 46862306a36Sopenharmony_ci * @exit: Optional pointer for IPC related cleanup 46962306a36Sopenharmony_ci * @post_fw_boot: Optional pointer to execute IPC related tasks after firmware 47062306a36Sopenharmony_ci * boot. 47162306a36Sopenharmony_ci * 47262306a36Sopenharmony_ci * @tx_msg: Function pointer for sending a 'short' IPC message 47362306a36Sopenharmony_ci * @set_get_data: Function pointer for set/get data ('large' IPC message). This 47462306a36Sopenharmony_ci * function may split up the 'large' message and use the @tx_msg 47562306a36Sopenharmony_ci * path to transfer individual chunks, or use other means to transfer 47662306a36Sopenharmony_ci * the message. 47762306a36Sopenharmony_ci * @get_reply: Function pointer for fetching the reply to 47862306a36Sopenharmony_ci * sdev->ipc->msg.reply_data 47962306a36Sopenharmony_ci * @rx_msg: Function pointer for handling a received message 48062306a36Sopenharmony_ci * 48162306a36Sopenharmony_ci * Note: both @tx_msg and @set_get_data considered as TX functions and they are 48262306a36Sopenharmony_ci * serialized for the duration of the instructed transfer. A large message sent 48362306a36Sopenharmony_ci * via @set_get_data is a single transfer even if at the hardware level it is 48462306a36Sopenharmony_ci * handled with multiple chunks. 48562306a36Sopenharmony_ci */ 48662306a36Sopenharmony_cistruct sof_ipc_ops { 48762306a36Sopenharmony_ci const struct sof_ipc_tplg_ops *tplg; 48862306a36Sopenharmony_ci const struct sof_ipc_pm_ops *pm; 48962306a36Sopenharmony_ci const struct sof_ipc_pcm_ops *pcm; 49062306a36Sopenharmony_ci const struct sof_ipc_fw_loader_ops *fw_loader; 49162306a36Sopenharmony_ci const struct sof_ipc_fw_tracing_ops *fw_tracing; 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci int (*init)(struct snd_sof_dev *sdev); 49462306a36Sopenharmony_ci void (*exit)(struct snd_sof_dev *sdev); 49562306a36Sopenharmony_ci int (*post_fw_boot)(struct snd_sof_dev *sdev); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci int (*tx_msg)(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes, 49862306a36Sopenharmony_ci void *reply_data, size_t reply_bytes, bool no_pm); 49962306a36Sopenharmony_ci int (*set_get_data)(struct snd_sof_dev *sdev, void *data, size_t data_bytes, 50062306a36Sopenharmony_ci bool set); 50162306a36Sopenharmony_ci int (*get_reply)(struct snd_sof_dev *sdev); 50262306a36Sopenharmony_ci void (*rx_msg)(struct snd_sof_dev *sdev); 50362306a36Sopenharmony_ci}; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci/* SOF generic IPC data */ 50662306a36Sopenharmony_cistruct snd_sof_ipc { 50762306a36Sopenharmony_ci struct snd_sof_dev *sdev; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci /* protects messages and the disable flag */ 51062306a36Sopenharmony_ci struct mutex tx_mutex; 51162306a36Sopenharmony_ci /* disables further sending of ipc's */ 51262306a36Sopenharmony_ci bool disable_ipc_tx; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci /* Maximum allowed size of a single IPC message/reply */ 51562306a36Sopenharmony_ci size_t max_payload_size; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci struct snd_sof_ipc_msg msg; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci /* IPC ops based on version */ 52062306a36Sopenharmony_ci const struct sof_ipc_ops *ops; 52162306a36Sopenharmony_ci}; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci/* Helper to retrieve the IPC ops */ 52462306a36Sopenharmony_ci#define sof_ipc_get_ops(sdev, ops_name) \ 52562306a36Sopenharmony_ci (((sdev)->ipc && (sdev)->ipc->ops) ? (sdev)->ipc->ops->ops_name : NULL) 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci/* 52862306a36Sopenharmony_ci * SOF Device Level. 52962306a36Sopenharmony_ci */ 53062306a36Sopenharmony_cistruct snd_sof_dev { 53162306a36Sopenharmony_ci struct device *dev; 53262306a36Sopenharmony_ci spinlock_t ipc_lock; /* lock for IPC users */ 53362306a36Sopenharmony_ci spinlock_t hw_lock; /* lock for HW IO access */ 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci /* 53662306a36Sopenharmony_ci * When true the DSP is not used. 53762306a36Sopenharmony_ci * It is set under the following condition: 53862306a36Sopenharmony_ci * User sets the SOF_DBG_DSPLESS_MODE flag in sof_debug module parameter 53962306a36Sopenharmony_ci * and 54062306a36Sopenharmony_ci * the platform advertises that it can support such mode 54162306a36Sopenharmony_ci * pdata->desc->dspless_mode_supported is true. 54262306a36Sopenharmony_ci */ 54362306a36Sopenharmony_ci bool dspless_mode_selected; 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci /* Main, Base firmware image */ 54662306a36Sopenharmony_ci struct sof_firmware basefw; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci /* 54962306a36Sopenharmony_ci * ASoC components. plat_drv fields are set dynamically so 55062306a36Sopenharmony_ci * can't use const 55162306a36Sopenharmony_ci */ 55262306a36Sopenharmony_ci struct snd_soc_component_driver plat_drv; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci /* current DSP power state */ 55562306a36Sopenharmony_ci struct sof_dsp_power_state dsp_power_state; 55662306a36Sopenharmony_ci /* mutex to protect the dsp_power_state access */ 55762306a36Sopenharmony_ci struct mutex power_state_access; 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci /* Intended power target of system suspend */ 56062306a36Sopenharmony_ci enum sof_system_suspend_state system_suspend_target; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci /* DSP firmware boot */ 56362306a36Sopenharmony_ci wait_queue_head_t boot_wait; 56462306a36Sopenharmony_ci enum sof_fw_state fw_state; 56562306a36Sopenharmony_ci bool first_boot; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci /* work queue in case the probe is implemented in two steps */ 56862306a36Sopenharmony_ci struct work_struct probe_work; 56962306a36Sopenharmony_ci bool probe_completed; 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci /* DSP HW differentiation */ 57262306a36Sopenharmony_ci struct snd_sof_pdata *pdata; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci /* IPC */ 57562306a36Sopenharmony_ci struct snd_sof_ipc *ipc; 57662306a36Sopenharmony_ci struct snd_sof_mailbox fw_info_box; /* FW shared memory */ 57762306a36Sopenharmony_ci struct snd_sof_mailbox dsp_box; /* DSP initiated IPC */ 57862306a36Sopenharmony_ci struct snd_sof_mailbox host_box; /* Host initiated IPC */ 57962306a36Sopenharmony_ci struct snd_sof_mailbox stream_box; /* Stream position update */ 58062306a36Sopenharmony_ci struct snd_sof_mailbox debug_box; /* Debug info updates */ 58162306a36Sopenharmony_ci struct snd_sof_ipc_msg *msg; 58262306a36Sopenharmony_ci int ipc_irq; 58362306a36Sopenharmony_ci u32 next_comp_id; /* monotonic - reset during S3 */ 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci /* memory bases for mmaped DSPs - set by dsp_init() */ 58662306a36Sopenharmony_ci void __iomem *bar[SND_SOF_BARS]; /* DSP base address */ 58762306a36Sopenharmony_ci int mmio_bar; 58862306a36Sopenharmony_ci int mailbox_bar; 58962306a36Sopenharmony_ci size_t dsp_oops_offset; 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci /* debug */ 59262306a36Sopenharmony_ci struct dentry *debugfs_root; 59362306a36Sopenharmony_ci struct list_head dfsentry_list; 59462306a36Sopenharmony_ci bool dbg_dump_printed; 59562306a36Sopenharmony_ci bool ipc_dump_printed; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci /* firmware loader */ 59862306a36Sopenharmony_ci struct sof_ipc_fw_ready fw_ready; 59962306a36Sopenharmony_ci struct sof_ipc_fw_version fw_version; 60062306a36Sopenharmony_ci struct sof_ipc_cc_version *cc_version; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci /* topology */ 60362306a36Sopenharmony_ci struct snd_soc_tplg_ops *tplg_ops; 60462306a36Sopenharmony_ci struct list_head pcm_list; 60562306a36Sopenharmony_ci struct list_head kcontrol_list; 60662306a36Sopenharmony_ci struct list_head widget_list; 60762306a36Sopenharmony_ci struct list_head pipeline_list; 60862306a36Sopenharmony_ci struct list_head dai_list; 60962306a36Sopenharmony_ci struct list_head dai_link_list; 61062306a36Sopenharmony_ci struct list_head route_list; 61162306a36Sopenharmony_ci struct snd_soc_component *component; 61262306a36Sopenharmony_ci u32 enabled_cores_mask; /* keep track of enabled cores */ 61362306a36Sopenharmony_ci bool led_present; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci /* FW configuration */ 61662306a36Sopenharmony_ci struct sof_ipc_window *info_window; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci /* IPC timeouts in ms */ 61962306a36Sopenharmony_ci int ipc_timeout; 62062306a36Sopenharmony_ci int boot_timeout; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci /* firmwre tracing */ 62362306a36Sopenharmony_ci bool fw_trace_is_supported; /* set with Kconfig or module parameter */ 62462306a36Sopenharmony_ci void *fw_trace_data; /* private data used by firmware tracing implementation */ 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci bool msi_enabled; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci /* DSP core context */ 62962306a36Sopenharmony_ci u32 num_cores; 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci /* 63262306a36Sopenharmony_ci * ref count per core that will be modified during system suspend/resume and during pcm 63362306a36Sopenharmony_ci * hw_params/hw_free. This doesn't need to be protected with a mutex because pcm 63462306a36Sopenharmony_ci * hw_params/hw_free are already protected by the PCM mutex in the ALSA framework in 63562306a36Sopenharmony_ci * sound/core/ when streams are active and during system suspend/resume, streams are 63662306a36Sopenharmony_ci * already suspended. 63762306a36Sopenharmony_ci */ 63862306a36Sopenharmony_ci int dsp_core_ref_count[SOF_MAX_DSP_NUM_CORES]; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci /* 64162306a36Sopenharmony_ci * Used to keep track of registered IPC client devices so that they can 64262306a36Sopenharmony_ci * be removed when the parent SOF module is removed. 64362306a36Sopenharmony_ci */ 64462306a36Sopenharmony_ci struct list_head ipc_client_list; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci /* mutex to protect client list */ 64762306a36Sopenharmony_ci struct mutex ipc_client_mutex; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci /* 65062306a36Sopenharmony_ci * Used for tracking the IPC client's RX registration for DSP initiated 65162306a36Sopenharmony_ci * message handling. 65262306a36Sopenharmony_ci */ 65362306a36Sopenharmony_ci struct list_head ipc_rx_handler_list; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci /* 65662306a36Sopenharmony_ci * Used for tracking the IPC client's registration for DSP state change 65762306a36Sopenharmony_ci * notification 65862306a36Sopenharmony_ci */ 65962306a36Sopenharmony_ci struct list_head fw_state_handler_list; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci /* to protect the ipc_rx_handler_list and dsp_state_handler_list list */ 66262306a36Sopenharmony_ci struct mutex client_event_handler_mutex; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /* quirks to override topology values */ 66562306a36Sopenharmony_ci bool mclk_id_override; 66662306a36Sopenharmony_ci u16 mclk_id_quirk; /* same size as in IPC3 definitions */ 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci void *private; /* core does not touch this */ 66962306a36Sopenharmony_ci}; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci/* 67262306a36Sopenharmony_ci * Device Level. 67362306a36Sopenharmony_ci */ 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ciint snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data); 67662306a36Sopenharmony_ciint snd_sof_device_remove(struct device *dev); 67762306a36Sopenharmony_ciint snd_sof_device_shutdown(struct device *dev); 67862306a36Sopenharmony_cibool snd_sof_device_probe_completed(struct device *dev); 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ciint snd_sof_runtime_suspend(struct device *dev); 68162306a36Sopenharmony_ciint snd_sof_runtime_resume(struct device *dev); 68262306a36Sopenharmony_ciint snd_sof_runtime_idle(struct device *dev); 68362306a36Sopenharmony_ciint snd_sof_resume(struct device *dev); 68462306a36Sopenharmony_ciint snd_sof_suspend(struct device *dev); 68562306a36Sopenharmony_ciint snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev); 68662306a36Sopenharmony_ciint snd_sof_prepare(struct device *dev); 68762306a36Sopenharmony_civoid snd_sof_complete(struct device *dev); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_civoid snd_sof_new_platform_drv(struct snd_sof_dev *sdev); 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci/* 69262306a36Sopenharmony_ci * Compress support 69362306a36Sopenharmony_ci */ 69462306a36Sopenharmony_ciextern struct snd_compress_ops sof_compressed_ops; 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci/* 69762306a36Sopenharmony_ci * Firmware loading. 69862306a36Sopenharmony_ci */ 69962306a36Sopenharmony_ciint snd_sof_load_firmware_raw(struct snd_sof_dev *sdev); 70062306a36Sopenharmony_ciint snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev); 70162306a36Sopenharmony_ciint snd_sof_run_firmware(struct snd_sof_dev *sdev); 70262306a36Sopenharmony_civoid snd_sof_fw_unload(struct snd_sof_dev *sdev); 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci/* 70562306a36Sopenharmony_ci * IPC low level APIs. 70662306a36Sopenharmony_ci */ 70762306a36Sopenharmony_cistruct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev); 70862306a36Sopenharmony_civoid snd_sof_ipc_free(struct snd_sof_dev *sdev); 70962306a36Sopenharmony_civoid snd_sof_ipc_get_reply(struct snd_sof_dev *sdev); 71062306a36Sopenharmony_civoid snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id); 71162306a36Sopenharmony_cistatic inline void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev) 71262306a36Sopenharmony_ci{ 71362306a36Sopenharmony_ci sdev->ipc->ops->rx_msg(sdev); 71462306a36Sopenharmony_ci} 71562306a36Sopenharmony_ciint sof_ipc_tx_message(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes, 71662306a36Sopenharmony_ci void *reply_data, size_t reply_bytes); 71762306a36Sopenharmony_cistatic inline int sof_ipc_tx_message_no_reply(struct snd_sof_ipc *ipc, void *msg_data, 71862306a36Sopenharmony_ci size_t msg_bytes) 71962306a36Sopenharmony_ci{ 72062306a36Sopenharmony_ci return sof_ipc_tx_message(ipc, msg_data, msg_bytes, NULL, 0); 72162306a36Sopenharmony_ci} 72262306a36Sopenharmony_ciint sof_ipc_set_get_data(struct snd_sof_ipc *ipc, void *msg_data, 72362306a36Sopenharmony_ci size_t msg_bytes, bool set); 72462306a36Sopenharmony_ciint sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes, 72562306a36Sopenharmony_ci void *reply_data, size_t reply_bytes); 72662306a36Sopenharmony_cistatic inline int sof_ipc_tx_message_no_pm_no_reply(struct snd_sof_ipc *ipc, void *msg_data, 72762306a36Sopenharmony_ci size_t msg_bytes) 72862306a36Sopenharmony_ci{ 72962306a36Sopenharmony_ci return sof_ipc_tx_message_no_pm(ipc, msg_data, msg_bytes, NULL, 0); 73062306a36Sopenharmony_ci} 73162306a36Sopenharmony_ciint sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes, 73262306a36Sopenharmony_ci size_t reply_bytes); 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_cistatic inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_id) 73562306a36Sopenharmony_ci{ 73662306a36Sopenharmony_ci snd_sof_ipc_get_reply(sdev); 73762306a36Sopenharmony_ci snd_sof_ipc_reply(sdev, msg_id); 73862306a36Sopenharmony_ci} 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci/* 74162306a36Sopenharmony_ci * Trace/debug 74262306a36Sopenharmony_ci */ 74362306a36Sopenharmony_ciint snd_sof_dbg_init(struct snd_sof_dev *sdev); 74462306a36Sopenharmony_civoid snd_sof_free_debug(struct snd_sof_dev *sdev); 74562306a36Sopenharmony_ciint snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev, 74662306a36Sopenharmony_ci void *base, size_t size, 74762306a36Sopenharmony_ci const char *name, mode_t mode); 74862306a36Sopenharmony_civoid sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, 74962306a36Sopenharmony_ci u32 panic_code, u32 tracep_code, void *oops, 75062306a36Sopenharmony_ci struct sof_ipc_panic_info *panic_info, 75162306a36Sopenharmony_ci void *stack, size_t stack_words); 75262306a36Sopenharmony_civoid snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg); 75362306a36Sopenharmony_ciint snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev); 75462306a36Sopenharmony_ciint snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev, 75562306a36Sopenharmony_ci enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size, 75662306a36Sopenharmony_ci const char *name, enum sof_debugfs_access_type access_type); 75762306a36Sopenharmony_ci/* Firmware tracing */ 75862306a36Sopenharmony_ciint sof_fw_trace_init(struct snd_sof_dev *sdev); 75962306a36Sopenharmony_civoid sof_fw_trace_free(struct snd_sof_dev *sdev); 76062306a36Sopenharmony_civoid sof_fw_trace_fw_crashed(struct snd_sof_dev *sdev); 76162306a36Sopenharmony_civoid sof_fw_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state); 76262306a36Sopenharmony_ciint sof_fw_trace_resume(struct snd_sof_dev *sdev); 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci/* 76562306a36Sopenharmony_ci * DSP Architectures. 76662306a36Sopenharmony_ci */ 76762306a36Sopenharmony_cistatic inline void sof_stack(struct snd_sof_dev *sdev, const char *level, 76862306a36Sopenharmony_ci void *oops, u32 *stack, u32 stack_words) 76962306a36Sopenharmony_ci{ 77062306a36Sopenharmony_ci sof_dsp_arch_ops(sdev)->dsp_stack(sdev, level, oops, stack, 77162306a36Sopenharmony_ci stack_words); 77262306a36Sopenharmony_ci} 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_cistatic inline void sof_oops(struct snd_sof_dev *sdev, const char *level, void *oops) 77562306a36Sopenharmony_ci{ 77662306a36Sopenharmony_ci if (sof_dsp_arch_ops(sdev)->dsp_oops) 77762306a36Sopenharmony_ci sof_dsp_arch_ops(sdev)->dsp_oops(sdev, level, oops); 77862306a36Sopenharmony_ci} 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ciextern const struct dsp_arch_ops sof_xtensa_arch_ops; 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci/* 78362306a36Sopenharmony_ci * Firmware state tracking 78462306a36Sopenharmony_ci */ 78562306a36Sopenharmony_civoid sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state); 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci/* 78862306a36Sopenharmony_ci * Utilities 78962306a36Sopenharmony_ci */ 79062306a36Sopenharmony_civoid sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value); 79162306a36Sopenharmony_civoid sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value); 79262306a36Sopenharmony_ciu32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr); 79362306a36Sopenharmony_ciu64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr); 79462306a36Sopenharmony_civoid sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset, 79562306a36Sopenharmony_ci void *message, size_t bytes); 79662306a36Sopenharmony_civoid sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset, 79762306a36Sopenharmony_ci void *message, size_t bytes); 79862306a36Sopenharmony_ciint sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, 79962306a36Sopenharmony_ci u32 offset, void *src, size_t size); 80062306a36Sopenharmony_ciint sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, 80162306a36Sopenharmony_ci u32 offset, void *dest, size_t size); 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ciint sof_ipc_msg_data(struct snd_sof_dev *sdev, 80462306a36Sopenharmony_ci struct snd_sof_pcm_stream *sps, 80562306a36Sopenharmony_ci void *p, size_t sz); 80662306a36Sopenharmony_ciint sof_set_stream_data_offset(struct snd_sof_dev *sdev, 80762306a36Sopenharmony_ci struct snd_sof_pcm_stream *sps, 80862306a36Sopenharmony_ci size_t posn_offset); 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ciint sof_stream_pcm_open(struct snd_sof_dev *sdev, 81162306a36Sopenharmony_ci struct snd_pcm_substream *substream); 81262306a36Sopenharmony_ciint sof_stream_pcm_close(struct snd_sof_dev *sdev, 81362306a36Sopenharmony_ci struct snd_pcm_substream *substream); 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ciint sof_machine_check(struct snd_sof_dev *sdev); 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci/* SOF client support */ 81862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT) 81962306a36Sopenharmony_ciint sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id, 82062306a36Sopenharmony_ci const void *data, size_t size); 82162306a36Sopenharmony_civoid sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id); 82262306a36Sopenharmony_ciint sof_register_clients(struct snd_sof_dev *sdev); 82362306a36Sopenharmony_civoid sof_unregister_clients(struct snd_sof_dev *sdev); 82462306a36Sopenharmony_civoid sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf); 82562306a36Sopenharmony_civoid sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev); 82662306a36Sopenharmony_ciint sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state); 82762306a36Sopenharmony_ciint sof_resume_clients(struct snd_sof_dev *sdev); 82862306a36Sopenharmony_ci#else /* CONFIG_SND_SOC_SOF_CLIENT */ 82962306a36Sopenharmony_cistatic inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, 83062306a36Sopenharmony_ci u32 id, const void *data, size_t size) 83162306a36Sopenharmony_ci{ 83262306a36Sopenharmony_ci return 0; 83362306a36Sopenharmony_ci} 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_cistatic inline void sof_client_dev_unregister(struct snd_sof_dev *sdev, 83662306a36Sopenharmony_ci const char *name, u32 id) 83762306a36Sopenharmony_ci{ 83862306a36Sopenharmony_ci} 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_cistatic inline int sof_register_clients(struct snd_sof_dev *sdev) 84162306a36Sopenharmony_ci{ 84262306a36Sopenharmony_ci return 0; 84362306a36Sopenharmony_ci} 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_cistatic inline void sof_unregister_clients(struct snd_sof_dev *sdev) 84662306a36Sopenharmony_ci{ 84762306a36Sopenharmony_ci} 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_cistatic inline void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf) 85062306a36Sopenharmony_ci{ 85162306a36Sopenharmony_ci} 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_cistatic inline void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev) 85462306a36Sopenharmony_ci{ 85562306a36Sopenharmony_ci} 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_cistatic inline int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state) 85862306a36Sopenharmony_ci{ 85962306a36Sopenharmony_ci return 0; 86062306a36Sopenharmony_ci} 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_cistatic inline int sof_resume_clients(struct snd_sof_dev *sdev) 86362306a36Sopenharmony_ci{ 86462306a36Sopenharmony_ci return 0; 86562306a36Sopenharmony_ci} 86662306a36Sopenharmony_ci#endif /* CONFIG_SND_SOC_SOF_CLIENT */ 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci/* Main ops for IPC implementations */ 86962306a36Sopenharmony_ciextern const struct sof_ipc_ops ipc3_ops; 87062306a36Sopenharmony_ciextern const struct sof_ipc_ops ipc4_ops; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci#endif 873