// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
// Copyright(c) 2023 Intel Corporation

/*
 * Soundwire Intel ops for LunarLake
 */

#include <linux/acpi.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_intel.h>
#include <linux/string_choices.h>
#include <sound/hdaudio.h>
#include <sound/hda-mlink.h>
#include <sound/hda-sdw-bpt.h>
#include <sound/hda_register.h>
#include <sound/pcm_params.h>
#include "cadence_master.h"
#include "bus.h"
#include "intel.h"

static int sdw_slave_bpt_stream_add(struct sdw_slave *slave, struct sdw_stream_runtime *stream)
{
	struct sdw_stream_config sconfig = {0};
	struct sdw_port_config pconfig = {0};
	int ret;

	/* arbitrary configuration */
	sconfig.frame_rate = 16000;
	sconfig.ch_count = 1;
	sconfig.bps = 32; /* this is required for BPT/BRA */
	sconfig.direction = SDW_DATA_DIR_RX;
	sconfig.type = SDW_STREAM_BPT;

	pconfig.num = 0;
	pconfig.ch_mask = BIT(0);

	ret = sdw_stream_add_slave(slave, &sconfig, &pconfig, 1, stream);
	if (ret)
		dev_err(&slave->dev, "%s: failed: %d\n", __func__, ret);

	return ret;
}

#define READ_PDI1_MIN_SIZE	12

static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *slave,
				       struct sdw_bpt_msg *msg)
{
	struct sdw_cdns *cdns = &sdw->cdns;
	struct sdw_bus *bus = &cdns->bus;
	struct sdw_master_prop *prop = &bus->prop;
	struct sdw_stream_runtime *stream;
	struct sdw_stream_config sconfig;
	struct sdw_port_config *pconfig;
	unsigned int pdi0_buf_size_pre_frame;
	unsigned int pdi1_buf_size_pre_frame;
	unsigned int pdi0_buffer_size_;
	unsigned int pdi1_buffer_size_;
	unsigned int pdi0_buffer_size;
	unsigned int tx_dma_bandwidth;
	unsigned int pdi1_buffer_size;
	unsigned int rx_dma_bandwidth;
	unsigned int fake_num_frames;
	unsigned int data_per_frame;
	unsigned int tx_total_bytes;
	struct sdw_cdns_pdi *pdi0;
	struct sdw_cdns_pdi *pdi1;
	unsigned int rx_alignment;
	unsigned int tx_alignment;
	unsigned int num_frames_;
	unsigned int num_frames;
	unsigned int fake_size;
	unsigned int tx_pad;
	unsigned int rx_pad;
	int command;
	int ret1;
	int ret;
	int dir;
	int len;
	int i;

	if (cdns->bus.bpt_stream) {
		dev_err(cdns->dev, "%s: BPT stream already exists\n", __func__);
		return -EAGAIN;
	}

	stream = sdw_alloc_stream("BPT", SDW_STREAM_BPT);
	if (!stream)
		return -ENOMEM;

	cdns->bus.bpt_stream = stream;

	ret = sdw_slave_bpt_stream_add(slave, stream);
	if (ret < 0)
		goto release_stream;

	/* handle PDI0 first */
	dir = SDW_DATA_DIR_TX;

