Commit fd4d58d1 authored by Mika Westerberg's avatar Mika Westerberg
Browse files

thunderbolt: Enable CL2 low power state



For USB4 v2 routers we can also enable CL2 which allows better power
savings and thermal management than CL0s and CL1.

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent d49b4f04
Loading
Loading
Loading
Loading
+19 −12
Original line number Diff line number Diff line
@@ -17,18 +17,23 @@ MODULE_PARM_DESC(clx, "allow low power states on the high-speed lanes (default:

static const char *clx_name(unsigned int clx)
{
	if (!clx)
		return "disabled";

	if (clx & TB_CL2)
	switch (clx) {
	case TB_CL0S | TB_CL1 | TB_CL2:
		return "CL0s/CL1/CL2";
	if (clx & TB_CL1)
	case TB_CL1 | TB_CL2:
		return "CL1/CL2";
	case TB_CL0S | TB_CL2:
		return "CL0s/CL2";
	case TB_CL0S | TB_CL1:
		return "CL0s/CL1";
	if (clx & TB_CL0S)
	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)
{
@@ -104,6 +109,8 @@ static int tb_port_clx_set(struct tb_port *port, unsigned int clx, bool enable)
		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;
@@ -291,8 +298,6 @@ bool tb_switch_clx_is_supported(const struct tb_switch *sw)
static bool validate_mask(unsigned int clx)
{
	/* Previous states need to be enabled */
	if (clx & TB_CL2)
		return (clx & (TB_CL0S | TB_CL1)) == (TB_CL0S | TB_CL1);
	if (clx & TB_CL1)
		return (clx & TB_CL0S) == TB_CL0S;
	return true;
@@ -331,8 +336,10 @@ int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx)
	    !tb_switch_clx_is_supported(sw))
		return 0;

	/* CL2 is not yet supported */
	if (clx & TB_CL2)
	/* 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);
+6 −3
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ static void tb_discover_dp_resources(struct tb *tb)
static int tb_enable_clx(struct tb_switch *sw)
{
	struct tb_cm *tcm = tb_priv(sw->tb);
	unsigned int clx = TB_CL0S | TB_CL1;
	const struct tb_tunnel *tunnel;
	int ret;

@@ -275,10 +276,12 @@ static int tb_enable_clx(struct tb_switch *sw)
	}

	/*
	 * CL0s and CL1 are enabled and supported together.
	 * Silently ignore CLx enabling in case CLx is not supported.
	 * Initially try with CL2. If that's not supported by the
	 * topology try with CL0s and CL1 and then give up.
	 */
	ret = tb_switch_clx_enable(sw, TB_CL0S | TB_CL1);
	ret = tb_switch_clx_enable(sw, clx | TB_CL2);
	if (ret == -EOPNOTSUPP)
		ret = tb_switch_clx_enable(sw, clx);
	return ret == -EOPNOTSUPP ? 0 : ret;
}