// 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) 2022 Intel Corporation. All rights reserved.
//

#include <sound/pcm_params.h>
#include <sound/sof/ipc4/header.h>
#include "sof-audio.h"
#include "sof-priv.h"
#include "ops.h"
#include "ipc4-priv.h"
#include "ipc4-topology.h"
#include "ipc4-fw-reg.h"

static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state,
					     struct ipc4_pipeline_set_state_data *trigger_list)
{
	struct sof_ipc4_msg msg = {{ 0 }};
	u32 primary, ipc_size;

	/* trigger a single pipeline */
	if (trigger_list->count == 1)
		return sof_ipc4_set_pipeline_state(sdev, trigger_list->pipeline_instance_ids[0],
						   state);

	primary = state;
	primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_SET_PIPELINE_STATE);
	primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
	msg.primary = primary;

	/* trigger multiple pipelines with a single IPC */
	msg.extension = SOF_IPC4_GLB_PIPE_STATE_EXT_MULTI;

	/* ipc_size includes the count and the pipeline IDs for the number of pipelines */
	ipc_size = sizeof(u32) * (trigger_list->count + 1);
	msg.data_size = ipc_size;
	msg.data_ptr = trigger_list;

	return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, ipc_size);
}

int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 instance_id, u32 state)
{
	struct sof_ipc4_msg msg = {{ 0 }};
	u32 primary;

	dev_dbg(sdev->dev, "ipc4 set pipeline instance %d state %d", instance_id, state);

	primary = state;
	primary |= SOF_IPC4_GLB_PIPE_STATE_ID(instance_id);
	primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_SET_PIPELINE_STATE);
	primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);

	msg.primary = primary;

	return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
}
EXPORT_SYMBOL(sof_ipc4_set_pipeline_state);

static void sof_ipc4_add_pipeline_by_priority(struct ipc4_pipeline_set_state_data *trigger_list,
					      struct snd_sof_widget *pipe_widget,
					      s8 *pipe_priority, bool ascend)
{
	struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
	int i, j;

	for (i = 0; i < trigger_list->count; i++) {
		/* add pipeline from low priority to high */
		if (ascend && pipeline->priority < pipe_priority[i])
			break;
		/* add pipeline from high priority to low */
		else if (!ascend && pipeline->priority > pipe_priority[i])
			break;
	}

	for (j = trigger_list->count - 1; j >= i; j--) {
		trigger_list->pipeline_instance_ids[j + 1] = trigger_list->pipeline_instance_ids[j];
		pipe_priority[j + 1] = pipe_priority[j];
	}

	trigger_list->pipeline_instance_ids[i] = pipe_widget->instance_id;
	trigger_list->count++;
	pipe_priority[i] = pipeline->priority;
}

static void
sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state,
				      struct snd_sof_pipeline *spipe,
				      struct ipc4_pipeline_set_state_data *trigger_list,
				      s8 *pipe_priority)
{
	struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
	struct sof_ipc4_pipeline *pipeline = pipe_widget->private;

	if (pipeline->skip_during_fe_trigger && state != SOF_IPC4_PIPE_RESET)
		return;

	switch (state) {
	case SOF_IPC4_PIPE_RUNNING:
		/*
		 * Trigger pipeline if all PCMs containing it are paused or if it is RUNNING
		 * for the first time
		 */
		if (spipe->started_count == spipe->paused_count)
			sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority,
							  false);
		break;
	case SOF_IPC4_PIPE_RESET:
		/* RESET if the pipeline is neither running nor paused */
		if (!spipe->started_count && !spipe->paused_count)
			sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority,
							  true);
		break;
	case SOF_IPC4_PIPE_PAUSED:
		/* Pause the pipeline only when its started_count is 1 more than paused_count */
		if (spipe->paused_count == (spipe->started_count - 1))
			sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority,
							  true);
		break;
	default:
		break;
	}
}

static void
sof_ipc4_update_pipeline_state(struct snd_sof_dev *sdev, int state, int cmd,
			       struct snd_sof_pipeline *spipe,
			       struct ipc4_pipeline_set_state_data *trigger_list)
{
	struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
	struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
	int i;

	if (pipeline->skip_during_fe_trigger && state != SOF_IPC4_PIPE_RESET)
		return;