	pdi0 = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, 1,  dir, 0);
	if (!pdi0) {
		dev_err(cdns->dev, "%s: sdw_cdns_alloc_pdi0 failed\n", __func__);
		ret = -EINVAL;
		goto remove_slave;
	}

	sdw_cdns_config_stream(cdns, 1, dir, pdi0);

	/* handle PDI1  */
	dir = SDW_DATA_DIR_RX;

	pdi1 = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, 1,  dir, 1);
	if (!pdi1) {
		dev_err(cdns->dev, "%s: sdw_cdns_alloc_pdi1 failed\n", __func__);
		ret = -EINVAL;
		goto remove_slave;
	}

	sdw_cdns_config_stream(cdns, 1, dir, pdi1);

	/*
	 * the port config direction, number of channels and frame
	 * rate is totally arbitrary
	 */
	sconfig.direction = dir;
	sconfig.ch_count = 1;
	sconfig.frame_rate = 16000;
	sconfig.type = SDW_STREAM_BPT;
	sconfig.bps = 32; /* this is required for BPT/BRA */

	/* Port configuration */
	pconfig = kzalloc_objs(*pconfig, 2);
	if (!pconfig) {
		ret =  -ENOMEM;
		goto remove_slave;
	}

	for (i = 0; i < 2 /* num_pdi */; i++) {
		pconfig[i].num = i;
		pconfig[i].ch_mask = 1;
	}

	ret = sdw_stream_add_master(&cdns->bus, &sconfig, pconfig, 2, stream);
	kfree(pconfig);

	if (ret < 0) {
		dev_err(cdns->dev, "add master to stream failed:%d\n", ret);
		goto remove_slave;
	}

	ret = sdw_prepare_stream(cdns->bus.bpt_stream);
	if (ret < 0)
		goto remove_master;

	command = (msg->flags & SDW_MSG_FLAG_WRITE) ? 0 : 1;

	ret = sdw_cdns_bpt_find_bandwidth(command, cdns->bus.params.row,
					  cdns->bus.params.col,
					  prop->default_frame_rate,
					  &tx_dma_bandwidth, &rx_dma_bandwidth);
	if (ret < 0)
		goto deprepare_stream;

	len = 0;
	pdi0_buffer_size = 0;
	pdi1_buffer_size = 0;
	num_frames = 0;
	/* Add up pdi buffer size and frame numbers of each BPT sections */
	for (i = 0; i < msg->sections; i++) {
		ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row,
						     cdns->bus.params.col,
						     msg->sec[i].len, SDW_BPT_MSG_MAX_BYTES,
						     &data_per_frame, &pdi0_buffer_size_,
						     &pdi1_buffer_size_, &num_frames_);
		if (ret < 0)
			goto deprepare_stream;

		len += msg->sec[i].len;
		pdi0_buffer_size += pdi0_buffer_size_;
		pdi1_buffer_size += pdi1_buffer_size_;
		num_frames += num_frames_;
	}

	sdw->bpt_ctx.pdi0_buffer_size = pdi0_buffer_size;
	sdw->bpt_ctx.pdi1_buffer_size = pdi1_buffer_size;
	sdw->bpt_ctx.num_frames = num_frames;
	sdw->bpt_ctx.data_per_frame = data_per_frame;

	rx_alignment = hda_sdw_bpt_get_buf_size_alignment(rx_dma_bandwidth);
	tx_alignment = hda_sdw_bpt_get_buf_size_alignment(tx_dma_bandwidth);

	if (command) { /* read */
		/* Get buffer size of a full frame */
		ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row,
						     cdns->bus.params.col,
						     data_per_frame, SDW_BPT_MSG_MAX_BYTES,
						     &data_per_frame, &pdi0_buf_size_pre_frame,
						     &pdi1_buf_size_pre_frame, &fake_num_frames);
		if (ret < 0)
			goto deprepare_stream;

		/* find fake pdi1 buffer size */
		rx_pad = rx_alignment - (pdi1_buffer_size % rx_alignment);
		while (rx_pad <= READ_PDI1_MIN_SIZE)
			rx_pad += rx_alignment;

		pdi1_buffer_size += rx_pad;
		/* It is fine if we request more than enough byte to read */
		fake_num_frames = DIV_ROUND_UP(rx_pad, pdi1_buf_size_pre_frame);
		fake_size = fake_num_frames * data_per_frame;

		/* find fake pdi0 buffer size */
		pdi0_buffer_size += (fake_num_frames * pdi0_buf_size_pre_frame);
		tx_pad = tx_alignment - (pdi0_buffer_size % tx_alignment);
		pdi0_buffer_size += tx_pad;
	} else { /* write */
		/*
		 * For the write command, the rx data block is 4, and the rx buffer size of a frame
		 * is 8. So the rx buffer size (pdi0_buffer_size) is always a multiple of rx
		 * alignment.
		 */
		tx_pad = tx_alignment - (pdi0_buffer_size % tx_alignment);
		pdi0_buffer_size += tx_pad;
	}

	dev_dbg(cdns->dev, "Message len %d transferred in %d frames (%d per frame)\n",
		len, num_frames, data_per_frame);
	dev_dbg(cdns->dev, "sizes pdi0 %d pdi1 %d tx_bandwidth %d rx_bandwidth %d\n",
		pdi0_buffer_size, pdi1_buffer_size, tx_dma_bandwidth, rx_dma_bandwidth);

	ret = hda_sdw_bpt_open(cdns->dev->parent, /* PCI device */
			       sdw->instance, &sdw->bpt_ctx.bpt_tx_stream,
			       &sdw->bpt_ctx.dmab_tx_bdl, pdi0_buffer_size, tx_dma_bandwidth,
			       &sdw->bpt_ctx.bpt_rx_stream, &sdw->bpt_ctx.dmab_rx_bdl,
			       pdi1_buffer_size, rx_dma_bandwidth);
	if (ret < 0) {
		dev_err(cdns->dev, "%s: hda_sdw_bpt_open failed %d\n", __func__, ret);
		goto deprepare_stream;
	}

	if (!command) {
		ret = sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec, msg->sections,
							data_per_frame,
							sdw->bpt_ctx.dmab_tx_bdl.area,
							pdi0_buffer_size, &tx_total_bytes);
	} else {
		ret = sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec, msg->sections,
						       data_per_frame,
						       sdw->bpt_ctx.dmab_tx_bdl.area,
						       pdi0_buffer_size, &tx_total_bytes,
						       fake_size);
	}

	if (!ret)
		return 0;

	dev_err(cdns->dev, "%s: sdw_prepare_%s_dma_buffer failed %d\n",
		__func__, str_read_write(command), ret);

	ret1 = hda_sdw_bpt_close(cdns->dev->parent, /* PCI device */
				 sdw->bpt_ctx.bpt_tx_stream, &sdw->bpt_ctx.dmab_tx_bdl,
				 sdw->bpt_ctx.bpt_rx_stream, &sdw->bpt_ctx.dmab_rx_bdl);
	if (ret1 < 0)
		dev_err(cdns->dev, "%s:  hda_sdw_bpt_close failed: ret %d\n",
			__func__, ret1);

