/* SPDX-License-Identifier: GPL-2.0-or-later */

#define __SIMPLE_DEVICE__

#include <bootmode.h>
#include <console/console.h>
#include <device/pci.h>
#include <intelblocks/p2sb.h>
#include <intelblocks/pcr.h>
#include <intelblocks/pmc_ipc.h>
#include <intelblocks/systemagent.h>
#include <intelblocks/tcss.h>
#include <inttypes.h>
#include <lib.h>
#include <security/vboot/vboot_common.h>
#include <soc/pci_devs.h>
#include <soc/pcr_ids.h>
#include <soc/tcss.h>
#include <drivers/intel/pmc_mux/conn/chip.h>

#define BIAS_CTRL_VW_INDEX_SHIFT		16
#define BIAS_CTRL_BIT_POS_SHIFT			8
#define WAIT_FOR_DISPLAYPORT_TIMEOUT_MS		1000
#define WAIT_FOR_DP_MODE_ENTRY_TIMEOUT_MS	500
#define WAIT_FOR_HPD_TIMEOUT_MS			3000

static uint32_t tcss_make_conn_cmd(int u, int u3, int u2, int ufp, int hsl,
					int sbu, int acc)
{
	return TCSS_CD_FIELD(USAGE, u) |
		TCSS_CD_FIELD(USB3, u3) |
		TCSS_CD_FIELD(USB2, u2) |
		TCSS_CD_FIELD(UFP, ufp) |
		TCSS_CD_FIELD(HSL, hsl) |
		TCSS_CD_FIELD(SBU, sbu) |
		TCSS_CD_FIELD(ACC, acc);
}

static uint32_t tcss_make_alt_mode_cmd_buf_0(int u, int u3, int m)
{
	return TCSS_ALT_FIELD(USAGE, u) |
		TCSS_ALT_FIELD(USB3, u3) |
		TCSS_ALT_FIELD(MODE, m);
}

static uint32_t tcss_make_alt_mode_cmd_buf_1(int p, int c, int ufp, int dp)
{
	return TCSS_ALT_FIELD(POLARITY, p) |
		TCSS_ALT_FIELD(CABLE, c) |
		TCSS_ALT_FIELD(UFP, ufp) |
		TCSS_ALT_FIELD(DP_MODE, dp);
}

static uint32_t tcss_make_safe_mode_cmd(int u, int u3)
{
	return TCSS_CD_FIELD(USAGE, u) |
		TCSS_CD_FIELD(USB3, u3);
}


static uint32_t tcss_make_hpd_mode_cmd(int u, int u3, int hpd_lvl, int hpd_irq)
{
	return TCSS_HPD_FIELD(USAGE, u) |
		TCSS_HPD_FIELD(USB3, u3) |
		TCSS_HPD_FIELD(LVL, hpd_lvl) |
		TCSS_HPD_FIELD(IRQ, hpd_irq);
}

static int send_pmc_req(int cmd_type, const struct pmc_ipc_buffer *req,
			struct pmc_ipc_buffer *res, uint32_t size)
{
	uint32_t cmd_reg;
	uint32_t res_reg;
	int tries = 2;
	int r;

	cmd_reg = pmc_make_ipc_cmd(PMC_IPC_USBC_CMD_ID, PMC_IPC_USBC_SUBCMD_ID,
				   size);

	printk(BIOS_DEBUG, "Raw Buffer output 0 %08" PRIx32 "\n", req->buf[0]);
	printk(BIOS_DEBUG, "Raw Buffer output 1 %08" PRIx32 "\n", req->buf[1]);

	do {
		r = pmc_send_ipc_cmd(cmd_reg, req, res);
		if (r < 0) {
			printk(BIOS_ERR, "pmc_send_ipc_cmd failed\n");
			return -1;
		}

		res_reg = res->buf[0];
		if (cmd_type == CONNECT_REQ) {
			if (!TCSS_CONN_STATUS_HAS_FAILED(res_reg)) {
				printk(BIOS_DEBUG, "pmc_send_ipc_cmd succeeded\n");
				return 0;
			}

			if (TCSS_CONN_STATUS_IS_FATAL(res_reg)) {
				printk(BIOS_ERR, "pmc_send_ipc_cmd status: fatal\n");
				return -1;
			}
		} else {
			if (!TCSS_STATUS_HAS_FAILED(res_reg)) {
				printk(BIOS_DEBUG, "pmc_send_ipc_cmd succeeded\n");
				return 0;
			}

			if (TCSS_STATUS_IS_FATAL(res_reg)) {
				printk(BIOS_ERR, "pmc_send_ipc_cmd status: fatal\n");
				return -1;
			}
		}
	} while (--tries >= 0);

