Skip to content

Commit fd4d58d

Browse files
committed
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: Mika Westerberg <mika.westerberg@linux.intel.com>
1 parent d49b4f0 commit fd4d58d

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

drivers/thunderbolt/clx.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,22 @@ MODULE_PARM_DESC(clx, "allow low power states on the high-speed lanes (default:
1717

1818
static const char *clx_name(unsigned int clx)
1919
{
20-
if (!clx)
21-
return "disabled";
22-
23-
if (clx & TB_CL2)
20+
switch (clx) {
21+
case TB_CL0S | TB_CL1 | TB_CL2:
2422
return "CL0s/CL1/CL2";
25-
if (clx & TB_CL1)
23+
case TB_CL1 | TB_CL2:
24+
return "CL1/CL2";
25+
case TB_CL0S | TB_CL2:
26+
return "CL0s/CL2";
27+
case TB_CL0S | TB_CL1:
2628
return "CL0s/CL1";
27-
if (clx & TB_CL0S)
29+
case TB_CL0S:
2830
return "CL0s";
29-
30-
return "unknown";
31+
case 0:
32+
return "disabled";
33+
default:
34+
return "unknown";
35+
}
3136
}
3237

3338
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)
104109
mask |= LANE_ADP_CS_1_CL0S_ENABLE;
105110
if (clx & TB_CL1)
106111
mask |= LANE_ADP_CS_1_CL1_ENABLE;
112+
if (clx & TB_CL2)
113+
mask |= LANE_ADP_CS_1_CL2_ENABLE;
107114

108115
if (!mask)
109116
return -EOPNOTSUPP;
@@ -291,8 +298,6 @@ bool tb_switch_clx_is_supported(const struct tb_switch *sw)
291298
static bool validate_mask(unsigned int clx)
292299
{
293300
/* Previous states need to be enabled */
294-
if (clx & TB_CL2)
295-
return (clx & (TB_CL0S | TB_CL1)) == (TB_CL0S | TB_CL1);
296301
if (clx & TB_CL1)
297302
return (clx & TB_CL0S) == TB_CL0S;
298303
return true;
@@ -331,8 +336,10 @@ int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx)
331336
!tb_switch_clx_is_supported(sw))
332337
return 0;
333338

334-
/* CL2 is not yet supported */
335-
if (clx & TB_CL2)
339+
/* Only support CL2 for v2 routers */
340+
if ((clx & TB_CL2) &&
341+
(usb4_switch_version(parent_sw) < 2 ||
342+
usb4_switch_version(sw) < 2))
336343
return -EOPNOTSUPP;
337344

338345
ret = tb_switch_pm_secondary_resolve(sw);

drivers/thunderbolt/tb.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ static void tb_discover_dp_resources(struct tb *tb)
244244
static int tb_enable_clx(struct tb_switch *sw)
245245
{
246246
struct tb_cm *tcm = tb_priv(sw->tb);
247+
unsigned int clx = TB_CL0S | TB_CL1;
247248
const struct tb_tunnel *tunnel;
248249
int ret;
249250

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

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

0 commit comments

Comments
 (0)