deprepare_stream:
	sdw_deprepare_stream(cdns->bus.bpt_stream);

remove_master:
	ret1 = sdw_stream_remove_master(&cdns->bus, cdns->bus.bpt_stream);
	if (ret1 < 0)
		dev_err(cdns->dev, "%s: remove master failed: %d\n",
			__func__, ret1);

remove_slave:
	ret1 = sdw_stream_remove_slave(slave, cdns->bus.bpt_stream);
	if (ret1 < 0)
		dev_err(cdns->dev, "%s: remove slave failed: %d\n",
			__func__, ret1);

release_stream:
	sdw_release_stream(cdns->bus.bpt_stream);
	cdns->bus.bpt_stream = NULL;

	return ret;
}

static void intel_ace2x_bpt_close_stream(struct sdw_intel *sdw, struct sdw_slave *slave,
					 struct sdw_bpt_msg *msg)
{
	struct sdw_cdns *cdns = &sdw->cdns;
	int ret;

	ret = hda_sdw_bpt_close(cdns->dev->parent /* PCI device */, sdw->bpt_ctx.bpt_tx_stream,
				&sdw->bpt_ctx.dmab_tx_bdl, sdw->bpt_ctx.bpt_rx_stream,
				&sdw->bpt_ctx.dmab_rx_bdl);
	if (ret < 0)
		dev_err(cdns->dev, "%s:  hda_sdw_bpt_close failed: ret %d\n",
			__func__, ret);

	ret = sdw_deprepare_stream(cdns->bus.bpt_stream);
	if (ret < 0)
		dev_err(cdns->dev, "%s: sdw_deprepare_stream failed: ret %d\n",
			__func__, ret);

	ret = sdw_stream_remove_master(&cdns->bus, cdns->bus.bpt_stream);
	if (ret < 0)
		dev_err(cdns->dev, "%s: remove master failed: %d\n",
			__func__, ret);

	ret = sdw_stream_remove_slave(slave, cdns->bus.bpt_stream);
	if (ret < 0)
		dev_err(cdns->dev, "%s: remove slave failed: %d\n",
			__func__, ret);

	cdns->bus.bpt_stream = NULL;
}

#define INTEL_BPT_MSG_BYTE_MIN 16

static int intel_ace2x_bpt_send_async(struct sdw_intel *sdw, struct sdw_slave *slave,
				      struct sdw_bpt_msg *msg)
{
	struct sdw_cdns *cdns = &sdw->cdns;
	int len = 0;
	int ret;
	int i;

	for (i = 0; i < msg->sections; i++)
		len += msg->sec[i].len;

	if (len < INTEL_BPT_MSG_BYTE_MIN) {
		dev_err(cdns->dev, "BPT message length %d is less than the minimum bytes %d\n",
			len, INTEL_BPT_MSG_BYTE_MIN);
		return -EINVAL;
	}

	dev_dbg(cdns->dev, "BPT Transfer start\n");

	ret = intel_ace2x_bpt_open_stream(sdw, slave, msg);
	if (ret < 0)
		return ret;

	ret = hda_sdw_bpt_send_async(cdns->dev->parent, /* PCI device */
				     sdw->bpt_ctx.bpt_tx_stream, sdw->bpt_ctx.bpt_rx_stream);
	if (ret < 0) {
		dev_err(cdns->dev, "%s:   hda_sdw_bpt_send_async failed: %d\n",
			__func__, ret);

		intel_ace2x_bpt_close_stream(sdw, slave, msg);

		return ret;
	}

	ret = sdw_enable_stream(cdns->bus.bpt_stream);
	if (ret < 0) {
		dev_err(cdns->dev, "%s: sdw_stream_enable failed: %d\n",
			__func__, ret);
		intel_ace2x_bpt_close_stream(sdw, slave, msg);
	}

	return ret;
}

static int intel_ace2x_bpt_wait(struct sdw_intel *sdw, struct sdw_slave *slave,
				struct sdw_bpt_msg *msg)
{
	struct sdw_cdns *cdns = &sdw->cdns;
	int ret;

	dev_dbg(cdns->dev, "BPT Transfer wait\n");

	ret = hda_sdw_bpt_wait(cdns->dev->parent, /* PCI device */
			       sdw->bpt_ctx.bpt_tx_stream, sdw->bpt_ctx.bpt_rx_stream);
	if (ret < 0)
		dev_err(cdns->dev, "%s: hda_sdw_bpt_wait failed: %d\n", __func__, ret);

