// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * SoundWire AMD Manager driver
 *
 * Copyright 2023-24 Advanced Micro Devices, Inc.
 */

#include <linux/completion.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/pm_runtime.h>
#include <linux/wait.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "bus.h"
#include "amd_init.h"
#include "amd_manager.h"

#define DRV_NAME "amd_sdw_manager"

#define to_amd_sdw(b)	container_of(b, struct amd_sdw_manager, bus)

static int amd_init_sdw_manager(struct amd_sdw_manager *amd_manager)
{
	u32 val;
	int ret;

	writel(AMD_SDW_ENABLE, amd_manager->mmio + ACP_SW_EN);
	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_EN_STATUS, val, val, ACP_DELAY_US,
				 AMD_SDW_TIMEOUT);
	if (ret)
		return ret;

	/* SoundWire manager bus reset */
	writel(AMD_SDW_BUS_RESET_REQ, amd_manager->mmio + ACP_SW_BUS_RESET_CTRL);
	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_BUS_RESET_CTRL, val,
				 (val & AMD_SDW_BUS_RESET_DONE), ACP_DELAY_US, AMD_SDW_TIMEOUT);
	if (ret)
		return ret;

	writel(AMD_SDW_BUS_RESET_CLEAR_REQ, amd_manager->mmio + ACP_SW_BUS_RESET_CTRL);
	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_BUS_RESET_CTRL, val, !val,
				 ACP_DELAY_US, AMD_SDW_TIMEOUT);
	if (ret) {
		dev_err(amd_manager->dev, "Failed to reset SoundWire manager instance%d\n",
			amd_manager->instance);
		return ret;
	}

	writel(AMD_SDW_DISABLE, amd_manager->mmio + ACP_SW_EN);
	return readl_poll_timeout(amd_manager->mmio + ACP_SW_EN_STATUS, val, !val, ACP_DELAY_US,
				  AMD_SDW_TIMEOUT);
}

static int amd_enable_sdw_manager(struct amd_sdw_manager *amd_manager)
{
	u32 val;

	writel(AMD_SDW_ENABLE, amd_manager->mmio + ACP_SW_EN);
	return readl_poll_timeout(amd_manager->mmio + ACP_SW_EN_STATUS, val, val, ACP_DELAY_US,
				  AMD_SDW_TIMEOUT);
}

