1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * CLx support 4 * 5 * Copyright (C) 2020 - 2023, Intel Corporation 6 * Authors: Gil Fine <gil.fine@intel.com> 7 * Mika Westerberg <mika.westerberg@linux.intel.com> 8 */ 9 10 #include <linux/module.h> 11 12 #include "tb.h" 13 14 static bool clx_enabled = true; 15 module_param_named(clx, clx_enabled, bool, 0444); 16 MODULE_PARM_DESC(clx, "allow low power states on the high-speed lanes (default: true)"); 17 18 static const char *clx_name(unsigned int clx) 19 { 20 switch (clx) { 21 case TB_CL0S | TB_CL1 | TB_CL2: 22 return "CL0s/CL1/CL2"; 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: 28 return "CL0s/CL1"; 29 case TB_CL0S: 30 return "CL0s"; 31 case 0: 32 return "disabled"; 33 default: 34 return "unknown"; 35 } 36 } 37 38 static int tb_port_pm_secondary_set(struct tb_port *port, bool secondary) 39 { 40 u32 phy; 41 int ret; 42 43 ret = tb_port_read(port, &phy, TB_CFG_PORT, 44 port->cap_phy + LANE_ADP_CS_1, 1); 45 if (ret) 46 return ret; 47 48 if (secondary) 49 phy |= LANE_ADP_CS_1_PMS; 50 else 51 phy &= ~LANE_ADP_CS_1_PMS; 52 53 return tb_port_write(port, &phy, TB_CFG_PORT, 54 port->cap_phy + LANE_ADP_CS_1, 1); 55 } 56 57 static int tb_port_pm_secondary_enable(struct tb_port *port) 58 { 59 return tb_port_pm_secondary_set(port, true); 60 } 61 62 static int tb_port_pm_secondary_disable(struct tb_port *port) 63 { 64 return tb_port_pm_secondary_set(port, false); 65 } 66 67 /* Called for USB4 or Titan Ridge routers only */ 68 static bool tb_port_clx_supported(struct tb_port *port, unsigned int clx) 69 { 70 u32 val, mask = 0; 71 bool ret; 72 73 /* Don't enable CLx in case of two single-lane links */ 74 if (!port->bonded && port->dual_link_port) 75 return false; 76 77 /* Don't enable CLx in case of inter-domain link */ 78 if (port->xdomain) 79 return false; 80 81 if (tb_switch_is_usb4(port->sw)) { 82 if (!usb4_port_clx_supported(port)) 83 return false; 84 } else if (!tb_lc_is_clx_supported(port)) { 85 return false; 86 } 87 88 if (clx & TB_CL0S) 89 mask |= LANE_ADP_CS_0_CL0S_SUPPORT; 90 if (clx & TB_CL1) 91 mask |= LANE_ADP_CS_0_CL1_SUPPORT; 92 if (clx & TB_CL2) 93 mask |= LANE_ADP_CS_0_CL2_SUPPORT; 94 95 ret = tb_port_read(port, &val, TB_CFG_PORT, 96 port->cap_phy + LANE_ADP_CS_0, 1); 97 if (ret) 98 return false; 99 100 return !!(val & mask); 101 } 102 103 static int tb_port_clx_set(struct tb_port *port, unsigned int clx, bool enable) 104 { 105 u32 phy, mask = 0; 106 int ret; 107 108 if (clx & TB_CL0S) 109 mask |= LANE_ADP_CS_1_CL0S_ENABLE; 110 if (clx & TB_CL1) 111 mask |= LANE_ADP_CS_1_CL1_ENABLE; 112 if (clx & TB_CL2) 113 mask |= LANE_ADP_CS_1_CL2_ENABLE; 114 115 if (!mask) 116 return -EOPNOTSUPP; 117 118 ret = tb_port_read(port, &phy, TB_CFG_PORT, 119 port->cap_phy + LANE_ADP_CS_1, 1); 120 if (ret) 121 return ret; 122 123 if (enable) 124 phy |= mask; 125 else 126 phy &= ~mask; 127 128 return tb_port_write(port, &phy, TB_CFG_PORT, 129 port->cap_phy + LANE_ADP_CS_1, 1); 130 } 131 132 static int tb_port_clx_disable(struct tb_port *port, unsigned int clx) 133 { 134 return tb_port_clx_set(port, clx, false); 135 } 136 137 static int tb_port_clx_enable(struct tb_port *port, unsigned int clx) 138 { 139 return tb_port_clx_set(port, clx, true); 140 } 141 142 static int tb_port_clx(struct tb_port *port) 143 { 144 u32 val; 145 int ret; 146 147 if (!tb_port_clx_supported(port, TB_CL0S | TB_CL1 | TB_CL2)) 148 return 0; 149 150 ret = tb_port_read(port, &val, TB_CFG_PORT, 151 port->cap_phy + LANE_ADP_CS_1, 1); 152 if (ret) 153 return ret; 154 155 if (val & LANE_ADP_CS_1_CL0S_ENABLE) 156 ret |= TB_CL0S; 157 if (val & LANE_ADP_CS_1_CL1_ENABLE) 158 ret |= TB_CL1; 159 if (val & LANE_ADP_CS_1_CL2_ENABLE) 160 ret |= TB_CL2; 161 162 return ret; 163 } 164 165 /** 166 * tb_port_clx_is_enabled() - Is given CL state enabled 167 * @port: USB4 port to check 168 * @clx: Mask of CL states to check 169 * 170 * Return: %true if any of the given CL states is enabled for @port, 171 * %false otherwise. 172 */ 173 bool tb_port_clx_is_enabled(struct tb_port *port, unsigned int clx) 174 { 175 return !!(tb_port_clx(port) & clx); 176 } 177 178 /** 179 * tb_switch_clx_is_supported() - Is CLx supported on this type of router 180 * @sw: The router to check CLx support for 181 * 182 * Return: %true if CLx is supported, %false otherwise. 183 */ 184 static bool tb_switch_clx_is_supported(const struct tb_switch *sw) 185 { 186 if (!clx_enabled) 187 return false; 188 189 if (sw->quirks & QUIRK_NO_CLX) 190 return false; 191 192 /* 193 * CLx is not enabled and validated on Intel USB4 platforms 194 * before Alder Lake. 195 */ 196 if (tb_switch_is_tiger_lake(sw)) 197 return false; 198 199 return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw); 200 } 201 202 /** 203 * tb_switch_clx_init() - Initialize router CL states 204 * @sw: Router 205 * 206 * Can be called for any router. Initializes the current CL state by 207 * reading it from the hardware. 208 * 209 * Return: %0 on success, negative errno otherwise. 210 */ 211 int tb_switch_clx_init(struct tb_switch *sw) 212 { 213 struct tb_port *up, *down; 214 unsigned int clx, tmp; 215 216 if (tb_switch_is_icm(sw)) 217 return 0; 218 219 if (!tb_route(sw)) 220 return 0; 221 222 if (!tb_switch_clx_is_supported(sw)) 223 return 0; 224 225 up = tb_upstream_port(sw); 226 down = tb_switch_downstream_port(sw); 227 228 clx = tb_port_clx(up); 229 tmp = tb_port_clx(down); 230 if (clx != tmp) 231 tb_sw_warn(sw, "CLx: inconsistent configuration %#x != %#x\n", 232 clx, tmp); 233 234 tb_sw_dbg(sw, "CLx: current mode: %s\n", clx_name(clx)); 235 236 sw->clx = clx; 237 return 0; 238 } 239 240 static int tb_switch_pm_secondary_resolve(struct tb_switch *sw) 241 { 242 struct tb_port *up, *down; 243 int ret; 244 245 if (!tb_route(sw)) 246 return 0; 247 248 up = tb_upstream_port(sw); 249 down = tb_switch_downstream_port(sw); 250 ret = tb_port_pm_secondary_enable(up); 251 if (ret) 252 return ret; 253 254 return tb_port_pm_secondary_disable(down); 255 } 256 257 static int tb_switch_mask_clx_objections(struct tb_switch *sw) 258 { 259 int up_port = sw->config.upstream_port_number; 260 u32 offset, val[2], mask_obj, unmask_obj; 261 int ret, i; 262 263 /* Only Titan Ridge of pre-USB4 devices support CLx states */ 264 if (!tb_switch_is_titan_ridge(sw)) 265 return 0; 266 267 if (!tb_route(sw)) 268 return 0; 269 270 /* 271 * In Titan Ridge there are only 2 dual-lane Thunderbolt ports: 272 * Port A consists of lane adapters 1,2 and 273 * Port B consists of lane adapters 3,4 274 * If upstream port is A, (lanes are 1,2), we mask objections from 275 * port B (lanes 3,4) and unmask objections from Port A and vice-versa. 276 */ 277 if (up_port == 1) { 278 mask_obj = TB_LOW_PWR_C0_PORT_B_MASK; 279 unmask_obj = TB_LOW_PWR_C1_PORT_A_MASK; 280 offset = TB_LOW_PWR_C1_CL1; 281 } else { 282 mask_obj = TB_LOW_PWR_C1_PORT_A_MASK; 283 unmask_obj = TB_LOW_PWR_C0_PORT_B_MASK; 284 offset = TB_LOW_PWR_C3_CL1; 285 } 286 287 ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, 288 sw->cap_lp + offset, ARRAY_SIZE(val)); 289 if (ret) 290 return ret; 291 292 for (i = 0; i < ARRAY_SIZE(val); i++) { 293 val[i] |= mask_obj; 294 val[i] &= ~unmask_obj; 295 } 296 297 return tb_sw_write(sw, &val, TB_CFG_SWITCH, 298 sw->cap_lp + offset, ARRAY_SIZE(val)); 299 } 300 301 static bool validate_mask(unsigned int clx) 302 { 303 /* Previous states need to be enabled */ 304 if (clx & TB_CL1) 305 return (clx & TB_CL0S) == TB_CL0S; 306 return true; 307 } 308 309 /** 310 * tb_switch_clx_enable() - Enable CLx on upstream port of specified router 311 * @sw: Router to enable CLx for 312 * @clx: The CLx state to enable 313 * 314 * CLx is enabled only if both sides of the link support CLx, and if both sides 315 * of the link are not configured as two single lane links and only if the link 316 * is not inter-domain link. The complete set of conditions is described in CM 317 * Guide 1.0 section 8.1. 318 * 319 * Return: %0 on success, negative errno otherwise. 320 */ 321 int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx) 322 { 323 bool up_clx_support, down_clx_support; 324 struct tb_switch *parent_sw; 325 struct tb_port *up, *down; 326 int ret; 327 328 if (!clx || sw->clx == clx) 329 return 0; 330 331 if (!validate_mask(clx)) 332 return -EINVAL; 333 334 parent_sw = tb_switch_parent(sw); 335 if (!parent_sw) 336 return 0; 337 338 if (!tb_switch_clx_is_supported(parent_sw) || 339 !tb_switch_clx_is_supported(sw)) 340 return 0; 341 342 /* Only support CL2 for v2 routers */ 343 if ((clx & TB_CL2) && 344 (usb4_switch_version(parent_sw) < 2 || 345 usb4_switch_version(sw) < 2)) 346 return -EOPNOTSUPP; 347 348 ret = tb_switch_pm_secondary_resolve(sw); 349 if (ret) 350 return ret; 351 352 up = tb_upstream_port(sw); 353 down = tb_switch_downstream_port(sw); 354 355 up_clx_support = tb_port_clx_supported(up, clx); 356 down_clx_support = tb_port_clx_supported(down, clx); 357 358 tb_port_dbg(up, "CLx: %s %ssupported\n", clx_name(clx), 359 up_clx_support ? "" : "not "); 360 tb_port_dbg(down, "CLx: %s %ssupported\n", clx_name(clx), 361 down_clx_support ? "" : "not "); 362 363 if (!up_clx_support || !down_clx_support) 364 return -EOPNOTSUPP; 365 366 ret = tb_port_clx_enable(up, clx); 367 if (ret) 368 return ret; 369 370 ret = tb_port_clx_enable(down, clx); 371 if (ret) { 372 tb_port_clx_disable(up, clx); 373 return ret; 374 } 375 376 ret = tb_switch_mask_clx_objections(sw); 377 if (ret) { 378 tb_port_clx_disable(up, clx); 379 tb_port_clx_disable(down, clx); 380 return ret; 381 } 382 383 sw->clx |= clx; 384 385 tb_sw_dbg(sw, "CLx: %s enabled\n", clx_name(clx)); 386 return 0; 387 } 388 389 /** 390 * tb_switch_clx_disable() - Disable CLx on upstream port of specified router 391 * @sw: Router to disable CLx for 392 * 393 * Disables all CL states of the given router. Can be called on any 394 * router and if the states were not enabled already does nothing. 395 * 396 * Return: CL states that were disabled or negative errno otherwise. 397 */ 398 int tb_switch_clx_disable(struct tb_switch *sw) 399 { 400 unsigned int clx = sw->clx; 401 struct tb_port *up, *down; 402 int ret; 403 404 if (!tb_switch_clx_is_supported(sw)) 405 return 0; 406 407 if (!clx) 408 return 0; 409 410 if (sw->is_unplugged) 411 return clx; 412 413 up = tb_upstream_port(sw); 414 down = tb_switch_downstream_port(sw); 415 416 ret = tb_port_clx_disable(up, clx); 417 if (ret) 418 return ret; 419 420 ret = tb_port_clx_disable(down, clx); 421 if (ret) 422 return ret; 423 424 sw->clx = 0; 425 426 tb_sw_dbg(sw, "CLx: %s disabled\n", clx_name(clx)); 427 return clx; 428 } 429