	ret = sdw_disable_stream(cdns->bus.bpt_stream);
	if (ret < 0) {
		dev_err(cdns->dev, "%s: sdw_stream_enable failed: %d\n",
			__func__, ret);
		goto err;
	}

	if (msg->flags & SDW_MSG_FLAG_WRITE) {
		ret = sdw_cdns_check_write_response(cdns->dev, sdw->bpt_ctx.dmab_rx_bdl.area,
						    sdw->bpt_ctx.pdi1_buffer_size,
						    sdw->bpt_ctx.num_frames);
		if (ret < 0)
			dev_err(cdns->dev, "%s: BPT Write failed %d\n", __func__, ret);
	} else {
		ret = sdw_cdns_check_read_response(cdns->dev, sdw->bpt_ctx.dmab_rx_bdl.area,
						   sdw->bpt_ctx.pdi1_buffer_size,
						   msg->sec, msg->sections, sdw->bpt_ctx.num_frames,
						   sdw->bpt_ctx.data_per_frame);
		if (ret < 0)
			dev_err(cdns->dev, "%s: BPT Read failed %d\n", __func__, ret);
	}

err:
	intel_ace2x_bpt_close_stream(sdw, slave, msg);

	return ret;
}

/*
 * shim vendor-specific (vs) ops
 */

static void intel_shim_vs_init(struct sdw_intel *sdw)
{
	void __iomem *shim_vs = sdw->link_res->shim_vs;
	struct sdw_bus *bus = &sdw->cdns.bus;
	struct sdw_intel_prop *intel_prop;
	u16 clde;
	u16 doaise2;
	u16 dodse2;
	u16 clds;
	u16 clss;
	u16 doaise;
	u16 doais;
	u16 dodse;
	u16 dods;
	u16 act;

	intel_prop = bus->vendor_specific_prop;
	clde = intel_prop->clde;
	doaise2 = intel_prop->doaise2;
	dodse2 = intel_prop->dodse2;
	clds = intel_prop->clds;
	clss = intel_prop->clss;
	doaise = intel_prop->doaise;
	doais = intel_prop->doais;
	dodse = intel_prop->dodse;
	dods = intel_prop->dods;

	act = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL);
	u16p_replace_bits(&act, clde, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE);
	u16p_replace_bits(&act, doaise2, SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2);
	u16p_replace_bits(&act, dodse2, SDW_SHIM3_INTEL_VS_ACTMCTL_DODSE2);
	u16p_replace_bits(&act, clds, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDS);
	u16p_replace_bits(&act, clss, SDW_SHIM3_INTEL_VS_ACTMCTL_CLSS);
	u16p_replace_bits(&act, doaise, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE);
	u16p_replace_bits(&act, doais, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS);
	u16p_replace_bits(&act, dodse, SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE);
	u16p_replace_bits(&act, dods, SDW_SHIM2_INTEL_VS_ACTMCTL_DODS);
	act |= SDW_SHIM2_INTEL_VS_ACTMCTL_DACTQE;
	intel_writew(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL, act);
	usleep_range(10, 15);
}

static void intel_shim_vs_set_clock_source(struct sdw_intel *sdw, u32 source)
{
	void __iomem *shim_vs = sdw->link_res->shim_vs;
	u32 val;

	val = intel_readl(shim_vs, SDW_SHIM2_INTEL_VS_LVSCTL);

	u32p_replace_bits(&val, source, SDW_SHIM2_INTEL_VS_LVSCTL_MLCS);

	intel_writel(shim_vs, SDW_SHIM2_INTEL_VS_LVSCTL, val);

	dev_dbg(sdw->cdns.dev, "clock source %d LVSCTL %#x\n", source, val);
}

static int intel_shim_check_wake(struct sdw_intel *sdw)
{
	/*
	 * We follow the HDaudio example and resume unconditionally
	 * without checking the WAKESTS bit for that specific link
	 */

	return 1;
}

static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
{
	u16 lsdiid = 0;
	u16 wake_en;
	u16 wake_sts;
	int ret;

	mutex_lock(sdw->link_res->shim_lock);

	ret = hdac_bus_eml_sdw_get_lsdiid_unlocked(sdw->link_res->hbus, sdw->instance, &lsdiid);
	if (ret < 0)
		goto unlock;

	wake_en = snd_hdac_chip_readw(sdw->link_res->hbus, WAKEEN);

	if (wake_enable) {
		/* Enable the wakeup */
		wake_en |= lsdiid;

		snd_hdac_chip_writew(sdw->link_res->hbus, WAKEEN, wake_en);
	} else {
		/* Disable the wake up interrupt */
		wake_en &= ~lsdiid;
		snd_hdac_chip_writew(sdw->link_res->hbus, WAKEEN, wake_en);

		/* Clear wake status (W1C) */
		wake_sts = snd_hdac_chip_readw(sdw->link_res->hbus, STATESTS);
		wake_sts |= lsdiid;
		snd_hdac_chip_writew(sdw->link_res->hbus, STATESTS, wake_sts);
	}
unlock:
	mutex_unlock(sdw->link_res->shim_lock);
}