static int amd_disable_sdw_manager(struct amd_sdw_manager *amd_manager)
{
	u32 val;

	writel(AMD_SDW_DISABLE, amd_manager->mmio + ACP_SW_EN);
	/*
	 * After invoking manager disable sequence, check whether
	 * manager has executed clock stop sequence. In this case,
	 * manager should ignore checking enable status register.
	 */
	val = readl(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
	if (val)
		return 0;
	return readl_poll_timeout(amd_manager->mmio + ACP_SW_EN_STATUS, val, !val, ACP_DELAY_US,
				  AMD_SDW_TIMEOUT);
}

static void amd_enable_sdw_interrupts(struct amd_sdw_manager *amd_manager)
{
	u32 val;

	mutex_lock(amd_manager->acp_sdw_lock);
	val = sdw_manager_reg_mask_array[amd_manager->instance];
	amd_updatel(amd_manager->acp_mmio, ACP_EXTERNAL_INTR_CNTL(amd_manager->instance), val, val);
	mutex_unlock(amd_manager->acp_sdw_lock);

	writel(AMD_SDW_IRQ_MASK_0TO7, amd_manager->mmio +
		       ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
	writel(AMD_SDW_IRQ_MASK_8TO11, amd_manager->mmio +
		       ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
	writel(AMD_SDW_IRQ_ERROR_MASK, amd_manager->mmio + ACP_SW_ERROR_INTR_MASK);
}

static void amd_disable_sdw_interrupts(struct amd_sdw_manager *amd_manager)
{
	u32 irq_mask;

	mutex_lock(amd_manager->acp_sdw_lock);
	irq_mask = sdw_manager_reg_mask_array[amd_manager->instance];
	amd_updatel(amd_manager->acp_mmio, ACP_EXTERNAL_INTR_CNTL(amd_manager->instance),
		    irq_mask, 0);
	mutex_unlock(amd_manager->acp_sdw_lock);

	writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
	writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
	writel(0x00, amd_manager->mmio + ACP_SW_ERROR_INTR_MASK);
}

static int amd_deinit_sdw_manager(struct amd_sdw_manager *amd_manager)
{
	amd_disable_sdw_interrupts(amd_manager);
	return amd_disable_sdw_manager(amd_manager);
}

static void amd_sdw_set_frameshape(struct amd_sdw_manager *amd_manager)
{
	u32 frame_size;

	frame_size = (amd_manager->rows_index << 3) | amd_manager->cols_index;
	writel(frame_size, amd_manager->mmio + ACP_SW_FRAMESIZE);
}

static void amd_sdw_wake_enable(struct amd_sdw_manager *amd_manager, bool enable)
{
	u32 wake_ctrl;

	wake_ctrl = readl(amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
	if (enable)
		wake_ctrl |= AMD_SDW_WAKE_INTR_MASK;
	else
		wake_ctrl &= ~AMD_SDW_WAKE_INTR_MASK;

	writel(wake_ctrl, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
}

static int amd_sdw_set_device_state(struct amd_sdw_manager *amd_manager, u32 target_device_state)
{
	u32 sdw_dev_state;

	sdw_dev_state = readl(amd_manager->acp_mmio + AMD_SDW_DEVICE_STATE);
	switch (amd_manager->instance) {
	case ACP_SDW0:
		u32p_replace_bits(&sdw_dev_state, target_device_state,
				  AMD_SDW0_DEVICE_STATE_MASK);
		break;
	case ACP_SDW1:
		u32p_replace_bits(&sdw_dev_state, target_device_state,
				  AMD_SDW1_DEVICE_STATE_MASK);
		break;
	default:
		return -EINVAL;
	}
	writel(sdw_dev_state, amd_manager->acp_mmio + AMD_SDW_DEVICE_STATE);
	sdw_dev_state = readl(amd_manager->acp_mmio + AMD_SDW_DEVICE_STATE);
	dev_dbg(amd_manager->dev, "AMD_SDW_DEVICE_STATE:0x%x\n", sdw_dev_state);
	return 0;
}

static int amd_sdw_host_wake_enable(struct amd_sdw_manager *amd_manager, bool enable)
{
	u32 intr_cntl1;
	u32 sdw_host_wake_irq_mask;

	if (!amd_manager->wake_en_mask)
		return 0;

	switch (amd_manager->instance) {
	case ACP_SDW0:
		sdw_host_wake_irq_mask = AMD_SDW0_HOST_WAKE_INTR_MASK;
		break;
	case ACP_SDW1:
		sdw_host_wake_irq_mask = AMD_SDW1_HOST_WAKE_INTR_MASK;
		break;
	default:
		return -EINVAL;
	}

	intr_cntl1 = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(ACP_SDW1));
	if (enable)
		intr_cntl1 |= sdw_host_wake_irq_mask;
	else
		intr_cntl1 &= ~sdw_host_wake_irq_mask;
	writel(intr_cntl1, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(ACP_SDW1));
	return 0;
}

static void amd_sdw_ctl_word_prep(u32 *lower_word, u32 *upper_word, struct sdw_msg *msg,
				  int cmd_offset)
{
	u32 upper_data;
	u32 lower_data = 0;
	u16 addr;
	u8 upper_addr, lower_addr;
	u8 data = 0;

	addr = msg->addr + cmd_offset;
	upper_addr = (addr & 0xFF00) >> 8;
	lower_addr = addr & 0xFF;

	if (msg->flags == SDW_MSG_FLAG_WRITE)
		data = msg->buf[cmd_offset];

	upper_data = FIELD_PREP(AMD_SDW_MCP_CMD_DEV_ADDR, msg->dev_num);
	upper_data |= FIELD_PREP(AMD_SDW_MCP_CMD_COMMAND, msg->flags + 2);
	upper_data |= FIELD_PREP(AMD_SDW_MCP_CMD_REG_ADDR_HIGH, upper_addr);
	lower_data |= FIELD_PREP(AMD_SDW_MCP_CMD_REG_ADDR_LOW, lower_addr);
	lower_data |= FIELD_PREP(AMD_SDW_MCP_CMD_REG_DATA, data);

	*upper_word = upper_data;
	*lower_word = lower_data;
}

static u64 amd_sdw_send_cmd_get_resp(struct amd_sdw_manager *amd_manager, u32 lower_data,
				     u32 upper_data)
{
	u64 resp;
	u32 lower_resp, upper_resp;
	u32 sts;
	int ret;

	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_IMM_CMD_STS, sts,
				 !(sts & AMD_SDW_IMM_CMD_BUSY), ACP_DELAY_US, AMD_SDW_TIMEOUT);
	if (ret) {
		dev_err(amd_manager->dev, "SDW%x previous cmd status clear failed\n",
			amd_manager->instance);
		return ret;
	}

	if (sts & AMD_SDW_IMM_RES_VALID) {
		dev_err(amd_manager->dev, "SDW%x manager is in bad state\n", amd_manager->instance);
		writel(AMD_SDW_IMM_RES_VALID, amd_manager->mmio + ACP_SW_IMM_CMD_STS);
	}
	writel(upper_data, amd_manager->mmio + ACP_SW_IMM_CMD_UPPER_WORD);
	writel(lower_data, amd_manager->mmio + ACP_SW_IMM_CMD_LOWER_QWORD);

	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_IMM_CMD_STS, sts,
				 (sts & AMD_SDW_IMM_RES_VALID), ACP_DELAY_US, AMD_SDW_TIMEOUT);
	if (ret) {
		dev_err(amd_manager->dev, "SDW%x cmd response timeout occurred\n",
			amd_manager->instance);
		return ret;
	}
	upper_resp = readl(amd_manager->mmio + ACP_SW_IMM_RESP_UPPER_WORD);
	lower_resp = readl(amd_manager->mmio + ACP_SW_IMM_RESP_LOWER_QWORD);

	writel(AMD_SDW_IMM_RES_VALID, amd_manager->mmio + ACP_SW_IMM_CMD_STS);
	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_IMM_CMD_STS, sts,
				 !(sts & AMD_SDW_IMM_RES_VALID), ACP_DELAY_US, AMD_SDW_TIMEOUT);
	if (ret) {
		dev_err(amd_manager->dev, "SDW%x cmd status retry failed\n",
			amd_manager->instance);
		return ret;
	}
	resp = upper_resp;
	resp = (resp << 32) | lower_resp;
	return resp;
}

static enum sdw_command_response
amd_program_scp_addr(struct amd_sdw_manager *amd_manager, struct sdw_msg *msg)
{
	struct sdw_msg scp_msg = {0};
	u64 response_buf[2] = {0};
	u32 upper_data = 0, lower_data = 0;
	int index;

	scp_msg.dev_num = msg->dev_num;
	scp_msg.addr = SDW_SCP_ADDRPAGE1;
	scp_msg.buf = &msg->addr_page1;
	scp_msg.flags = SDW_MSG_FLAG_WRITE;
	amd_sdw_ctl_word_prep(&lower_data, &upper_data, &scp_msg, 0);
	response_buf[0] = amd_sdw_send_cmd_get_resp(amd_manager, lower_data, upper_data);
	scp_msg.addr = SDW_SCP_ADDRPAGE2;
	scp_msg.buf = &msg->addr_page2;
	amd_sdw_ctl_word_prep(&lower_data, &upper_data, &scp_msg, 0);
	response_buf[1] = amd_sdw_send_cmd_get_resp(amd_manager, lower_data, upper_data);

	for (index = 0; index < 2; index++) {
		if (response_buf[index] == -ETIMEDOUT) {
			dev_err_ratelimited(amd_manager->dev,
					    "SCP_addrpage command timeout for Slave %d\n",
					    msg->dev_num);
			return SDW_CMD_TIMEOUT;
		} else if (!(response_buf[index] & AMD_SDW_MCP_RESP_ACK)) {
			if (response_buf[index] & AMD_SDW_MCP_RESP_NACK) {
				dev_err_ratelimited(amd_manager->dev,
						    "SCP_addrpage NACKed for Slave %d\n",
						    msg->dev_num);
				return SDW_CMD_FAIL;
			}
			dev_dbg_ratelimited(amd_manager->dev, "SCP_addrpage ignored for Slave %d\n",
					    msg->dev_num);
			return SDW_CMD_IGNORED;
		}
	}
	return SDW_CMD_OK;
}

static int amd_prep_msg(struct amd_sdw_manager *amd_manager, struct sdw_msg *msg)
{
	int ret;

	if (msg->page) {
		ret = amd_program_scp_addr(amd_manager, msg);
		if (ret) {
			msg->len = 0;
			return ret;
		}
	}
	switch (msg->flags) {
	case SDW_MSG_FLAG_READ:
	case SDW_MSG_FLAG_WRITE:
		break;
	default:
		dev_err(amd_manager->dev, "Invalid msg cmd: %d\n", msg->flags);
		return -EINVAL;
	}
	return 0;
}

static enum sdw_command_response amd_sdw_fill_msg_resp(struct amd_sdw_manager *amd_manager,
						       struct sdw_msg *msg, u64 response,
						       int offset)
{
	if (response & AMD_SDW_MCP_RESP_ACK) {
		if (msg->flags == SDW_MSG_FLAG_READ)
			msg->buf[offset] = FIELD_GET(AMD_SDW_MCP_RESP_RDATA, response);
	} else {
		if (response == -ETIMEDOUT) {
			dev_err_ratelimited(amd_manager->dev, "command timeout for Slave %d\n",
					    msg->dev_num);
			return SDW_CMD_TIMEOUT;
		} else if (response & AMD_SDW_MCP_RESP_NACK) {
			dev_err_ratelimited(amd_manager->dev,
					    "command response NACK received for Slave %d\n",
					    msg->dev_num);
			return SDW_CMD_FAIL;
		}
		dev_dbg_ratelimited(amd_manager->dev, "command is ignored for Slave %d\n",
				    msg->dev_num);
		return SDW_CMD_IGNORED;
	}
	return SDW_CMD_OK;
}

static unsigned int _amd_sdw_xfer_msg(struct amd_sdw_manager *amd_manager, struct sdw_msg *msg,
				      int cmd_offset)
{
	u64 response;
	u32 upper_data = 0, lower_data = 0;

	amd_sdw_ctl_word_prep(&lower_data, &upper_data, msg, cmd_offset);
	response = amd_sdw_send_cmd_get_resp(amd_manager, lower_data, upper_data);
	return amd_sdw_fill_msg_resp(amd_manager, msg, response, cmd_offset);
}

static enum sdw_command_response amd_sdw_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	int ret, i;

	ret = amd_prep_msg(amd_manager, msg);
	if (ret)
		return SDW_CMD_FAIL_OTHER;
	for (i = 0; i < msg->len; i++) {
		ret = _amd_sdw_xfer_msg(amd_manager, msg, i);
		if (ret)
			return ret;
	}
	return SDW_CMD_OK;
}

