1 // SPDX-License-Identifier: GPL-2.0
3 * Thunderbolt Time Management Unit (TMU) support
5 * Copyright (C) 2019, Intel Corporation
6 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
7 * Rajmohan Mani <rajmohan.mani@intel.com>
10 #include <linux/delay.h>
14 static const unsigned int tmu_rates
[] = {
15 [TB_SWITCH_TMU_MODE_OFF
] = 0,
16 [TB_SWITCH_TMU_MODE_LOWRES
] = 1000,
17 [TB_SWITCH_TMU_MODE_HIFI_UNI
] = 16,
18 [TB_SWITCH_TMU_MODE_HIFI_BI
] = 16,
19 [TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
] = 16,
23 unsigned int freq_meas_window
;
24 unsigned int avg_const
;
25 unsigned int delta_avg_const
;
26 unsigned int repl_timeout
;
27 unsigned int repl_threshold
;
29 unsigned int dirswitch_n
;
31 [TB_SWITCH_TMU_MODE_OFF
] = { },
32 [TB_SWITCH_TMU_MODE_LOWRES
] = { 30, 4, },
33 [TB_SWITCH_TMU_MODE_HIFI_UNI
] = { 800, 8, },
34 [TB_SWITCH_TMU_MODE_HIFI_BI
] = { 800, 8, },
35 [TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
] = {
36 800, 4, 0, 3125, 25, 128, 255,
40 static const char *tmu_mode_name(enum tb_switch_tmu_mode mode
)
43 case TB_SWITCH_TMU_MODE_OFF
:
45 case TB_SWITCH_TMU_MODE_LOWRES
:
46 return "uni-directional, LowRes";
47 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
48 return "uni-directional, HiFi";
49 case TB_SWITCH_TMU_MODE_HIFI_BI
:
50 return "bi-directional, HiFi";
51 case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
:
52 return "enhanced uni-directional, MedRes";
58 static bool tb_switch_tmu_enhanced_is_supported(const struct tb_switch
*sw
)
60 return usb4_switch_version(sw
) > 1;
63 static int tb_switch_set_tmu_mode_params(struct tb_switch
*sw
,
64 enum tb_switch_tmu_mode mode
)
69 freq
= tmu_params
[mode
].freq_meas_window
;
70 avg
= tmu_params
[mode
].avg_const
;
72 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
73 sw
->tmu
.cap
+ TMU_RTR_CS_0
, 1);
77 val
&= ~TMU_RTR_CS_0_FREQ_WIND_MASK
;
78 val
|= FIELD_PREP(TMU_RTR_CS_0_FREQ_WIND_MASK
, freq
);
80 ret
= tb_sw_write(sw
, &val
, TB_CFG_SWITCH
,
81 sw
->tmu
.cap
+ TMU_RTR_CS_0
, 1);
85 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
86 sw
->tmu
.cap
+ TMU_RTR_CS_15
, 1);
90 val
&= ~TMU_RTR_CS_15_FREQ_AVG_MASK
&
91 ~TMU_RTR_CS_15_DELAY_AVG_MASK
&
92 ~TMU_RTR_CS_15_OFFSET_AVG_MASK
&
93 ~TMU_RTR_CS_15_ERROR_AVG_MASK
;
94 val
|= FIELD_PREP(TMU_RTR_CS_15_FREQ_AVG_MASK
, avg
) |
95 FIELD_PREP(TMU_RTR_CS_15_DELAY_AVG_MASK
, avg
) |
96 FIELD_PREP(TMU_RTR_CS_15_OFFSET_AVG_MASK
, avg
) |
97 FIELD_PREP(TMU_RTR_CS_15_ERROR_AVG_MASK
, avg
);
99 ret
= tb_sw_write(sw
, &val
, TB_CFG_SWITCH
,
100 sw
->tmu
.cap
+ TMU_RTR_CS_15
, 1);
104 if (tb_switch_tmu_enhanced_is_supported(sw
)) {
105 u32 delta_avg
= tmu_params
[mode
].delta_avg_const
;
107 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
108 sw
->tmu
.cap
+ TMU_RTR_CS_18
, 1);
112 val
&= ~TMU_RTR_CS_18_DELTA_AVG_CONST_MASK
;
113 val
|= FIELD_PREP(TMU_RTR_CS_18_DELTA_AVG_CONST_MASK
, delta_avg
);
115 ret
= tb_sw_write(sw
, &val
, TB_CFG_SWITCH
,
116 sw
->tmu
.cap
+ TMU_RTR_CS_18
, 1);
122 static bool tb_switch_tmu_ucap_is_supported(struct tb_switch
*sw
)
127 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
128 sw
->tmu
.cap
+ TMU_RTR_CS_0
, 1);
132 return !!(val
& TMU_RTR_CS_0_UCAP
);
135 static int tb_switch_tmu_rate_read(struct tb_switch
*sw
)
140 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
141 sw
->tmu
.cap
+ TMU_RTR_CS_3
, 1);
145 val
>>= TMU_RTR_CS_3_TS_PACKET_INTERVAL_SHIFT
;
149 static int tb_switch_tmu_rate_write(struct tb_switch
*sw
, int rate
)
154 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
155 sw
->tmu
.cap
+ TMU_RTR_CS_3
, 1);
159 val
&= ~TMU_RTR_CS_3_TS_PACKET_INTERVAL_MASK
;
160 val
|= rate
<< TMU_RTR_CS_3_TS_PACKET_INTERVAL_SHIFT
;
162 return tb_sw_write(sw
, &val
, TB_CFG_SWITCH
,
163 sw
->tmu
.cap
+ TMU_RTR_CS_3
, 1);
166 static int tb_port_tmu_write(struct tb_port
*port
, u8 offset
, u32 mask
,
172 ret
= tb_port_read(port
, &data
, TB_CFG_PORT
, port
->cap_tmu
+ offset
, 1);
179 return tb_port_write(port
, &data
, TB_CFG_PORT
,
180 port
->cap_tmu
+ offset
, 1);
183 static int tb_port_tmu_set_unidirectional(struct tb_port
*port
,
188 if (!port
->sw
->tmu
.has_ucap
)
191 val
= unidirectional
? TMU_ADP_CS_3_UDM
: 0;
192 return tb_port_tmu_write(port
, TMU_ADP_CS_3
, TMU_ADP_CS_3_UDM
, val
);
195 static inline int tb_port_tmu_unidirectional_disable(struct tb_port
*port
)
197 return tb_port_tmu_set_unidirectional(port
, false);
200 static inline int tb_port_tmu_unidirectional_enable(struct tb_port
*port
)
202 return tb_port_tmu_set_unidirectional(port
, true);
205 static bool tb_port_tmu_is_unidirectional(struct tb_port
*port
)
210 ret
= tb_port_read(port
, &val
, TB_CFG_PORT
,
211 port
->cap_tmu
+ TMU_ADP_CS_3
, 1);
215 return val
& TMU_ADP_CS_3_UDM
;
218 static bool tb_port_tmu_is_enhanced(struct tb_port
*port
)
223 ret
= tb_port_read(port
, &val
, TB_CFG_PORT
,
224 port
->cap_tmu
+ TMU_ADP_CS_8
, 1);
228 return val
& TMU_ADP_CS_8_EUDM
;
231 /* Can be called to non-v2 lane adapters too */
232 static int tb_port_tmu_enhanced_enable(struct tb_port
*port
, bool enable
)
237 if (!tb_switch_tmu_enhanced_is_supported(port
->sw
))
240 ret
= tb_port_read(port
, &val
, TB_CFG_PORT
,
241 port
->cap_tmu
+ TMU_ADP_CS_8
, 1);
246 val
|= TMU_ADP_CS_8_EUDM
;
248 val
&= ~TMU_ADP_CS_8_EUDM
;
250 return tb_port_write(port
, &val
, TB_CFG_PORT
,
251 port
->cap_tmu
+ TMU_ADP_CS_8
, 1);
254 static int tb_port_set_tmu_mode_params(struct tb_port
*port
,
255 enum tb_switch_tmu_mode mode
)
257 u32 repl_timeout
, repl_threshold
, repl_n
, dirswitch_n
, val
;
260 repl_timeout
= tmu_params
[mode
].repl_timeout
;
261 repl_threshold
= tmu_params
[mode
].repl_threshold
;
262 repl_n
= tmu_params
[mode
].repl_n
;
263 dirswitch_n
= tmu_params
[mode
].dirswitch_n
;
265 ret
= tb_port_read(port
, &val
, TB_CFG_PORT
,
266 port
->cap_tmu
+ TMU_ADP_CS_8
, 1);
270 val
&= ~TMU_ADP_CS_8_REPL_TIMEOUT_MASK
;
271 val
&= ~TMU_ADP_CS_8_REPL_THRESHOLD_MASK
;
272 val
|= FIELD_PREP(TMU_ADP_CS_8_REPL_TIMEOUT_MASK
, repl_timeout
);
273 val
|= FIELD_PREP(TMU_ADP_CS_8_REPL_THRESHOLD_MASK
, repl_threshold
);
275 ret
= tb_port_write(port
, &val
, TB_CFG_PORT
,
276 port
->cap_tmu
+ TMU_ADP_CS_8
, 1);
280 ret
= tb_port_read(port
, &val
, TB_CFG_PORT
,
281 port
->cap_tmu
+ TMU_ADP_CS_9
, 1);
285 val
&= ~TMU_ADP_CS_9_REPL_N_MASK
;
286 val
&= ~TMU_ADP_CS_9_DIRSWITCH_N_MASK
;
287 val
|= FIELD_PREP(TMU_ADP_CS_9_REPL_N_MASK
, repl_n
);
288 val
|= FIELD_PREP(TMU_ADP_CS_9_DIRSWITCH_N_MASK
, dirswitch_n
);
290 return tb_port_write(port
, &val
, TB_CFG_PORT
,
291 port
->cap_tmu
+ TMU_ADP_CS_9
, 1);
294 /* Can be called to non-v2 lane adapters too */
295 static int tb_port_tmu_rate_write(struct tb_port
*port
, int rate
)
300 if (!tb_switch_tmu_enhanced_is_supported(port
->sw
))
303 ret
= tb_port_read(port
, &val
, TB_CFG_PORT
,
304 port
->cap_tmu
+ TMU_ADP_CS_9
, 1);
308 val
&= ~TMU_ADP_CS_9_ADP_TS_INTERVAL_MASK
;
309 val
|= FIELD_PREP(TMU_ADP_CS_9_ADP_TS_INTERVAL_MASK
, rate
);
311 return tb_port_write(port
, &val
, TB_CFG_PORT
,
312 port
->cap_tmu
+ TMU_ADP_CS_9
, 1);
315 static int tb_port_tmu_time_sync(struct tb_port
*port
, bool time_sync
)
317 u32 val
= time_sync
? TMU_ADP_CS_6_DTS
: 0;
319 return tb_port_tmu_write(port
, TMU_ADP_CS_6
, TMU_ADP_CS_6_DTS
, val
);
322 static int tb_port_tmu_time_sync_disable(struct tb_port
*port
)
324 return tb_port_tmu_time_sync(port
, true);
327 static int tb_port_tmu_time_sync_enable(struct tb_port
*port
)
329 return tb_port_tmu_time_sync(port
, false);
332 static int tb_switch_tmu_set_time_disruption(struct tb_switch
*sw
, bool set
)
334 u32 val
, offset
, bit
;
337 if (tb_switch_is_usb4(sw
)) {
338 offset
= sw
->tmu
.cap
+ TMU_RTR_CS_0
;
339 bit
= TMU_RTR_CS_0_TD
;
341 offset
= sw
->cap_vsec_tmu
+ TB_TIME_VSEC_3_CS_26
;
342 bit
= TB_TIME_VSEC_3_CS_26_TD
;
345 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
, offset
, 1);
354 return tb_sw_write(sw
, &val
, TB_CFG_SWITCH
, offset
, 1);
357 static int tmu_mode_init(struct tb_switch
*sw
)
362 ucap
= tb_switch_tmu_ucap_is_supported(sw
);
364 tb_sw_dbg(sw
, "TMU: supports uni-directional mode\n");
365 enhanced
= tb_switch_tmu_enhanced_is_supported(sw
);
367 tb_sw_dbg(sw
, "TMU: supports enhanced uni-directional mode\n");
369 ret
= tb_switch_tmu_rate_read(sw
);
375 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_OFF
;
378 struct tb_port
*up
= tb_upstream_port(sw
);
380 if (enhanced
&& tb_port_tmu_is_enhanced(up
)) {
381 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
;
382 } else if (ucap
&& tb_port_tmu_is_unidirectional(up
)) {
383 if (tmu_rates
[TB_SWITCH_TMU_MODE_LOWRES
] == rate
)
384 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_LOWRES
;
385 else if (tmu_rates
[TB_SWITCH_TMU_MODE_HIFI_UNI
] == rate
)
386 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_HIFI_UNI
;
388 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_HIFI_BI
;
391 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_HIFI_BI
;
394 /* Update the initial request to match the current mode */
395 sw
->tmu
.mode_request
= sw
->tmu
.mode
;
396 sw
->tmu
.has_ucap
= ucap
;
402 * tb_switch_tmu_init() - Initialize switch TMU structures
403 * @sw: Switch to initialized
405 * This function must be called before other TMU related functions to
406 * makes the internal structures are filled in correctly. Does not
407 * change any hardware configuration.
409 int tb_switch_tmu_init(struct tb_switch
*sw
)
411 struct tb_port
*port
;
414 if (tb_switch_is_icm(sw
))
417 ret
= tb_switch_find_cap(sw
, TB_SWITCH_CAP_TMU
);
421 tb_switch_for_each_port(sw
, port
) {
424 cap
= tb_port_find_cap(port
, TB_PORT_CAP_TIME1
);
429 ret
= tmu_mode_init(sw
);
433 tb_sw_dbg(sw
, "TMU: current mode: %s\n", tmu_mode_name(sw
->tmu
.mode
));
438 * tb_switch_tmu_post_time() - Update switch local time
439 * @sw: Switch whose time to update
441 * Updates switch local time using time posting procedure.
443 int tb_switch_tmu_post_time(struct tb_switch
*sw
)
445 unsigned int post_time_high_offset
, post_time_high
= 0;
446 unsigned int post_local_time_offset
, post_time_offset
;
447 struct tb_switch
*root_switch
= sw
->tb
->root_switch
;
448 u64 hi
, mid
, lo
, local_time
, post_time
;
449 int i
, ret
, retries
= 100;
450 u32 gm_local_time
[3];
455 if (!tb_switch_is_usb4(sw
))
458 /* Need to be able to read the grand master time */
459 if (!root_switch
->tmu
.cap
)
462 ret
= tb_sw_read(root_switch
, gm_local_time
, TB_CFG_SWITCH
,
463 root_switch
->tmu
.cap
+ TMU_RTR_CS_1
,
464 ARRAY_SIZE(gm_local_time
));
468 for (i
= 0; i
< ARRAY_SIZE(gm_local_time
); i
++)
469 tb_sw_dbg(root_switch
, "TMU: local_time[%d]=0x%08x\n", i
,
472 /* Convert to nanoseconds (drop fractional part) */
473 hi
= gm_local_time
[2] & TMU_RTR_CS_3_LOCAL_TIME_NS_MASK
;
474 mid
= gm_local_time
[1];
475 lo
= (gm_local_time
[0] & TMU_RTR_CS_1_LOCAL_TIME_NS_MASK
) >>
476 TMU_RTR_CS_1_LOCAL_TIME_NS_SHIFT
;
477 local_time
= hi
<< 48 | mid
<< 16 | lo
;
479 /* Tell the switch that time sync is disrupted for a while */
480 ret
= tb_switch_tmu_set_time_disruption(sw
, true);
484 post_local_time_offset
= sw
->tmu
.cap
+ TMU_RTR_CS_22
;
485 post_time_offset
= sw
->tmu
.cap
+ TMU_RTR_CS_24
;
486 post_time_high_offset
= sw
->tmu
.cap
+ TMU_RTR_CS_25
;
489 * Write the Grandmaster time to the Post Local Time registers
492 ret
= tb_sw_write(sw
, &local_time
, TB_CFG_SWITCH
,
493 post_local_time_offset
, 2);
498 * Have the new switch update its local time by:
499 * 1) writing 0x1 to the Post Time Low register and 0xffffffff to
500 * Post Time High register.
501 * 2) write 0 to Post Time High register and then wait for
502 * the completion of the post_time register becomes 0.
503 * This means the time has been converged properly.
505 post_time
= 0xffffffff00000001ULL
;
507 ret
= tb_sw_write(sw
, &post_time
, TB_CFG_SWITCH
, post_time_offset
, 2);
511 ret
= tb_sw_write(sw
, &post_time_high
, TB_CFG_SWITCH
,
512 post_time_high_offset
, 1);
518 ret
= tb_sw_read(sw
, &post_time
, TB_CFG_SWITCH
,
519 post_time_offset
, 2);
522 } while (--retries
&& post_time
);
529 tb_sw_dbg(sw
, "TMU: updated local time to %#llx\n", local_time
);
532 tb_switch_tmu_set_time_disruption(sw
, false);
536 static int disable_enhanced(struct tb_port
*up
, struct tb_port
*down
)
541 * Router may already been disconnected so ignore errors on the
544 tb_port_tmu_rate_write(up
, 0);
545 tb_port_tmu_enhanced_enable(up
, false);
547 ret
= tb_port_tmu_rate_write(down
, 0);
550 return tb_port_tmu_enhanced_enable(down
, false);
554 * tb_switch_tmu_disable() - Disable TMU of a switch
555 * @sw: Switch whose TMU to disable
557 * Turns off TMU of @sw if it is enabled. If not enabled does nothing.
559 int tb_switch_tmu_disable(struct tb_switch
*sw
)
561 /* Already disabled? */
562 if (sw
->tmu
.mode
== TB_SWITCH_TMU_MODE_OFF
)
566 struct tb_port
*down
, *up
;
569 down
= tb_switch_downstream_port(sw
);
570 up
= tb_upstream_port(sw
);
572 * In case of uni-directional time sync, TMU handshake is
573 * initiated by upstream router. In case of bi-directional
574 * time sync, TMU handshake is initiated by downstream router.
575 * We change downstream router's rate to off for both uni/bidir
576 * cases although it is needed only for the bi-directional mode.
577 * We avoid changing upstream router's mode since it might
578 * have another downstream router plugged, that is set to
579 * uni-directional mode and we don't want to change it's TMU
582 ret
= tb_switch_tmu_rate_write(sw
, tmu_rates
[TB_SWITCH_TMU_MODE_OFF
]);
586 tb_port_tmu_time_sync_disable(up
);
587 ret
= tb_port_tmu_time_sync_disable(down
);
591 switch (sw
->tmu
.mode
) {
592 case TB_SWITCH_TMU_MODE_LOWRES
:
593 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
594 /* The switch may be unplugged so ignore any errors */
595 tb_port_tmu_unidirectional_disable(up
);
596 ret
= tb_port_tmu_unidirectional_disable(down
);
601 case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
:
602 ret
= disable_enhanced(up
, down
);
611 tb_switch_tmu_rate_write(sw
, tmu_rates
[TB_SWITCH_TMU_MODE_OFF
]);
614 sw
->tmu
.mode
= TB_SWITCH_TMU_MODE_OFF
;
616 tb_sw_dbg(sw
, "TMU: disabled\n");
620 /* Called only when there is failure enabling requested mode */
621 static void tb_switch_tmu_off(struct tb_switch
*sw
)
623 unsigned int rate
= tmu_rates
[TB_SWITCH_TMU_MODE_OFF
];
624 struct tb_port
*down
, *up
;
626 down
= tb_switch_downstream_port(sw
);
627 up
= tb_upstream_port(sw
);
629 * In case of any failure in one of the steps when setting
630 * bi-directional or uni-directional TMU mode, get back to the TMU
631 * configurations in off mode. In case of additional failures in
632 * the functions below, ignore them since the caller shall already
635 tb_port_tmu_time_sync_disable(down
);
636 tb_port_tmu_time_sync_disable(up
);
638 switch (sw
->tmu
.mode_request
) {
639 case TB_SWITCH_TMU_MODE_LOWRES
:
640 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
641 tb_switch_tmu_rate_write(tb_switch_parent(sw
), rate
);
643 case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
:
644 disable_enhanced(up
, down
);
650 /* Always set the rate to 0 */
651 tb_switch_tmu_rate_write(sw
, rate
);
653 tb_switch_set_tmu_mode_params(sw
, sw
->tmu
.mode
);
654 tb_port_tmu_unidirectional_disable(down
);
655 tb_port_tmu_unidirectional_disable(up
);
659 * This function is called when the previous TMU mode was
660 * TB_SWITCH_TMU_MODE_OFF.
662 static int tb_switch_tmu_enable_bidirectional(struct tb_switch
*sw
)
664 struct tb_port
*up
, *down
;
667 up
= tb_upstream_port(sw
);
668 down
= tb_switch_downstream_port(sw
);
670 ret
= tb_port_tmu_unidirectional_disable(up
);
674 ret
= tb_port_tmu_unidirectional_disable(down
);
678 ret
= tb_switch_tmu_rate_write(sw
, tmu_rates
[TB_SWITCH_TMU_MODE_HIFI_BI
]);
682 ret
= tb_port_tmu_time_sync_enable(up
);
686 ret
= tb_port_tmu_time_sync_enable(down
);
693 tb_switch_tmu_off(sw
);
697 /* Only needed for Titan Ridge */
698 static int tb_switch_tmu_disable_objections(struct tb_switch
*sw
)
700 struct tb_port
*up
= tb_upstream_port(sw
);
704 ret
= tb_sw_read(sw
, &val
, TB_CFG_SWITCH
,
705 sw
->cap_vsec_tmu
+ TB_TIME_VSEC_3_CS_9
, 1);
709 val
&= ~TB_TIME_VSEC_3_CS_9_TMU_OBJ_MASK
;
711 ret
= tb_sw_write(sw
, &val
, TB_CFG_SWITCH
,
712 sw
->cap_vsec_tmu
+ TB_TIME_VSEC_3_CS_9
, 1);
716 return tb_port_tmu_write(up
, TMU_ADP_CS_6
,
717 TMU_ADP_CS_6_DISABLE_TMU_OBJ_MASK
,
718 TMU_ADP_CS_6_DISABLE_TMU_OBJ_CL1
|
719 TMU_ADP_CS_6_DISABLE_TMU_OBJ_CL2
);
723 * This function is called when the previous TMU mode was
724 * TB_SWITCH_TMU_MODE_OFF.
726 static int tb_switch_tmu_enable_unidirectional(struct tb_switch
*sw
)
728 struct tb_port
*up
, *down
;
731 up
= tb_upstream_port(sw
);
732 down
= tb_switch_downstream_port(sw
);
733 ret
= tb_switch_tmu_rate_write(tb_switch_parent(sw
),
734 tmu_rates
[sw
->tmu
.mode_request
]);
738 ret
= tb_switch_set_tmu_mode_params(sw
, sw
->tmu
.mode_request
);
742 ret
= tb_port_tmu_unidirectional_enable(up
);
746 ret
= tb_port_tmu_time_sync_enable(up
);
750 ret
= tb_port_tmu_unidirectional_enable(down
);
754 ret
= tb_port_tmu_time_sync_enable(down
);
761 tb_switch_tmu_off(sw
);
766 * This function is called when the previous TMU mode was
767 * TB_SWITCH_TMU_RATE_OFF.
769 static int tb_switch_tmu_enable_enhanced(struct tb_switch
*sw
)
771 unsigned int rate
= tmu_rates
[sw
->tmu
.mode_request
];
772 struct tb_port
*up
, *down
;
775 /* Router specific parameters first */
776 ret
= tb_switch_set_tmu_mode_params(sw
, sw
->tmu
.mode_request
);
780 up
= tb_upstream_port(sw
);
781 down
= tb_switch_downstream_port(sw
);
783 ret
= tb_port_set_tmu_mode_params(up
, sw
->tmu
.mode_request
);
787 ret
= tb_port_tmu_rate_write(up
, rate
);
791 ret
= tb_port_tmu_enhanced_enable(up
, true);
795 ret
= tb_port_set_tmu_mode_params(down
, sw
->tmu
.mode_request
);
799 ret
= tb_port_tmu_rate_write(down
, rate
);
803 ret
= tb_port_tmu_enhanced_enable(down
, true);
810 tb_switch_tmu_off(sw
);
814 static void tb_switch_tmu_change_mode_prev(struct tb_switch
*sw
)
816 unsigned int rate
= tmu_rates
[sw
->tmu
.mode
];
817 struct tb_port
*down
, *up
;
819 down
= tb_switch_downstream_port(sw
);
820 up
= tb_upstream_port(sw
);
822 * In case of any failure in one of the steps when change mode,
823 * get back to the TMU configurations in previous mode.
824 * In case of additional failures in the functions below,
825 * ignore them since the caller shall already report a failure.
827 switch (sw
->tmu
.mode
) {
828 case TB_SWITCH_TMU_MODE_LOWRES
:
829 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
830 tb_port_tmu_set_unidirectional(down
, true);
831 tb_switch_tmu_rate_write(tb_switch_parent(sw
), rate
);
834 case TB_SWITCH_TMU_MODE_HIFI_BI
:
835 tb_port_tmu_set_unidirectional(down
, false);
836 tb_switch_tmu_rate_write(sw
, rate
);
843 tb_switch_set_tmu_mode_params(sw
, sw
->tmu
.mode
);
845 switch (sw
->tmu
.mode
) {
846 case TB_SWITCH_TMU_MODE_LOWRES
:
847 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
848 tb_port_tmu_set_unidirectional(up
, true);
851 case TB_SWITCH_TMU_MODE_HIFI_BI
:
852 tb_port_tmu_set_unidirectional(up
, false);
860 static int tb_switch_tmu_change_mode(struct tb_switch
*sw
)
862 unsigned int rate
= tmu_rates
[sw
->tmu
.mode_request
];
863 struct tb_port
*up
, *down
;
866 up
= tb_upstream_port(sw
);
867 down
= tb_switch_downstream_port(sw
);
869 /* Program the upstream router downstream facing lane adapter */
870 switch (sw
->tmu
.mode_request
) {
871 case TB_SWITCH_TMU_MODE_LOWRES
:
872 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
873 ret
= tb_port_tmu_set_unidirectional(down
, true);
876 ret
= tb_switch_tmu_rate_write(tb_switch_parent(sw
), rate
);
881 case TB_SWITCH_TMU_MODE_HIFI_BI
:
882 ret
= tb_port_tmu_set_unidirectional(down
, false);
885 ret
= tb_switch_tmu_rate_write(sw
, rate
);
891 /* Not allowed to change modes from other than above */
895 ret
= tb_switch_set_tmu_mode_params(sw
, sw
->tmu
.mode_request
);
899 /* Program the new mode and the downstream router lane adapter */
900 switch (sw
->tmu
.mode_request
) {
901 case TB_SWITCH_TMU_MODE_LOWRES
:
902 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
903 ret
= tb_port_tmu_set_unidirectional(up
, true);
908 case TB_SWITCH_TMU_MODE_HIFI_BI
:
909 ret
= tb_port_tmu_set_unidirectional(up
, false);
915 /* Not allowed to change modes from other than above */
919 ret
= tb_port_tmu_time_sync_enable(down
);
923 ret
= tb_port_tmu_time_sync_enable(up
);
930 tb_switch_tmu_change_mode_prev(sw
);
935 * tb_switch_tmu_enable() - Enable TMU on a router
936 * @sw: Router whose TMU to enable
938 * Enables TMU of a router to be in uni-directional Normal/HiFi or
939 * bi-directional HiFi mode. Calling tb_switch_tmu_configure() is
940 * required before calling this function.
942 int tb_switch_tmu_enable(struct tb_switch
*sw
)
946 if (tb_switch_tmu_is_enabled(sw
))
949 if (tb_switch_is_titan_ridge(sw
) &&
950 (sw
->tmu
.mode_request
== TB_SWITCH_TMU_MODE_LOWRES
||
951 sw
->tmu
.mode_request
== TB_SWITCH_TMU_MODE_HIFI_UNI
)) {
952 ret
= tb_switch_tmu_disable_objections(sw
);
957 ret
= tb_switch_tmu_set_time_disruption(sw
, true);
963 * The used mode changes are from OFF to
964 * HiFi-Uni/HiFi-BiDir/Normal-Uni or from Normal-Uni to
967 if (sw
->tmu
.mode
== TB_SWITCH_TMU_MODE_OFF
) {
968 switch (sw
->tmu
.mode_request
) {
969 case TB_SWITCH_TMU_MODE_LOWRES
:
970 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
971 ret
= tb_switch_tmu_enable_unidirectional(sw
);
974 case TB_SWITCH_TMU_MODE_HIFI_BI
:
975 ret
= tb_switch_tmu_enable_bidirectional(sw
);
977 case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
:
978 ret
= tb_switch_tmu_enable_enhanced(sw
);
984 } else if (sw
->tmu
.mode
== TB_SWITCH_TMU_MODE_LOWRES
||
985 sw
->tmu
.mode
== TB_SWITCH_TMU_MODE_HIFI_UNI
||
986 sw
->tmu
.mode
== TB_SWITCH_TMU_MODE_HIFI_BI
) {
987 ret
= tb_switch_tmu_change_mode(sw
);
993 * Host router port configurations are written as
994 * part of configurations for downstream port of the parent
995 * of the child node - see above.
996 * Here only the host router' rate configuration is written.
998 ret
= tb_switch_tmu_rate_write(sw
, tmu_rates
[sw
->tmu
.mode_request
]);
1002 tb_sw_warn(sw
, "TMU: failed to enable mode %s: %d\n",
1003 tmu_mode_name(sw
->tmu
.mode_request
), ret
);
1005 sw
->tmu
.mode
= sw
->tmu
.mode_request
;
1006 tb_sw_dbg(sw
, "TMU: mode set to: %s\n", tmu_mode_name(sw
->tmu
.mode
));
1009 return tb_switch_tmu_set_time_disruption(sw
, false);
1013 * tb_switch_tmu_configure() - Configure the TMU mode
1014 * @sw: Router whose mode to change
1015 * @mode: Mode to configure
1017 * Selects the TMU mode that is enabled when tb_switch_tmu_enable() is
1020 * Returns %0 in success and negative errno otherwise. Specifically
1021 * returns %-EOPNOTSUPP if the requested mode is not possible (not
1022 * supported by the router and/or topology).
1024 int tb_switch_tmu_configure(struct tb_switch
*sw
, enum tb_switch_tmu_mode mode
)
1027 case TB_SWITCH_TMU_MODE_OFF
:
1030 case TB_SWITCH_TMU_MODE_LOWRES
:
1031 case TB_SWITCH_TMU_MODE_HIFI_UNI
:
1032 if (!sw
->tmu
.has_ucap
)
1036 case TB_SWITCH_TMU_MODE_HIFI_BI
:
1039 case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI
: {
1040 const struct tb_switch
*parent_sw
= tb_switch_parent(sw
);
1042 if (!parent_sw
|| !tb_switch_tmu_enhanced_is_supported(parent_sw
))
1044 if (!tb_switch_tmu_enhanced_is_supported(sw
))
1051 tb_sw_warn(sw
, "TMU: unsupported mode %u\n", mode
);
1055 if (sw
->tmu
.mode_request
!= mode
) {
1056 tb_sw_dbg(sw
, "TMU: mode change %s -> %s requested\n",
1057 tmu_mode_name(sw
->tmu
.mode
), tmu_mode_name(mode
));
1058 sw
->tmu
.mode_request
= mode
;