// SPDX-License-Identifier: GPL-2.0
/*
 * CLx support
 *
 * Copyright (C) 2020 - 2023, Intel Corporation
 * Authors: Gil Fine <gil.fine@intel.com>
 *	    Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/module.h>

#include "tb.h"

static bool clx_enabled = true;
module_param_named(clx, clx_enabled, bool, 0444);
MODULE_PARM_DESC(clx, "allow low power states on the high-speed lanes (default: true)");

static const char *clx_name(unsigned int clx)
{
	switch (clx) {
	case TB_CL0S | TB_CL1 | TB_CL2:
		return "CL0s/CL1/CL2";
	case TB_CL1 | TB_CL2:
		return "CL1/CL2";
	case TB_CL0S | TB_CL2:
		return "CL0s/CL2";
	case TB_CL0S | TB_CL1:
		return "CL0s/CL1";
	case TB_CL0S:
		return "CL0s";
	case 0:
		return "disabled";
	default:
		return "unknown";
	}
}

static int tb_port_pm_secondary_set(struct tb_port *port, bool secondary)
{
	u32 phy;
	int ret;

	ret = tb_port_read(port, &phy, TB_CFG_PORT,
			   port->cap_phy + LANE_ADP_CS_1, 1);
	if (ret)
		return ret;

	if (secondary)
		phy |= LANE_ADP_CS_1_PMS;
	else
		phy &= ~LANE_ADP_CS_1_PMS;

	return tb_port_write(port, &phy, TB_CFG_PORT,
			     port->cap_phy + LANE_ADP_CS_1, 1);
}

static int tb_port_pm_secondary_enable(struct tb_port *port)
{
	return tb_port_pm_secondary_set(port, true);
}

static int tb_port_pm_secondary_disable(struct tb_port *port)
{
	return tb_port_pm_secondary_set(port, false);
}

/* Called for USB4 or Titan Ridge routers only */
static bool tb_port_clx_supported(struct tb_port *port, unsigned int clx)
{
	u32 val, mask = 0;
	bool ret;

	/* Don't enable CLx in case of two single-lane links */
	if (!port->bonded && port->dual_link_port)
		return false;

	/* Don't enable CLx in case of inter-domain link */
	if (port->xdomain)
		return false;

	if (tb_switch_is_usb4(port->sw)) {
		if (!usb4_port_clx_supported(port))
			return false;
	} else if (!tb_lc_is_clx_supported(port)) {
		return false;
	}

	if (clx & TB_CL0S)
		mask |= LANE_ADP_CS_0_CL0S_SUPPORT;
	if (clx & TB_CL1)
		mask |= LANE_ADP_CS_0_CL1_SUPPORT;
	if (clx & TB_CL2)
		mask |= LANE_ADP_CS_0_CL2_SUPPORT;

	ret = tb_port_read(port, &val, TB_CFG_PORT,
			   port->cap_phy + LANE_ADP_CS_0, 1);
	if (ret)
		return false;

	return !!(val & mask);
}

static int tb_port_clx_set(struct tb_port *port, unsigned int clx, bool enable)
{
	u32 phy, mask = 0;
	int ret;

	if (clx & TB_CL0S)
		mask |= LANE_ADP_CS_1_CL0S_ENABLE;
	if (clx & TB_CL1)
		mask |= LANE_ADP_CS_1_CL1_ENABLE;
	if (clx & TB_CL2)
		mask |= LANE_ADP_CS_1_CL2_ENABLE;

	if (!mask)
		return -EOPNOTSUPP;

	ret = tb_port_read(port, &phy, TB_CFG_PORT,
			   port->cap_phy + LANE_ADP_CS_1, 1);
	if (ret)
		return ret;

	if (enable)
		phy |= mask;
	else
		phy &= ~mask;

	return tb_port_write(port, &phy, TB_CFG_PORT,
			     port->cap_phy + LANE_ADP_CS_1, 1);
}

static int tb_port_clx_disable(struct tb_port *port, unsigned int clx)
{
	return tb_port_clx_set(port, clx, false);
}

static int tb_port_clx_enable(struct tb_port *port, unsigned int clx)
{
	return tb_port_clx_set(port, clx, true);
}