	/* set state for pipeline if it was just triggered */
	for (i = 0; i < trigger_list->count; i++) {
		if (trigger_list->pipeline_instance_ids[i] == pipe_widget->instance_id) {
			pipeline->state = state;
			break;
		}
	}

	switch (state) {
	case SOF_IPC4_PIPE_PAUSED:
		switch (cmd) {
		case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
			/*
			 * increment paused_count if the PAUSED is the final state during
			 * the PAUSE trigger
			 */
			spipe->paused_count++;
			break;
		case SNDRV_PCM_TRIGGER_STOP:
		case SNDRV_PCM_TRIGGER_SUSPEND:
			/*
			 * decrement started_count if PAUSED is the final state during the
			 * STOP trigger
			 */
			spipe->started_count--;
			break;
		default:
			break;
		}
		break;
	case SOF_IPC4_PIPE_RUNNING:
		switch (cmd) {
		case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
			/* decrement paused_count for RELEASE */
			spipe->paused_count--;
			break;
		case SNDRV_PCM_TRIGGER_START:
		case SNDRV_PCM_TRIGGER_RESUME:
			/* increment started_count for START/RESUME */
			spipe->started_count++;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
}

/*
 * The picture below represents the pipeline state machine wrt PCM actions corresponding to the
 * triggers and ioctls
 *				+---------------+
 *				|               |
 *				|    INIT       |
 *				|               |
 *				+-------+-------+
 *					|
 *					|
 *					| START
 *					|
 *					|
 * +----------------+		   +------v-------+		  +-------------+
 * |                |   START     |              |   HW_FREE	  |             |
 * |   RUNNING      <-------------+  PAUSED      +--------------> +   RESET     |
 * |                |   PAUSE     |              |		  |             |
 * +------+---------+   RELEASE   +---------+----+		  +-------------+
 *	  |				     ^
 *	  |				     |
 *	  |				     |
 *	  |				     |
 *	  |		PAUSE		     |
 *	  +---------------------------------+
 *			STOP/SUSPEND
 *
 * Note that during system suspend, the suspend trigger is followed by a hw_free in
 * sof_pcm_trigger(). So, the final state during suspend would be RESET.
 * Also, since the SOF driver doesn't support full resume, streams would be restarted with the
 * prepare ioctl before the START trigger.
 */

/*
 * Chained DMA is a special case where there is no processing on
 * DSP. The samples are just moved over by host side DMA to a single
 * buffer on DSP and directly from there to link DMA. However, the
 * model on SOF driver has two notional pipelines, one at host DAI,
 * and another at link DAI. They both shall have the use_chain_dma
 * attribute.
 */

static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev,
				      struct snd_sof_pcm_stream_pipeline_list *pipeline_list,
				      int state, int cmd)
{
	bool allocate, enable, set_fifo_size;
	struct sof_ipc4_msg msg = {{ 0 }};
	int i;

	switch (state) {
	case SOF_IPC4_PIPE_RUNNING: /* Allocate and start chained dma */
		allocate = true;
		enable = true;
		/*
		 * SOF assumes creation of a new stream from the presence of fifo_size
		 * in the message, so we must leave it out in pause release case.
		 */
		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
			set_fifo_size = false;
		else
			set_fifo_size = true;
		break;
	case SOF_IPC4_PIPE_PAUSED: /* Disable chained DMA. */
		allocate = true;
		enable = false;
		set_fifo_size = false;
		break;
	case SOF_IPC4_PIPE_RESET: /* Disable and free chained DMA. */
		allocate = false;
		enable = false;
		set_fifo_size = false;
		break;
	default:
		dev_err(sdev->dev, "Unexpected state %d", state);
		return -EINVAL;
	}

	msg.primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CHAIN_DMA);
	msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
	msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);

	/*
	 * To set-up the DMA chain, the host DMA ID and SCS setting
	 * are retrieved from the host pipeline configuration. Likewise
	 * the link DMA ID and fifo_size are retrieved from the link
	 * pipeline configuration.
	 */
	for (i = 0; i < pipeline_list->count; i++) {
		struct snd_sof_pipeline *spipe = pipeline_list->pipelines[i];
		struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
		struct sof_ipc4_pipeline *pipeline = pipe_widget->private;

		if (!pipeline->use_chain_dma) {
			dev_err(sdev->dev,
				"All pipelines in chained DMA stream should have use_chain_dma attribute set.");
			return -EINVAL;
		}

		msg.primary |= pipeline->msg.primary;

		/* Add fifo_size (actually DMA buffer size) field to the message */
		if (set_fifo_size)
			msg.extension |= pipeline->msg.extension;
	}

	if (allocate)
		msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_ALLOCATE_MASK;

	if (enable)
		msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_ENABLE_MASK;

	return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
}