static void amd_sdw_fill_slave_status(struct amd_sdw_manager *amd_manager, u16 index, u32 status)
{
	switch (status) {
	case SDW_SLAVE_ATTACHED:
	case SDW_SLAVE_UNATTACHED:
	case SDW_SLAVE_ALERT:
		amd_manager->status[index] = status;
		break;
	default:
		amd_manager->status[index] = SDW_SLAVE_RESERVED;
		break;
	}
}

static void amd_sdw_process_ping_status(u64 response, struct amd_sdw_manager *amd_manager)
{
	u64 slave_stat;
	u32 val;
	u16 dev_index;

	/* slave status response */
	slave_stat = FIELD_GET(AMD_SDW_MCP_SLAVE_STAT_0_3, response);
	slave_stat |= FIELD_GET(AMD_SDW_MCP_SLAVE_STAT_4_11, response) << 8;
	dev_dbg(amd_manager->dev, "slave_stat:0x%llx\n", slave_stat);
	for (dev_index = 0; dev_index <= SDW_MAX_DEVICES; ++dev_index) {
		val = (slave_stat >> (dev_index * 2)) & AMD_SDW_MCP_SLAVE_STATUS_MASK;
		dev_dbg(amd_manager->dev, "val:0x%x\n", val);
		amd_sdw_fill_slave_status(amd_manager, dev_index, val);
	}
}

static void amd_sdw_read_and_process_ping_status(struct amd_sdw_manager *amd_manager)
{
	u64 response;

	mutex_lock(&amd_manager->bus.msg_lock);
	response = amd_sdw_send_cmd_get_resp(amd_manager, 0, 0);
	mutex_unlock(&amd_manager->bus.msg_lock);
	amd_sdw_process_ping_status(response, amd_manager);
}

static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	u64 response;
	u32 slave_stat;

	response = amd_sdw_send_cmd_get_resp(amd_manager, 0, 0);
	/* slave status from ping response */
	slave_stat = FIELD_GET(AMD_SDW_MCP_SLAVE_STAT_0_3, response);
	slave_stat |= FIELD_GET(AMD_SDW_MCP_SLAVE_STAT_4_11, response) << 8;
	dev_dbg(amd_manager->dev, "slave_stat:0x%x\n", slave_stat);
	return slave_stat;
}

static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime *stream)
{
	struct sdw_transport_data t_data = {0};
	struct sdw_master_runtime *m_rt;
	struct sdw_port_runtime *p_rt;
	struct sdw_bus_params *b_params = &bus->params;
	int port_bo, hstart, hstop, sample_int;
	unsigned int rate, bps;

	port_bo = 0;
	hstart = 1;
	hstop = bus->params.col - 1;
	t_data.hstop = hstop;
	t_data.hstart = hstart;

	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
		rate = m_rt->stream->params.rate;
		bps = m_rt->stream->params.bps;
		sample_int = (bus->params.curr_dr_freq / rate);
		list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
			port_bo = (p_rt->num * 64) + 1;
			dev_dbg(bus->dev, "p_rt->num=%d hstart=%d hstop=%d port_bo=%d\n",
				p_rt->num, hstart, hstop, port_bo);
			sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
					      false, SDW_BLK_GRP_CNT_1, sample_int,
					      port_bo, port_bo >> 8, hstart, hstop,
					      SDW_BLK_PKG_PER_PORT, p_rt->lane);

			sdw_fill_port_params(&p_rt->port_params,
					     p_rt->num, bps,
					     SDW_PORT_FLOW_MODE_ISOCH,
					     b_params->m_data_mode);
			t_data.hstart = hstart;
			t_data.hstop = hstop;
			t_data.block_offset = port_bo;
			t_data.sub_block_offset = 0;
		}
		sdw_compute_slave_ports(m_rt, &t_data);
	}
	return 0;
}

static int amd_sdw_port_params(struct sdw_bus *bus, struct sdw_port_params *p_params,
			       unsigned int bank)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	u32 frame_fmt_reg, dpn_frame_fmt;

	dev_dbg(amd_manager->dev, "p_params->num:0x%x\n", p_params->num);
	switch (amd_manager->acp_rev) {
	case ACP63_PCI_REV_ID:
		switch (amd_manager->instance) {
		case ACP_SDW0:
			frame_fmt_reg = acp63_sdw0_dp_reg[p_params->num].frame_fmt_reg;
			break;
		case ACP_SDW1:
			frame_fmt_reg = acp63_sdw1_dp_reg[p_params->num].frame_fmt_reg;
			break;
		default:
			return -EINVAL;
		}
		break;
	case ACP70_PCI_REV_ID:
	case ACP71_PCI_REV_ID:
	case ACP72_PCI_REV_ID:
		frame_fmt_reg = acp70_sdw_dp_reg[p_params->num].frame_fmt_reg;
		break;
	default:
		return -EINVAL;
	}

	dpn_frame_fmt = readl(amd_manager->mmio + frame_fmt_reg);
	u32p_replace_bits(&dpn_frame_fmt, p_params->flow_mode, AMD_DPN_FRAME_FMT_PFM);
	u32p_replace_bits(&dpn_frame_fmt, p_params->data_mode, AMD_DPN_FRAME_FMT_PDM);
	u32p_replace_bits(&dpn_frame_fmt, p_params->bps - 1, AMD_DPN_FRAME_FMT_WORD_LEN);
	writel(dpn_frame_fmt, amd_manager->mmio + frame_fmt_reg);
	return 0;
}

