909 lines · 29.5 KB · C
RawDownload
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) *//* * This file is provided under a dual BSD/GPLv2 license.  When using or * redistributing this file, you may do so under either license. * * Copyright(c) 2018 Intel Corporation * * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> */ #ifndef __SOUND_SOC_SOF_PRIV_H#define __SOUND_SOC_SOF_PRIV_H #include <linux/device.h>#include <sound/hdaudio.h>#include <sound/sof.h>#include <sound/sof/info.h>#include <sound/sof/pm.h>#include <sound/sof/trace.h>#include <sound/compress_params.h>#include <uapi/sound/sof/fw.h>#include <sound/sof/ext_manifest.h> struct snd_sof_pcm_stream; /* Flag definitions used in sof_core_debug (sof_debug module parameter) */#define SOF_DBG_ENABLE_TRACE	BIT(0)#define SOF_DBG_RETAIN_CTX	BIT(1)	/* prevent DSP D3 on FW exception */#define SOF_DBG_VERIFY_TPLG	BIT(2) /* verify topology during load */#define SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE	BIT(3) /* 0: use topology token							* 1: override topology							*/#define SOF_DBG_DYNAMIC_PIPELINES_ENABLE	BIT(4) /* 0: use static pipelines							* 1: use dynamic pipelines							*/#define SOF_DBG_DISABLE_MULTICORE		BIT(5) /* schedule all pipelines/widgets							* on primary core							*/#define SOF_DBG_PRINT_ALL_DUMPS		BIT(6) /* Print all ipc and dsp dumps */#define SOF_DBG_IGNORE_D3_PERSISTENT		BIT(7) /* ignore the DSP D3 persistent capability							* and always download firmware upon D3 exit							*/#define SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS	BIT(8) /* print DMA position updates							* in dmesg logs							*/#define SOF_DBG_PRINT_IPC_SUCCESS_LOGS		BIT(9) /* print IPC success							* in dmesg logs							*/#define SOF_DBG_FORCE_NOCODEC			BIT(10) /* ignore all codec-related							 * configurations							 */#define SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD	BIT(11) /* On top of the IPC message header							 * dump the message payload also							 */#define SOF_DBG_DSPLESS_MODE			BIT(15) /* Do not initialize and use the DSP */ /* Flag definitions used for controlling the DSP dump behavior */#define SOF_DBG_DUMP_REGS		BIT(0)#define SOF_DBG_DUMP_MBOX		BIT(1)#define SOF_DBG_DUMP_TEXT		BIT(2)#define SOF_DBG_DUMP_PCI		BIT(3)/* Output this dump (at the DEBUG level) only when SOF_DBG_PRINT_ALL_DUMPS is set */#define SOF_DBG_DUMP_OPTIONAL		BIT(4) /* global debug state set by SOF_DBG_ flags */bool sof_debug_check_flag(int mask); /* max BARs mmaped devices can use */#define SND_SOF_BARS	8 /* time in ms for runtime suspend delay */#define SND_SOF_SUSPEND_DELAY_MS	2000 /* DMA buffer size for trace */#define DMA_BUF_SIZE_FOR_TRACE (PAGE_SIZE * 16) #define SOF_IPC_DSP_REPLY		0#define SOF_IPC_HOST_REPLY		1 /* So far the primary core on all DSPs has ID 0 */#define SOF_DSP_PRIMARY_CORE 0 /* max number of DSP cores */#define SOF_MAX_DSP_NUM_CORES 8 struct sof_dsp_power_state {	u32 state;	u32 substate; /* platform-specific */}; /* System suspend target state */enum sof_system_suspend_state {	SOF_SUSPEND_NONE = 0,	SOF_SUSPEND_S0IX,	SOF_SUSPEND_S3,	SOF_SUSPEND_S4,	SOF_SUSPEND_S5,}; enum sof_dfsentry_type {	SOF_DFSENTRY_TYPE_IOMEM = 0,	SOF_DFSENTRY_TYPE_BUF,}; enum sof_debugfs_access_type {	SOF_DEBUGFS_ACCESS_ALWAYS = 0,	SOF_DEBUGFS_ACCESS_D0_ONLY,}; struct sof_compr_stream {	u64 copied_total;	u32 sampling_rate;	u16 channels;	u16 sample_container_bytes;	struct snd_codec codec_params;	size_t posn_offset;}; struct snd_sof_dev;struct snd_sof_ipc_msg;struct snd_sof_ipc;struct snd_sof_debugfs_map;struct snd_soc_tplg_ops;struct snd_soc_component;struct snd_sof_pdata; /** * struct snd_sof_platform_stream_params - platform dependent stream parameters * @phy_addr:		Platform dependent address to be used, if  @use_phy_addr *			is true * @stream_tag:		Stream tag to use * @use_phy_addr:	Use the provided @phy_addr for configuration * @no_ipc_position:	Disable position update IPC from firmware * @cont_update_posn:	Continuous position update. */struct snd_sof_platform_stream_params {	u32 phy_addr;	u16 stream_tag;	bool use_phy_address;	bool no_ipc_position;	bool cont_update_posn;}; /** * struct sof_firmware - Container struct for SOF firmware * @fw:			Pointer to the firmware * @payload_offset:	Offset of the data within the loaded firmware image to be *			loaded to the DSP (skipping for example ext_manifest section) */struct sof_firmware {	const struct firmware *fw;	u32 payload_offset;}; enum sof_dai_access {	SOF_DAI_DSP_ACCESS,	/* access from DSP only */	SOF_DAI_HOST_ACCESS,	/* access from host only */ 	SOF_DAI_ACCESS_NUM}; /* * SOF DSP HW abstraction operations. * Used to abstract DSP HW architecture and any IO busses between host CPU * and DSP device(s). */struct snd_sof_dsp_ops { 	/* probe/remove/shutdown */	int (*probe_early)(struct snd_sof_dev *sof_dev); /* optional */	int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */	void (*remove)(struct snd_sof_dev *sof_dev); /* optional */	void (*remove_late)(struct snd_sof_dev *sof_dev); /* optional */	int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */ 	/* DSP core boot / reset */	int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */	int (*stall)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */	int (*reset)(struct snd_sof_dev *sof_dev); /* optional */	int (*core_get)(struct snd_sof_dev *sof_dev, int core); /* optional */	int (*core_put)(struct snd_sof_dev *sof_dev, int core); /* optional */ 	/*	 * Register IO: only used by respective drivers themselves,	 * TODO: consider removing these operations and calling respective	 * implementations directly	 */	void (*write8)(struct snd_sof_dev *sof_dev, void __iomem *addr,		       u8 value); /* optional */	u8 (*read8)(struct snd_sof_dev *sof_dev,		    void __iomem *addr); /* optional */	void (*write)(struct snd_sof_dev *sof_dev, void __iomem *addr,		      u32 value); /* optional */	u32 (*read)(struct snd_sof_dev *sof_dev,		    void __iomem *addr); /* optional */	void (*write64)(struct snd_sof_dev *sof_dev, void __iomem *addr,			u64 value); /* optional */	u64 (*read64)(struct snd_sof_dev *sof_dev,		      void __iomem *addr); /* optional */ 	/* memcpy IO */	int (*block_read)(struct snd_sof_dev *sof_dev,			  enum snd_sof_fw_blk_type type, u32 offset,			  void *dest, size_t size); /* mandatory */	int (*block_write)(struct snd_sof_dev *sof_dev,			   enum snd_sof_fw_blk_type type, u32 offset,			   void *src, size_t size); /* mandatory */ 	/* Mailbox IO */	void (*mailbox_read)(struct snd_sof_dev *sof_dev,			     u32 offset, void *dest,			     size_t size); /* optional */	void (*mailbox_write)(struct snd_sof_dev *sof_dev,			      u32 offset, void *src,			      size_t size); /* optional */ 	/* doorbell */	irqreturn_t (*irq_handler)(int irq, void *context); /* optional */	irqreturn_t (*irq_thread)(int irq, void *context); /* optional */ 	/* ipc */	int (*send_msg)(struct snd_sof_dev *sof_dev,			struct snd_sof_ipc_msg *msg); /* mandatory */ 	/* FW loading */	int (*load_firmware)(struct snd_sof_dev *sof_dev); /* mandatory */	int (*load_module)(struct snd_sof_dev *sof_dev,			   struct snd_sof_mod_hdr *hdr); /* optional */ 	/* connect pcm substream to a host stream */	int (*pcm_open)(struct snd_sof_dev *sdev,			struct snd_pcm_substream *substream); /* optional */	/* disconnect pcm substream to a host stream */	int (*pcm_close)(struct snd_sof_dev *sdev,			 struct snd_pcm_substream *substream); /* optional */ 	/* host stream hw params */	int (*pcm_hw_params)(struct snd_sof_dev *sdev,			     struct snd_pcm_substream *substream,			     struct snd_pcm_hw_params *params,			     struct snd_sof_platform_stream_params *platform_params); /* optional */ 	/* host stream hw_free */	int (*pcm_hw_free)(struct snd_sof_dev *sdev,			   struct snd_pcm_substream *substream); /* optional */ 	/* host stream trigger */	int (*pcm_trigger)(struct snd_sof_dev *sdev,			   struct snd_pcm_substream *substream,			   int cmd); /* optional */ 	/* host stream pointer */	snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev,					 struct snd_pcm_substream *substream); /* optional */ 	/* pcm ack */	int (*pcm_ack)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); /* optional */ 	/*	 * optional callback to retrieve the number of frames left/arrived from/to	 * the DSP on the DAI side (link/codec/DMIC/etc).	 *	 * The callback is used when the firmware does not provide this information	 * via the shared SRAM window and it can be retrieved by host.	 */	u64 (*get_dai_frame_counter)(struct snd_sof_dev *sdev,				     struct snd_soc_component *component,				     struct snd_pcm_substream *substream); /* optional */ 	/*	 * Optional callback to retrieve the number of bytes left/arrived from/to	 * the DSP on the host side (bytes between host ALSA buffer and DSP).	 *	 * The callback is needed for ALSA delay reporting.	 */	u64 (*get_host_byte_counter)(struct snd_sof_dev *sdev,				     struct snd_soc_component *component,				     struct snd_pcm_substream *substream); /* optional */ 	/* host read DSP stream data */	int (*ipc_msg_data)(struct snd_sof_dev *sdev,			    struct snd_sof_pcm_stream *sps,			    void *p, size_t sz); /* mandatory */ 	/* host side configuration of the stream's data offset in stream mailbox area */	int (*set_stream_data_offset)(struct snd_sof_dev *sdev,				      struct snd_sof_pcm_stream *sps,				      size_t posn_offset); /* optional */ 	/* pre/post firmware run */	int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */	int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ 	/* parse platform specific extended manifest, optional */	int (*parse_platform_ext_manifest)(struct snd_sof_dev *sof_dev,					   const struct sof_ext_man_elem_header *hdr); 	/* DSP PM */	int (*suspend)(struct snd_sof_dev *sof_dev,		       u32 target_state); /* optional */	int (*resume)(struct snd_sof_dev *sof_dev); /* optional */	int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */	int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */	int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */	int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */	int (*set_power_state)(struct snd_sof_dev *sdev,			       const struct sof_dsp_power_state *target_state); /* optional */ 	/* DSP clocking */	int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */ 	/* debug */	const struct snd_sof_debugfs_map *debug_map; /* optional */	int debug_map_count; /* optional */	void (*dbg_dump)(struct snd_sof_dev *sof_dev,			 u32 flags); /* optional */	void (*ipc_dump)(struct snd_sof_dev *sof_dev); /* optional */	int (*debugfs_add_region_item)(struct snd_sof_dev *sdev,				       enum snd_sof_fw_blk_type blk_type, u32 offset,				       size_t size, const char *name,				       enum sof_debugfs_access_type access_type); /* optional */ 	/* host DMA trace (IPC3) */	int (*trace_init)(struct snd_sof_dev *sdev,			  struct snd_dma_buffer *dmatb,			  struct sof_ipc_dma_trace_params_ext *dtrace_params); /* optional */	int (*trace_release)(struct snd_sof_dev *sdev); /* optional */	int (*trace_trigger)(struct snd_sof_dev *sdev,			     int cmd); /* optional */ 	/* misc */	int (*get_bar_index)(struct snd_sof_dev *sdev,			     u32 type); /* optional */	int (*get_mailbox_offset)(struct snd_sof_dev *sdev);/* mandatory for common loader code */	int (*get_window_offset)(struct snd_sof_dev *sdev,				 u32 id);/* mandatory for common loader code */ 	/* machine driver ops */	int (*machine_register)(struct snd_sof_dev *sdev,				void *pdata); /* optional */	void (*machine_unregister)(struct snd_sof_dev *sdev,				   void *pdata); /* optional */	struct snd_soc_acpi_mach * (*machine_select)(struct snd_sof_dev *sdev); /* optional */	void (*set_mach_params)(struct snd_soc_acpi_mach *mach,				struct snd_sof_dev *sdev); /* optional */ 	/* IPC client ops */	int (*register_ipc_clients)(struct snd_sof_dev *sdev); /* optional */	void (*unregister_ipc_clients)(struct snd_sof_dev *sdev); /* optional */ 	/* DAI ops */	struct snd_soc_dai_driver *drv;	int num_drv; 	bool (*is_chain_dma_supported)(struct snd_sof_dev *sdev, u32 dai_type); /* optional */ 	/* ALSA HW info flags, will be stored in snd_pcm_runtime.hw.info */	u32 hw_info; 	const struct dsp_arch_ops *dsp_arch_ops;}; /* DSP architecture specific callbacks for oops and stack dumps */struct dsp_arch_ops {	void (*dsp_oops)(struct snd_sof_dev *sdev, const char *level, void *oops);	void (*dsp_stack)(struct snd_sof_dev *sdev, const char *level, void *oops,			  u32 *stack, u32 stack_words);}; #define sof_dsp_arch_ops(sdev) ((sdev)->pdata->desc->ops->dsp_arch_ops) /* FS entry for debug files that can expose DSP memories, registers */struct snd_sof_dfsentry {	size_t size;	size_t buf_data_size;  /* length of buffered data for file read operation */	enum sof_dfsentry_type type;	/*	 * access_type specifies if the	 * memory -> DSP resource (memory, register etc) is always accessible	 * or if it is accessible only when the DSP is in D0.	 */	enum sof_debugfs_access_type access_type;#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)	char *cache_buf; /* buffer to cache the contents of debugfs memory */#endif	struct snd_sof_dev *sdev;	struct list_head list;  /* list in sdev dfsentry list */	union {		void __iomem *io_mem;		void *buf;	};}; /* Debug mapping for any DSP memory or registers that can used for debug */struct snd_sof_debugfs_map {	const char *name;	u32 bar;	u32 offset;	u32 size;	/*	 * access_type specifies if the memory is always accessible	 * or if it is accessible only when the DSP is in D0.	 */	enum sof_debugfs_access_type access_type;}; /* mailbox descriptor, used for host <-> DSP IPC */struct snd_sof_mailbox {	size_t size;	u32 offset;}; /* IPC message descriptor for host <-> DSP IO */struct snd_sof_ipc_msg {	/* message data */	void *msg_data;	void *reply_data;	size_t msg_size;	size_t reply_size;	int reply_error; 	bool ipc_complete; 	wait_queue_head_t waitq; 	/* notification, firmware initiated messages */	void *rx_data;}; /** * struct sof_ipc_fw_tracing_ops - IPC-specific firmware tracing ops * @init:	Function pointer for initialization of the tracing * @free:	Optional function pointer for freeing of the tracing * @fw_crashed:	Optional function pointer to notify the tracing of a firmware crash * @suspend:	Function pointer for system/runtime suspend * @resume:	Function pointer for system/runtime resume */struct sof_ipc_fw_tracing_ops {	int (*init)(struct snd_sof_dev *sdev);	void (*free)(struct snd_sof_dev *sdev);	void (*fw_crashed)(struct snd_sof_dev *sdev);	void (*suspend)(struct snd_sof_dev *sdev, pm_message_t pm_state);	int (*resume)(struct snd_sof_dev *sdev);}; /** * struct sof_ipc_pm_ops - IPC-specific PM ops * @ctx_save:		Optional function pointer for context save * @ctx_restore:	Optional function pointer for context restore * @set_core_state:	Optional function pointer for turning on/off a DSP core * @set_pm_gate:	Optional function pointer for pm gate settings */struct sof_ipc_pm_ops {	int (*ctx_save)(struct snd_sof_dev *sdev);	int (*ctx_restore)(struct snd_sof_dev *sdev);	int (*set_core_state)(struct snd_sof_dev *sdev, int core_idx, bool on);	int (*set_pm_gate)(struct snd_sof_dev *sdev, u32 flags);}; /** * struct sof_ipc_fw_loader_ops - IPC/FW-specific loader ops * @validate:		Function pointer for validating the firmware image * @parse_ext_manifest:	Function pointer for parsing the manifest of the firmware * @load_fw_to_dsp:	Optional function pointer for loading the firmware to the *			DSP. *			The function implements generic, hardware independent way *			of loading the initial firmware and its modules (if any). */struct sof_ipc_fw_loader_ops {	int (*validate)(struct snd_sof_dev *sdev);	size_t (*parse_ext_manifest)(struct snd_sof_dev *sdev);	int (*load_fw_to_dsp)(struct snd_sof_dev *sdev);}; struct sof_ipc_tplg_ops;struct sof_ipc_pcm_ops; /** * struct sof_ipc_ops - IPC-specific ops * @tplg:	Pointer to IPC-specific topology ops * @pm:		Pointer to PM ops * @pcm:	Pointer to PCM ops * @fw_loader:	Pointer to Firmware Loader ops * @fw_tracing:	Optional pointer to Firmware tracing ops * * @init:	Optional pointer for IPC related initialization * @exit:	Optional pointer for IPC related cleanup * @post_fw_boot: Optional pointer to execute IPC related tasks after firmware *		boot. * * @tx_msg:	Function pointer for sending a 'short' IPC message * @set_get_data: Function pointer for set/get data ('large' IPC message). This *		function may split up the 'large' message and use the @tx_msg *		path to transfer individual chunks, or use other means to transfer *		the message. * @get_reply:	Function pointer for fetching the reply to *		sdev->ipc->msg.reply_data * @rx_msg:	Function pointer for handling a received message * * Note: both @tx_msg and @set_get_data considered as TX functions and they are

Lines 1–500 of 909.