1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Thunderbolt Time Management Unit (TMU) support 4 * 5 * Copyright (C) 2019, Intel Corporation 6 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> 7 * Rajmohan Mani <rajmohan.mani@intel.com> 8 */ 9 10 #include <linux/delay.h> 11 12 #include "tb.h" 13 14 static const char *tb_switch_tmu_mode_name(const struct tb_switch *sw) 15 { 16 bool root_switch = !tb_route(sw); 17 18 switch (sw->tmu.rate) { 19 case TB_SWITCH_TMU_RATE_OFF: 20 return "off"; 21 22 case TB_SWITCH_TMU_RATE_HIFI: 23 /* Root switch does not have upstream directionality */ 24 if (root_switch) 25 return "HiFi"; 26 if (sw->tmu.unidirectional) 27 return "uni-directional, HiFi"; 28 return "bi-directional, HiFi"; 29 30 case TB_SWITCH_TMU_RATE_NORMAL: 31 if (root_switch) 32 return "normal"; 33 return "uni-directional, normal"; 34 35 default: 36 return "unknown"; 37 } 38 } 39 40 static bool tb_switch_tmu_ucap_supported(struct tb_switch *sw) 41 { 42 int ret; 43 u32 val; 44 45 ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, 46 sw->tmu.cap + TMU_RTR_CS_0, 1); 47 if (ret) 48 return false; 49 50 return !!(val & TMU_RTR_CS_0_UCAP); 51 } 52 53 static int tb_switch_tmu_rate_read(struct tb_switch *sw) 54 { 55 int ret; 56 u32 val; 57 58 ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, 59 sw->tmu.cap + TMU_RTR_CS_3, 1); 60 if (ret) 61 return ret; 62 63 val >>= TMU_RTR_CS_3_TS_PACKET_INTERVAL_SHIFT; 64 return val; 65 } 66 67 static int tb_switch_tmu_rate_write(struct tb_switch *sw, int rate) 68 { 69 int ret; 70 u32 val; 71 72 ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, 73 sw->tmu.cap + TMU_RTR_CS_3, 1); 74 if (ret) 75 return ret; 76 77 val &= ~TMU_RTR_CS_3_TS_PACKET_INTERVAL_MASK; 78 val |= rate << TMU_RTR_CS_3_TS_PACKET_INTERVAL_SHIFT; 79 80 return tb_sw_write(sw, &val, TB_CFG_SWITCH, 81 sw->tmu.cap + TMU_RTR_CS_3, 1); 82 } 83 84 static int tb_port_tmu_write(struct tb_port *port, u8 offset, u32 mask, 85 u32 value) 86 { 87 u32 data; 88 int ret; 89 90 ret = tb_port_read(port, &data, TB_CFG_PORT, port->cap_tmu + offset, 1); 91 if (ret) 92 return ret; 93 94 data &= ~mask; 95 data |= value; 96 97 return tb_port_write(port, &data, TB_CFG_PORT, 98 port->cap_tmu + offset, 1); 99 } 100 101 static int tb_port_tmu_set_unidirectional(struct tb_port *port, 102 bool unidirectional) 103 { 104 u32 val; 105 106 if (!port->sw->tmu.has_ucap) 107 return 0; 108 109 val = unidirectional ? TMU_ADP_CS_3_UDM : 0; 110 return tb_port_tmu_write(port, TMU_ADP_CS_3, TMU_ADP_CS_3_UDM, val); 111 } 112 113 static inline int tb_port_tmu_unidirectional_disable(struct tb_port *port) 114 { 115 return tb_port_tmu_set_unidirectional(port, false); 116 } 117 118 static bool tb_port_tmu_is_unidirectional(struct tb_port *port) 119 { 120 int ret; 121 u32 val; 122 123 ret = tb_port_read(port, &val, TB_CFG_PORT, 124 port->cap_tmu + TMU_ADP_CS_3, 1); 125 if (ret) 126 return false; 127 128 return val & TMU_ADP_CS_3_UDM; 129 } 130 131 static int tb_switch_tmu_set_time_disruption(struct tb_switch *sw, bool set) 132 { 133 int ret; 134 u32 val; 135 136 ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, 137 sw->tmu.cap + TMU_RTR_CS_0, 1); 138 if (ret) 139 return ret; 140 141 if (set) 142 val |= TMU_RTR_CS_0_TD; 143 else 144 val &= ~TMU_RTR_CS_0_TD; 145 146 return tb_sw_write(sw, &val, TB_CFG_SWITCH, 147 sw->tmu.cap + TMU_RTR_CS_0, 1); 148 } 149 150 /** 151 * tb_switch_tmu_init() - Initialize switch TMU structures 152 * @sw: Switch to initialized 153 * 154 * This function must be called before other TMU related functions to 155 * makes the internal structures are filled in correctly. Does not 156 * change any hardware configuration. 157 */ 158 int tb_switch_tmu_init(struct tb_switch *sw) 159 { 160 struct tb_port *port; 161 int ret; 162 163 if (tb_switch_is_icm(sw)) 164 return 0; 165 166 ret = tb_switch_find_cap(sw, TB_SWITCH_CAP_TMU); 167 if (ret > 0) 168 sw->tmu.cap = ret; 169 170 tb_switch_for_each_port(sw, port) { 171 int cap; 172 173 cap = tb_port_find_cap(port, TB_PORT_CAP_TIME1); 174 if (cap > 0) 175 port->cap_tmu = cap; 176 } 177 178 ret = tb_switch_tmu_rate_read(sw); 179 if (ret < 0) 180 return ret; 181 182 sw->tmu.rate = ret; 183 184 sw->tmu.has_ucap = tb_switch_tmu_ucap_supported(sw); 185 if (sw->tmu.has_ucap) { 186 tb_sw_dbg(sw, "TMU: supports uni-directional mode\n"); 187 188 if (tb_route(sw)) { 189 struct tb_port *up = tb_upstream_port(sw); 190 191 sw->tmu.unidirectional = 192 tb_port_tmu_is_unidirectional(up); 193 } 194 } else { 195 sw->tmu.unidirectional = false; 196 } 197 198 tb_sw_dbg(sw, "TMU: current mode: %s\n", tb_switch_tmu_mode_name(sw)); 199 return 0; 200 } 201 202 /** 203 * tb_switch_tmu_post_time() - Update switch local time 204 * @sw: Switch whose time to update 205 * 206 * Updates switch local time using time posting procedure. 207 */ 208 int tb_switch_tmu_post_time(struct tb_switch *sw) 209 { 210 unsigned int post_local_time_offset, post_time_offset; 211 struct tb_switch *root_switch = sw->tb->root_switch; 212 u64 hi, mid, lo, local_time, post_time; 213 int i, ret, retries = 100; 214 u32 gm_local_time[3]; 215 216 if (!tb_route(sw)) 217 return 0; 218 219 if (!tb_switch_is_usb4(sw)) 220 return 0; 221 222 /* Need to be able to read the grand master time */ 223 if (!root_switch->tmu.cap) 224 return 0; 225 226 ret = tb_sw_read(root_switch, gm_local_time, TB_CFG_SWITCH, 227 root_switch->tmu.cap + TMU_RTR_CS_1, 228 ARRAY_SIZE(gm_local_time)); 229 if (ret) 230 return ret; 231 232 for (i = 0; i < ARRAY_SIZE(gm_local_time); i++) 233 tb_sw_dbg(root_switch, "local_time[%d]=0x%08x\n", i, 234 gm_local_time[i]); 235 236 /* Convert to nanoseconds (drop fractional part) */ 237 hi = gm_local_time[2] & TMU_RTR_CS_3_LOCAL_TIME_NS_MASK; 238 mid = gm_local_time[1]; 239 lo = (gm_local_time[0] & TMU_RTR_CS_1_LOCAL_TIME_NS_MASK) >> 240 TMU_RTR_CS_1_LOCAL_TIME_NS_SHIFT; 241 local_time = hi << 48 | mid << 16 | lo; 242 243 /* Tell the switch that time sync is disrupted for a while */ 244 ret = tb_switch_tmu_set_time_disruption(sw, true); 245 if (ret) 246 return ret; 247 248 post_local_time_offset = sw->tmu.cap + TMU_RTR_CS_22; 249 post_time_offset = sw->tmu.cap + TMU_RTR_CS_24; 250 251 /* 252 * Write the Grandmaster time to the Post Local Time registers 253 * of the new switch. 254 */ 255 ret = tb_sw_write(sw, &local_time, TB_CFG_SWITCH, 256 post_local_time_offset, 2); 257 if (ret) 258 goto out; 259 260 /* 261 * Have the new switch update its local time (by writing 1 to 262 * the post_time registers) and wait for the completion of the 263 * same (post_time register becomes 0). This means the time has 264 * been converged properly. 265 */ 266 post_time = 1; 267 268 ret = tb_sw_write(sw, &post_time, TB_CFG_SWITCH, post_time_offset, 2); 269 if (ret) 270 goto out; 271 272 do { 273 usleep_range(5, 10); 274 ret = tb_sw_read(sw, &post_time, TB_CFG_SWITCH, 275 post_time_offset, 2); 276 if (ret) 277 goto out; 278 } while (--retries && post_time); 279 280 if (!retries) { 281 ret = -ETIMEDOUT; 282 goto out; 283 } 284 285 tb_sw_dbg(sw, "TMU: updated local time to %#llx\n", local_time); 286 287 out: 288 tb_switch_tmu_set_time_disruption(sw, false); 289 return ret; 290 } 291 292 /** 293 * tb_switch_tmu_disable() - Disable TMU of a switch 294 * @sw: Switch whose TMU to disable 295 * 296 * Turns off TMU of @sw if it is enabled. If not enabled does nothing. 297 */ 298 int tb_switch_tmu_disable(struct tb_switch *sw) 299 { 300 int ret; 301 302 if (!tb_switch_is_usb4(sw)) 303 return 0; 304 305 /* Already disabled? */ 306 if (sw->tmu.rate == TB_SWITCH_TMU_RATE_OFF) 307 return 0; 308 309 if (sw->tmu.unidirectional) { 310 struct tb_switch *parent = tb_switch_parent(sw); 311 struct tb_port *up, *down; 312 313 up = tb_upstream_port(sw); 314 down = tb_port_at(tb_route(sw), parent); 315 316 /* The switch may be unplugged so ignore any errors */ 317 tb_port_tmu_unidirectional_disable(up); 318 ret = tb_port_tmu_unidirectional_disable(down); 319 if (ret) 320 return ret; 321 } 322 323 tb_switch_tmu_rate_write(sw, TB_SWITCH_TMU_RATE_OFF); 324 325 sw->tmu.unidirectional = false; 326 sw->tmu.rate = TB_SWITCH_TMU_RATE_OFF; 327 328 tb_sw_dbg(sw, "TMU: disabled\n"); 329 return 0; 330 } 331 332 /** 333 * tb_switch_tmu_enable() - Enable TMU on a switch 334 * @sw: Switch whose TMU to enable 335 * 336 * Enables TMU of a switch to be in bi-directional, HiFi mode. In this mode 337 * all tunneling should work. 338 */ 339 int tb_switch_tmu_enable(struct tb_switch *sw) 340 { 341 int ret; 342 343 if (!tb_switch_is_usb4(sw)) 344 return 0; 345 346 if (tb_switch_tmu_is_enabled(sw)) 347 return 0; 348 349 ret = tb_switch_tmu_set_time_disruption(sw, true); 350 if (ret) 351 return ret; 352 353 /* Change mode to bi-directional */ 354 if (tb_route(sw) && sw->tmu.unidirectional) { 355 struct tb_switch *parent = tb_switch_parent(sw); 356 struct tb_port *up, *down; 357 358 up = tb_upstream_port(sw); 359 down = tb_port_at(tb_route(sw), parent); 360 361 ret = tb_port_tmu_unidirectional_disable(down); 362 if (ret) 363 return ret; 364 365 ret = tb_switch_tmu_rate_write(sw, TB_SWITCH_TMU_RATE_HIFI); 366 if (ret) 367 return ret; 368 369 ret = tb_port_tmu_unidirectional_disable(up); 370 if (ret) 371 return ret; 372 } else { 373 ret = tb_switch_tmu_rate_write(sw, TB_SWITCH_TMU_RATE_HIFI); 374 if (ret) 375 return ret; 376 } 377 378 sw->tmu.unidirectional = false; 379 sw->tmu.rate = TB_SWITCH_TMU_RATE_HIFI; 380 tb_sw_dbg(sw, "TMU: mode set to: %s\n", tb_switch_tmu_mode_name(sw)); 381 382 return tb_switch_tmu_set_time_disruption(sw, false); 383 } 384