static int amd_sdw_transport_params(struct sdw_bus *bus,
				    struct sdw_transport_params *params,
				    enum sdw_reg_bank bank)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	u32 dpn_frame_fmt;
	u32 dpn_sampleinterval;
	u32 dpn_hctrl;
	u32 dpn_offsetctrl;
	u32 dpn_lanectrl;
	u32 frame_fmt_reg, sample_int_reg, hctrl_dp0_reg;
	u32 offset_reg, lane_ctrl_ch_en_reg;

	switch (amd_manager->acp_rev) {
	case ACP63_PCI_REV_ID:
		switch (amd_manager->instance) {
		case ACP_SDW0:
			frame_fmt_reg = acp63_sdw0_dp_reg[params->port_num].frame_fmt_reg;
			sample_int_reg = acp63_sdw0_dp_reg[params->port_num].sample_int_reg;
			hctrl_dp0_reg = acp63_sdw0_dp_reg[params->port_num].hctrl_dp0_reg;
			offset_reg = acp63_sdw0_dp_reg[params->port_num].offset_reg;
			lane_ctrl_ch_en_reg =
					acp63_sdw0_dp_reg[params->port_num].lane_ctrl_ch_en_reg;
			break;
		case ACP_SDW1:
			frame_fmt_reg = acp63_sdw1_dp_reg[params->port_num].frame_fmt_reg;
			sample_int_reg = acp63_sdw1_dp_reg[params->port_num].sample_int_reg;
			hctrl_dp0_reg = acp63_sdw1_dp_reg[params->port_num].hctrl_dp0_reg;
			offset_reg = acp63_sdw1_dp_reg[params->port_num].offset_reg;
			lane_ctrl_ch_en_reg =
					acp63_sdw1_dp_reg[params->port_num].lane_ctrl_ch_en_reg;
			break;
		default:
			return -EINVAL;
		}
		break;
	case ACP70_PCI_REV_ID:
	case ACP71_PCI_REV_ID:
	case ACP72_PCI_REV_ID:
		frame_fmt_reg = acp70_sdw_dp_reg[params->port_num].frame_fmt_reg;
		sample_int_reg = acp70_sdw_dp_reg[params->port_num].sample_int_reg;
		hctrl_dp0_reg = acp70_sdw_dp_reg[params->port_num].hctrl_dp0_reg;
		offset_reg = acp70_sdw_dp_reg[params->port_num].offset_reg;
		lane_ctrl_ch_en_reg = acp70_sdw_dp_reg[params->port_num].lane_ctrl_ch_en_reg;
		break;
	default:
		return -EINVAL;
	}
	writel(AMD_SDW_SSP_COUNTER_VAL, amd_manager->mmio + ACP_SW_SSP_COUNTER);

	dpn_frame_fmt = readl(amd_manager->mmio + frame_fmt_reg);
	u32p_replace_bits(&dpn_frame_fmt, params->blk_pkg_mode, AMD_DPN_FRAME_FMT_BLK_PKG_MODE);
	u32p_replace_bits(&dpn_frame_fmt, params->blk_grp_ctrl, AMD_DPN_FRAME_FMT_BLK_GRP_CTRL);
	u32p_replace_bits(&dpn_frame_fmt, SDW_STREAM_PCM, AMD_DPN_FRAME_FMT_PCM_OR_PDM);
	writel(dpn_frame_fmt, amd_manager->mmio + frame_fmt_reg);

	dpn_sampleinterval = params->sample_interval - 1;
	writel(dpn_sampleinterval, amd_manager->mmio + sample_int_reg);

	dpn_hctrl = FIELD_PREP(AMD_DPN_HCTRL_HSTOP, params->hstop);
	dpn_hctrl |= FIELD_PREP(AMD_DPN_HCTRL_HSTART, params->hstart);
	writel(dpn_hctrl, amd_manager->mmio + hctrl_dp0_reg);

	dpn_offsetctrl = FIELD_PREP(AMD_DPN_OFFSET_CTRL_1, params->offset1);
	dpn_offsetctrl |= FIELD_PREP(AMD_DPN_OFFSET_CTRL_2, params->offset2);
	writel(dpn_offsetctrl, amd_manager->mmio + offset_reg);

	/*
	 * lane_ctrl_ch_en_reg will be used to program lane_ctrl and ch_mask
	 * parameters.
	 */
	dpn_lanectrl = readl(amd_manager->mmio + lane_ctrl_ch_en_reg);
	u32p_replace_bits(&dpn_lanectrl, params->lane_ctrl, AMD_DPN_CH_EN_LCTRL);
	writel(dpn_lanectrl, amd_manager->mmio + lane_ctrl_ch_en_reg);
	return 0;
}

static int amd_sdw_port_enable(struct sdw_bus *bus,
			       struct sdw_enable_ch *enable_ch,
			       unsigned int bank)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	u32 dpn_ch_enable;
	u32 lane_ctrl_ch_en_reg;

	switch (amd_manager->acp_rev) {
	case ACP63_PCI_REV_ID:
		switch (amd_manager->instance) {
		case ACP_SDW0:
			lane_ctrl_ch_en_reg =
					acp63_sdw0_dp_reg[enable_ch->port_num].lane_ctrl_ch_en_reg;
			break;
		case ACP_SDW1:
			lane_ctrl_ch_en_reg =
					acp63_sdw1_dp_reg[enable_ch->port_num].lane_ctrl_ch_en_reg;
			break;
		default:
			return -EINVAL;
		}
		break;
	case ACP70_PCI_REV_ID:
	case ACP71_PCI_REV_ID:
	case ACP72_PCI_REV_ID:
		lane_ctrl_ch_en_reg = acp70_sdw_dp_reg[enable_ch->port_num].lane_ctrl_ch_en_reg;
		break;
	default:
		return -EINVAL;
	}

	/*
	 * lane_ctrl_ch_en_reg will be used to program lane_ctrl and ch_mask
	 * parameters.
	 */
	dpn_ch_enable = readl(amd_manager->mmio + lane_ctrl_ch_en_reg);
	u32p_replace_bits(&dpn_ch_enable, enable_ch->ch_mask, AMD_DPN_CH_EN_CHMASK);
	if (enable_ch->enable)
		writel(dpn_ch_enable, amd_manager->mmio + lane_ctrl_ch_en_reg);
	else
		writel(0, amd_manager->mmio + lane_ctrl_ch_en_reg);
	return 0;
}

