Merge tag 'linux-kselftest-kunit-6.6-rc2' of git://git.kernel.org/pub/scm/linux/kerne...
[linux-2.6-microblaze.git] / drivers / thunderbolt / clx.c
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  * Returns true if any of the given CL states is enabled for @port.
171  */
172 bool tb_port_clx_is_enabled(struct tb_port *port, unsigned int clx)
173 {
174         return !!(tb_port_clx(port) & clx);
175 }
176
177 /**
178  * tb_switch_clx_init() - Initialize router CL states
179  * @sw: Router
180  *
181  * Can be called for any router. Initializes the current CL state by
182  * reading it from the hardware.
183  *
184  * Returns %0 in case of success and negative errno in case of failure.
185  */
186 int tb_switch_clx_init(struct tb_switch *sw)
187 {
188         struct tb_port *up, *down;
189         unsigned int clx, tmp;
190
191         if (tb_switch_is_icm(sw))
192                 return 0;
193
194         if (!tb_route(sw))
195                 return 0;
196
197         if (!tb_switch_clx_is_supported(sw))
198                 return 0;
199
200         up = tb_upstream_port(sw);
201         down = tb_switch_downstream_port(sw);
202
203         clx = tb_port_clx(up);
204         tmp = tb_port_clx(down);
205         if (clx != tmp)
206                 tb_sw_warn(sw, "CLx: inconsistent configuration %#x != %#x\n",
207                            clx, tmp);
208
209         tb_sw_dbg(sw, "CLx: current mode: %s\n", clx_name(clx));
210
211         sw->clx = clx;
212         return 0;
213 }
214
215 static int tb_switch_pm_secondary_resolve(struct tb_switch *sw)
216 {
217         struct tb_port *up, *down;
218         int ret;
219
220         if (!tb_route(sw))
221                 return 0;
222
223         up = tb_upstream_port(sw);
224         down = tb_switch_downstream_port(sw);
225         ret = tb_port_pm_secondary_enable(up);
226         if (ret)
227                 return ret;
228
229         return tb_port_pm_secondary_disable(down);
230 }
231
232 static int tb_switch_mask_clx_objections(struct tb_switch *sw)
233 {
234         int up_port = sw->config.upstream_port_number;
235         u32 offset, val[2], mask_obj, unmask_obj;
236         int ret, i;
237
238         /* Only Titan Ridge of pre-USB4 devices support CLx states */
239         if (!tb_switch_is_titan_ridge(sw))
240                 return 0;
241
242         if (!tb_route(sw))
243                 return 0;
244
245         /*
246          * In Titan Ridge there are only 2 dual-lane Thunderbolt ports:
247          * Port A consists of lane adapters 1,2 and
248          * Port B consists of lane adapters 3,4
249          * If upstream port is A, (lanes are 1,2), we mask objections from
250          * port B (lanes 3,4) and unmask objections from Port A and vice-versa.
251          */
252         if (up_port == 1) {
253                 mask_obj = TB_LOW_PWR_C0_PORT_B_MASK;
254                 unmask_obj = TB_LOW_PWR_C1_PORT_A_MASK;
255                 offset = TB_LOW_PWR_C1_CL1;
256         } else {
257                 mask_obj = TB_LOW_PWR_C1_PORT_A_MASK;
258                 unmask_obj = TB_LOW_PWR_C0_PORT_B_MASK;
259                 offset = TB_LOW_PWR_C3_CL1;
260         }
261
262         ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
263                          sw->cap_lp + offset, ARRAY_SIZE(val));
264         if (ret)
265                 return ret;
266
267         for (i = 0; i < ARRAY_SIZE(val); i++) {
268                 val[i] |= mask_obj;
269                 val[i] &= ~unmask_obj;
270         }
271
272         return tb_sw_write(sw, &val, TB_CFG_SWITCH,
273                            sw->cap_lp + offset, ARRAY_SIZE(val));
274 }
275
276 /**
277  * tb_switch_clx_is_supported() - Is CLx supported on this type of router
278  * @sw: The router to check CLx support for
279  */
280 bool tb_switch_clx_is_supported(const struct tb_switch *sw)
281 {
282         if (!clx_enabled)
283                 return false;
284
285         if (sw->quirks & QUIRK_NO_CLX)
286                 return false;
287
288         /*
289          * CLx is not enabled and validated on Intel USB4 platforms
290          * before Alder Lake.
291          */
292         if (tb_switch_is_tiger_lake(sw))
293                 return false;
294
295         return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw);
296 }
297
298 static bool validate_mask(unsigned int clx)
299 {
300         /* Previous states need to be enabled */
301         if (clx & TB_CL1)
302                 return (clx & TB_CL0S) == TB_CL0S;
303         return true;
304 }
305
306 /**
307  * tb_switch_clx_enable() - Enable CLx on upstream port of specified router
308  * @sw: Router to enable CLx for
309  * @clx: The CLx state to enable
310  *
311  * CLx is enabled only if both sides of the link support CLx, and if both sides
312  * of the link are not configured as two single lane links and only if the link
313  * is not inter-domain link. The complete set of conditions is described in CM
314  * Guide 1.0 section 8.1.
315  *
316  * Returns %0 on success or an error code on failure.
317  */
318 int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx)
319 {
320         bool up_clx_support, down_clx_support;
321         struct tb_switch *parent_sw;
322         struct tb_port *up, *down;
323         int ret;
324
325         if (!clx || sw->clx == clx)
326                 return 0;
327
328         if (!validate_mask(clx))
329                 return -EINVAL;
330
331         parent_sw = tb_switch_parent(sw);
332         if (!parent_sw)
333                 return 0;
334
335         if (!tb_switch_clx_is_supported(parent_sw) ||
336             !tb_switch_clx_is_supported(sw))
337                 return 0;
338
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))
343                 return -EOPNOTSUPP;
344
345         ret = tb_switch_pm_secondary_resolve(sw);
346         if (ret)
347                 return ret;
348
349         up = tb_upstream_port(sw);
350         down = tb_switch_downstream_port(sw);
351
352         up_clx_support = tb_port_clx_supported(up, clx);
353         down_clx_support = tb_port_clx_supported(down, clx);
354
355         tb_port_dbg(up, "CLx: %s %ssupported\n", clx_name(clx),
356                     up_clx_support ? "" : "not ");
357         tb_port_dbg(down, "CLx: %s %ssupported\n", clx_name(clx),
358                     down_clx_support ? "" : "not ");
359
360         if (!up_clx_support || !down_clx_support)
361                 return -EOPNOTSUPP;
362
363         ret = tb_port_clx_enable(up, clx);
364         if (ret)
365                 return ret;
366
367         ret = tb_port_clx_enable(down, clx);
368         if (ret) {
369                 tb_port_clx_disable(up, clx);
370                 return ret;
371         }
372
373         ret = tb_switch_mask_clx_objections(sw);
374         if (ret) {
375                 tb_port_clx_disable(up, clx);
376                 tb_port_clx_disable(down, clx);
377                 return ret;
378         }
379
380         sw->clx |= clx;
381
382         tb_sw_dbg(sw, "CLx: %s enabled\n", clx_name(clx));
383         return 0;
384 }
385
386 /**
387  * tb_switch_clx_disable() - Disable CLx on upstream port of specified router
388  * @sw: Router to disable CLx for
389  *
390  * Disables all CL states of the given router. Can be called on any
391  * router and if the states were not enabled already does nothing.
392  *
393  * Returns the CL states that were disabled or negative errno in case of
394  * failure.
395  */
396 int tb_switch_clx_disable(struct tb_switch *sw)
397 {
398         unsigned int clx = sw->clx;
399         struct tb_port *up, *down;
400         int ret;
401
402         if (!tb_switch_clx_is_supported(sw))
403                 return 0;
404
405         if (!clx)
406                 return 0;
407
408         up = tb_upstream_port(sw);
409         down = tb_switch_downstream_port(sw);
410
411         ret = tb_port_clx_disable(up, clx);
412         if (ret)
413                 return ret;
414
415         ret = tb_port_clx_disable(down, clx);
416         if (ret)
417                 return ret;
418
419         sw->clx = 0;
420
421         tb_sw_dbg(sw, "CLx: %s disabled\n", clx_name(clx));
422         return clx;
423 }