summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/tmu.c
diff options
context:
space:
mode:
authorGil Fine <gil.fine@intel.com>2021-12-17 03:16:43 +0200
committerMika Westerberg <mika.westerberg@linux.intel.com>2021-12-28 10:43:56 +0300
commit43f977bc60b1cfd3c1d220a9a0a06493fbf3985d (patch)
treee1dd6423c1c4b1e0defc5454a90f09f041a2b105 /drivers/thunderbolt/tmu.c
parent483c9d8275aff428df433e9d7c718609345500e2 (diff)
thunderbolt: Enable CL0s for Intel Titan Ridge
Low power link states (called collectively CLx) are used to reduce transmitter and receiver power when a high-speed lane is idle. The simplest one being called CL0s. Follow what we already do for USB4 device routers and enable CL0s for Intel Titan Ridge device router too. This allows better thermal management. Signed-off-by: Gil Fine <gil.fine@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/tmu.c')
-rw-r--r--drivers/thunderbolt/tmu.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/drivers/thunderbolt/tmu.c b/drivers/thunderbolt/tmu.c
index 8392d1352c98..e4a07a26f693 100644
--- a/drivers/thunderbolt/tmu.c
+++ b/drivers/thunderbolt/tmu.c
@@ -334,7 +334,12 @@ out:
*/
int tb_switch_tmu_disable(struct tb_switch *sw)
{
- if (!tb_switch_is_usb4(sw))
+ /*
+ * No need to disable TMU on devices that don't support CLx since
+ * on these devices e.g. Alpine Ridge and earlier, the TMU mode
+ * HiFi bi-directional is enabled by default and we don't change it.
+ */
+ if (!tb_switch_is_clx_supported(sw))
return 0;
/* Already disabled? */
@@ -450,6 +455,31 @@ out:
return ret;
}
+static int tb_switch_tmu_objection_mask(struct tb_switch *sw)
+{
+ u32 val;
+ int ret;
+
+ ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
+ sw->cap_vsec_tmu + TB_TIME_VSEC_3_CS_9, 1);
+ if (ret)
+ return ret;
+
+ val &= ~TB_TIME_VSEC_3_CS_9_TMU_OBJ_MASK;
+
+ return tb_sw_write(sw, &val, TB_CFG_SWITCH,
+ sw->cap_vsec_tmu + TB_TIME_VSEC_3_CS_9, 1);
+}
+
+static int tb_switch_tmu_unidirectional_enable(struct tb_switch *sw)
+{
+ struct tb_port *up = tb_upstream_port(sw);
+
+ return tb_port_tmu_write(up, TMU_ADP_CS_6,
+ TMU_ADP_CS_6_DISABLE_TMU_OBJ_MASK,
+ TMU_ADP_CS_6_DISABLE_TMU_OBJ_MASK);
+}
+
/*
* This function is called when the previous TMU mode was
* TB_SWITCH_TMU_RATE_OFF.
@@ -497,12 +527,31 @@ static int tb_switch_tmu_hifi_enable(struct tb_switch *sw)
if (unidirectional && !sw->tmu.has_ucap)
return -EOPNOTSUPP;
- if (!tb_switch_is_usb4(sw))
+ /*
+ * No need to enable TMU on devices that don't support CLx since on
+ * these devices e.g. Alpine Ridge and earlier, the TMU mode HiFi
+ * bi-directional is enabled by default.
+ */
+ if (!tb_switch_is_clx_supported(sw))
return 0;
if (tb_switch_tmu_hifi_is_enabled(sw, sw->tmu.unidirectional_request))
return 0;
+ if (tb_switch_is_titan_ridge(sw) && unidirectional) {
+ /* Titan Ridge supports only CL0s */
+ if (!tb_switch_is_cl0s_enabled(sw))
+ return -EOPNOTSUPP;
+
+ ret = tb_switch_tmu_objection_mask(sw);
+ if (ret)
+ return ret;
+
+ ret = tb_switch_tmu_unidirectional_enable(sw);
+ if (ret)
+ return ret;
+ }
+
ret = tb_switch_tmu_set_time_disruption(sw, true);
if (ret)
return ret;