static int tb_port_clx(struct tb_port *port)
{
	u32 val;
	int ret;

	if (!tb_port_clx_supported(port, TB_CL0S | TB_CL1 | TB_CL2))
		return 0;

	ret = tb_port_read(port, &val, TB_CFG_PORT,
			   port->cap_phy + LANE_ADP_CS_1, 1);
	if (ret)
		return ret;

	if (val & LANE_ADP_CS_1_CL0S_ENABLE)
		ret |= TB_CL0S;
	if (val & LANE_ADP_CS_1_CL1_ENABLE)
		ret |= TB_CL1;
	if (val & LANE_ADP_CS_1_CL2_ENABLE)
		ret |= TB_CL2;

	return ret;
}

/**
 * tb_port_clx_is_enabled() - Is given CL state enabled
 * @port: USB4 port to check
 * @clx: Mask of CL states to check
 *
 * Returns true if any of the given CL states is enabled for @port.
 */
bool tb_port_clx_is_enabled(struct tb_port *port, unsigned int clx)
{
	return !!(tb_port_clx(port) & clx);
}

/**
 * tb_switch_clx_is_supported() - Is CLx supported on this type of router
 * @sw: The router to check CLx support for
 */
static bool tb_switch_clx_is_supported(const struct tb_switch *sw)
{
	if (!clx_enabled)
		return false;

	if (sw->quirks & QUIRK_NO_CLX)
		return false;

	/*
	 * CLx is not enabled and validated on Intel USB4 platforms
	 * before Alder Lake.
	 */
	if (tb_switch_is_tiger_lake(sw))
		return false;

	return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw);
}

/**
 * tb_switch_clx_init() - Initialize router CL states
 * @sw: Router
 *
 * Can be called for any router. Initializes the current CL state by
 * reading it from the hardware.
 *
 * Returns %0 in case of success and negative errno in case of failure.
 */
int tb_switch_clx_init(struct tb_switch *sw)
{
	struct tb_port *up, *down;
	unsigned int clx, tmp;

	if (tb_switch_is_icm(sw))
		return 0;

	if (!tb_route(sw))
		return 0;

	if (!tb_switch_clx_is_supported(sw))
		return 0;

	up = tb_upstream_port(sw);
	down = tb_switch_downstream_port(sw);

	clx = tb_port_clx(up);
	tmp = tb_port_clx(down);
	if (clx != tmp)
		tb_sw_warn(sw, "CLx: inconsistent configuration %#x != %#x\n",
			   clx, tmp);

	tb_sw_dbg(sw, "CLx: current mode: %s\n", clx_name(clx));

	sw->clx = clx;
	return 0;
}

static int tb_switch_pm_secondary_resolve(struct tb_switch *sw)
{
	struct tb_port *up, *down;
	int ret;

	if (!tb_route(sw))
		return 0;

	up = tb_upstream_port(sw);
	down = tb_switch_downstream_port(sw);
	ret = tb_port_pm_secondary_enable(up);
	if (ret)
		return ret;

	return tb_port_pm_secondary_disable(down);
}

static int tb_switch_mask_clx_objections(struct tb_switch *sw)
{
	int up_port = sw->config.upstream_port_number;
	u32 offset, val[2], mask_obj, unmask_obj;
	int ret, i;

	/* Only Titan Ridge of pre-USB4 devices support CLx states */
	if (!tb_switch_is_titan_ridge(sw))
		return 0;

	if (!tb_route(sw))
		return 0;

	/*
	 * In Titan Ridge there are only 2 dual-lane Thunderbolt ports:
	 * Port A consists of lane adapters 1,2 and
	 * Port B consists of lane adapters 3,4
	 * If upstream port is A, (lanes are 1,2), we mask objections from
	 * port B (lanes 3,4) and unmask objections from Port A and vice-versa.
	 */
	if (up_port == 1) {
		mask_obj = TB_LOW_PWR_C0_PORT_B_MASK;
		unmask_obj = TB_LOW_PWR_C1_PORT_A_MASK;
		offset = TB_LOW_PWR_C1_CL1;
	} else {
		mask_obj = TB_LOW_PWR_C1_PORT_A_MASK;
		unmask_obj = TB_LOW_PWR_C0_PORT_B_MASK;
		offset = TB_LOW_PWR_C3_CL1;
	}

	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
			 sw->cap_lp + offset, ARRAY_SIZE(val));
	if (ret)
		return ret;

	for (i = 0; i < ARRAY_SIZE(val); i++) {
		val[i] |= mask_obj;
		val[i] &= ~unmask_obj;
	}

	return tb_sw_write(sw, &val, TB_CFG_SWITCH,
			   sw->cap_lp + offset, ARRAY_SIZE(val));
}