static int sdw_master_read_amd_prop(struct sdw_bus *bus)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	struct fwnode_handle *link;
	struct sdw_master_prop *prop;
	u32 quirk_mask = 0;
	u32 wake_en_mask = 0;
	u32 power_mode_mask = 0;
	char name[32];

	prop = &bus->prop;
	/* Find manager handle */
	snprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", bus->link_id);
	link = device_get_named_child_node(bus->dev, name);
	if (!link) {
		dev_err(bus->dev, "Manager node %s not found\n", name);
		return -EIO;
	}
	fwnode_property_read_u32(link, "amd-sdw-enable", &quirk_mask);
	if (!(quirk_mask & AMD_SDW_QUIRK_MASK_BUS_ENABLE))
		prop->hw_disabled = true;
	prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH |
		       SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY;

	fwnode_property_read_u32(link, "amd-sdw-wakeup-enable", &wake_en_mask);
	amd_manager->wake_en_mask = wake_en_mask;
	fwnode_property_read_u32(link, "amd-sdw-power-mode", &power_mode_mask);
	amd_manager->power_mode_mask = power_mode_mask;

	fwnode_handle_put(link);

	return 0;
}

static int amd_prop_read(struct sdw_bus *bus)
{
	sdw_master_read_prop(bus);
	sdw_master_read_amd_prop(bus);
	return 0;
}

static const struct sdw_master_port_ops amd_sdw_port_ops = {
	.dpn_set_port_params = amd_sdw_port_params,
	.dpn_set_port_transport_params = amd_sdw_transport_params,
	.dpn_port_enable_ch = amd_sdw_port_enable,
};

static const struct sdw_master_ops amd_sdw_ops = {
	.read_prop = amd_prop_read,
	.xfer_msg = amd_sdw_xfer_msg,
	.read_ping_status = amd_sdw_read_ping_status,
};

static int amd_sdw_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
	struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai);
	struct sdw_amd_dai_runtime *dai_runtime;
	struct sdw_stream_config sconfig;
	int ch, dir;
	int ret;

	dai_runtime = amd_manager->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;
	dev_dbg(amd_manager->dev, "dir:%d dai->id:0x%x\n", dir, dai->id);

	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 = dai->id;
	pconfig->ch_mask = (1 << ch) - 1;
	ret = sdw_stream_add_master(&amd_manager->bus, &sconfig,
				    pconfig, 1, dai_runtime->stream);
	if (ret)
		dev_err(amd_manager->dev, "add manager to stream failed:%d\n", ret);

	return ret;
}

static int amd_sdw_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
	struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai);
	struct sdw_amd_dai_runtime *dai_runtime;
	int ret;

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

	ret = sdw_stream_remove_master(&amd_manager->bus, dai_runtime->stream);
	if (ret < 0)
		dev_err(dai->dev, "remove manager from stream %s failed: %d\n",
			dai_runtime->stream->name, ret);
	return ret;
}

static int amd_set_sdw_stream(struct snd_soc_dai *dai, void *stream, int direction)
{
	struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai);
	struct sdw_amd_dai_runtime *dai_runtime;

	dai_runtime = amd_manager->dai_runtime_array[dai->id];
	if (stream) {
		/* first paranoia check */
		if (dai_runtime) {
			dev_err(dai->dev, "dai_runtime already allocated for dai %s\n",	dai->name);
			return -EINVAL;
		}

		/* allocate and set dai_runtime info */
		dai_runtime = kzalloc_obj(*dai_runtime);
		if (!dai_runtime)
			return -ENOMEM;

		dai_runtime->stream_type = SDW_STREAM_PCM;
		dai_runtime->bus = &amd_manager->bus;
		dai_runtime->stream = stream;
		amd_manager->dai_runtime_array[dai->id] = dai_runtime;
	} else {
		/* second paranoia check */
		if (!dai_runtime) {
			dev_err(dai->dev, "dai_runtime not allocated for dai %s\n", dai->name);
			return -EINVAL;
		}

		/* for NULL stream we release allocated dai_runtime */
		kfree(dai_runtime);
		amd_manager->dai_runtime_array[dai->id] = NULL;
	}
	return 0;
}

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

static void *amd_get_sdw_stream(struct snd_soc_dai *dai, int direction)
{
	struct amd_sdw_manager *amd_manager = snd_soc_dai_get_drvdata(dai);
	struct sdw_amd_dai_runtime *dai_runtime;

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

	return dai_runtime->stream;
}

static const struct snd_soc_dai_ops amd_sdw_dai_ops = {
	.hw_params = amd_sdw_hw_params,
	.hw_free = amd_sdw_hw_free,
	.set_stream = amd_pcm_set_sdw_stream,
	.get_stream = amd_get_sdw_stream,
};

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

static int amd_sdw_register_dais(struct amd_sdw_manager *amd_manager)
{
	struct sdw_amd_dai_runtime **dai_runtime_array;
	struct snd_soc_dai_driver *dais;
	struct snd_soc_pcm_stream *stream;
	struct device *dev;
	int i, num_dais;

	dev = amd_manager->dev;
	num_dais = amd_manager->num_dout_ports + amd_manager->num_din_ports;
	dais = devm_kcalloc(dev, num_dais, sizeof(*dais), GFP_KERNEL);
	if (!dais)
		return -ENOMEM;

	dai_runtime_array = devm_kcalloc(dev, num_dais,
					 sizeof(struct sdw_amd_dai_runtime *),
					 GFP_KERNEL);
	if (!dai_runtime_array)
		return -ENOMEM;
	amd_manager->dai_runtime_array = dai_runtime_array;
	for (i = 0; i < num_dais; i++) {
		dais[i].name = devm_kasprintf(dev, GFP_KERNEL, "SDW%d Pin%d", amd_manager->instance,
					      i);
		if (!dais[i].name)
			return -ENOMEM;
		if (i < amd_manager->num_dout_ports)
			stream = &dais[i].playback;
		else
			stream = &dais[i].capture;

		stream->channels_min = 2;
		stream->channels_max = 2;
		stream->rates = SNDRV_PCM_RATE_48000;
		stream->formats = SNDRV_PCM_FMTBIT_S16_LE;

		dais[i].ops = &amd_sdw_dai_ops;
		dais[i].id = i;
	}

	return devm_snd_soc_register_component(dev, &amd_sdw_dai_component,
					       dais, num_dais);
}