static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
				      struct snd_pcm_substream *substream, int state, int cmd)
{
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
	struct ipc4_pipeline_set_state_data *trigger_list;
	struct snd_sof_widget *pipe_widget;
	struct sof_ipc4_pipeline *pipeline;
	struct snd_sof_pipeline *spipe;
	struct snd_sof_pcm *spcm;
	u8 *pipe_priority;
	int ret;
	int i;

	dev_dbg(sdev->dev, "trigger cmd: %d state: %d\n", cmd, state);

	spcm = snd_sof_find_spcm_dai(component, rtd);
	if (!spcm)
		return -EINVAL;

	pipeline_list = &spcm->stream[substream->stream].pipeline_list;

	/* nothing to trigger if the list is empty */
	if (!pipeline_list->pipelines || !pipeline_list->count)
		return 0;

	spipe = pipeline_list->pipelines[0];
	pipe_widget = spipe->pipe_widget;
	pipeline = pipe_widget->private;

	/*
	 * If use_chain_dma attribute is set we proceed to chained DMA
	 * trigger function that handles the rest for the substream.
	 */
	if (pipeline->use_chain_dma)
		return sof_ipc4_chain_dma_trigger(sdev, pipeline_list, state, cmd);

	/* allocate memory for the pipeline data */
	trigger_list = kzalloc(struct_size(trigger_list, pipeline_instance_ids,
					   pipeline_list->count), GFP_KERNEL);
	if (!trigger_list)
		return -ENOMEM;

	pipe_priority = kzalloc(pipeline_list->count, GFP_KERNEL);
	if (!pipe_priority) {
		kfree(trigger_list);
		return -ENOMEM;
	}

	mutex_lock(&ipc4_data->pipeline_state_mutex);

	/*
	 * IPC4 requires pipelines to be triggered in order starting at the sink and
	 * walking all the way to the source. So traverse the pipeline_list in the order
	 * sink->source when starting PCM's and in the reverse order to pause/stop PCM's.
	 * Skip the pipelines that have their skip_during_fe_trigger flag set. If there is a fork
	 * in the pipeline, the order of triggering between the left/right paths will be
	 * indeterministic. But the sink->source trigger order sink->source would still be
	 * guaranteed for each fork independently.
	 */
	if (state == SOF_IPC4_PIPE_RUNNING || state == SOF_IPC4_PIPE_RESET)
		for (i = pipeline_list->count - 1; i >= 0; i--) {
			spipe = pipeline_list->pipelines[i];
			sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list,
							      pipe_priority);
		}
	else
		for (i = 0; i < pipeline_list->count; i++) {
			spipe = pipeline_list->pipelines[i];
			sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list,
							      pipe_priority);
		}

	/* return if all pipelines are in the requested state already */
	if (!trigger_list->count) {
		ret = 0;
		goto free;
	}

	/* no need to pause before reset or before pause release */
	if (state == SOF_IPC4_PIPE_RESET || cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
		goto skip_pause_transition;

	/*
	 * set paused state for pipelines if the final state is PAUSED or when the pipeline
	 * is set to RUNNING for the first time after the PCM is started.
	 */
	ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, trigger_list);
	if (ret < 0) {
		dev_err(sdev->dev, "failed to pause all pipelines\n");
		goto free;
	}

	/* update PAUSED state for all pipelines just triggered */
	for (i = 0; i < pipeline_list->count ; i++) {
		spipe = pipeline_list->pipelines[i];
		sof_ipc4_update_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, cmd, spipe,
					       trigger_list);
	}

	/* return if this is the final state */
	if (state == SOF_IPC4_PIPE_PAUSED)
		goto free;