static int intel_link_power_up(struct sdw_intel *sdw)
{
	struct sdw_bus *bus = &sdw->cdns.bus;
	struct sdw_master_prop *prop = &bus->prop;
	u32 *shim_mask = sdw->link_res->shim_mask;
	unsigned int link_id = sdw->instance;
	u32 clock_source;
	u32 syncprd;
	int ret;

	if (prop->mclk_freq % 6000000) {
		if (prop->mclk_freq % 2400000) {
			syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24_576;
			clock_source = SDW_SHIM2_MLCS_CARDINAL_CLK;
		} else {
			syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4;
			clock_source = SDW_SHIM2_MLCS_XTAL_CLK;
		}
	} else {
		syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_96;
		clock_source = SDW_SHIM2_MLCS_AUDIO_PLL_CLK;
	}

	mutex_lock(sdw->link_res->shim_lock);

	ret = hdac_bus_eml_sdw_power_up_unlocked(sdw->link_res->hbus, link_id);
	if (ret < 0) {
		dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_power_up failed: %d\n",
			__func__, ret);
		goto out;
	}

	intel_shim_vs_set_clock_source(sdw, clock_source);

	if (!*shim_mask) {
		/* we first need to program the SyncPRD/CPU registers */
		dev_dbg(sdw->cdns.dev, "first link up, programming SYNCPRD\n");

		ret =  hdac_bus_eml_sdw_set_syncprd_unlocked(sdw->link_res->hbus, syncprd);
		if (ret < 0) {
			dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_set_syncprd failed: %d\n",
				__func__, ret);
			goto out;
		}

		/* SYNCPU will change once link is active */
		ret =  hdac_bus_eml_sdw_wait_syncpu_unlocked(sdw->link_res->hbus);
		if (ret < 0) {
			dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_wait_syncpu failed: %d\n",
				__func__, ret);
			goto out;
		}

		hdac_bus_eml_enable_interrupt_unlocked(sdw->link_res->hbus, true,
						       AZX_REG_ML_LEPTR_ID_SDW, true);
	}

	*shim_mask |= BIT(link_id);

	sdw->cdns.link_up = true;

	intel_shim_vs_init(sdw);

out:
	mutex_unlock(sdw->link_res->shim_lock);

	return ret;
}

static int intel_link_power_down(struct sdw_intel *sdw)
{
	u32 *shim_mask = sdw->link_res->shim_mask;
	unsigned int link_id = sdw->instance;
	int ret;

	mutex_lock(sdw->link_res->shim_lock);

	sdw->cdns.link_up = false;

	*shim_mask &= ~BIT(link_id);

	if (!*shim_mask)
		hdac_bus_eml_enable_interrupt_unlocked(sdw->link_res->hbus, true,
						       AZX_REG_ML_LEPTR_ID_SDW, false);

	ret = hdac_bus_eml_sdw_power_down_unlocked(sdw->link_res->hbus, link_id);
	if (ret < 0) {
		dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_power_down failed: %d\n",
			__func__, ret);

		/*
		 * we leave the sdw->cdns.link_up flag as false since we've disabled
		 * the link at this point and cannot handle interrupts any longer.
		 */
	}

	mutex_unlock(sdw->link_res->shim_lock);

	return ret;
}

static void intel_sync_arm(struct sdw_intel *sdw)
{
	unsigned int link_id = sdw->instance;

	mutex_lock(sdw->link_res->shim_lock);

	hdac_bus_eml_sdw_sync_arm_unlocked(sdw->link_res->hbus, link_id);

	mutex_unlock(sdw->link_res->shim_lock);
}

static int intel_sync_go_unlocked(struct sdw_intel *sdw)
{
	int ret;

	ret = hdac_bus_eml_sdw_sync_go_unlocked(sdw->link_res->hbus);
	if (ret < 0)
		dev_err(sdw->cdns.dev, "%s: SyncGO clear failed: %d\n", __func__, ret);

	return ret;
}

static int intel_sync_go(struct sdw_intel *sdw)
{
	int ret;

	mutex_lock(sdw->link_res->shim_lock);

	ret = intel_sync_go_unlocked(sdw);

	mutex_unlock(sdw->link_res->shim_lock);

	return ret;
}

static bool intel_check_cmdsync_unlocked(struct sdw_intel *sdw)
{
	return hdac_bus_eml_sdw_check_cmdsync_unlocked(sdw->link_res->hbus);
}

/* DAI callbacks */
static int intel_params_stream(struct sdw_intel *sdw,
			       struct snd_pcm_substream *substream,
			       struct snd_soc_dai *dai,
			       struct snd_pcm_hw_params *hw_params,
			       int link_id, int alh_stream_id)
{
	struct sdw_intel_link_res *res = sdw->link_res;
	struct sdw_intel_stream_params_data params_data;

	params_data.substream = substream;
	params_data.dai = dai;
	params_data.hw_params = hw_params;
	params_data.link_id = link_id;
	params_data.alh_stream_id = alh_stream_id;

	if (res->ops && res->ops->params_stream && res->dev)
		return res->ops->params_stream(res->dev,
					       &params_data);
	return -EIO;
}

