xref: /linux/drivers/thunderbolt/clx.c (revision 6093a688a07da07808f0122f9aa2a3eed250d853)
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