	printk(BIOS_ERR, "pmc_send_ipc_cmd failed after retries\n");
	return -1;
}

static int send_pmc_disconnect_request(int port, const struct tcss_port_map *port_map)
{
	uint32_t cmd;
	struct pmc_ipc_buffer req = { 0 };
	struct pmc_ipc_buffer rsp;

	cmd = tcss_make_conn_cmd(PMC_IPC_TCSS_DISC_REQ_RES, port_map->usb3_port,
				port_map->usb2_port, 0, 0, 0, 0);

	req.buf[0] = cmd;

	printk(BIOS_DEBUG, "port C%d DISC req: usage %d usb3 %d usb2 %d\n",
		port,
		GET_TCSS_CD_FIELD(USAGE, cmd),
		GET_TCSS_CD_FIELD(USB3, cmd),
		GET_TCSS_CD_FIELD(USB2, cmd));

	return send_pmc_req(CONNECT_REQ, &req, &rsp, PMC_IPC_DISC_REQ_SIZE);
}

static int send_pmc_connect_request(int port, const struct usbc_mux_info *mux_data,
					const struct tcss_port_map *port_map)
{
	uint32_t cmd;
	struct pmc_ipc_buffer req = { 0 };
	struct pmc_ipc_buffer rsp;

	cmd = tcss_make_conn_cmd(
		PMC_IPC_TCSS_CONN_REQ_RES,
		port_map->usb3_port,
		port_map->usb2_port,
		mux_data->ufp,
		mux_data->polarity,
		mux_data->polarity,
		mux_data->dbg_acc);

	req.buf[0] = cmd;

	printk(BIOS_DEBUG, "port C%d CONN req: usage %d usb3 %d usb2 %d "
	      "ufp %d ori_hsl %d ori_sbu %d dbg_acc %d\n",
	      port,
	      GET_TCSS_CD_FIELD(USAGE, cmd),
	      GET_TCSS_CD_FIELD(USB3, cmd),
	      GET_TCSS_CD_FIELD(USB2, cmd),
	      GET_TCSS_CD_FIELD(UFP, cmd),
	      GET_TCSS_CD_FIELD(HSL, cmd),
	      GET_TCSS_CD_FIELD(SBU, cmd),
	      GET_TCSS_CD_FIELD(ACC, cmd));

	return send_pmc_req(CONNECT_REQ, &req, &rsp, PMC_IPC_CONN_REQ_SIZE);
}

static int send_pmc_safe_mode_request(int port, const struct usbc_mux_info *mux_data,
					const struct tcss_port_map *port_map)
{
	uint32_t cmd;
	struct pmc_ipc_buffer req = { 0 };
	struct pmc_ipc_buffer rsp;

	cmd = tcss_make_safe_mode_cmd(PMC_IPC_TCSS_SAFE_MODE_REQ_RES, port_map->usb3_port);

	req.buf[0] = cmd;

	printk(BIOS_DEBUG, "port C%d SAFE req: usage %d usb3 %d\n",
		port,
		GET_TCSS_CD_FIELD(USAGE, cmd),
		GET_TCSS_CD_FIELD(USB3, cmd));

	return send_pmc_req(SAFE_REQ, &req, &rsp, PMC_IPC_SAFE_REQ_SIZE);
}

static int send_pmc_dp_hpd_request(int port, const struct usbc_mux_info *mux_data,
					const struct tcss_port_map *port_map)
{
	struct pmc_ipc_buffer req = { 0 };
	struct pmc_ipc_buffer rsp;
	uint32_t cmd;

	cmd = tcss_make_hpd_mode_cmd(
		PMC_IPC_TCSS_HPD_REQ_RES,
		port_map->usb3_port,
		mux_data->hpd_lvl,
		mux_data->hpd_irq);

	req.buf[0] = cmd;

	return send_pmc_req(HPD_REQ, &req, &rsp, PMC_IPC_HPD_REQ_SIZE);
}

static uint8_t get_dp_mode(uint8_t dp_pin_mode)
{
	switch (dp_pin_mode) {
	case MODE_DP_PIN_A:
	case MODE_DP_PIN_B:
	case MODE_DP_PIN_C:
	case MODE_DP_PIN_D:
	case MODE_DP_PIN_E:
	case MODE_DP_PIN_F:
		return log2(dp_pin_mode) + 1;
	default:
		return 0;
	}
}