static bool validate_mask(unsigned int clx)
{
	/* Previous states need to be enabled */
	if (clx & TB_CL1)
		return (clx & TB_CL0S) == TB_CL0S;
	return true;
}

/**
 * tb_switch_clx_enable() - Enable CLx on upstream port of specified router
 * @sw: Router to enable CLx for
 * @clx: The CLx state to enable
 *
 * CLx is enabled only if both sides of the link support CLx, and if both sides
 * of the link are not configured as two single lane links and only if the link
 * is not inter-domain link. The complete set of conditions is described in CM
 * Guide 1.0 section 8.1.
 *
 * Returns %0 on success or an error code on failure.
 */
int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx)
{
	bool up_clx_support, down_clx_support;
	struct tb_switch *parent_sw;
	struct tb_port *up, *down;
	int ret;

	if (!clx || sw->clx == clx)
		return 0;

	if (!validate_mask(clx))
		return -EINVAL;

	parent_sw = tb_switch_parent(sw);
	if (!parent_sw)
		return 0;

	if (!tb_switch_clx_is_supported(parent_sw) ||
	    !tb_switch_clx_is_supported(sw))
		return 0;

	/* Only support CL2 for v2 routers */
	if ((clx & TB_CL2) &&
	    (usb4_switch_version(parent_sw) < 2 ||
	     usb4_switch_version(sw) < 2))
		return -EOPNOTSUPP;

	ret = tb_switch_pm_secondary_resolve(sw);
	if (ret)
		return ret;

	up = tb_upstream_port(sw);
	down = tb_switch_downstream_port(sw);

	up_clx_support = tb_port_clx_supported(up, clx);
	down_clx_support = tb_port_clx_supported(down, clx);

	tb_port_dbg(up, "CLx: %s %ssupported\n", clx_name(clx),
		    up_clx_support ? "" : "not ");
	tb_port_dbg(down, "CLx: %s %ssupported\n", clx_name(clx),
		    down_clx_support ? "" : "not ");

	if (!up_clx_support || !down_clx_support)
		return -EOPNOTSUPP;

	ret = tb_port_clx_enable(up, clx);
	if (ret)
		return ret;

	ret = tb_port_clx_enable(down, clx);
	if (ret) {
		tb_port_clx_disable(up, clx);
		return ret;
	}

	ret = tb_switch_mask_clx_objections(sw);
	if (ret) {
		tb_port_clx_disable(up, clx);
		tb_port_clx_disable(down, clx);
		return ret;
	}

	sw->clx |= clx;

	tb_sw_dbg(sw, "CLx: %s enabled\n", clx_name(clx));
	return 0;
}

/**
 * tb_switch_clx_disable() - Disable CLx on upstream port of specified router
 * @sw: Router to disable CLx for
 *
 * Disables all CL states of the given router. Can be called on any
 * router and if the states were not enabled already does nothing.
 *
 * Returns the CL states that were disabled or negative errno in case of
 * failure.
 */
int tb_switch_clx_disable(struct tb_switch *sw)
{
	unsigned int clx = sw->clx;
	struct tb_port *up, *down;
	int ret;

	if (!tb_switch_clx_is_supported(sw))
		return 0;

	if (!clx)
		return 0;

	if (sw->is_unplugged)
		return clx;

	up = tb_upstream_port(sw);
	down = tb_switch_downstream_port(sw);

	ret = tb_port_clx_disable(up, clx);
	if (ret)
		return ret;

	ret = tb_port_clx_disable(down, clx);
	if (ret)
		return ret;

	sw->clx = 0;

	tb_sw_dbg(sw, "CLx: %s disabled\n", clx_name(clx));
	return clx;
}