static void amd_sdw_update_slave_status_work(struct work_struct *work)
{
	struct amd_sdw_manager *amd_manager =
		container_of(work, struct amd_sdw_manager, amd_sdw_work);
	int retry_count = 0;

	if (amd_manager->status[0] == SDW_SLAVE_ATTACHED) {
		writel(0, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
		writel(0, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
	}

update_status:
	sdw_handle_slave_status(&amd_manager->bus, amd_manager->status);
	/*
	 * During the peripheral enumeration sequence, the SoundWire manager interrupts
	 * are masked. Once the device number programming is done for all peripherals,
	 * interrupts will be unmasked. Read the peripheral device status from ping command
	 * and process the response. This sequence will ensure all peripheral devices enumerated
	 * and initialized properly.
	 */
	if (amd_manager->status[0] == SDW_SLAVE_ATTACHED) {
		if (retry_count++ < SDW_MAX_DEVICES) {
			writel(AMD_SDW_IRQ_MASK_0TO7, amd_manager->mmio +
			       ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
			writel(AMD_SDW_IRQ_MASK_8TO11, amd_manager->mmio +
			       ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
			amd_sdw_read_and_process_ping_status(amd_manager);
			goto update_status;
		} else {
			dev_err_ratelimited(amd_manager->dev,
					    "Device0 detected after %d iterations\n",
					    retry_count);
		}
	}
}

static void amd_sdw_update_slave_status(u32 status_change_0to7, u32 status_change_8to11,
					struct amd_sdw_manager *amd_manager)
{
	u64 slave_stat;
	u32 val;
	int dev_index;

	if (status_change_0to7 == AMD_SDW_SLAVE_0_ATTACHED)
		memset(amd_manager->status, 0, sizeof(amd_manager->status));
	slave_stat = status_change_0to7;
	slave_stat |= FIELD_GET(AMD_SDW_MCP_SLAVE_STATUS_8TO_11, status_change_8to11) << 32;
	dev_dbg(amd_manager->dev, "status_change_0to7:0x%x status_change_8to11:0x%x\n",
		status_change_0to7, status_change_8to11);
	if (slave_stat) {
		for (dev_index = 0; dev_index <= SDW_MAX_DEVICES; ++dev_index) {
			if (slave_stat & AMD_SDW_MCP_SLAVE_STATUS_VALID_MASK(dev_index)) {
				val = (slave_stat >> AMD_SDW_MCP_SLAVE_STAT_SHIFT_MASK(dev_index)) &
				      AMD_SDW_MCP_SLAVE_STATUS_MASK;
				amd_sdw_fill_slave_status(amd_manager, dev_index, val);
			}
		}
	}
}

static void amd_sdw_process_wake_event(struct amd_sdw_manager *amd_manager)
{
	dev_dbg(amd_manager->dev, "SoundWire Wake event reported\n");
	pm_request_resume(amd_manager->dev);
	writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));
	writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
}

static void amd_sdw_irq_thread(struct work_struct *work)
{
	struct amd_sdw_manager *amd_manager =
			container_of(work, struct amd_sdw_manager, amd_sdw_irq_thread);
	u32 status_change_8to11;
	u32 status_change_0to7;

	status_change_8to11 = readl(amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
	status_change_0to7 = readl(amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_0TO7);
	if (!status_change_0to7 && !status_change_8to11)
		return;

	dev_dbg(amd_manager->dev, "[SDW%d] SDW INT: 0to7=0x%x, 8to11=0x%x\n",
		amd_manager->instance, status_change_0to7, status_change_8to11);
	if (status_change_8to11 & AMD_SDW_WAKE_STAT_MASK)
		return amd_sdw_process_wake_event(amd_manager);

	if (status_change_8to11 & AMD_SDW_PREQ_INTR_STAT) {
		amd_sdw_read_and_process_ping_status(amd_manager);
	} else {
		/* Check for the updated status on peripheral device */
		amd_sdw_update_slave_status(status_change_0to7, status_change_8to11, amd_manager);
	}
	if (status_change_8to11 || status_change_0to7)
		schedule_work(&amd_manager->amd_sdw_work);
	writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
	writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_0TO7);
}

int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager)
{
	struct sdw_master_prop *prop;
	int ret;

	prop = &amd_manager->bus.prop;
	if (!prop->hw_disabled) {
		ret = amd_init_sdw_manager(amd_manager);
		if (ret)
			return ret;
		amd_enable_sdw_interrupts(amd_manager);
		ret = amd_enable_sdw_manager(amd_manager);
		if (ret)
			return ret;
		amd_sdw_set_frameshape(amd_manager);
	}
	/* Enable runtime PM */
	pm_runtime_set_autosuspend_delay(amd_manager->dev, AMD_SDW_MASTER_SUSPEND_DELAY_MS);
	pm_runtime_use_autosuspend(amd_manager->dev);
	pm_runtime_mark_last_busy(amd_manager->dev);
	pm_runtime_set_active(amd_manager->dev);
	pm_runtime_enable(amd_manager->dev);
	return 0;
}

static int amd_sdw_manager_probe(struct platform_device *pdev)
{
	const struct acp_sdw_pdata *pdata = pdev->dev.platform_data;
	struct resource *res;
	struct device *dev = &pdev->dev;
	struct sdw_master_prop *prop;
	struct sdw_bus_params *params;
	struct amd_sdw_manager *amd_manager;
	int ret;

	amd_manager = devm_kzalloc(dev, sizeof(struct amd_sdw_manager), GFP_KERNEL);
	if (!amd_manager)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENOMEM;

	amd_manager->acp_mmio = devm_ioremap(dev, res->start, resource_size(res));
	if (!amd_manager->acp_mmio) {
		dev_err(dev, "mmio not found\n");
		return -ENOMEM;
	}
	amd_manager->instance = pdata->instance;
	amd_manager->mmio = amd_manager->acp_mmio +
			    (amd_manager->instance * SDW_MANAGER_REG_OFFSET);
	amd_manager->acp_sdw_lock = pdata->acp_sdw_lock;
	amd_manager->acp_rev = pdata->acp_rev;
	amd_manager->cols_index = sdw_find_col_index(AMD_SDW_DEFAULT_COLUMNS);
	amd_manager->rows_index = sdw_find_row_index(AMD_SDW_DEFAULT_ROWS);
	amd_manager->dev = dev;
	amd_manager->bus.ops = &amd_sdw_ops;
	amd_manager->bus.port_ops = &amd_sdw_port_ops;
	amd_manager->bus.compute_params = &amd_sdw_compute_params;
	amd_manager->bus.clk_stop_timeout = 200;
	amd_manager->bus.link_id = amd_manager->instance;

	/*
	 * Due to BIOS compatibility, the two links are exposed within
	 * the scope of a single controller. If this changes, the
	 * controller_id will have to be updated with drv_data
	 * information.
	 */
	amd_manager->bus.controller_id = 0;
	dev_dbg(dev, "acp_rev:0x%x\n", amd_manager->acp_rev);
	switch (amd_manager->acp_rev) {
	case ACP63_PCI_REV_ID:
		switch (amd_manager->instance) {
		case ACP_SDW0:
			amd_manager->num_dout_ports = AMD_ACP63_SDW0_MAX_TX_PORTS;
			amd_manager->num_din_ports = AMD_ACP63_SDW0_MAX_RX_PORTS;
			break;
		case ACP_SDW1:
			amd_manager->num_dout_ports = AMD_ACP63_SDW1_MAX_TX_PORTS;
			amd_manager->num_din_ports = AMD_ACP63_SDW1_MAX_RX_PORTS;
			break;
		default:
			return -EINVAL;
		}
		break;
	case ACP70_PCI_REV_ID:
	case ACP71_PCI_REV_ID:
	case ACP72_PCI_REV_ID:
		amd_manager->num_dout_ports = AMD_ACP70_SDW_MAX_TX_PORTS;
		amd_manager->num_din_ports = AMD_ACP70_SDW_MAX_RX_PORTS;
		break;
	default:
		return -EINVAL;
	}

	params = &amd_manager->bus.params;

	params->col = AMD_SDW_DEFAULT_COLUMNS;
	params->row = AMD_SDW_DEFAULT_ROWS;
	prop = &amd_manager->bus.prop;
	prop->clk_freq = &amd_sdw_freq_tbl[0];
	prop->mclk_freq = AMD_SDW_BUS_BASE_FREQ;
	prop->max_clk_freq = AMD_SDW_DEFAULT_CLK_FREQ;

	ret = sdw_bus_master_add(&amd_manager->bus, dev, dev->fwnode);
	if (ret) {
		dev_err(dev, "Failed to register SoundWire manager(%d)\n", ret);
		return ret;
	}
	ret = amd_sdw_register_dais(amd_manager);
	if (ret) {
		dev_err(dev, "CPU DAI registration failed\n");
		sdw_bus_master_delete(&amd_manager->bus);
		return ret;
	}
	dev_set_drvdata(dev, amd_manager);
	INIT_WORK(&amd_manager->amd_sdw_irq_thread, amd_sdw_irq_thread);
	INIT_WORK(&amd_manager->amd_sdw_work, amd_sdw_update_slave_status_work);
	return 0;
}

static void amd_sdw_manager_remove(struct platform_device *pdev)
{
	struct amd_sdw_manager *amd_manager = dev_get_drvdata(&pdev->dev);
	int ret;

	pm_runtime_disable(&pdev->dev);
	cancel_work_sync(&amd_manager->amd_sdw_work);
	amd_disable_sdw_interrupts(amd_manager);
	sdw_bus_master_delete(&amd_manager->bus);
	ret = amd_disable_sdw_manager(amd_manager);
	if (ret)
		dev_err(&pdev->dev, "Failed to disable device (%pe)\n", ERR_PTR(ret));
}

static int amd_sdw_clock_stop(struct amd_sdw_manager *amd_manager)
{
	u32 val;
	int ret;

	ret = sdw_bus_prep_clk_stop(&amd_manager->bus);
	if (ret < 0 && ret != -ENODATA) {
		dev_err(amd_manager->dev, "prepare clock stop failed %d", ret);
		return 0;
	}
	ret = sdw_bus_clk_stop(&amd_manager->bus);
	if (ret < 0 && ret != -ENODATA) {
		dev_err(amd_manager->dev, "bus clock stop failed %d", ret);
		return 0;
	}

	ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL, val,
				 (val & AMD_SDW_CLK_STOP_DONE), ACP_DELAY_US, AMD_SDW_TIMEOUT);
	if (ret) {
		dev_err(amd_manager->dev, "SDW%x clock stop failed\n", amd_manager->instance);
		return 0;
	}

	amd_manager->clk_stopped = true;
	if (amd_manager->wake_en_mask)
		writel(0x01, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));

	dev_dbg(amd_manager->dev, "SDW%x clock stop successful\n", amd_manager->instance);
	return 0;
}