skip_pause_transition:
	/* else set the RUNNING/RESET state in the DSP */
	ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list);
	if (ret < 0) {
		dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state);
		goto free;
	}

	/* update RUNNING/RESET state for all pipelines that were just triggered */
	for (i = 0; i < pipeline_list->count; i++) {
		spipe = pipeline_list->pipelines[i];
		sof_ipc4_update_pipeline_state(sdev, state, cmd, spipe, trigger_list);
	}

free:
	mutex_unlock(&ipc4_data->pipeline_state_mutex);
	kfree(trigger_list);
	kfree(pipe_priority);
	return ret;
}

static int sof_ipc4_pcm_trigger(struct snd_soc_component *component,
				struct snd_pcm_substream *substream, int cmd)
{
	int state;

	/* determine the pipeline state */
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		state = SOF_IPC4_PIPE_PAUSED;
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_START:
		state = SOF_IPC4_PIPE_RUNNING;
		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_STOP:
		state = SOF_IPC4_PIPE_PAUSED;
		break;
	default:
		dev_err(component->dev, "%s: unhandled trigger cmd %d\n", __func__, cmd);
		return -EINVAL;
	}

	/* set the pipeline state */
	return sof_ipc4_trigger_pipelines(component, substream, state, cmd);
}

static int sof_ipc4_pcm_hw_free(struct snd_soc_component *component,
				struct snd_pcm_substream *substream)
{
	/* command is not relevant with RESET, so just pass 0 */
	return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET, 0);
}

static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name,
						 struct snd_pcm_hw_params *params)
{
	struct snd_sof_dai_link *slink;
	struct snd_sof_dai *dai;
	bool dai_link_found = false;
	int i;

	list_for_each_entry(slink, &sdev->dai_link_list, list) {
		if (!strcmp(slink->link->name, link_name)) {
			dai_link_found = true;
			break;
		}
	}

	if (!dai_link_found)
		return;

	for (i = 0; i < slink->num_hw_configs; i++) {
		struct snd_soc_tplg_hw_config *hw_config = &slink->hw_configs[i];

		if (params_rate(params) == le32_to_cpu(hw_config->fsync_rate)) {
			/* set current config for all DAI's with matching name */
			list_for_each_entry(dai, &sdev->dai_list, list)
				if (!strcmp(slink->link->name, dai->name))
					dai->current_config = le32_to_cpu(hw_config->id);
			break;
		}
	}
}

/*
 * Fixup DAI link parameters for sampling rate based on
 * DAI copier configuration.
 */
static int sof_ipc4_pcm_dai_link_fixup_rate(struct snd_sof_dev *sdev,
					    struct snd_pcm_hw_params *params,
					    struct sof_ipc4_copier *ipc4_copier)
{
	struct sof_ipc4_pin_format *pin_fmts = ipc4_copier->available_fmt.input_pin_fmts;
	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int num_input_formats = ipc4_copier->available_fmt.num_input_formats;
	unsigned int fe_rate = params_rate(params);
	bool fe_be_rate_match = false;
	bool single_be_rate = true;
	unsigned int be_rate;
	int i;

	/*
	 * Copier does not change sampling rate, so we
	 * need to only consider the input pin information.
	 */
	for (i = 0; i < num_input_formats; i++) {
		unsigned int val = pin_fmts[i].audio_fmt.sampling_frequency;

		if (i == 0)
			be_rate = val;
		else if (val != be_rate)
			single_be_rate = false;

		if (val == fe_rate) {
			fe_be_rate_match = true;
			break;
		}
	}

	/*
	 * If rate is different than FE rate, topology must
	 * contain an SRC. But we do require topology to
	 * define a single rate in the DAI copier config in
	 * this case (FE rate may be variable).
	 */
	if (!fe_be_rate_match) {
		if (!single_be_rate) {
			dev_err(sdev->dev, "Unable to select sampling rate for DAI link\n");
			return -EINVAL;
		}

		rate->min = be_rate;
		rate->max = rate->min;
	}

	return 0;
}

