linux/sound/soc/intel/skylake/skl-messages.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  skl-message.c - HDA DSP interface for FW registration, Pipe and Module
 *  configurations
 *
 *  Copyright (C) 2015 Intel Corp
 *  Author:Rafal Redzimski <[email protected]>
 *	   Jeeja KP <[email protected]>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/slab.h>
#include <linux/pci.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <uapi/sound/skl-tplg-interface.h>
#include "skl-sst-dsp.h"
#include "cnl-sst-dsp.h"
#include "skl-sst-ipc.h"
#include "skl.h"
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"
#include "skl-topology.h"

static int skl_alloc_dma_buf(struct device *dev,
		struct snd_dma_buffer *dmab, size_t size)
{}

static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
{}

#define SKL_ASTATE_PARAM_ID

void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data)
{}

static int skl_dsp_setup_spib(struct device *dev, unsigned int size,
				int stream_tag, int enable)
{}

static int skl_dsp_prepare(struct device *dev, unsigned int format,
			unsigned int size, struct snd_dma_buffer *dmab)
{}

static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag)
{}

static int skl_dsp_cleanup(struct device *dev,
		struct snd_dma_buffer *dmab, int stream_tag)
{}

static struct skl_dsp_loader_ops skl_get_loader_ops(void)
{
	struct skl_dsp_loader_ops loader_ops;

	memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops));

	loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
	loader_ops.free_dma_buf = skl_free_dma_buf;

	return loader_ops;
};

static struct skl_dsp_loader_ops bxt_get_loader_ops(void)
{
	struct skl_dsp_loader_ops loader_ops;

	memset(&loader_ops, 0, sizeof(loader_ops));

	loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
	loader_ops.free_dma_buf = skl_free_dma_buf;
	loader_ops.prepare = skl_dsp_prepare;
	loader_ops.trigger = skl_dsp_trigger;
	loader_ops.cleanup = skl_dsp_cleanup;

	return loader_ops;
};

static const struct skl_dsp_ops dsp_ops[] =;

const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
{}

int skl_init_dsp(struct skl_dev *skl)
{}

int skl_free_dsp(struct skl_dev *skl)
{}

/*
 * In the case of "suspend_active" i.e, the Audio IP being active
 * during system suspend, immediately excecute any pending D0i3 work
 * before suspending. This is needed for the IP to work in low power
 * mode during system suspend. In the case of normal suspend, cancel
 * any pending D0i3 work.
 */
int skl_suspend_late_dsp(struct skl_dev *skl)
{}

int skl_suspend_dsp(struct skl_dev *skl)
{}

int skl_resume_dsp(struct skl_dev *skl)
{}

enum skl_bitdepth skl_get_bit_depth(int params)
{}

/*
 * Each module in DSP expects a base module configuration, which consists of
 * PCM format information, which we calculate in driver and resource values
 * which are read from widget information passed through topology binary
 * This is send when we create a module with INIT_INSTANCE IPC msg
 */
static void skl_set_base_module_format(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_base_cfg *base_cfg)
{}

static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
			    struct skl_module_fmt *format)
{}

/*
 * Any module configuration begins with a base module configuration but
 * can be followed by a generic extension containing audio format for all
 * module's pins that are in use.
 */
static void skl_set_base_ext_module_format(struct skl_dev *skl,
					   struct skl_module_cfg *mconfig,
					   struct skl_base_cfg_ext *base_cfg_ext)
{}

/*
 * Copies copier capabilities into copier module and updates copier module
 * config size.
 */
static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
				struct skl_cpr_cfg *cpr_mconfig)
{}

#define SKL_NON_GATEWAY_CPR_NODE_ID
/*
 * Calculate the gatewat settings required for copier module, type of
 * gateway and index of gateway to use
 */
static u32 skl_get_node_id(struct skl_dev *skl,
			struct skl_module_cfg *mconfig)
{}

static void skl_setup_cpr_gateway_cfg(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_cpr_cfg *cpr_mconfig)
{}

#define DMA_CONTROL_ID
#define DMA_I2S_BLOB_SIZE

int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
				u32 caps_size, u32 node_id)
{}
EXPORT_SYMBOL_GPL();

static void skl_setup_out_format(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_audio_data_format *out_fmt)
{}

/*
 * DSP needs SRC module for frequency conversion, SRC takes base module
 * configuration and the target frequency as extra parameter passed as src
 * config
 */
static void skl_set_src_format(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_src_module_cfg *src_mconfig)
{}