static int amd_sdw_clock_stop_exit(struct amd_sdw_manager *amd_manager)
{
	int ret;
	u32 val;

	if (amd_manager->clk_stopped) {
		val = readl(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
		val |= AMD_SDW_CLK_RESUME_REQ;
		writel(val, amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
		ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL, val,
					 (val & AMD_SDW_CLK_RESUME_DONE), ACP_DELAY_US,
					 AMD_SDW_TIMEOUT);
		if (val & AMD_SDW_CLK_RESUME_DONE) {
			writel(0, amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
			ret = sdw_bus_exit_clk_stop(&amd_manager->bus);
			if (ret < 0)
				dev_err(amd_manager->dev, "bus failed to exit clock stop %d\n",
					ret);
			amd_manager->clk_stopped = false;
		}
	}
	if (amd_manager->clk_stopped) {
		dev_err(amd_manager->dev, "SDW%x clock stop exit failed\n", amd_manager->instance);
		return 0;
	}
	dev_dbg(amd_manager->dev, "SDW%x clock stop exit successful\n", amd_manager->instance);
	return 0;
}

static int amd_resume_child_device(struct device *dev, void *data)
{
	struct sdw_slave *slave = dev_to_sdw_dev(dev);
	int ret;

	if (!slave->probed) {
		dev_dbg(dev, "skipping device, no probed driver\n");
		return 0;
	}
	if (!slave->dev_num_sticky) {
		dev_dbg(dev, "skipping device, never detected on bus\n");
		return 0;
	}
	ret = pm_request_resume(dev);
	if (ret < 0) {
		dev_err(dev, "pm_request_resume failed: %d\n", ret);
		return ret;
	}
	return 0;
}

static int __maybe_unused amd_pm_prepare(struct device *dev)
{
	struct amd_sdw_manager *amd_manager = dev_get_drvdata(dev);
	struct sdw_bus *bus = &amd_manager->bus;
	int ret;

	if (bus->prop.hw_disabled) {
		dev_dbg(bus->dev, "SoundWire manager %d is disabled, ignoring\n",
			bus->link_id);
		return 0;
	}
	/*
	 * When multiple peripheral devices connected over the same link, if SoundWire manager
	 * device is not in runtime suspend state, observed that device alerts are missing
	 * without pm_prepare on AMD platforms in clockstop mode0.
	 */
	if (amd_manager->power_mode_mask) {
		ret = pm_runtime_resume(dev);
		if (ret < 0) {
			dev_err(bus->dev, "pm_runtime_resume failed: %d\n", ret);
			return 0;
		}
	}
	/* To force peripheral devices to system level suspend state, resume the devices
	 * from runtime suspend state first. Without that unable to dispatch the alert
	 * status to peripheral driver during system level resume as they are in runtime
	 * suspend state.
	 */
	ret = device_for_each_child(bus->dev, NULL, amd_resume_child_device);
	if (ret < 0)
		dev_err(dev, "amd_resume_child_device failed: %d\n", ret);
	return 0;
}

static int __maybe_unused amd_suspend(struct device *dev)
{
	struct amd_sdw_manager *amd_manager = dev_get_drvdata(dev);
	struct sdw_bus *bus = &amd_manager->bus;
	int ret;

	if (bus->prop.hw_disabled) {
		dev_dbg(bus->dev, "SoundWire manager %d is disabled, ignoring\n",
			bus->link_id);
		return 0;
	}

	if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) {
		cancel_work_sync(&amd_manager->amd_sdw_work);
		amd_sdw_wake_enable(amd_manager, false);
		if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
			ret = amd_sdw_host_wake_enable(amd_manager, false);
			if (ret)
				return ret;
		}
		ret = amd_sdw_clock_stop(amd_manager);
		if (ret)
			return ret;
	} else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) {
		cancel_work_sync(&amd_manager->amd_sdw_work);
		amd_sdw_wake_enable(amd_manager, false);
		if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
			ret = amd_sdw_host_wake_enable(amd_manager, false);
			if (ret)
				return ret;
		}
		/*
		 * As per hardware programming sequence on AMD platforms,
		 * clock stop should be invoked first before powering-off
		 */
		ret = amd_sdw_clock_stop(amd_manager);
		if (ret)
			return ret;
		ret = amd_deinit_sdw_manager(amd_manager);
		if (ret)
			return ret;
	}
	if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
		ret = amd_sdw_set_device_state(amd_manager, AMD_SDW_DEVICE_STATE_D3);
		if (ret)
			return ret;
	}
	return 0;
}