static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
				       struct snd_pcm_hw_params *params)
{
	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
	struct snd_sof_dai *dai = snd_sof_find_dai(component, rtd->dai_link->name);
	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
	struct sof_ipc4_audio_format *ipc4_fmt;
	struct sof_ipc4_copier *ipc4_copier;
	bool single_fmt = false;
	u32 valid_bits = 0;
	int dir, ret;

	if (!dai) {
		dev_err(component->dev, "%s: No DAI found with name %s\n", __func__,
			rtd->dai_link->name);
		return -EINVAL;
	}

	ipc4_copier = dai->private;
	if (!ipc4_copier) {
		dev_err(component->dev, "%s: No private data found for DAI %s\n",
			__func__, rtd->dai_link->name);
		return -EINVAL;
	}

	for_each_pcm_streams(dir) {
		struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, dir);

		if (w) {
			struct sof_ipc4_available_audio_format *available_fmt =
				&ipc4_copier->available_fmt;
			struct snd_sof_widget *swidget = w->dobj.private;
			struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
			struct sof_ipc4_pipeline *pipeline = pipe_widget->private;

			/* Chain DMA does not use copiers, so no fixup needed */
			if (pipeline->use_chain_dma)
				return 0;

			if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
				if (sof_ipc4_copier_is_single_format(sdev,
					available_fmt->output_pin_fmts,
					available_fmt->num_output_formats)) {
					ipc4_fmt = &available_fmt->output_pin_fmts->audio_fmt;
					single_fmt = true;
				}
			} else {
				if (sof_ipc4_copier_is_single_format(sdev,
					available_fmt->input_pin_fmts,
					available_fmt->num_input_formats)) {
					ipc4_fmt = &available_fmt->input_pin_fmts->audio_fmt;
					single_fmt = true;
				}
			}
		}
	}

	ret = sof_ipc4_pcm_dai_link_fixup_rate(sdev, params, ipc4_copier);
	if (ret)
		return ret;

	if (single_fmt) {
		snd_mask_none(fmt);
		valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(ipc4_fmt->fmt_cfg);
		dev_dbg(component->dev, "Set %s to %d bit format\n", dai->name, valid_bits);
	}

	/* Set format if it is specified */
	switch (valid_bits) {
	case 16:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
		break;
	case 24:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
		break;
	case 32:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
		break;
	default:
		break;
	}

	switch (ipc4_copier->dai_type) {
	case SOF_DAI_INTEL_SSP:
		ipc4_ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);
		break;
	default:
		break;
	}

	return 0;
}

static void sof_ipc4_pcm_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm)
{
	struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
	int stream;

	for_each_pcm_streams(stream) {
		pipeline_list = &spcm->stream[stream].pipeline_list;
		kfree(pipeline_list->pipelines);
		pipeline_list->pipelines = NULL;
		kfree(spcm->stream[stream].private);
		spcm->stream[stream].private = NULL;
	}
}

static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm)
{
	struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
	struct sof_ipc4_timestamp_info *stream_info;
	bool support_info = true;
	u32 abi_version;
	u32 abi_offset;
	int stream;

	abi_offset = offsetof(struct sof_ipc4_fw_registers, abi_ver);
	sof_mailbox_read(sdev, sdev->fw_info_box.offset + abi_offset, &abi_version,
			 sizeof(abi_version));

	if (abi_version < SOF_IPC4_FW_REGS_ABI_VER)
		support_info = false;

	for_each_pcm_streams(stream) {
		pipeline_list = &spcm->stream[stream].pipeline_list;

		/* allocate memory for max number of pipeline IDs */
		pipeline_list->pipelines = kcalloc(ipc4_data->max_num_pipelines,
						   sizeof(struct snd_sof_widget *), GFP_KERNEL);
		if (!pipeline_list->pipelines) {
			sof_ipc4_pcm_free(sdev, spcm);
			return -ENOMEM;
		}

		if (!support_info)
			continue;

		stream_info = kzalloc(sizeof(*stream_info), GFP_KERNEL);
		if (!stream_info) {
			sof_ipc4_pcm_free(sdev, spcm);
			return -ENOMEM;
		}

		spcm->stream[stream].private = stream_info;
	}

	return 0;
}