static int intel_free_stream(struct sdw_intel *sdw,
			     struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai,
			     int link_id)

{
	struct sdw_intel_link_res *res = sdw->link_res;
	struct sdw_intel_stream_free_data free_data;

	free_data.substream = substream;
	free_data.dai = dai;
	free_data.link_id = link_id;

	if (res->ops && res->ops->free_stream && res->dev)
		return res->ops->free_stream(res->dev,
					     &free_data);

	return 0;
}

/*
 * DAI operations
 */
static int intel_hw_params(struct snd_pcm_substream *substream,
			   struct snd_pcm_hw_params *params,
			   struct snd_soc_dai *dai)
{
	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
	struct sdw_intel *sdw = cdns_to_intel(cdns);
	struct sdw_cdns_dai_runtime *dai_runtime;
	struct sdw_cdns_pdi *pdi;
	struct sdw_stream_config sconfig;
	int ch, dir;
	int ret;

	dai_runtime = cdns->dai_runtime_array[dai->id];
	if (!dai_runtime)
		return -EIO;

	ch = params_channels(params);
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		dir = SDW_DATA_DIR_RX;
	else
		dir = SDW_DATA_DIR_TX;

	pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id);
	if (!pdi)
		return -EINVAL;

	/* use same definitions for alh_id as previous generations */
	pdi->intel_alh_id = (sdw->instance * 16) + pdi->num + 3;
	if (pdi->num >= 2)
		pdi->intel_alh_id += 2;

	/* the SHIM will be configured in the callback functions */

	sdw_cdns_config_stream(cdns, ch, dir, pdi);

	/* store pdi and state, may be needed in prepare step */
	dai_runtime->paused = false;
	dai_runtime->suspended = false;
	dai_runtime->pdi = pdi;

	/* Inform DSP about PDI stream number */
	ret = intel_params_stream(sdw, substream, dai, params,
				  sdw->instance,
				  pdi->intel_alh_id);
	if (ret)
		return ret;

	sconfig.direction = dir;
	sconfig.ch_count = ch;
	sconfig.frame_rate = params_rate(params);
	sconfig.type = dai_runtime->stream_type;

	sconfig.bps = snd_pcm_format_width(params_format(params));

	/* Port configuration */
	struct sdw_port_config *pconfig __free(kfree) = kzalloc_obj(*pconfig);
	if (!pconfig)
		return -ENOMEM;

	pconfig->num = pdi->num;
	pconfig->ch_mask = (1 << ch) - 1;

	ret = sdw_stream_add_master(&cdns->bus, &sconfig,
				    pconfig, 1, dai_runtime->stream);
	if (ret)
		dev_err(cdns->dev, "add master to stream failed:%d\n", ret);

	return ret;
}

static int intel_prepare(struct snd_pcm_substream *substream,
			 struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
	struct sdw_intel *sdw = cdns_to_intel(cdns);
	struct sdw_cdns_dai_runtime *dai_runtime;
	struct snd_pcm_hw_params *hw_params;
	int ch, dir;

	dai_runtime = cdns->dai_runtime_array[dai->id];
	if (!dai_runtime) {
		dev_err(dai->dev, "failed to get dai runtime in %s\n",
			__func__);
		return -EIO;
	}

	hw_params = &rtd->dpcm[substream->stream].hw_params;
	if (dai_runtime->suspended) {
		dai_runtime->suspended = false;

		/*
		 * .prepare() is called after system resume, where we
		 * need to reinitialize the SHIM/ALH/Cadence IP.
		 * .prepare() is also called to deal with underflows,
		 * but in those cases we cannot touch ALH/SHIM
		 * registers
		 */

		/* configure stream */
		ch = params_channels(hw_params);
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
			dir = SDW_DATA_DIR_RX;
		else
			dir = SDW_DATA_DIR_TX;

		/* the SHIM will be configured in the callback functions */

		sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi);
	}

	/* Inform DSP about PDI stream number */
	return intel_params_stream(sdw, substream, dai, hw_params, sdw->instance,
				   dai_runtime->pdi->intel_alh_id);
}

static int
intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
	struct sdw_intel *sdw = cdns_to_intel(cdns);
	struct sdw_cdns_dai_runtime *dai_runtime;
	int ret;

	dai_runtime = cdns->dai_runtime_array[dai->id];
	if (!dai_runtime)
		return -EIO;

	/*
	 * The sdw stream state will transition to RELEASED when stream->
	 * master_list is empty. So the stream state will transition to
	 * DEPREPARED for the first cpu-dai and to RELEASED for the last
	 * cpu-dai.
	 */
	ret = sdw_stream_remove_master(&cdns->bus, dai_runtime->stream);
	if (ret < 0) {
		dev_err(dai->dev, "remove master from stream %s failed: %d\n",
			dai_runtime->stream->name, ret);
		return ret;
	}

	ret = intel_free_stream(sdw, substream, dai, sdw->instance);
	if (ret < 0) {
		dev_err(dai->dev, "intel_free_stream: failed %d\n", ret);
		return ret;
	}

	dai_runtime->pdi = NULL;

	return 0;
}