static int __maybe_unused amd_suspend_runtime(struct device *dev)
{
	struct amd_sdw_manager *amd_manager = dev_get_drvdata(dev);
	struct sdw_bus *bus = &amd_manager->bus;
	int ret;
	u32 val;

	if (bus->prop.hw_disabled) {
		dev_dbg(bus->dev, "SoundWire manager %d is disabled,\n",
			bus->link_id);
		return 0;
	}
	if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) {
		amd_sdw_wake_enable(amd_manager, true);
		if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
			ret = amd_sdw_host_wake_enable(amd_manager, true);
			if (ret)
				return ret;
		}
		ret = amd_sdw_clock_stop(amd_manager);
		if (ret)
			return ret;
	} else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) {
		amd_sdw_wake_enable(amd_manager, true);
		if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
			ret = amd_sdw_host_wake_enable(amd_manager, true);
			if (ret)
				return ret;
		}
		ret = amd_sdw_clock_stop(amd_manager);
		if (ret)
			return ret;
		ret = amd_deinit_sdw_manager(amd_manager);
		if (ret)
			return ret;
	}
	if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
		ret = amd_sdw_set_device_state(amd_manager, AMD_SDW_DEVICE_STATE_D3);
		if (ret)
			return ret;
		if (amd_manager->wake_en_mask) {
			val = readl(amd_manager->acp_mmio + ACP_PME_EN);
			if (!val) {
				writel(1, amd_manager->acp_mmio + ACP_PME_EN);
				val = readl(amd_manager->acp_mmio + ACP_PME_EN);
				dev_dbg(amd_manager->dev, "ACP_PME_EN:0x%x\n", val);
			}
		}
	}
	return 0;
}

static int __maybe_unused amd_resume_runtime(struct device *dev)
{
	struct amd_sdw_manager *amd_manager = dev_get_drvdata(dev);
	struct sdw_bus *bus = &amd_manager->bus;
	int ret;
	u32 val;

	if (bus->prop.hw_disabled) {
		dev_dbg(bus->dev, "SoundWire manager %d is disabled, ignoring\n",
			bus->link_id);
		return 0;
	}

	if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) {
		ret = amd_sdw_clock_stop_exit(amd_manager);
		if (ret)
			return ret;
		if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
			ret = amd_sdw_host_wake_enable(amd_manager, false);
			if (ret)
				return ret;
		}
	} else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) {
		writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));
		if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
			ret = amd_sdw_host_wake_enable(amd_manager, false);
			if (ret)
				return ret;
		}
		val = readl(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
		if (val) {
			val |= AMD_SDW_CLK_RESUME_REQ;
			writel(val, amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
			ret = readl_poll_timeout(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL, val,
						 (val & AMD_SDW_CLK_RESUME_DONE), ACP_DELAY_US,
						 AMD_SDW_TIMEOUT);
			if (val & AMD_SDW_CLK_RESUME_DONE) {
				writel(0, amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
				amd_manager->clk_stopped = false;
			}
		}
		sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
		amd_init_sdw_manager(amd_manager);
		amd_enable_sdw_interrupts(amd_manager);
		ret = amd_enable_sdw_manager(amd_manager);
		if (ret)
			return ret;
		amd_sdw_set_frameshape(amd_manager);
	}
	if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) {
		ret = amd_sdw_set_device_state(amd_manager, AMD_SDW_DEVICE_STATE_D0);
		if (ret)
			return ret;
	}
	return 0;
}

static const struct dev_pm_ops amd_pm = {
	.prepare = amd_pm_prepare,
	SET_SYSTEM_SLEEP_PM_OPS(amd_suspend, amd_resume_runtime)
	SET_RUNTIME_PM_OPS(amd_suspend_runtime, amd_resume_runtime, NULL)
};

static struct platform_driver amd_sdw_driver = {
	.probe	= &amd_sdw_manager_probe,
	.remove = &amd_sdw_manager_remove,
	.driver = {
		.name	= "amd_sdw_manager",
		.pm = &amd_pm,
	}
};
module_platform_driver(amd_sdw_driver);

MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD SoundWire driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("platform:" DRV_NAME);