static void sof_ipc4_build_time_info(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *spcm)
{
	struct sof_ipc4_copier *host_copier = NULL;
	struct sof_ipc4_copier *dai_copier = NULL;
	struct sof_ipc4_llp_reading_slot llp_slot;
	struct sof_ipc4_timestamp_info *info;
	struct snd_soc_dapm_widget *widget;
	struct snd_sof_dai *dai;
	int i;

	/* find host & dai to locate info in memory window */
	for_each_dapm_widgets(spcm->list, i, widget) {
		struct snd_sof_widget *swidget = widget->dobj.private;

		if (!swidget)
			continue;

		if (WIDGET_IS_AIF(swidget->widget->id)) {
			host_copier = swidget->private;
		} else if (WIDGET_IS_DAI(swidget->widget->id)) {
			dai = swidget->private;
			dai_copier = dai->private;
		}
	}

	/* both host and dai copier must be valid for time_info */
	if (!host_copier || !dai_copier) {
		dev_err(sdev->dev, "host or dai copier are not found\n");
		return;
	}

	info = spcm->private;
	info->host_copier = host_copier;
	info->dai_copier = dai_copier;
	info->llp_offset = offsetof(struct sof_ipc4_fw_registers, llp_gpdma_reading_slots) +
				    sdev->fw_info_box.offset;

	/* find llp slot used by current dai */
	for (i = 0; i < SOF_IPC4_MAX_LLP_GPDMA_READING_SLOTS; i++) {
		sof_mailbox_read(sdev, info->llp_offset, &llp_slot, sizeof(llp_slot));
		if (llp_slot.node_id == dai_copier->data.gtw_cfg.node_id)
			break;

		info->llp_offset += sizeof(llp_slot);
	}

	if (i < SOF_IPC4_MAX_LLP_GPDMA_READING_SLOTS)
		return;

	/* if no llp gpdma slot is used, check aggregated sdw slot */
	info->llp_offset = offsetof(struct sof_ipc4_fw_registers, llp_sndw_reading_slots) +
					sdev->fw_info_box.offset;
	for (i = 0; i < SOF_IPC4_MAX_LLP_SNDW_READING_SLOTS; i++) {
		sof_mailbox_read(sdev, info->llp_offset, &llp_slot, sizeof(llp_slot));
		if (llp_slot.node_id == dai_copier->data.gtw_cfg.node_id)
			break;

		info->llp_offset += sizeof(llp_slot);
	}

	if (i < SOF_IPC4_MAX_LLP_SNDW_READING_SLOTS)
		return;

	/* check EVAD slot */
	info->llp_offset = offsetof(struct sof_ipc4_fw_registers, llp_evad_reading_slot) +
					sdev->fw_info_box.offset;
	sof_mailbox_read(sdev, info->llp_offset, &llp_slot, sizeof(llp_slot));
	if (llp_slot.node_id != dai_copier->data.gtw_cfg.node_id)
		info->llp_offset = 0;
}

static int sof_ipc4_pcm_hw_params(struct snd_soc_component *component,
				  struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *params,
				  struct snd_sof_platform_stream_params *platform_params)
{
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct sof_ipc4_timestamp_info *time_info;
	struct snd_sof_pcm *spcm;

	spcm = snd_sof_find_spcm_dai(component, rtd);
	if (!spcm)
		return -EINVAL;

	time_info = spcm->stream[substream->stream].private;
	/* delay calculation is not supported by current fw_reg ABI */
	if (!time_info)
		return 0;

	time_info->stream_start_offset = SOF_IPC4_INVALID_STREAM_POSITION;
	time_info->llp_offset = 0;

	sof_ipc4_build_time_info(sdev, &spcm->stream[substream->stream]);

	return 0;
}

static int sof_ipc4_get_stream_start_offset(struct snd_sof_dev *sdev,
					    struct snd_pcm_substream *substream,
					    struct snd_sof_pcm_stream *stream,
					    struct sof_ipc4_timestamp_info *time_info)
{
	struct sof_ipc4_copier *host_copier = time_info->host_copier;
	struct sof_ipc4_copier *dai_copier = time_info->dai_copier;
	struct sof_ipc4_pipeline_registers ppl_reg;
	u64 stream_start_position;
	u32 dai_sample_size;
	u32 ch, node_index;
	u32 offset;

	if (!host_copier || !dai_copier)
		return -EINVAL;

