1  /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2  /*
3   * This file is provided under a dual BSD/GPLv2 license.  When using or
4   * redistributing this file, you may do so under either license.
5   *
6   * Copyright(c) 2018 Intel Corporation
7   *
8   * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9   */
10  
11  #ifndef __SOUND_SOC_SOF_PRIV_H
12  #define __SOUND_SOC_SOF_PRIV_H
13  
14  #include <linux/device.h>
15  #include <sound/hdaudio.h>
16  #include <sound/sof.h>
17  #include <sound/sof/info.h>
18  #include <sound/sof/pm.h>
19  #include <sound/sof/trace.h>
20  #include <uapi/sound/sof/fw.h>
21  #include <sound/sof/ext_manifest.h>
22  
23  struct snd_sof_pcm_stream;
24  
25  /* Flag definitions used in sof_core_debug (sof_debug module parameter) */
26  #define SOF_DBG_ENABLE_TRACE	BIT(0)
27  #define SOF_DBG_RETAIN_CTX	BIT(1)	/* prevent DSP D3 on FW exception */
28  #define SOF_DBG_VERIFY_TPLG	BIT(2) /* verify topology during load */
29  #define SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE	BIT(3) /* 0: use topology token
30  							* 1: override topology
31  							*/
32  #define SOF_DBG_DYNAMIC_PIPELINES_ENABLE	BIT(4) /* 0: use static pipelines
33  							* 1: use dynamic pipelines
34  							*/
35  #define SOF_DBG_DISABLE_MULTICORE		BIT(5) /* schedule all pipelines/widgets
36  							* on primary core
37  							*/
38  #define SOF_DBG_PRINT_ALL_DUMPS		BIT(6) /* Print all ipc and dsp dumps */
39  #define SOF_DBG_IGNORE_D3_PERSISTENT		BIT(7) /* ignore the DSP D3 persistent capability
40  							* and always download firmware upon D3 exit
41  							*/
42  #define SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS	BIT(8) /* print DMA position updates
43  							* in dmesg logs
44  							*/
45  #define SOF_DBG_PRINT_IPC_SUCCESS_LOGS		BIT(9) /* print IPC success
46  							* in dmesg logs
47  							*/
48  #define SOF_DBG_FORCE_NOCODEC			BIT(10) /* ignore all codec-related
49  							 * configurations
50  							 */
51  #define SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD	BIT(11) /* On top of the IPC message header
52  							 * dump the message payload also
53  							 */
54  #define SOF_DBG_DSPLESS_MODE			BIT(15) /* Do not initialize and use the DSP */
55  
56  /* Flag definitions used for controlling the DSP dump behavior */
57  #define SOF_DBG_DUMP_REGS		BIT(0)
58  #define SOF_DBG_DUMP_MBOX		BIT(1)
59  #define SOF_DBG_DUMP_TEXT		BIT(2)
60  #define SOF_DBG_DUMP_PCI		BIT(3)
61  /* Output this dump (at the DEBUG level) only when SOF_DBG_PRINT_ALL_DUMPS is set */
62  #define SOF_DBG_DUMP_OPTIONAL		BIT(4)
63  
64  /* global debug state set by SOF_DBG_ flags */
65  bool sof_debug_check_flag(int mask);
66  
67  /* max BARs mmaped devices can use */
68  #define SND_SOF_BARS	8
69  
70  /* time in ms for runtime suspend delay */
71  #define SND_SOF_SUSPEND_DELAY_MS	2000
72  
73  /* DMA buffer size for trace */
74  #define DMA_BUF_SIZE_FOR_TRACE (PAGE_SIZE * 16)
75  
76  #define SOF_IPC_DSP_REPLY		0
77  #define SOF_IPC_HOST_REPLY		1
78  
79  /* convenience constructor for DAI driver streams */
80  #define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt) \
81  	{.stream_name = sname, .channels_min = scmin, .channels_max = scmax, \
82  	 .rates = srates, .formats = sfmt}
83  
84  #define SOF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
85  	SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT)
86  
87  /* So far the primary core on all DSPs has ID 0 */
88  #define SOF_DSP_PRIMARY_CORE 0
89  
90  /* max number of DSP cores */
91  #define SOF_MAX_DSP_NUM_CORES 8
92  
93  struct sof_dsp_power_state {
94  	u32 state;
95  	u32 substate; /* platform-specific */
96  };
97  
98  /* System suspend target state */
99  enum sof_system_suspend_state {
100  	SOF_SUSPEND_NONE = 0,
101  	SOF_SUSPEND_S0IX,
102  	SOF_SUSPEND_S3,
103  	SOF_SUSPEND_S4,
104  	SOF_SUSPEND_S5,
105  };
106  
107  enum sof_dfsentry_type {
108  	SOF_DFSENTRY_TYPE_IOMEM = 0,
109  	SOF_DFSENTRY_TYPE_BUF,
110  };
111  
112  enum sof_debugfs_access_type {
113  	SOF_DEBUGFS_ACCESS_ALWAYS = 0,
114  	SOF_DEBUGFS_ACCESS_D0_ONLY,
115  };
116  
117  struct sof_compr_stream {
118  	u64 copied_total;
119  	u32 sampling_rate;
120  	u16 channels;
121  	u16 sample_container_bytes;
122  	size_t posn_offset;
123  };
124  
125  struct snd_sof_dev;
126  struct snd_sof_ipc_msg;
127  struct snd_sof_ipc;
128  struct snd_sof_debugfs_map;
129  struct snd_soc_tplg_ops;
130  struct snd_soc_component;
131  struct snd_sof_pdata;
132  
133  /**
134   * struct snd_sof_platform_stream_params - platform dependent stream parameters
135   * @phy_addr:		Platform dependent address to be used, if  @use_phy_addr
136   *			is true
137   * @stream_tag:		Stream tag to use
138   * @use_phy_addr:	Use the provided @phy_addr for configuration
139   * @no_ipc_position:	Disable position update IPC from firmware
140   * @cont_update_posn:	Continuous position update.
141   */
142  struct snd_sof_platform_stream_params {
143  	u32 phy_addr;
144  	u16 stream_tag;
145  	bool use_phy_address;
146  	bool no_ipc_position;
147  	bool cont_update_posn;
148  };
149  
150  /**
151   * struct sof_firmware - Container struct for SOF firmware
152   * @fw:			Pointer to the firmware
153   * @payload_offset:	Offset of the data within the loaded firmware image to be
154   *			loaded to the DSP (skipping for example ext_manifest section)
155   */
156  struct sof_firmware {
157  	const struct firmware *fw;
158  	u32 payload_offset;
159  };
160  
161  enum sof_dai_access {
162  	SOF_DAI_DSP_ACCESS,	/* access from DSP only */
163  	SOF_DAI_HOST_ACCESS,	/* access from host only */
164  
165  	SOF_DAI_ACCESS_NUM
166  };
167  
168  /*
169   * SOF DSP HW abstraction operations.
170   * Used to abstract DSP HW architecture and any IO busses between host CPU
171   * and DSP device(s).
172   */
173  struct snd_sof_dsp_ops {
174  
175  	/* probe/remove/shutdown */
176  	int (*probe_early)(struct snd_sof_dev *sof_dev); /* optional */
177  	int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */
178  	void (*remove)(struct snd_sof_dev *sof_dev); /* optional */
179  	void (*remove_late)(struct snd_sof_dev *sof_dev); /* optional */
180  	int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */
181  
182  	/* DSP core boot / reset */
183  	int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */
184  	int (*stall)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */
185  	int (*reset)(struct snd_sof_dev *sof_dev); /* optional */
186  	int (*core_get)(struct snd_sof_dev *sof_dev, int core); /* optional */
187  	int (*core_put)(struct snd_sof_dev *sof_dev, int core); /* optional */
188  
189  	/*
190  	 * Register IO: only used by respective drivers themselves,
191  	 * TODO: consider removing these operations and calling respective
192  	 * implementations directly
193  	 */
194  	void (*write8)(struct snd_sof_dev *sof_dev, void __iomem *addr,
195  		       u8 value); /* optional */
196  	u8 (*read8)(struct snd_sof_dev *sof_dev,
197  		    void __iomem *addr); /* optional */
198  	void (*write)(struct snd_sof_dev *sof_dev, void __iomem *addr,
199  		      u32 value); /* optional */
200  	u32 (*read)(struct snd_sof_dev *sof_dev,
201  		    void __iomem *addr); /* optional */
202  	void (*write64)(struct snd_sof_dev *sof_dev, void __iomem *addr,
203  			u64 value); /* optional */
204  	u64 (*read64)(struct snd_sof_dev *sof_dev,
205  		      void __iomem *addr); /* optional */
206  
207  	/* memcpy IO */
208  	int (*block_read)(struct snd_sof_dev *sof_dev,
209  			  enum snd_sof_fw_blk_type type, u32 offset,
210  			  void *dest, size_t size); /* mandatory */
211  	int (*block_write)(struct snd_sof_dev *sof_dev,
212  			   enum snd_sof_fw_blk_type type, u32 offset,
213  			   void *src, size_t size); /* mandatory */
214  
215  	/* Mailbox IO */
216  	void (*mailbox_read)(struct snd_sof_dev *sof_dev,
217  			     u32 offset, void *dest,
218  			     size_t size); /* optional */
219  	void (*mailbox_write)(struct snd_sof_dev *sof_dev,
220  			      u32 offset, void *src,
221  			      size_t size); /* optional */
222  
223  	/* doorbell */
224  	irqreturn_t (*irq_handler)(int irq, void *context); /* optional */
225  	irqreturn_t (*irq_thread)(int irq, void *context); /* optional */
226  
227  	/* ipc */
228  	int (*send_msg)(struct snd_sof_dev *sof_dev,
229  			struct snd_sof_ipc_msg *msg); /* mandatory */
230  
231  	/* FW loading */
232  	int (*load_firmware)(struct snd_sof_dev *sof_dev); /* mandatory */
233  	int (*load_module)(struct snd_sof_dev *sof_dev,
234  			   struct snd_sof_mod_hdr *hdr); /* optional */
235  
236  	/* connect pcm substream to a host stream */
237  	int (*pcm_open)(struct snd_sof_dev *sdev,
238  			struct snd_pcm_substream *substream); /* optional */
239  	/* disconnect pcm substream to a host stream */
240  	int (*pcm_close)(struct snd_sof_dev *sdev,
241  			 struct snd_pcm_substream *substream); /* optional */
242  
243  	/* host stream hw params */
244  	int (*pcm_hw_params)(struct snd_sof_dev *sdev,
245  			     struct snd_pcm_substream *substream,
246  			     struct snd_pcm_hw_params *params,
247  			     struct snd_sof_platform_stream_params *platform_params); /* optional */
248  
249  	/* host stream hw_free */
250  	int (*pcm_hw_free)(struct snd_sof_dev *sdev,
251  			   struct snd_pcm_substream *substream); /* optional */
252  
253  	/* host stream trigger */
254  	int (*pcm_trigger)(struct snd_sof_dev *sdev,
255  			   struct snd_pcm_substream *substream,
256  			   int cmd); /* optional */
257  
258  	/* host stream pointer */
259  	snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev,
260  					 struct snd_pcm_substream *substream); /* optional */
261  
262  	/* pcm ack */
263  	int (*pcm_ack)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); /* optional */
264  
265  	/*
266  	 * optional callback to retrieve the number of frames left/arrived from/to
267  	 * the DSP on the DAI side (link/codec/DMIC/etc).
268  	 *
269  	 * The callback is used when the firmware does not provide this information
270  	 * via the shared SRAM window and it can be retrieved by host.
271  	 */
272  	u64 (*get_dai_frame_counter)(struct snd_sof_dev *sdev,
273  				     struct snd_soc_component *component,
274  				     struct snd_pcm_substream *substream); /* optional */
275  
276  	/*
277  	 * Optional callback to retrieve the number of bytes left/arrived from/to
278  	 * the DSP on the host side (bytes between host ALSA buffer and DSP).
279  	 *
280  	 * The callback is needed for ALSA delay reporting.
281  	 */
282  	u64 (*get_host_byte_counter)(struct snd_sof_dev *sdev,
283  				     struct snd_soc_component *component,
284  				     struct snd_pcm_substream *substream); /* optional */
285  
286  	/* host read DSP stream data */
287  	int (*ipc_msg_data)(struct snd_sof_dev *sdev,
288  			    struct snd_sof_pcm_stream *sps,
289  			    void *p, size_t sz); /* mandatory */
290  
291  	/* host side configuration of the stream's data offset in stream mailbox area */
292  	int (*set_stream_data_offset)(struct snd_sof_dev *sdev,
293  				      struct snd_sof_pcm_stream *sps,
294  				      size_t posn_offset); /* optional */
295  
296  	/* pre/post firmware run */
297  	int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
298  	int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
299  
300  	/* parse platform specific extended manifest, optional */
301  	int (*parse_platform_ext_manifest)(struct snd_sof_dev *sof_dev,
302  					   const struct sof_ext_man_elem_header *hdr);
303  
304  	/* DSP PM */
305  	int (*suspend)(struct snd_sof_dev *sof_dev,
306  		       u32 target_state); /* optional */
307  	int (*resume)(struct snd_sof_dev *sof_dev); /* optional */
308  	int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */
309  	int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */
310  	int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */
311  	int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
312  	int (*set_power_state)(struct snd_sof_dev *sdev,
313  			       const struct sof_dsp_power_state *target_state); /* optional */
314  
315  	/* DSP clocking */
316  	int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */
317  
318  	/* debug */
319  	const struct snd_sof_debugfs_map *debug_map; /* optional */
320  	int debug_map_count; /* optional */
321  	void (*dbg_dump)(struct snd_sof_dev *sof_dev,
322  			 u32 flags); /* optional */
323  	void (*ipc_dump)(struct snd_sof_dev *sof_dev); /* optional */
324  	int (*debugfs_add_region_item)(struct snd_sof_dev *sdev,
325  				       enum snd_sof_fw_blk_type blk_type, u32 offset,
326  				       size_t size, const char *name,
327  				       enum sof_debugfs_access_type access_type); /* optional */
328  
329  	/* host DMA trace (IPC3) */
330  	int (*trace_init)(struct snd_sof_dev *sdev,
331  			  struct snd_dma_buffer *dmatb,
332  			  struct sof_ipc_dma_trace_params_ext *dtrace_params); /* optional */
333  	int (*trace_release)(struct snd_sof_dev *sdev); /* optional */
334  	int (*trace_trigger)(struct snd_sof_dev *sdev,
335  			     int cmd); /* optional */
336  
337  	/* misc */
338  	int (*get_bar_index)(struct snd_sof_dev *sdev,
339  			     u32 type); /* optional */
340  	int (*get_mailbox_offset)(struct snd_sof_dev *sdev);/* mandatory for common loader code */
341  	int (*get_window_offset)(struct snd_sof_dev *sdev,
342  				 u32 id);/* mandatory for common loader code */
343  
344  	/* machine driver ops */
345  	int (*machine_register)(struct snd_sof_dev *sdev,
346  				void *pdata); /* optional */
347  	void (*machine_unregister)(struct snd_sof_dev *sdev,
348  				   void *pdata); /* optional */
349  	struct snd_soc_acpi_mach * (*machine_select)(struct snd_sof_dev *sdev); /* optional */
350  	void (*set_mach_params)(struct snd_soc_acpi_mach *mach,
351  				struct snd_sof_dev *sdev); /* optional */
352  
353  	/* IPC client ops */
354  	int (*register_ipc_clients)(struct snd_sof_dev *sdev); /* optional */
355  	void (*unregister_ipc_clients)(struct snd_sof_dev *sdev); /* optional */
356  
357  	/* DAI ops */
358  	struct snd_soc_dai_driver *drv;
359  	int num_drv;
360  
361  	bool (*is_chain_dma_supported)(struct snd_sof_dev *sdev, u32 dai_type); /* optional */
362  
363  	/* ALSA HW info flags, will be stored in snd_pcm_runtime.hw.info */
364  	u32 hw_info;
365  
366  	const struct dsp_arch_ops *dsp_arch_ops;
367  };
368  
369  /* DSP architecture specific callbacks for oops and stack dumps */
370  struct dsp_arch_ops {
371  	void (*dsp_oops)(struct snd_sof_dev *sdev, const char *level, void *oops);
372  	void (*dsp_stack)(struct snd_sof_dev *sdev, const char *level, void *oops,
373  			  u32 *stack, u32 stack_words);
374  };
375  
376  #define sof_dsp_arch_ops(sdev) ((sdev)->pdata->desc->ops->dsp_arch_ops)
377  
378  /* FS entry for debug files that can expose DSP memories, registers */
379  struct snd_sof_dfsentry {
380  	size_t size;
381  	size_t buf_data_size;  /* length of buffered data for file read operation */
382  	enum sof_dfsentry_type type;
383  	/*
384  	 * access_type specifies if the
385  	 * memory -> DSP resource (memory, register etc) is always accessible
386  	 * or if it is accessible only when the DSP is in D0.
387  	 */
388  	enum sof_debugfs_access_type access_type;
389  #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
390  	char *cache_buf; /* buffer to cache the contents of debugfs memory */
391  #endif
392  	struct snd_sof_dev *sdev;
393  	struct list_head list;  /* list in sdev dfsentry list */
394  	union {
395  		void __iomem *io_mem;
396  		void *buf;
397  	};
398  };
399  
400  /* Debug mapping for any DSP memory or registers that can used for debug */
401  struct snd_sof_debugfs_map {
402  	const char *name;
403  	u32 bar;
404  	u32 offset;
405  	u32 size;
406  	/*
407  	 * access_type specifies if the memory is always accessible
408  	 * or if it is accessible only when the DSP is in D0.
409  	 */
410  	enum sof_debugfs_access_type access_type;
411  };
412  
413  /* mailbox descriptor, used for host <-> DSP IPC */
414  struct snd_sof_mailbox {
415  	size_t size;
416  	u32 offset;
417  };
418  
419  /* IPC message descriptor for host <-> DSP IO */
420  struct snd_sof_ipc_msg {
421  	/* message data */
422  	void *msg_data;
423  	void *reply_data;
424  	size_t msg_size;
425  	size_t reply_size;
426  	int reply_error;
427  
428  	bool ipc_complete;
429  
430  	wait_queue_head_t waitq;
431  
432  	/* notification, firmware initiated messages */
433  	void *rx_data;
434  };
435  
436  /**
437   * struct sof_ipc_fw_tracing_ops - IPC-specific firmware tracing ops
438   * @init:	Function pointer for initialization of the tracing
439   * @free:	Optional function pointer for freeing of the tracing
440   * @fw_crashed:	Optional function pointer to notify the tracing of a firmware crash
441   * @suspend:	Function pointer for system/runtime suspend
442   * @resume:	Function pointer for system/runtime resume
443   */
444  struct sof_ipc_fw_tracing_ops {
445  	int (*init)(struct snd_sof_dev *sdev);
446  	void (*free)(struct snd_sof_dev *sdev);
447  	void (*fw_crashed)(struct snd_sof_dev *sdev);
448  	void (*suspend)(struct snd_sof_dev *sdev, pm_message_t pm_state);
449  	int (*resume)(struct snd_sof_dev *sdev);
450  };
451  
452  /**
453   * struct sof_ipc_pm_ops - IPC-specific PM ops
454   * @ctx_save:		Optional function pointer for context save
455   * @ctx_restore:	Optional function pointer for context restore
456   * @set_core_state:	Optional function pointer for turning on/off a DSP core
457   * @set_pm_gate:	Optional function pointer for pm gate settings
458   */
459  struct sof_ipc_pm_ops {
460  	int (*ctx_save)(struct snd_sof_dev *sdev);
461  	int (*ctx_restore)(struct snd_sof_dev *sdev);
462  	int (*set_core_state)(struct snd_sof_dev *sdev, int core_idx, bool on);
463  	int (*set_pm_gate)(struct snd_sof_dev *sdev, u32 flags);
464  };
465  
466  /**
467   * struct sof_ipc_fw_loader_ops - IPC/FW-specific loader ops
468   * @validate:		Function pointer for validating the firmware image
469   * @parse_ext_manifest:	Function pointer for parsing the manifest of the firmware
470   * @load_fw_to_dsp:	Optional function pointer for loading the firmware to the
471   *			DSP.
472   *			The function implements generic, hardware independent way
473   *			of loading the initial firmware and its modules (if any).
474   */
475  struct sof_ipc_fw_loader_ops {
476  	int (*validate)(struct snd_sof_dev *sdev);
477  	size_t (*parse_ext_manifest)(struct snd_sof_dev *sdev);
478  	int (*load_fw_to_dsp)(struct snd_sof_dev *sdev);
479  };
480  
481  struct sof_ipc_tplg_ops;
482  struct sof_ipc_pcm_ops;
483  
484  /**
485   * struct sof_ipc_ops - IPC-specific ops
486   * @tplg:	Pointer to IPC-specific topology ops
487   * @pm:		Pointer to PM ops
488   * @pcm:	Pointer to PCM ops
489   * @fw_loader:	Pointer to Firmware Loader ops
490   * @fw_tracing:	Optional pointer to Firmware tracing ops
491   *
492   * @init:	Optional pointer for IPC related initialization
493   * @exit:	Optional pointer for IPC related cleanup
494   * @post_fw_boot: Optional pointer to execute IPC related tasks after firmware
495   *		boot.
496   *
497   * @tx_msg:	Function pointer for sending a 'short' IPC message
498   * @set_get_data: Function pointer for set/get data ('large' IPC message). This
499   *		function may split up the 'large' message and use the @tx_msg
500   *		path to transfer individual chunks, or use other means to transfer
501   *		the message.
502   * @get_reply:	Function pointer for fetching the reply to
503   *		sdev->ipc->msg.reply_data
504   * @rx_msg:	Function pointer for handling a received message
505   *
506   * Note: both @tx_msg and @set_get_data considered as TX functions and they are
507   * serialized for the duration of the instructed transfer. A large message sent
508   * via @set_get_data is a single transfer even if at the hardware level it is
509   * handled with multiple chunks.
510   */
511  struct sof_ipc_ops {
512  	const struct sof_ipc_tplg_ops *tplg;
513  	const struct sof_ipc_pm_ops *pm;
514  	const struct sof_ipc_pcm_ops *pcm;
515  	const struct sof_ipc_fw_loader_ops *fw_loader;
516  	const struct sof_ipc_fw_tracing_ops *fw_tracing;
517  
518  	int (*init)(struct snd_sof_dev *sdev);
519  	void (*exit)(struct snd_sof_dev *sdev);
520  	int (*post_fw_boot)(struct snd_sof_dev *sdev);
521  
522  	int (*tx_msg)(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes,
523  		      void *reply_data, size_t reply_bytes, bool no_pm);
524  	int (*set_get_data)(struct snd_sof_dev *sdev, void *data, size_t data_bytes,
525  			    bool set);
526  	int (*get_reply)(struct snd_sof_dev *sdev);
527  	void (*rx_msg)(struct snd_sof_dev *sdev);
528  };
529  
530  /* SOF generic IPC data */
531  struct snd_sof_ipc {
532  	struct snd_sof_dev *sdev;
533  
534  	/* protects messages and the disable flag */
535  	struct mutex tx_mutex;
536  	/* disables further sending of ipc's */
537  	bool disable_ipc_tx;
538  
539  	/* Maximum allowed size of a single IPC message/reply */
540  	size_t max_payload_size;
541  
542  	struct snd_sof_ipc_msg msg;
543  
544  	/* IPC ops based on version */
545  	const struct sof_ipc_ops *ops;
546  };
547  
548  /* Helper to retrieve the IPC ops */
549  #define sof_ipc_get_ops(sdev, ops_name)		\
550  		(((sdev)->ipc && (sdev)->ipc->ops) ? (sdev)->ipc->ops->ops_name : NULL)
551  
552  /*
553   * SOF Device Level.
554   */
555  struct snd_sof_dev {
556  	struct device *dev;
557  	spinlock_t ipc_lock;	/* lock for IPC users */
558  	spinlock_t hw_lock;	/* lock for HW IO access */
559  
560  	/*
561  	 * When true the DSP is not used.
562  	 * It is set under the following condition:
563  	 * User sets the SOF_DBG_DSPLESS_MODE flag in sof_debug module parameter
564  	 * and
565  	 * the platform advertises that it can support such mode
566  	 * pdata->desc->dspless_mode_supported is true.
567  	 */
568  	bool dspless_mode_selected;
569  
570  	/* Main, Base firmware image */
571  	struct sof_firmware basefw;
572  
573  	/*
574  	 * ASoC components. plat_drv fields are set dynamically so
575  	 * can't use const
576  	 */
577  	struct snd_soc_component_driver plat_drv;
578  
579  	/* current DSP power state */
580  	struct sof_dsp_power_state dsp_power_state;
581  	/* mutex to protect the dsp_power_state access */
582  	struct mutex power_state_access;
583  
584  	/* Intended power target of system suspend */
585  	enum sof_system_suspend_state system_suspend_target;
586  
587  	/* DSP firmware boot */
588  	wait_queue_head_t boot_wait;
589  	enum sof_fw_state fw_state;
590  	bool first_boot;
591  
592  	/* work queue in case the probe is implemented in two steps */
593  	struct work_struct probe_work;
594  	bool probe_completed;
595  
596  	/* DSP HW differentiation */
597  	struct snd_sof_pdata *pdata;
598  
599  	/* IPC */
600  	struct snd_sof_ipc *ipc;
601  	struct snd_sof_mailbox fw_info_box;	/* FW shared memory */
602  	struct snd_sof_mailbox dsp_box;		/* DSP initiated IPC */
603  	struct snd_sof_mailbox host_box;	/* Host initiated IPC */
604  	struct snd_sof_mailbox stream_box;	/* Stream position update */
605  	struct snd_sof_mailbox debug_box;	/* Debug info updates */
606  	struct snd_sof_ipc_msg *msg;
607  	int ipc_irq;
608  	u32 next_comp_id; /* monotonic - reset during S3 */
609  
610  	/* memory bases for mmaped DSPs - set by dsp_init() */
611  	void __iomem *bar[SND_SOF_BARS];	/* DSP base address */
612  	int mmio_bar;
613  	int mailbox_bar;
614  	size_t dsp_oops_offset;
615  
616  	/* debug */
617  	struct dentry *debugfs_root;
618  	struct list_head dfsentry_list;
619  	bool dbg_dump_printed;
620  	bool ipc_dump_printed;
621  	bool d3_prevented; /* runtime pm use count incremented to prevent context lost */
622  
623  	/* firmware loader */
624  	struct sof_ipc_fw_ready fw_ready;
625  	struct sof_ipc_fw_version fw_version;
626  	struct sof_ipc_cc_version *cc_version;
627  
628  	/* topology */
629  	struct snd_soc_tplg_ops *tplg_ops;
630  	struct list_head pcm_list;
631  	struct list_head kcontrol_list;
632  	struct list_head widget_list;
633  	struct list_head pipeline_list;
634  	struct list_head dai_list;
635  	struct list_head dai_link_list;
636  	struct list_head route_list;
637  	struct snd_soc_component *component;
638  	u32 enabled_cores_mask; /* keep track of enabled cores */
639  	bool led_present;
640  
641  	/* FW configuration */
642  	struct sof_ipc_window *info_window;
643  
644  	/* IPC timeouts in ms */
645  	int ipc_timeout;
646  	int boot_timeout;
647  
648  	/* firmwre tracing */
649  	bool fw_trace_is_supported; /* set with Kconfig or module parameter */
650  	void *fw_trace_data; /* private data used by firmware tracing implementation */
651  
652  	bool msi_enabled;
653  
654  	/* DSP core context */
655  	u32 num_cores;
656  
657  	/*
658  	 * ref count per core that will be modified during system suspend/resume and during pcm
659  	 * hw_params/hw_free. This doesn't need to be protected with a mutex because pcm
660  	 * hw_params/hw_free are already protected by the PCM mutex in the ALSA framework in
661  	 * sound/core/ when streams are active and during system suspend/resume, streams are
662  	 * already suspended.
663  	 */
664  	int dsp_core_ref_count[SOF_MAX_DSP_NUM_CORES];
665  
666  	/*
667  	 * Used to keep track of registered IPC client devices so that they can
668  	 * be removed when the parent SOF module is removed.
669  	 */
670  	struct list_head ipc_client_list;
671  
672  	/* mutex to protect client list */
673  	struct mutex ipc_client_mutex;
674  
675  	/*
676  	 * Used for tracking the IPC client's RX registration for DSP initiated
677  	 * message handling.
678  	 */
679  	struct list_head ipc_rx_handler_list;
680  
681  	/*
682  	 * Used for tracking the IPC client's registration for DSP state change
683  	 * notification
684  	 */
685  	struct list_head fw_state_handler_list;
686  
687  	/* to protect the ipc_rx_handler_list  and  dsp_state_handler_list list */
688  	struct mutex client_event_handler_mutex;
689  
690  	/* quirks to override topology values */
691  	bool mclk_id_override;
692  	u16  mclk_id_quirk; /* same size as in IPC3 definitions */
693  
694  	void *private;			/* core does not touch this */
695  };
696  
697  /*
698   * Device Level.
699   */
700  
701  int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data);
702  int snd_sof_device_remove(struct device *dev);
703  int snd_sof_device_shutdown(struct device *dev);
704  bool snd_sof_device_probe_completed(struct device *dev);
705  
706  int snd_sof_runtime_suspend(struct device *dev);
707  int snd_sof_runtime_resume(struct device *dev);
708  int snd_sof_runtime_idle(struct device *dev);
709  int snd_sof_resume(struct device *dev);
710  int snd_sof_suspend(struct device *dev);
711  int snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev);
712  int snd_sof_prepare(struct device *dev);
713  void snd_sof_complete(struct device *dev);
714  
715  void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);
716  
717  /*
718   * Compress support
719   */
720  extern struct snd_compress_ops sof_compressed_ops;
721  
722  /*
723   * Firmware (firmware, libraries, topologies) file location
724   */
725  int sof_create_ipc_file_profile(struct snd_sof_dev *sdev,
726  				struct sof_loadable_file_profile *base_profile,
727  				struct sof_loadable_file_profile *out_profile);
728  
729  /*
730   * Firmware loading.
731   */
732  int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev);
733  int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev);
734  int snd_sof_run_firmware(struct snd_sof_dev *sdev);
735  void snd_sof_fw_unload(struct snd_sof_dev *sdev);
736  
737  /*
738   * IPC low level APIs.
739   */
740  struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev);
741  void snd_sof_ipc_free(struct snd_sof_dev *sdev);
742  void snd_sof_ipc_get_reply(struct snd_sof_dev *sdev);
743  void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id);
snd_sof_ipc_msgs_rx(struct snd_sof_dev * sdev)744  static inline void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
745  {
746  	sdev->ipc->ops->rx_msg(sdev);
747  }
748  int sof_ipc_tx_message(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes,
749  		       void *reply_data, size_t reply_bytes);
sof_ipc_tx_message_no_reply(struct snd_sof_ipc * ipc,void * msg_data,size_t msg_bytes)750  static inline int sof_ipc_tx_message_no_reply(struct snd_sof_ipc *ipc, void *msg_data,
751  					      size_t msg_bytes)
752  {
753  	return sof_ipc_tx_message(ipc, msg_data, msg_bytes, NULL, 0);
754  }
755  int sof_ipc_set_get_data(struct snd_sof_ipc *ipc, void *msg_data,
756  			 size_t msg_bytes, bool set);
757  int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes,
758  			     void *reply_data, size_t reply_bytes);
sof_ipc_tx_message_no_pm_no_reply(struct snd_sof_ipc * ipc,void * msg_data,size_t msg_bytes)759  static inline int sof_ipc_tx_message_no_pm_no_reply(struct snd_sof_ipc *ipc, void *msg_data,
760  						    size_t msg_bytes)
761  {
762  	return sof_ipc_tx_message_no_pm(ipc, msg_data, msg_bytes, NULL, 0);
763  }
764  int sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes,
765  		     size_t reply_bytes);
766  
snd_sof_ipc_process_reply(struct snd_sof_dev * sdev,u32 msg_id)767  static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_id)
768  {
769  	snd_sof_ipc_get_reply(sdev);
770  	snd_sof_ipc_reply(sdev, msg_id);
771  }
772  
773  /*
774   * Trace/debug
775   */
776  int snd_sof_dbg_init(struct snd_sof_dev *sdev);
777  void snd_sof_free_debug(struct snd_sof_dev *sdev);
778  int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev,
779  			     void *base, size_t size,
780  			     const char *name, mode_t mode);
781  void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level,
782  			      u32 panic_code, u32 tracep_code, void *oops,
783  			      struct sof_ipc_panic_info *panic_info,
784  			      void *stack, size_t stack_words);
785  void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg);
786  int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev);
787  int snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev,
788  		enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size,
789  		const char *name, enum sof_debugfs_access_type access_type);
790  /* Firmware tracing */
791  int sof_fw_trace_init(struct snd_sof_dev *sdev);
792  void sof_fw_trace_free(struct snd_sof_dev *sdev);
793  void sof_fw_trace_fw_crashed(struct snd_sof_dev *sdev);
794  void sof_fw_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state);
795  int sof_fw_trace_resume(struct snd_sof_dev *sdev);
796  
797  /*
798   * DSP Architectures.
799   */
sof_stack(struct snd_sof_dev * sdev,const char * level,void * oops,u32 * stack,u32 stack_words)800  static inline void sof_stack(struct snd_sof_dev *sdev, const char *level,
801  			     void *oops, u32 *stack, u32 stack_words)
802  {
803  		sof_dsp_arch_ops(sdev)->dsp_stack(sdev, level,  oops, stack,
804  						  stack_words);
805  }
806  
sof_oops(struct snd_sof_dev * sdev,const char * level,void * oops)807  static inline void sof_oops(struct snd_sof_dev *sdev, const char *level, void *oops)
808  {
809  	if (sof_dsp_arch_ops(sdev)->dsp_oops)
810  		sof_dsp_arch_ops(sdev)->dsp_oops(sdev, level, oops);
811  }
812  
813  extern const struct dsp_arch_ops sof_xtensa_arch_ops;
814  
815  /*
816   * Firmware state tracking
817   */
818  void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state);
819  
820  /*
821   * Utilities
822   */
823  void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value);
824  void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value);
825  u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr);
826  u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr);
827  void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset,
828  		       void *message, size_t bytes);
829  void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset,
830  		      void *message, size_t bytes);
831  int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
832  		    u32 offset, void *src, size_t size);
833  int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
834  		   u32 offset, void *dest, size_t size);
835  
836  int sof_ipc_msg_data(struct snd_sof_dev *sdev,
837  		     struct snd_sof_pcm_stream *sps,
838  		     void *p, size_t sz);
839  int sof_set_stream_data_offset(struct snd_sof_dev *sdev,
840  			       struct snd_sof_pcm_stream *sps,
841  			       size_t posn_offset);
842  
843  int sof_stream_pcm_open(struct snd_sof_dev *sdev,
844  			struct snd_pcm_substream *substream);
845  int sof_stream_pcm_close(struct snd_sof_dev *sdev,
846  			 struct snd_pcm_substream *substream);
847  
848  /* SOF client support */
849  #if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT)
850  int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,
851  			    const void *data, size_t size);
852  void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id);
853  int sof_register_clients(struct snd_sof_dev *sdev);
854  void sof_unregister_clients(struct snd_sof_dev *sdev);
855  void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf);
856  void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev);
857  int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state);
858  int sof_resume_clients(struct snd_sof_dev *sdev);
859  #else /* CONFIG_SND_SOC_SOF_CLIENT */
sof_client_dev_register(struct snd_sof_dev * sdev,const char * name,u32 id,const void * data,size_t size)860  static inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name,
861  					  u32 id, const void *data, size_t size)
862  {
863  	return 0;
864  }
865  
sof_client_dev_unregister(struct snd_sof_dev * sdev,const char * name,u32 id)866  static inline void sof_client_dev_unregister(struct snd_sof_dev *sdev,
867  					     const char *name, u32 id)
868  {
869  }
870  
sof_register_clients(struct snd_sof_dev * sdev)871  static inline int sof_register_clients(struct snd_sof_dev *sdev)
872  {
873  	return 0;
874  }
875  
sof_unregister_clients(struct snd_sof_dev * sdev)876  static inline  void sof_unregister_clients(struct snd_sof_dev *sdev)
877  {
878  }
879  
sof_client_ipc_rx_dispatcher(struct snd_sof_dev * sdev,void * msg_buf)880  static inline void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf)
881  {
882  }
883  
sof_client_fw_state_dispatcher(struct snd_sof_dev * sdev)884  static inline void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev)
885  {
886  }
887  
sof_suspend_clients(struct snd_sof_dev * sdev,pm_message_t state)888  static inline int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
889  {
890  	return 0;
891  }
892  
sof_resume_clients(struct snd_sof_dev * sdev)893  static inline int sof_resume_clients(struct snd_sof_dev *sdev)
894  {
895  	return 0;
896  }
897  #endif /* CONFIG_SND_SOC_SOF_CLIENT */
898  
899  /* Main ops for IPC implementations */
900  extern const struct sof_ipc_ops ipc3_ops;
901  extern const struct sof_ipc_ops ipc4_ops;
902  
903  #endif
904