linux/sound/soc/sof/sof-priv.h

/* 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 <[email protected]>
 */

#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 <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
#define SOF_DBG_RETAIN_CTX
#define SOF_DBG_VERIFY_TPLG
#define SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE
#define SOF_DBG_DYNAMIC_PIPELINES_ENABLE
#define SOF_DBG_DISABLE_MULTICORE
#define SOF_DBG_PRINT_ALL_DUMPS
#define SOF_DBG_IGNORE_D3_PERSISTENT
#define SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS
#define SOF_DBG_PRINT_IPC_SUCCESS_LOGS
#define SOF_DBG_FORCE_NOCODEC
#define SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD
#define SOF_DBG_DSPLESS_MODE

/* Flag definitions used for controlling the DSP dump behavior */
#define SOF_DBG_DUMP_REGS
#define SOF_DBG_DUMP_MBOX
#define SOF_DBG_DUMP_TEXT
#define SOF_DBG_DUMP_PCI
/* Output this dump (at the DEBUG level) only when SOF_DBG_PRINT_ALL_DUMPS is set */
#define SOF_DBG_DUMP_OPTIONAL

/* 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

/* time in ms for runtime suspend delay */
#define SND_SOF_SUSPEND_DELAY_MS

/* DMA buffer size for trace */
#define DMA_BUF_SIZE_FOR_TRACE

#define SOF_IPC_DSP_REPLY
#define SOF_IPC_HOST_REPLY

/* convenience constructor for DAI driver streams */
#define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt)

#define SOF_FORMATS

/* So far the primary core on all DSPs has ID 0 */
#define SOF_DSP_PRIMARY_CORE

/* max number of DSP cores */
#define SOF_MAX_DSP_NUM_CORES

struct sof_dsp_power_state {};

/* System suspend target state */
enum sof_system_suspend_state {};

enum sof_dfsentry_type {};

enum sof_debugfs_access_type {};

struct sof_compr_stream {};

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
 * @stream_tag:		Stream tag to use
 * @use_phy_addr:	Use the provided @phy_addr for configuration
 * @phy_addr:		Platform dependent address to be used, if  @use_phy_addr
 *			is true
 * @no_ipc_position:	Disable position update IPC from firmware
 */
struct snd_sof_platform_stream_params {};

/**
 * 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 {};

enum sof_dai_access {};

/*
 * 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 {};

/* DSP architecture specific callbacks for oops and stack dumps */
struct dsp_arch_ops {};

#define sof_dsp_arch_ops(sdev)

/* FS entry for debug files that can expose DSP memories, registers */
struct snd_sof_dfsentry {};

/* Debug mapping for any DSP memory or registers that can used for debug */
struct snd_sof_debugfs_map {};

/* mailbox descriptor, used for host <-> DSP IPC */
struct snd_sof_mailbox {};

/* IPC message descriptor for host <-> DSP IO */
struct snd_sof_ipc_msg {};

/**
 * 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 {};

/**
 * 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 {};

/**
 * 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 {};

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
 * serialized for the duration of the instructed transfer. A large message sent
 * via @set_get_data is a single transfer even if at the hardware level it is
 * handled with multiple chunks.
 */
struct sof_ipc_ops {};

/* SOF generic IPC data */
struct snd_sof_ipc {};

/* Helper to retrieve the IPC ops */
#define sof_ipc_get_ops(sdev, ops_name)

/*
 * SOF Device Level.
 */
struct snd_sof_dev {};

/*
 * Device Level.
 */

int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data);
int snd_sof_device_remove(struct device *dev);
int snd_sof_device_shutdown(struct device *dev);
bool snd_sof_device_probe_completed(struct device *dev);

int snd_sof_runtime_suspend(struct device *dev);
int snd_sof_runtime_resume(struct device *dev);
int snd_sof_runtime_idle(struct device *dev);
int snd_sof_resume(struct device *dev);
int snd_sof_suspend(struct device *dev);
int snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev);
int snd_sof_prepare(struct device *dev);
void snd_sof_complete(struct device *dev);

void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);

/*
 * Compress support
 */
extern struct snd_compress_ops sof_compressed_ops;

/*
 * Firmware (firmware, libraries, topologies) file location
 */
int sof_create_ipc_file_profile(struct snd_sof_dev *sdev,
				struct sof_loadable_file_profile *base_profile,
				struct sof_loadable_file_profile *out_profile);

/*
 * Firmware loading.
 */