static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai,
				    void *stream, int direction)
{
	return cdns_set_sdw_stream(dai, stream, direction);
}

static void *intel_get_sdw_stream(struct snd_soc_dai *dai,
				  int direction)
{
	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
	struct sdw_cdns_dai_runtime *dai_runtime;

	dai_runtime = cdns->dai_runtime_array[dai->id];
	if (!dai_runtime)
		return ERR_PTR(-EINVAL);

	return dai_runtime->stream;
}

static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
{
	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
	struct sdw_intel *sdw = cdns_to_intel(cdns);
	struct sdw_intel_link_res *res = sdw->link_res;
	struct sdw_cdns_dai_runtime *dai_runtime;
	int ret = 0;

	/*
	 * The .trigger callback is used to program HDaudio DMA and send required IPC to audio
	 * firmware.
	 */
	if (res->ops && res->ops->trigger) {
		ret = res->ops->trigger(substream, cmd, dai);
		if (ret < 0)
			return ret;
	}

	dai_runtime = cdns->dai_runtime_array[dai->id];
	if (!dai_runtime) {
		dev_err(dai->dev, "failed to get dai runtime in %s\n",
			__func__);
		return -EIO;
	}

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_SUSPEND:

		/*
		 * The .prepare callback is used to deal with xruns and resume operations.
		 * In the case of xruns, the DMAs and SHIM registers cannot be touched,
		 * but for resume operations the DMAs and SHIM registers need to be initialized.
		 * the .trigger callback is used to track the suspend case only.
		 */

		dai_runtime->suspended = true;

		break;

	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		dai_runtime->paused = true;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		dai_runtime->paused = false;
		break;
	default:
		break;
	}

	return ret;
}

static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
	.hw_params = intel_hw_params,
	.prepare = intel_prepare,
	.hw_free = intel_hw_free,
	.trigger = intel_trigger,
	.set_stream = intel_pcm_set_sdw_stream,
	.get_stream = intel_get_sdw_stream,
};

static const struct snd_soc_component_driver dai_component = {
	.name			= "soundwire",
};

/*
 * PDI routines
 */
static void intel_pdi_init(struct sdw_intel *sdw,
			   struct sdw_cdns_stream_config *config)
{
	void __iomem *shim = sdw->link_res->shim;
	int pcm_cap;

	/* PCM Stream Capability */
	pcm_cap = intel_readw(shim, SDW_SHIM2_PCMSCAP);

	config->pcm_bd = FIELD_GET(SDW_SHIM2_PCMSCAP_BSS, pcm_cap);
	config->pcm_in = FIELD_GET(SDW_SHIM2_PCMSCAP_ISS, pcm_cap);
	config->pcm_out = FIELD_GET(SDW_SHIM2_PCMSCAP_ISS, pcm_cap);

	dev_dbg(sdw->cdns.dev, "PCM cap bd:%d in:%d out:%d\n",
		config->pcm_bd, config->pcm_in, config->pcm_out);
}

static int
intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num)
{
	void __iomem *shim = sdw->link_res->shim;

	/* zero based values for channel count in register */
	return intel_readw(shim, SDW_SHIM2_PCMSYCHC(pdi_num)) + 1;
}

static void intel_pdi_get_ch_update(struct sdw_intel *sdw,
				    struct sdw_cdns_pdi *pdi,
				    unsigned int num_pdi,
				    unsigned int *num_ch)
{
	int ch_count = 0;
	int i;

	for (i = 0; i < num_pdi; i++) {
		pdi->ch_count = intel_pdi_get_ch_cap(sdw, pdi->num);
		ch_count += pdi->ch_count;
		pdi++;
	}

	*num_ch = ch_count;
}

static void intel_pdi_stream_ch_update(struct sdw_intel *sdw,
				       struct sdw_cdns_streams *stream)
{
	intel_pdi_get_ch_update(sdw, stream->bd, stream->num_bd,
				&stream->num_ch_bd);

	intel_pdi_get_ch_update(sdw, stream->in, stream->num_in,
				&stream->num_ch_in);

	intel_pdi_get_ch_update(sdw, stream->out, stream->num_out,
				&stream->num_ch_out);
}

static int intel_create_dai(struct sdw_cdns *cdns,
			    struct snd_soc_dai_driver *dais,
			    enum intel_pdi_type type,
			    u32 num, u32 off, u32 max_ch)
{
	int i;

	if (!num)
		return 0;

	for (i = off; i < (off + num); i++) {
		dais[i].name = devm_kasprintf(cdns->dev, GFP_KERNEL,
					      "SDW%d Pin%d",
					      cdns->instance, i);
		if (!dais[i].name)
			return -ENOMEM;

		if (type == INTEL_PDI_BD || type == INTEL_PDI_OUT) {
			dais[i].playback.channels_min = 1;
			dais[i].playback.channels_max = max_ch;
		}

		if (type == INTEL_PDI_BD || type == INTEL_PDI_IN) {
			dais[i].capture.channels_min = 1;
			dais[i].capture.channels_max = max_ch;
		}

		dais[i].ops = &intel_pcm_dai_ops;
	}

	return 0;
}