static int send_pmc_dp_mode_request(int port, const struct usbc_mux_info *mux_data,
					const struct tcss_port_map *port_map)
{
	uint32_t cmd;
	uint8_t dp_mode;
	int ret;

	struct pmc_ipc_buffer req = { 0 };
	struct pmc_ipc_buffer rsp;

	cmd = tcss_make_alt_mode_cmd_buf_0(
		PMC_IPC_TCSS_ALTMODE_REQ_RES,
		port_map->usb3_port,
		PMC_IPC_DP_MODE);

	req.buf[0] = cmd;

	printk(BIOS_DEBUG, "port C%d ALT_1 req: usage %d usb3 %d dp_mode %d\n",
		port,
		GET_TCSS_ALT_FIELD(USAGE, cmd),
		GET_TCSS_ALT_FIELD(USB3, cmd),
		GET_TCSS_ALT_FIELD(MODE, cmd));

	dp_mode = get_dp_mode(mux_data->dp_pin_mode);
	cmd = tcss_make_alt_mode_cmd_buf_1(
		mux_data->polarity,
		mux_data->cable,
		0, /* ufp is not supported in DP ALT Mode request */
		dp_mode);

	printk(BIOS_DEBUG, "port C%d ALT_2 req: polarity %d cable %d ufp %d "
				"dp_mode %d\n",
		port,
		GET_TCSS_ALT_FIELD(POLARITY, cmd),
		GET_TCSS_ALT_FIELD(CABLE, cmd),
		GET_TCSS_ALT_FIELD(UFP, cmd),
		GET_TCSS_ALT_FIELD(DP_MODE, cmd));

	req.buf[1] = cmd;

	ret = send_pmc_req(DP_REQ, &req, &rsp, PMC_IPC_ALT_REQ_SIZE);
	if (ret)
		return ret;

	send_pmc_dp_hpd_request(port, mux_data, port_map);
	return 0;
}

static void disconnect_tcss_devices(int port, const struct tcss_port_map *port_map)
{
	int ret;

	ret = send_pmc_disconnect_request(port, port_map);
	if (ret)
		printk(BIOS_ERR, "Failed to setup port:%d to initial state\n", port);
}

static void tcss_configure_dp_mode(const struct tcss_port_map *port_map, size_t num_ports)
{
	int ret, port_bitmask;
	size_t i;
	const struct usbc_ops *ops;
	struct usbc_mux_info mux_info;
	const struct tcss_port_map *port_info;

	if (!display_init_required())
		return;

	ops = usbc_get_ops();
	if (ops == NULL)
		return;

	port_bitmask = ops->dp_ops.wait_for_connection(WAIT_FOR_DISPLAYPORT_TIMEOUT_MS);
	if (!port_bitmask)	/* No DP device is connected */
		return;

	for (i = 0; i < num_ports; i++) {
		if (!(port_bitmask & BIT(i)))
			continue;

		ret = ops->dp_ops.enter_dp_mode(i);
		if (ret < 0)
			continue;

		ret = ops->dp_ops.wait_for_dp_mode_entry(i, WAIT_FOR_DP_MODE_ENTRY_TIMEOUT_MS);
		if (ret < 0)
			continue;

		ret = ops->dp_ops.wait_for_hpd(i, WAIT_FOR_HPD_TIMEOUT_MS);
		if (ret < 0)
			continue;

		ret = ops->mux_ops.get_mux_info(i, &mux_info);
		if (ret < 0)
			continue;

		port_info = &port_map[i];

		ret = send_pmc_connect_request(i, &mux_info, port_info);
		if (ret) {
			printk(BIOS_ERR, "Port %zu connect request failed\n", i);
			continue;
		}
		ret = send_pmc_safe_mode_request(i, &mux_info, port_info);
		if (ret) {
			printk(BIOS_ERR, "Port %zu safe mode request failed\n", i);
			continue;
		}

		ret = send_pmc_dp_mode_request(i, &mux_info, port_info);
		if (ret) {
			printk(BIOS_ERR, "Port C%zu mux set failed with error %d\n", i, ret);
		} else {
			printk(BIOS_INFO, "Port C%zu is configured to DP mode!\n", i);
			return;
		}
	}
}

static void tcss_configure_usb_mode(const struct tcss_port_map *port_map, size_t num_ports)
{
	int ret;
	size_t i;
	const struct usbc_ops *ops;
	struct usbc_mux_info mux_info;
	const struct tcss_port_map *port_info;

	ops = usbc_get_ops();
	if (ops == NULL)
		return;

	for (i = 0; i < num_ports; i++) {
		ret = ops->mux_ops.get_mux_info(i, &mux_info);
		if ((ret < 0) || !mux_info.usb || (mux_info.dp && mux_info.hpd_lvl))
			continue;

		port_info = &port_map[i];
		ret = send_pmc_connect_request(i, &mux_info, port_info);
		if (ret) {
			printk(BIOS_ERR, "Port %zu connect request failed\n", i);
			continue;
		}
	}
}

