Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
0002 /*
0003  * This file is provided under a dual BSD/GPLv2 license.  When using or
0004  * redistributing this file, you may do so under either license.
0005  *
0006  * Copyright(c) 2018 Intel Corporation. All rights reserved.
0007  *
0008  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
0009  */
0010 
0011 #ifndef __SOUND_SOC_SOF_PRIV_H
0012 #define __SOUND_SOC_SOF_PRIV_H
0013 
0014 #include <linux/device.h>
0015 #include <sound/hdaudio.h>
0016 #include <sound/sof.h>
0017 #include <sound/sof/info.h>
0018 #include <sound/sof/pm.h>
0019 #include <sound/sof/trace.h>
0020 #include <uapi/sound/sof/fw.h>
0021 #include <sound/sof/ext_manifest.h>
0022 
0023 /* Flag definitions used in sof_core_debug (sof_debug module parameter) */
0024 #define SOF_DBG_ENABLE_TRACE    BIT(0)
0025 #define SOF_DBG_RETAIN_CTX  BIT(1)  /* prevent DSP D3 on FW exception */
0026 #define SOF_DBG_VERIFY_TPLG BIT(2) /* verify topology during load */
0027 #define SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE  BIT(3) /* 0: use topology token
0028                             * 1: override topology
0029                             */
0030 #define SOF_DBG_DYNAMIC_PIPELINES_ENABLE    BIT(4) /* 0: use static pipelines
0031                             * 1: use dynamic pipelines
0032                             */
0033 #define SOF_DBG_DISABLE_MULTICORE       BIT(5) /* schedule all pipelines/widgets
0034                             * on primary core
0035                             */
0036 #define SOF_DBG_PRINT_ALL_DUMPS     BIT(6) /* Print all ipc and dsp dumps */
0037 #define SOF_DBG_IGNORE_D3_PERSISTENT        BIT(7) /* ignore the DSP D3 persistent capability
0038                             * and always download firmware upon D3 exit
0039                             */
0040 #define SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS  BIT(8) /* print DMA position updates
0041                             * in dmesg logs
0042                             */
0043 #define SOF_DBG_PRINT_IPC_SUCCESS_LOGS      BIT(9) /* print IPC success
0044                             * in dmesg logs
0045                             */
0046 
0047 /* Flag definitions used for controlling the DSP dump behavior */
0048 #define SOF_DBG_DUMP_REGS       BIT(0)
0049 #define SOF_DBG_DUMP_MBOX       BIT(1)
0050 #define SOF_DBG_DUMP_TEXT       BIT(2)
0051 #define SOF_DBG_DUMP_PCI        BIT(3)
0052 /* Output this dump (at the DEBUG level) only when SOF_DBG_PRINT_ALL_DUMPS is set */
0053 #define SOF_DBG_DUMP_OPTIONAL       BIT(4)
0054 
0055 /* global debug state set by SOF_DBG_ flags */
0056 bool sof_debug_check_flag(int mask);
0057 
0058 /* max BARs mmaped devices can use */
0059 #define SND_SOF_BARS    8
0060 
0061 /* time in ms for runtime suspend delay */
0062 #define SND_SOF_SUSPEND_DELAY_MS    2000
0063 
0064 /* DMA buffer size for trace */
0065 #define DMA_BUF_SIZE_FOR_TRACE (PAGE_SIZE * 16)
0066 
0067 #define SOF_IPC_DSP_REPLY       0
0068 #define SOF_IPC_HOST_REPLY      1
0069 
0070 /* convenience constructor for DAI driver streams */
0071 #define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt) \
0072     {.stream_name = sname, .channels_min = scmin, .channels_max = scmax, \
0073      .rates = srates, .formats = sfmt}
0074 
0075 #define SOF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
0076     SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT)
0077 
0078 /* So far the primary core on all DSPs has ID 0 */
0079 #define SOF_DSP_PRIMARY_CORE 0
0080 
0081 /* max number of DSP cores */
0082 #define SOF_MAX_DSP_NUM_CORES 8
0083 
0084 struct sof_dsp_power_state {
0085     u32 state;
0086     u32 substate; /* platform-specific */
0087 };
0088 
0089 /* System suspend target state */
0090 enum sof_system_suspend_state {
0091     SOF_SUSPEND_NONE = 0,
0092     SOF_SUSPEND_S0IX,
0093     SOF_SUSPEND_S3,
0094     SOF_SUSPEND_S4,
0095     SOF_SUSPEND_S5,
0096 };
0097 
0098 enum sof_dfsentry_type {
0099     SOF_DFSENTRY_TYPE_IOMEM = 0,
0100     SOF_DFSENTRY_TYPE_BUF,
0101 };
0102 
0103 enum sof_debugfs_access_type {
0104     SOF_DEBUGFS_ACCESS_ALWAYS = 0,
0105     SOF_DEBUGFS_ACCESS_D0_ONLY,
0106 };
0107 
0108 struct snd_sof_dev;
0109 struct snd_sof_ipc_msg;
0110 struct snd_sof_ipc;
0111 struct snd_sof_debugfs_map;
0112 struct snd_soc_tplg_ops;
0113 struct snd_soc_component;
0114 struct snd_sof_pdata;
0115 
0116 /**
0117  * struct snd_sof_platform_stream_params - platform dependent stream parameters
0118  * @stream_tag:     Stream tag to use
0119  * @use_phy_addr:   Use the provided @phy_addr for configuration
0120  * @phy_addr:       Platform dependent address to be used, if  @use_phy_addr
0121  *          is true
0122  * @no_ipc_position:    Disable position update IPC from firmware
0123  */
0124 struct snd_sof_platform_stream_params {
0125     u16 stream_tag;
0126     bool use_phy_address;
0127     u32 phy_addr;
0128     bool no_ipc_position;
0129     bool cont_update_posn;
0130 };
0131 
0132 /*
0133  * SOF DSP HW abstraction operations.
0134  * Used to abstract DSP HW architecture and any IO busses between host CPU
0135  * and DSP device(s).
0136  */
0137 struct snd_sof_dsp_ops {
0138 
0139     /* probe/remove/shutdown */
0140     int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */
0141     int (*remove)(struct snd_sof_dev *sof_dev); /* optional */
0142     int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */
0143 
0144     /* DSP core boot / reset */
0145     int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */
0146     int (*stall)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */
0147     int (*reset)(struct snd_sof_dev *sof_dev); /* optional */
0148     int (*core_get)(struct snd_sof_dev *sof_dev, int core); /* optional */
0149     int (*core_put)(struct snd_sof_dev *sof_dev, int core); /* optional */
0150 
0151     /*
0152      * Register IO: only used by respective drivers themselves,
0153      * TODO: consider removing these operations and calling respective
0154      * implementations directly
0155      */
0156     void (*write)(struct snd_sof_dev *sof_dev, void __iomem *addr,
0157               u32 value); /* optional */
0158     u32 (*read)(struct snd_sof_dev *sof_dev,
0159             void __iomem *addr); /* optional */
0160     void (*write64)(struct snd_sof_dev *sof_dev, void __iomem *addr,
0161             u64 value); /* optional */
0162     u64 (*read64)(struct snd_sof_dev *sof_dev,
0163               void __iomem *addr); /* optional */
0164 
0165     /* memcpy IO */
0166     int (*block_read)(struct snd_sof_dev *sof_dev,
0167               enum snd_sof_fw_blk_type type, u32 offset,
0168               void *dest, size_t size); /* mandatory */
0169     int (*block_write)(struct snd_sof_dev *sof_dev,
0170                enum snd_sof_fw_blk_type type, u32 offset,
0171                void *src, size_t size); /* mandatory */
0172 
0173     /* Mailbox IO */
0174     void (*mailbox_read)(struct snd_sof_dev *sof_dev,
0175                  u32 offset, void *dest,
0176                  size_t size); /* optional */
0177     void (*mailbox_write)(struct snd_sof_dev *sof_dev,
0178                   u32 offset, void *src,
0179                   size_t size); /* optional */
0180 
0181     /* doorbell */
0182     irqreturn_t (*irq_handler)(int irq, void *context); /* optional */
0183     irqreturn_t (*irq_thread)(int irq, void *context); /* optional */
0184 
0185     /* ipc */
0186     int (*send_msg)(struct snd_sof_dev *sof_dev,
0187             struct snd_sof_ipc_msg *msg); /* mandatory */
0188 
0189     /* FW loading */
0190     int (*load_firmware)(struct snd_sof_dev *sof_dev); /* mandatory */
0191     int (*load_module)(struct snd_sof_dev *sof_dev,
0192                struct snd_sof_mod_hdr *hdr); /* optional */
0193 
0194     /* connect pcm substream to a host stream */
0195     int (*pcm_open)(struct snd_sof_dev *sdev,
0196             struct snd_pcm_substream *substream); /* optional */
0197     /* disconnect pcm substream to a host stream */
0198     int (*pcm_close)(struct snd_sof_dev *sdev,
0199              struct snd_pcm_substream *substream); /* optional */
0200 
0201     /* host stream hw params */
0202     int (*pcm_hw_params)(struct snd_sof_dev *sdev,
0203                  struct snd_pcm_substream *substream,
0204                  struct snd_pcm_hw_params *params,
0205                  struct snd_sof_platform_stream_params *platform_params); /* optional */
0206 
0207     /* host stream hw_free */
0208     int (*pcm_hw_free)(struct snd_sof_dev *sdev,
0209                struct snd_pcm_substream *substream); /* optional */
0210 
0211     /* host stream trigger */
0212     int (*pcm_trigger)(struct snd_sof_dev *sdev,
0213                struct snd_pcm_substream *substream,
0214                int cmd); /* optional */
0215 
0216     /* host stream pointer */
0217     snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev,
0218                      struct snd_pcm_substream *substream); /* optional */
0219 
0220     /* pcm ack */
0221     int (*pcm_ack)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); /* optional */
0222 
0223     /* host read DSP stream data */
0224     int (*ipc_msg_data)(struct snd_sof_dev *sdev,
0225                 struct snd_pcm_substream *substream,
0226                 void *p, size_t sz); /* mandatory */
0227 
0228     /* host side configuration of the stream's data offset in stream mailbox area */
0229     int (*set_stream_data_offset)(struct snd_sof_dev *sdev,
0230                       struct snd_pcm_substream *substream,
0231                       size_t posn_offset); /* optional */
0232 
0233     /* pre/post firmware run */
0234     int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
0235     int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
0236 
0237     /* parse platform specific extended manifest, optional */
0238     int (*parse_platform_ext_manifest)(struct snd_sof_dev *sof_dev,
0239                        const struct sof_ext_man_elem_header *hdr);
0240 
0241     /* DSP PM */
0242     int (*suspend)(struct snd_sof_dev *sof_dev,
0243                u32 target_state); /* optional */
0244     int (*resume)(struct snd_sof_dev *sof_dev); /* optional */
0245     int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */
0246     int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */
0247     int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */
0248     int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
0249     int (*set_power_state)(struct snd_sof_dev *sdev,
0250                    const struct sof_dsp_power_state *target_state); /* optional */
0251 
0252     /* DSP clocking */
0253     int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */
0254 
0255     /* debug */
0256     const struct snd_sof_debugfs_map *debug_map; /* optional */
0257     int debug_map_count; /* optional */
0258     void (*dbg_dump)(struct snd_sof_dev *sof_dev,
0259              u32 flags); /* optional */
0260     void (*ipc_dump)(struct snd_sof_dev *sof_dev); /* optional */
0261     int (*debugfs_add_region_item)(struct snd_sof_dev *sdev,
0262                        enum snd_sof_fw_blk_type blk_type, u32 offset,
0263                        size_t size, const char *name,
0264                        enum sof_debugfs_access_type access_type); /* optional */
0265 
0266     /* host DMA trace (IPC3) */
0267     int (*trace_init)(struct snd_sof_dev *sdev,
0268               struct snd_dma_buffer *dmatb,
0269               struct sof_ipc_dma_trace_params_ext *dtrace_params); /* optional */
0270     int (*trace_release)(struct snd_sof_dev *sdev); /* optional */
0271     int (*trace_trigger)(struct snd_sof_dev *sdev,
0272                  int cmd); /* optional */
0273 
0274     /* misc */
0275     int (*get_bar_index)(struct snd_sof_dev *sdev,
0276                  u32 type); /* optional */
0277     int (*get_mailbox_offset)(struct snd_sof_dev *sdev);/* mandatory for common loader code */
0278     int (*get_window_offset)(struct snd_sof_dev *sdev,
0279                  u32 id);/* mandatory for common loader code */
0280 
0281     /* machine driver ops */
0282     int (*machine_register)(struct snd_sof_dev *sdev,
0283                 void *pdata); /* optional */
0284     void (*machine_unregister)(struct snd_sof_dev *sdev,
0285                    void *pdata); /* optional */
0286     struct snd_soc_acpi_mach * (*machine_select)(struct snd_sof_dev *sdev); /* optional */
0287     void (*set_mach_params)(struct snd_soc_acpi_mach *mach,
0288                 struct snd_sof_dev *sdev); /* optional */
0289 
0290     /* IPC client ops */
0291     int (*register_ipc_clients)(struct snd_sof_dev *sdev); /* optional */
0292     void (*unregister_ipc_clients)(struct snd_sof_dev *sdev); /* optional */
0293 
0294     /* DAI ops */
0295     struct snd_soc_dai_driver *drv;
0296     int num_drv;
0297 
0298     /* ALSA HW info flags, will be stored in snd_pcm_runtime.hw.info */
0299     u32 hw_info;
0300 
0301     const struct dsp_arch_ops *dsp_arch_ops;
0302 };
0303 
0304 /* DSP architecture specific callbacks for oops and stack dumps */
0305 struct dsp_arch_ops {
0306     void (*dsp_oops)(struct snd_sof_dev *sdev, const char *level, void *oops);
0307     void (*dsp_stack)(struct snd_sof_dev *sdev, const char *level, void *oops,
0308               u32 *stack, u32 stack_words);
0309 };
0310 
0311 #define sof_dsp_arch_ops(sdev) ((sdev)->pdata->desc->ops->dsp_arch_ops)
0312 
0313 /* FS entry for debug files that can expose DSP memories, registers */
0314 struct snd_sof_dfsentry {
0315     size_t size;
0316     size_t buf_data_size;  /* length of buffered data for file read operation */
0317     enum sof_dfsentry_type type;
0318     /*
0319      * access_type specifies if the
0320      * memory -> DSP resource (memory, register etc) is always accessible
0321      * or if it is accessible only when the DSP is in D0.
0322      */
0323     enum sof_debugfs_access_type access_type;
0324 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
0325     char *cache_buf; /* buffer to cache the contents of debugfs memory */
0326 #endif
0327     struct snd_sof_dev *sdev;
0328     struct list_head list;  /* list in sdev dfsentry list */
0329     union {
0330         void __iomem *io_mem;
0331         void *buf;
0332     };
0333 };
0334 
0335 /* Debug mapping for any DSP memory or registers that can used for debug */
0336 struct snd_sof_debugfs_map {
0337     const char *name;
0338     u32 bar;
0339     u32 offset;
0340     u32 size;
0341     /*
0342      * access_type specifies if the memory is always accessible
0343      * or if it is accessible only when the DSP is in D0.
0344      */
0345     enum sof_debugfs_access_type access_type;
0346 };
0347 
0348 /* mailbox descriptor, used for host <-> DSP IPC */
0349 struct snd_sof_mailbox {
0350     u32 offset;
0351     size_t size;
0352 };
0353 
0354 /* IPC message descriptor for host <-> DSP IO */
0355 struct snd_sof_ipc_msg {
0356     /* message data */
0357     void *msg_data;
0358     void *reply_data;
0359     size_t msg_size;
0360     size_t reply_size;
0361     int reply_error;
0362 
0363     /* notification, firmware initiated messages */
0364     void *rx_data;
0365 
0366     wait_queue_head_t waitq;
0367     bool ipc_complete;
0368 };
0369 
0370 /**
0371  * struct sof_ipc_fw_tracing_ops - IPC-specific firmware tracing ops
0372  * @init:   Function pointer for initialization of the tracing
0373  * @free:   Optional function pointer for freeing of the tracing
0374  * @fw_crashed: Optional function pointer to notify the tracing of a firmware crash
0375  * @suspend:    Function pointer for system/runtime suspend
0376  * @resume: Function pointer for system/runtime resume
0377  */
0378 struct sof_ipc_fw_tracing_ops {
0379     int (*init)(struct snd_sof_dev *sdev);
0380     void (*free)(struct snd_sof_dev *sdev);
0381     void (*fw_crashed)(struct snd_sof_dev *sdev);
0382     void (*suspend)(struct snd_sof_dev *sdev, pm_message_t pm_state);
0383     int (*resume)(struct snd_sof_dev *sdev);
0384 };
0385 
0386 /**
0387  * struct sof_ipc_pm_ops - IPC-specific PM ops
0388  * @ctx_save:       Optional function pointer for context save
0389  * @ctx_restore:    Optional function pointer for context restore
0390  * @set_core_state: Optional function pointer for turning on/off a DSP core
0391  */
0392 struct sof_ipc_pm_ops {
0393     int (*ctx_save)(struct snd_sof_dev *sdev);
0394     int (*ctx_restore)(struct snd_sof_dev *sdev);
0395     int (*set_core_state)(struct snd_sof_dev *sdev, int core_idx, bool on);
0396 };
0397 
0398 /**
0399  * struct sof_ipc_fw_loader_ops - IPC/FW-specific loader ops
0400  * @validate:       Function pointer for validating the firmware image
0401  * @parse_ext_manifest: Function pointer for parsing the manifest of the firmware
0402  * @load_fw_to_dsp: Optional function pointer for loading the firmware to the
0403  *          DSP.
0404  *          The function implements generic, hardware independent way
0405  *          of loading the initial firmware and its modules (if any).
0406  * @query_fw_configuration: Optional function pointer to query information and
0407  *          configuration from the booted firmware.
0408  *          Executed after the first successful firmware boot.
0409  */
0410 struct sof_ipc_fw_loader_ops {
0411     int (*validate)(struct snd_sof_dev *sdev);
0412     size_t (*parse_ext_manifest)(struct snd_sof_dev *sdev);
0413     int (*load_fw_to_dsp)(struct snd_sof_dev *sdev);
0414     int (*query_fw_configuration)(struct snd_sof_dev *sdev);
0415 };
0416 
0417 struct sof_ipc_tplg_ops;
0418 struct sof_ipc_pcm_ops;
0419 
0420 /**
0421  * struct sof_ipc_ops - IPC-specific ops
0422  * @tplg:   Pointer to IPC-specific topology ops
0423  * @pm:     Pointer to PM ops
0424  * @pcm:    Pointer to PCM ops
0425  * @fw_loader:  Pointer to Firmware Loader ops
0426  * @fw_tracing: Pointer to Firmware tracing ops
0427  *
0428  * @tx_msg: Function pointer for sending a 'short' IPC message
0429  * @set_get_data: Function pointer for set/get data ('large' IPC message). This
0430  *      function may split up the 'large' message and use the @tx_msg
0431  *      path to transfer individual chunks, or use other means to transfer
0432  *      the message.
0433  * @get_reply:  Function pointer for fetching the reply to
0434  *      sdev->ipc->msg.reply_data
0435  * @rx_msg: Function pointer for handling a received message
0436  *
0437  * Note: both @tx_msg and @set_get_data considered as TX functions and they are
0438  * serialized for the duration of the instructed transfer. A large message sent
0439  * via @set_get_data is a single transfer even if at the hardware level it is
0440  * handled with multiple chunks.
0441  */
0442 struct sof_ipc_ops {
0443     const struct sof_ipc_tplg_ops *tplg;
0444     const struct sof_ipc_pm_ops *pm;
0445     const struct sof_ipc_pcm_ops *pcm;
0446     const struct sof_ipc_fw_loader_ops *fw_loader;
0447     const struct sof_ipc_fw_tracing_ops *fw_tracing;
0448 
0449     int (*tx_msg)(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes,
0450               void *reply_data, size_t reply_bytes, bool no_pm);
0451     int (*set_get_data)(struct snd_sof_dev *sdev, void *data, size_t data_bytes,
0452                 bool set);
0453     int (*get_reply)(struct snd_sof_dev *sdev);
0454     void (*rx_msg)(struct snd_sof_dev *sdev);
0455 };
0456 
0457 /* SOF generic IPC data */
0458 struct snd_sof_ipc {
0459     struct snd_sof_dev *sdev;
0460 
0461     /* protects messages and the disable flag */
0462     struct mutex tx_mutex;
0463     /* disables further sending of ipc's */
0464     bool disable_ipc_tx;
0465 
0466     /* Maximum allowed size of a single IPC message/reply */
0467     size_t max_payload_size;
0468 
0469     struct snd_sof_ipc_msg msg;
0470 
0471     /* IPC ops based on version */
0472     const struct sof_ipc_ops *ops;
0473 };
0474 
0475 /*
0476  * SOF Device Level.
0477  */
0478 struct snd_sof_dev {
0479     struct device *dev;
0480     spinlock_t ipc_lock;    /* lock for IPC users */
0481     spinlock_t hw_lock; /* lock for HW IO access */
0482 
0483     /*
0484      * ASoC components. plat_drv fields are set dynamically so
0485      * can't use const
0486      */
0487     struct snd_soc_component_driver plat_drv;
0488 
0489     /* current DSP power state */
0490     struct sof_dsp_power_state dsp_power_state;
0491     /* mutex to protect the dsp_power_state access */
0492     struct mutex power_state_access;
0493 
0494     /* Intended power target of system suspend */
0495     enum sof_system_suspend_state system_suspend_target;
0496 
0497     /* DSP firmware boot */
0498     wait_queue_head_t boot_wait;
0499     enum sof_fw_state fw_state;
0500     bool first_boot;
0501 
0502     /* work queue in case the probe is implemented in two steps */
0503     struct work_struct probe_work;
0504     bool probe_completed;
0505 
0506     /* DSP HW differentiation */
0507     struct snd_sof_pdata *pdata;
0508 
0509     /* IPC */
0510     struct snd_sof_ipc *ipc;
0511     struct snd_sof_mailbox dsp_box;     /* DSP initiated IPC */
0512     struct snd_sof_mailbox host_box;    /* Host initiated IPC */
0513     struct snd_sof_mailbox stream_box;  /* Stream position update */
0514     struct snd_sof_mailbox debug_box;   /* Debug info updates */
0515     struct snd_sof_ipc_msg *msg;
0516     int ipc_irq;
0517     u32 next_comp_id; /* monotonic - reset during S3 */
0518 
0519     /* memory bases for mmaped DSPs - set by dsp_init() */
0520     void __iomem *bar[SND_SOF_BARS];    /* DSP base address */
0521     int mmio_bar;
0522     int mailbox_bar;
0523     size_t dsp_oops_offset;
0524 
0525     /* debug */
0526     struct dentry *debugfs_root;
0527     struct list_head dfsentry_list;
0528     bool dbg_dump_printed;
0529     bool ipc_dump_printed;
0530 
0531     /* firmware loader */
0532     struct sof_ipc_fw_ready fw_ready;
0533     struct sof_ipc_fw_version fw_version;
0534     struct sof_ipc_cc_version *cc_version;
0535 
0536     /* topology */
0537     struct snd_soc_tplg_ops *tplg_ops;
0538     struct list_head pcm_list;
0539     struct list_head kcontrol_list;
0540     struct list_head widget_list;
0541     struct list_head dai_list;
0542     struct list_head dai_link_list;
0543     struct list_head route_list;
0544     struct snd_soc_component *component;
0545     u32 enabled_cores_mask; /* keep track of enabled cores */
0546     bool led_present;
0547 
0548     /* FW configuration */
0549     struct sof_ipc_window *info_window;
0550 
0551     /* IPC timeouts in ms */
0552     int ipc_timeout;
0553     int boot_timeout;
0554 
0555     /* firmwre tracing */
0556     bool fw_trace_is_supported; /* set with Kconfig or module parameter */
0557     void *fw_trace_data; /* private data used by firmware tracing implementation */
0558 
0559     bool msi_enabled;
0560 
0561     /* DSP core context */
0562     u32 num_cores;
0563 
0564     /*
0565      * ref count per core that will be modified during system suspend/resume and during pcm
0566      * hw_params/hw_free. This doesn't need to be protected with a mutex because pcm
0567      * hw_params/hw_free are already protected by the PCM mutex in the ALSA framework in
0568      * sound/core/ when streams are active and during system suspend/resume, streams are
0569      * already suspended.
0570      */
0571     int dsp_core_ref_count[SOF_MAX_DSP_NUM_CORES];
0572 
0573     /*
0574      * Used to keep track of registered IPC client devices so that they can
0575      * be removed when the parent SOF module is removed.
0576      */
0577     struct list_head ipc_client_list;
0578 
0579     /* mutex to protect client list */
0580     struct mutex ipc_client_mutex;
0581 
0582     /*
0583      * Used for tracking the IPC client's RX registration for DSP initiated
0584      * message handling.
0585      */
0586     struct list_head ipc_rx_handler_list;
0587 
0588     /*
0589      * Used for tracking the IPC client's registration for DSP state change
0590      * notification
0591      */
0592     struct list_head fw_state_handler_list;
0593 
0594     /* to protect the ipc_rx_handler_list  and  dsp_state_handler_list list */
0595     struct mutex client_event_handler_mutex;
0596 
0597     void *private;          /* core does not touch this */
0598 };
0599 
0600 /*
0601  * Device Level.
0602  */
0603 
0604 int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data);
0605 int snd_sof_device_remove(struct device *dev);
0606 int snd_sof_device_shutdown(struct device *dev);
0607 bool snd_sof_device_probe_completed(struct device *dev);
0608 
0609 int snd_sof_runtime_suspend(struct device *dev);
0610 int snd_sof_runtime_resume(struct device *dev);
0611 int snd_sof_runtime_idle(struct device *dev);
0612 int snd_sof_resume(struct device *dev);
0613 int snd_sof_suspend(struct device *dev);
0614 int snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev);
0615 int snd_sof_prepare(struct device *dev);
0616 void snd_sof_complete(struct device *dev);
0617 
0618 void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);
0619 
0620 /*
0621  * Compress support
0622  */
0623 extern struct snd_compress_ops sof_compressed_ops;
0624 
0625 /*
0626  * Firmware loading.
0627  */
0628 int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev);
0629 int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev);
0630 int snd_sof_run_firmware(struct snd_sof_dev *sdev);
0631 void snd_sof_fw_unload(struct snd_sof_dev *sdev);
0632 
0633 /*
0634  * IPC low level APIs.
0635  */
0636 struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev);
0637 void snd_sof_ipc_free(struct snd_sof_dev *sdev);
0638 void snd_sof_ipc_get_reply(struct snd_sof_dev *sdev);
0639 void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id);
0640 static inline void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
0641 {
0642     sdev->ipc->ops->rx_msg(sdev);
0643 }
0644 int sof_ipc_tx_message(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes,
0645                void *reply_data, size_t reply_bytes);
0646 int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes,
0647                  void *reply_data, size_t reply_bytes);
0648 int sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes,
0649              size_t reply_bytes);
0650 
0651 static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_id)
0652 {
0653     snd_sof_ipc_get_reply(sdev);
0654     snd_sof_ipc_reply(sdev, msg_id);
0655 }
0656 
0657 /*
0658  * Trace/debug
0659  */
0660 int snd_sof_dbg_init(struct snd_sof_dev *sdev);
0661 void snd_sof_free_debug(struct snd_sof_dev *sdev);
0662 int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev,
0663                  void *base, size_t size,
0664                  const char *name, mode_t mode);
0665 void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level,
0666                   u32 panic_code, u32 tracep_code, void *oops,
0667                   struct sof_ipc_panic_info *panic_info,
0668                   void *stack, size_t stack_words);
0669 void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg);
0670 int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev);
0671 int snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev,
0672         enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size,
0673         const char *name, enum sof_debugfs_access_type access_type);
0674 /* Firmware tracing */
0675 int sof_fw_trace_init(struct snd_sof_dev *sdev);
0676 void sof_fw_trace_free(struct snd_sof_dev *sdev);
0677 void sof_fw_trace_fw_crashed(struct snd_sof_dev *sdev);
0678 void sof_fw_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state);
0679 int sof_fw_trace_resume(struct snd_sof_dev *sdev);
0680 
0681 /*
0682  * DSP Architectures.
0683  */
0684 static inline void sof_stack(struct snd_sof_dev *sdev, const char *level,
0685                  void *oops, u32 *stack, u32 stack_words)
0686 {
0687         sof_dsp_arch_ops(sdev)->dsp_stack(sdev, level,  oops, stack,
0688                           stack_words);
0689 }
0690 
0691 static inline void sof_oops(struct snd_sof_dev *sdev, const char *level, void *oops)
0692 {
0693     if (sof_dsp_arch_ops(sdev)->dsp_oops)
0694         sof_dsp_arch_ops(sdev)->dsp_oops(sdev, level, oops);
0695 }
0696 
0697 extern const struct dsp_arch_ops sof_xtensa_arch_ops;
0698 
0699 /*
0700  * Firmware state tracking
0701  */
0702 void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state);
0703 
0704 /*
0705  * Utilities
0706  */
0707 void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value);
0708 void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value);
0709 u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr);
0710 u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr);
0711 void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset,
0712                void *message, size_t bytes);
0713 void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset,
0714               void *message, size_t bytes);
0715 int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
0716             u32 offset, void *src, size_t size);
0717 int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
0718            u32 offset, void *dest, size_t size);
0719 
0720 int sof_ipc_msg_data(struct snd_sof_dev *sdev,
0721              struct snd_pcm_substream *substream,
0722              void *p, size_t sz);
0723 int sof_set_stream_data_offset(struct snd_sof_dev *sdev,
0724                    struct snd_pcm_substream *substream,
0725                    size_t posn_offset);
0726 
0727 int sof_stream_pcm_open(struct snd_sof_dev *sdev,
0728             struct snd_pcm_substream *substream);
0729 int sof_stream_pcm_close(struct snd_sof_dev *sdev,
0730              struct snd_pcm_substream *substream);
0731 
0732 int sof_machine_check(struct snd_sof_dev *sdev);
0733 
0734 /* SOF client support */
0735 #if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT)
0736 int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,
0737                 const void *data, size_t size);
0738 void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id);
0739 int sof_register_clients(struct snd_sof_dev *sdev);
0740 void sof_unregister_clients(struct snd_sof_dev *sdev);
0741 void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf);
0742 void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev);
0743 int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state);
0744 int sof_resume_clients(struct snd_sof_dev *sdev);
0745 #else /* CONFIG_SND_SOC_SOF_CLIENT */
0746 static inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name,
0747                       u32 id, const void *data, size_t size)
0748 {
0749     return 0;
0750 }
0751 
0752 static inline void sof_client_dev_unregister(struct snd_sof_dev *sdev,
0753                          const char *name, u32 id)
0754 {
0755 }
0756 
0757 static inline int sof_register_clients(struct snd_sof_dev *sdev)
0758 {
0759     return 0;
0760 }
0761 
0762 static inline  void sof_unregister_clients(struct snd_sof_dev *sdev)
0763 {
0764 }
0765 
0766 static inline void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf)
0767 {
0768 }
0769 
0770 static inline void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev)
0771 {
0772 }
0773 
0774 static inline int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
0775 {
0776     return 0;
0777 }
0778 
0779 static inline int sof_resume_clients(struct snd_sof_dev *sdev)
0780 {
0781     return 0;
0782 }
0783 #endif /* CONFIG_SND_SOC_SOF_CLIENT */
0784 
0785 /* Main ops for IPC implementations */
0786 extern const struct sof_ipc_ops ipc3_ops;
0787 extern const struct sof_ipc_ops ipc4_ops;
0788 
0789 #endif