static int intel_register_dai(struct sdw_intel *sdw)
{
	struct sdw_cdns_dai_runtime **dai_runtime_array;
	struct sdw_cdns_stream_config config;
	struct sdw_cdns *cdns = &sdw->cdns;
	struct sdw_cdns_streams *stream;
	struct snd_soc_dai_driver *dais;
	int num_dai;
	int ret;
	int off = 0;

	/* Read the PDI config and initialize cadence PDI */
	intel_pdi_init(sdw, &config);
	ret = sdw_cdns_pdi_init(cdns, config);
	if (ret)
		return ret;

	intel_pdi_stream_ch_update(sdw, &sdw->cdns.pcm);

	/* DAIs are created based on total number of PDIs supported */
	num_dai = cdns->pcm.num_pdi;

	dai_runtime_array = devm_kcalloc(cdns->dev, num_dai,
					 sizeof(struct sdw_cdns_dai_runtime *),
					 GFP_KERNEL);
	if (!dai_runtime_array)
		return -ENOMEM;
	cdns->dai_runtime_array = dai_runtime_array;

	dais = devm_kcalloc(cdns->dev, num_dai, sizeof(*dais), GFP_KERNEL);
	if (!dais)
		return -ENOMEM;

	/* Create PCM DAIs */
	stream = &cdns->pcm;

	ret = intel_create_dai(cdns, dais, INTEL_PDI_IN, cdns->pcm.num_in,
			       off, stream->num_ch_in);
	if (ret)
		return ret;

	off += cdns->pcm.num_in;
	ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT, cdns->pcm.num_out,
			       off, stream->num_ch_out);
	if (ret)
		return ret;

	off += cdns->pcm.num_out;
	ret = intel_create_dai(cdns, dais, INTEL_PDI_BD, cdns->pcm.num_bd,
			       off, stream->num_ch_bd);
	if (ret)
		return ret;

	return devm_snd_soc_register_component(cdns->dev, &dai_component,
					       dais, num_dai);
}

static void intel_program_sdi(struct sdw_intel *sdw, int dev_num)
{
	int ret;

	ret = hdac_bus_eml_sdw_set_lsdiid(sdw->link_res->hbus, sdw->instance, dev_num);
	if (ret < 0)
		dev_err(sdw->cdns.dev, "%s: could not set lsdiid for link %d %d\n",
			__func__, sdw->instance, dev_num);
}

static int intel_get_link_count(struct sdw_intel *sdw)
{
	int ret;

	ret = hdac_bus_eml_get_count(sdw->link_res->hbus, true, AZX_REG_ML_LEPTR_ID_SDW);
	if (!ret) {
		dev_err(sdw->cdns.dev, "%s: could not retrieve link count\n", __func__);
		return -ENODEV;
	}

	if (ret > SDW_INTEL_MAX_LINKS) {
		dev_err(sdw->cdns.dev, "%s: link count %d exceed max %d\n", __func__, ret, SDW_INTEL_MAX_LINKS);
		return -EINVAL;
	}

	return ret;
}

const struct sdw_intel_hw_ops sdw_intel_lnl_hw_ops = {
	.debugfs_init = intel_ace2x_debugfs_init,
	.debugfs_exit = intel_ace2x_debugfs_exit,

	.get_link_count = intel_get_link_count,

	.register_dai = intel_register_dai,

	.check_clock_stop = intel_check_clock_stop,
	.start_bus = intel_start_bus,
	.start_bus_after_reset = intel_start_bus_after_reset,
	.start_bus_after_clock_stop = intel_start_bus_after_clock_stop,
	.stop_bus = intel_stop_bus,

	.link_power_up = intel_link_power_up,
	.link_power_down = intel_link_power_down,

	.shim_check_wake = intel_shim_check_wake,
	.shim_wake = intel_shim_wake,

	.pre_bank_switch = intel_pre_bank_switch,
	.post_bank_switch = intel_post_bank_switch,

	.sync_arm = intel_sync_arm,
	.sync_go_unlocked = intel_sync_go_unlocked,
	.sync_go = intel_sync_go,
	.sync_check_cmdsync_unlocked = intel_check_cmdsync_unlocked,

	.program_sdi = intel_program_sdi,

	.bpt_send_async = intel_ace2x_bpt_send_async,
	.bpt_wait = intel_ace2x_bpt_wait,
};
EXPORT_SYMBOL_NS(sdw_intel_lnl_hw_ops, "SOUNDWIRE_INTEL");

MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK");
MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_SDW_BPT");