int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev);
int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev);
int snd_sof_run_firmware(struct snd_sof_dev *sdev);
void snd_sof_fw_unload(struct snd_sof_dev *sdev);

/*
 * IPC low level APIs.
 */
struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev);
void snd_sof_ipc_free(struct snd_sof_dev *sdev);
void snd_sof_ipc_get_reply(struct snd_sof_dev *sdev);
void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id);
static inline void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
{}
int sof_ipc_tx_message(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes,
		       void *reply_data, size_t reply_bytes);
static inline int sof_ipc_tx_message_no_reply(struct snd_sof_ipc *ipc, void *msg_data,
					      size_t msg_bytes)
{}
int sof_ipc_set_get_data(struct snd_sof_ipc *ipc, void *msg_data,
			 size_t msg_bytes, bool set);
int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, void *msg_data, size_t msg_bytes,
			     void *reply_data, size_t reply_bytes);
static inline int sof_ipc_tx_message_no_pm_no_reply(struct snd_sof_ipc *ipc, void *msg_data,
						    size_t msg_bytes)
{}
int sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes,
		     size_t reply_bytes);

static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_id)
{}

/*
 * Trace/debug
 */
int snd_sof_dbg_init(struct snd_sof_dev *sdev);
void snd_sof_free_debug(struct snd_sof_dev *sdev);
int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev,
			     void *base, size_t size,
			     const char *name, mode_t mode);
void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level,
			      u32 panic_code, u32 tracep_code, void *oops,
			      struct sof_ipc_panic_info *panic_info,
			      void *stack, size_t stack_words);
void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg);
int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev);
int snd_sof_debugfs_add_region_item_iomem(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);
/* Firmware tracing */
int sof_fw_trace_init(struct snd_sof_dev *sdev);
void sof_fw_trace_free(struct snd_sof_dev *sdev);
void sof_fw_trace_fw_crashed(struct snd_sof_dev *sdev);
void sof_fw_trace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state);
int sof_fw_trace_resume(struct snd_sof_dev *sdev);

/*
 * DSP Architectures.
 */
static inline void sof_stack(struct snd_sof_dev *sdev, const char *level,
			     void *oops, u32 *stack, u32 stack_words)
{}

static inline void sof_oops(struct snd_sof_dev *sdev, const char *level, void *oops)
{}

extern const struct dsp_arch_ops sof_xtensa_arch_ops;

/*
 * Firmware state tracking
 */
void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state);

/*
 * Utilities
 */
void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value);
void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value);
u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr);
u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr);
void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset,
		       void *message, size_t bytes);
void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset,
		      void *message, size_t bytes);
int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
		    u32 offset, void *src, size_t size);
int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
		   u32 offset, void *dest, size_t size);

int sof_ipc_msg_data(struct snd_sof_dev *sdev,
		     struct snd_sof_pcm_stream *sps,
		     void *p, size_t sz);
int sof_set_stream_data_offset(struct snd_sof_dev *sdev,
			       struct snd_sof_pcm_stream *sps,
			       size_t posn_offset);

int sof_stream_pcm_open(struct snd_sof_dev *sdev,
			struct snd_pcm_substream *substream);
int sof_stream_pcm_close(struct snd_sof_dev *sdev,
			 struct snd_pcm_substream *substream);

/* SOF client support */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT)
int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,
			    const void *data, size_t size);
void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id);
int sof_register_clients(struct snd_sof_dev *sdev);
void sof_unregister_clients(struct snd_sof_dev *sdev);
void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf);
void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev);
int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state);
int sof_resume_clients(struct snd_sof_dev *sdev);
#else /* CONFIG_SND_SOC_SOF_CLIENT */
static inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name,
					  u32 id, const void *data, size_t size)
{
	return 0;
}

static inline void sof_client_dev_unregister(struct snd_sof_dev *sdev,
					     const char *name, u32 id)
{
}

static inline int sof_register_clients(struct snd_sof_dev *sdev)
{
	return 0;
}

static inline  void sof_unregister_clients(struct snd_sof_dev *sdev)
{
}

static inline void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf)
{
}

static inline void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev)
{
}

static inline int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
{
	return 0;
}

static inline int sof_resume_clients(struct snd_sof_dev *sdev)
{
	return 0;
}
#endif /* CONFIG_SND_SOC_SOF_CLIENT */

/* Main ops for IPC implementations */
extern const struct sof_ipc_ops ipc3_ops;
extern const struct sof_ipc_ops ipc4_ops;

#endif