static uint32_t calc_bias_ctrl_reg_value(gpio_t pad)
{
	unsigned int vw_index, vw_bit;
	const unsigned int cpu_pid = gpio_get_pad_cpu_portid(pad);
	if (!gpio_get_vw_info(pad, &vw_index, &vw_bit) || !cpu_pid)
		return 0;

	return vw_index << BIAS_CTRL_VW_INDEX_SHIFT |
		vw_bit << BIAS_CTRL_BIT_POS_SHIFT |
		cpu_pid;
}

void tcss_configure_aux_bias_pads_regbar(
	const struct typec_aux_bias_pads *pads)
{
	for (size_t i = 0; i < MAX_TYPE_C_PORTS; i++) {
		if (pads[i].pad_auxn_dc && pads[i].pad_auxp_dc) {
			REGBAR32(PID_IOM, IOM_AUX_BIAS_CTRL_PULLUP_OFFSET(i)) =
				calc_bias_ctrl_reg_value(pads[i].pad_auxp_dc);
			REGBAR32(PID_IOM, IOM_AUX_BIAS_CTRL_PULLDOWN_OFFSET(i)) =
				calc_bias_ctrl_reg_value(pads[i].pad_auxn_dc);
		}
	}
}

void ioe_tcss_configure_aux_bias_pads_sbi(
	const struct typec_aux_bias_pads *pads)
{
	for (size_t i = 0; i < MAX_TYPE_C_PORTS; i++) {
		if (pads[i].pad_auxn_dc && pads[i].pad_auxp_dc) {
			ioe_p2sb_sbi_write(PID_IOM, IOM_AUX_BIAS_CTRL_PULLUP_OFFSET(i),
				calc_bias_ctrl_reg_value(pads[i].pad_auxp_dc));
			ioe_p2sb_sbi_write(PID_IOM, IOM_AUX_BIAS_CTRL_PULLDOWN_OFFSET(i),
				calc_bias_ctrl_reg_value(pads[i].pad_auxn_dc));
		}
	}
}

const struct tcss_port_map *tcss_get_port_info(size_t *num_ports)
{
	static struct tcss_port_map port_map[MAX_TYPE_C_PORTS];
	size_t active_ports = 0;
	size_t port;

	for (port = 0; port < MAX_TYPE_C_PORTS; port++) {
		const struct device_path conn_path[] = {
			{.type = DEVICE_PATH_PCI, .pci.devfn = PCH_DEVFN_PMC},
			{.type = DEVICE_PATH_GENERIC, .generic.id = 0, .generic.subid = 0},
			{.type = DEVICE_PATH_GENERIC, .generic.id = port},
		};
		const struct device *conn = find_dev_nested_path(pci_root_bus(), conn_path,
								ARRAY_SIZE(conn_path));
		unsigned int usb2_port, usb3_port;

		if (!is_dev_enabled(conn))
			continue;

		if (CONFIG(DRIVERS_INTEL_PMC) &&
			intel_pmc_mux_conn_get_ports(conn, &usb2_port, &usb3_port)) {
			port_map[active_ports].usb2_port = usb2_port;
			port_map[active_ports].usb3_port = usb3_port;
			++active_ports;
		}
	}

	*num_ports = active_ports;
	return port_map;
}

void tcss_configure(const struct typec_aux_bias_pads aux_bias_pads[MAX_TYPE_C_PORTS])
{
	const struct tcss_port_map *port_map;
	size_t num_ports;
	size_t i;

	port_map = tcss_get_port_info(&num_ports);
	if ((port_map == NULL) || platform_is_resuming())
		return;

	if (CONFIG(TCSS_HAS_USBC_OPS))
		for (i = 0; i < num_ports; i++)
			disconnect_tcss_devices(i, &port_map[i]);

	/* This should be performed before alternate modes are entered */
	if (tcss_ops.configure_aux_bias_pads)
		tcss_ops.configure_aux_bias_pads(aux_bias_pads);

	if (CONFIG(ENABLE_TCSS_DISPLAY_DETECTION))
		tcss_configure_dp_mode(port_map, num_ports);

	if (CONFIG(ENABLE_TCSS_USB_DETECTION))
		tcss_configure_usb_mode(port_map, num_ports);
}

bool tcss_valid_tbt_auth(void)
{
	return REGBAR32(PID_IOM, IOM_CSME_IMR_TBT_STATUS) & TBT_VALID_AUTHENTICATION;
}