/*
 * DSP needs updown module to do channel conversion. updown module take base
 * module configuration and channel configuration
 * It also take coefficients and now we have defaults applied here
 */
static void skl_set_updown_mixer_format(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_up_down_mixer_cfg *mixer_mconfig)
{}

/*
 * 'copier' is DSP internal module which copies data from Host DMA (HDA host
 * dma) or link (hda link, SSP, PDM)
 * Here we calculate the copier module parameters, like PCM format, output
 * format, gateway settings
 * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg
 */
static void skl_set_copier_format(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_cpr_cfg *cpr_mconfig)
{}

/*
 * Mic select module allows selecting one or many input channels, thus
 * acting as a demux.
 *
 * Mic select module take base module configuration and out-format
 * configuration
 */
static void skl_set_base_outfmt_format(struct skl_dev *skl,
			struct skl_module_cfg *mconfig,
			struct skl_base_outfmt_cfg *base_outfmt_mcfg)
{}

static u16 skl_get_module_param_size(struct skl_dev *skl,
			struct skl_module_cfg *mconfig)
{}

/*
 * DSP firmware supports various modules like copier, SRC, updown etc.
 * These modules required various parameters to be calculated and sent for
 * the module initialization to DSP. By default a generic module needs only
 * base module format configuration
 */

static int skl_set_module_format(struct skl_dev *skl,
			struct skl_module_cfg *module_config,
			u16 *module_config_size,
			void **param_data)
{}

static int skl_get_queue_index(struct skl_module_pin *mpin,
				struct skl_module_inst_id id, int max)
{}

/*
 * Allocates queue for each module.
 * if dynamic, the pin_index is allocated 0 to max_pin.
 * In static, the pin_index is fixed based on module_id and instance id
 */
static int skl_alloc_queue(struct skl_module_pin *mpin,
			struct skl_module_cfg *tgt_cfg, int max)
{}

static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
{}

/* Module state will be set to unint, if all the out pin state is UNBIND */

static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
						struct skl_module_cfg *mcfg)
{}

/*
 * A module needs to be instanataited in DSP. A mdoule is present in a
 * collection of module referred as a PIPE.
 * We first calculate the module format, based on module type and then
 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
 */
int skl_init_module(struct skl_dev *skl,
			struct skl_module_cfg *mconfig)
{}

static void skl_dump_bind_info(struct skl_dev *skl, struct skl_module_cfg
	*src_module, struct skl_module_cfg *dst_module)
{}

/*
 * On module freeup, we need to unbind the module with modules
 * it is already bind.
 * Find the pin allocated and unbind then using bind_unbind IPC
 */
int skl_unbind_modules(struct skl_dev *skl,
			struct skl_module_cfg *src_mcfg,
			struct skl_module_cfg *dst_mcfg)
{}

#define CPR_SINK_FMT_PARAM_ID

/*
 * Once a module is instantiated it need to be 'bind' with other modules in
 * the pipeline. For binding we need to find the module pins which are bind
 * together
 * This function finds the pins and then sends bund_unbind IPC message to
 * DSP using IPC helper
 */
int skl_bind_modules(struct skl_dev *skl,
			struct skl_module_cfg *src_mcfg,
			struct skl_module_cfg *dst_mcfg)
{}

static int skl_set_pipe_state(struct skl_dev *skl, struct skl_pipe *pipe,
	enum skl_ipc_pipeline_state state)
{}

/*
 * A pipeline is a collection of modules. Before a module in instantiated a
 * pipeline needs to be created for it.
 * This function creates pipeline, by sending create pipeline IPC messages
 * to FW
 */
int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe)
{}

/*
 * A pipeline needs to be deleted on cleanup. If a pipeline is running,
 * then pause it first. Before actual deletion, pipeline should enter
 * reset state. Finish the procedure by sending delete pipeline IPC.
 * DSP will stop the DMA engines and release resources
 */
int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{}

/*
 * A pipeline is also a scheduling entity in DSP which can be run, stopped
 * For processing data the pipe need to be run by sending IPC set pipe state
 * to DSP
 */
int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{}

/*
 * Stop the pipeline by sending set pipe state IPC
 * DSP doesnt implement stop so we always send pause message
 */
int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{}

/*
 * Reset the pipeline by sending set pipe state IPC this will reset the DMA
 * from the DSP side
 */
int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{}

/* Algo parameter set helper function */
int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
				u32 param_id, struct skl_module_cfg *mcfg)
{}

int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
			  u32 param_id, struct skl_module_cfg *mcfg)
{}