	if (host_copier->data.gtw_cfg.node_id == SOF_IPC4_INVALID_NODE_ID)
		return -EINVAL;

	node_index = SOF_IPC4_NODE_INDEX(host_copier->data.gtw_cfg.node_id);
	offset = offsetof(struct sof_ipc4_fw_registers, pipeline_regs) + node_index * sizeof(ppl_reg);
	sof_mailbox_read(sdev, sdev->fw_info_box.offset + offset, &ppl_reg, sizeof(ppl_reg));
	if (ppl_reg.stream_start_offset == SOF_IPC4_INVALID_STREAM_POSITION)
		return -EINVAL;

	stream_start_position = ppl_reg.stream_start_offset;
	ch = dai_copier->data.out_format.fmt_cfg;
	ch = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(ch);
	dai_sample_size = (dai_copier->data.out_format.bit_depth >> 3) * ch;
	/* convert offset to sample count */
	do_div(stream_start_position, dai_sample_size);
	time_info->stream_start_offset = stream_start_position;

	return 0;
}

static snd_pcm_sframes_t sof_ipc4_pcm_delay(struct snd_soc_component *component,
					    struct snd_pcm_substream *substream)
{
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct sof_ipc4_timestamp_info *time_info;
	struct sof_ipc4_llp_reading_slot llp;
	snd_pcm_uframes_t head_ptr, tail_ptr;
	struct snd_sof_pcm_stream *stream;
	struct snd_sof_pcm *spcm;
	u64 tmp_ptr;
	int ret;

	spcm = snd_sof_find_spcm_dai(component, rtd);
	if (!spcm)
		return 0;

	stream = &spcm->stream[substream->stream];
	time_info = stream->private;
	if (!time_info)
		return 0;

	/*
	 * stream_start_offset is updated to memory window by FW based on
	 * pipeline statistics and it may be invalid if host query happens before
	 * the statistics is complete. And it will not change after the first initiailization.
	 */
	if (time_info->stream_start_offset == SOF_IPC4_INVALID_STREAM_POSITION) {
		ret = sof_ipc4_get_stream_start_offset(sdev, substream, stream, time_info);
		if (ret < 0)
			return 0;
	}

	/*
	 * HDaudio links don't support the LLP counter reported by firmware
	 * the link position is read directly from hardware registers.
	 */
	if (!time_info->llp_offset) {
		tmp_ptr = snd_sof_pcm_get_stream_position(sdev, component, substream);
		if (!tmp_ptr)
			return 0;
	} else {
		sof_mailbox_read(sdev, time_info->llp_offset, &llp, sizeof(llp));
		tmp_ptr = ((u64)llp.reading.llp_u << 32) | llp.reading.llp_l;
	}

	/* In two cases dai dma position is not accurate
	 * (1) dai pipeline is started before host pipeline
	 * (2) multiple streams mixed into one. Each stream has the same dai dma position
	 *
	 * Firmware calculates correct stream_start_offset for all cases including above two.
	 * Driver subtracts stream_start_offset from dai dma position to get accurate one
	 */
	tmp_ptr -= time_info->stream_start_offset;

	/* Calculate the delay taking into account that both pointer can wrap */
	div64_u64_rem(tmp_ptr, substream->runtime->boundary, &tmp_ptr);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		head_ptr = substream->runtime->status->hw_ptr;
		tail_ptr = tmp_ptr;
	} else {
		head_ptr = tmp_ptr;
		tail_ptr = substream->runtime->status->hw_ptr;
	}

	if (head_ptr < tail_ptr)
		return substream->runtime->boundary - tail_ptr + head_ptr;

	return head_ptr - tail_ptr;
}

const struct sof_ipc_pcm_ops ipc4_pcm_ops = {
	.hw_params = sof_ipc4_pcm_hw_params,
	.trigger = sof_ipc4_pcm_trigger,
	.hw_free = sof_ipc4_pcm_hw_free,
	.dai_link_fixup = sof_ipc4_pcm_dai_link_fixup,
	.pcm_setup = sof_ipc4_pcm_setup,
	.pcm_free = sof_ipc4_pcm_free,
	.delay = sof_ipc4_pcm_delay,
	.ipc_first_on_start = true,
	.platform_stop_during_hw_free = true,
};
