tmu.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  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. #include <linux/delay.h>
  10. #include "tb.h"
  11. static const unsigned int tmu_rates[] = {
  12. [TB_SWITCH_TMU_MODE_OFF] = 0,
  13. [TB_SWITCH_TMU_MODE_LOWRES] = 1000,
  14. [TB_SWITCH_TMU_MODE_HIFI_UNI] = 16,
  15. [TB_SWITCH_TMU_MODE_HIFI_BI] = 16,
  16. [TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI] = 16,
  17. };
  18. static const struct {
  19. unsigned int freq_meas_window;
  20. unsigned int avg_const;
  21. unsigned int delta_avg_const;
  22. unsigned int repl_timeout;
  23. unsigned int repl_threshold;
  24. unsigned int repl_n;
  25. unsigned int dirswitch_n;
  26. } tmu_params[] = {
  27. [TB_SWITCH_TMU_MODE_OFF] = { },
  28. [TB_SWITCH_TMU_MODE_LOWRES] = { 30, 4, },
  29. [TB_SWITCH_TMU_MODE_HIFI_UNI] = { 800, 8, },
  30. [TB_SWITCH_TMU_MODE_HIFI_BI] = { 800, 8, },
  31. [TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI] = {
  32. 800, 4, 0, 3125, 25, 128, 255,
  33. },
  34. };
  35. static const char *tmu_mode_name(enum tb_switch_tmu_mode mode)
  36. {
  37. switch (mode) {
  38. case TB_SWITCH_TMU_MODE_OFF:
  39. return "off";
  40. case TB_SWITCH_TMU_MODE_LOWRES:
  41. return "uni-directional, LowRes";
  42. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  43. return "uni-directional, HiFi";
  44. case TB_SWITCH_TMU_MODE_HIFI_BI:
  45. return "bi-directional, HiFi";
  46. case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI:
  47. return "enhanced uni-directional, MedRes";
  48. default:
  49. return "unknown";
  50. }
  51. }
  52. static bool tb_switch_tmu_enhanced_is_supported(const struct tb_switch *sw)
  53. {
  54. return usb4_switch_version(sw) > 1;
  55. }
  56. static int tb_switch_set_tmu_mode_params(struct tb_switch *sw,
  57. enum tb_switch_tmu_mode mode)
  58. {
  59. u32 freq, avg, val;
  60. int ret;
  61. freq = tmu_params[mode].freq_meas_window;
  62. avg = tmu_params[mode].avg_const;
  63. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  64. sw->tmu.cap + TMU_RTR_CS_0, 1);
  65. if (ret)
  66. return ret;
  67. val &= ~TMU_RTR_CS_0_FREQ_WIND_MASK;
  68. val |= FIELD_PREP(TMU_RTR_CS_0_FREQ_WIND_MASK, freq);
  69. ret = tb_sw_write(sw, &val, TB_CFG_SWITCH,
  70. sw->tmu.cap + TMU_RTR_CS_0, 1);
  71. if (ret)
  72. return ret;
  73. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  74. sw->tmu.cap + TMU_RTR_CS_15, 1);
  75. if (ret)
  76. return ret;
  77. val &= ~TMU_RTR_CS_15_FREQ_AVG_MASK &
  78. ~TMU_RTR_CS_15_DELAY_AVG_MASK &
  79. ~TMU_RTR_CS_15_OFFSET_AVG_MASK &
  80. ~TMU_RTR_CS_15_ERROR_AVG_MASK;
  81. val |= FIELD_PREP(TMU_RTR_CS_15_FREQ_AVG_MASK, avg) |
  82. FIELD_PREP(TMU_RTR_CS_15_DELAY_AVG_MASK, avg) |
  83. FIELD_PREP(TMU_RTR_CS_15_OFFSET_AVG_MASK, avg) |
  84. FIELD_PREP(TMU_RTR_CS_15_ERROR_AVG_MASK, avg);
  85. ret = tb_sw_write(sw, &val, TB_CFG_SWITCH,
  86. sw->tmu.cap + TMU_RTR_CS_15, 1);
  87. if (ret)
  88. return ret;
  89. if (tb_switch_tmu_enhanced_is_supported(sw)) {
  90. u32 delta_avg = tmu_params[mode].delta_avg_const;
  91. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  92. sw->tmu.cap + TMU_RTR_CS_18, 1);
  93. if (ret)
  94. return ret;
  95. val &= ~TMU_RTR_CS_18_DELTA_AVG_CONST_MASK;
  96. val |= FIELD_PREP(TMU_RTR_CS_18_DELTA_AVG_CONST_MASK, delta_avg);
  97. ret = tb_sw_write(sw, &val, TB_CFG_SWITCH,
  98. sw->tmu.cap + TMU_RTR_CS_18, 1);
  99. }
  100. return ret;
  101. }
  102. static bool tb_switch_tmu_ucap_is_supported(struct tb_switch *sw)
  103. {
  104. int ret;
  105. u32 val;
  106. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  107. sw->tmu.cap + TMU_RTR_CS_0, 1);
  108. if (ret)
  109. return false;
  110. return !!(val & TMU_RTR_CS_0_UCAP);
  111. }
  112. static int tb_switch_tmu_rate_read(struct tb_switch *sw)
  113. {
  114. int ret;
  115. u32 val;
  116. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  117. sw->tmu.cap + TMU_RTR_CS_3, 1);
  118. if (ret)
  119. return ret;
  120. val >>= TMU_RTR_CS_3_TS_PACKET_INTERVAL_SHIFT;
  121. return val;
  122. }
  123. static int tb_switch_tmu_rate_write(struct tb_switch *sw, int rate)
  124. {
  125. int ret;
  126. u32 val;
  127. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  128. sw->tmu.cap + TMU_RTR_CS_3, 1);
  129. if (ret)
  130. return ret;
  131. val &= ~TMU_RTR_CS_3_TS_PACKET_INTERVAL_MASK;
  132. val |= rate << TMU_RTR_CS_3_TS_PACKET_INTERVAL_SHIFT;
  133. return tb_sw_write(sw, &val, TB_CFG_SWITCH,
  134. sw->tmu.cap + TMU_RTR_CS_3, 1);
  135. }
  136. static int tb_port_tmu_write(struct tb_port *port, u8 offset, u32 mask,
  137. u32 value)
  138. {
  139. u32 data;
  140. int ret;
  141. ret = tb_port_read(port, &data, TB_CFG_PORT, port->cap_tmu + offset, 1);
  142. if (ret)
  143. return ret;
  144. data &= ~mask;
  145. data |= value;
  146. return tb_port_write(port, &data, TB_CFG_PORT,
  147. port->cap_tmu + offset, 1);
  148. }
  149. static int tb_port_tmu_set_unidirectional(struct tb_port *port,
  150. bool unidirectional)
  151. {
  152. u32 val;
  153. if (!port->sw->tmu.has_ucap)
  154. return 0;
  155. val = unidirectional ? TMU_ADP_CS_3_UDM : 0;
  156. return tb_port_tmu_write(port, TMU_ADP_CS_3, TMU_ADP_CS_3_UDM, val);
  157. }
  158. static inline int tb_port_tmu_unidirectional_disable(struct tb_port *port)
  159. {
  160. return tb_port_tmu_set_unidirectional(port, false);
  161. }
  162. static inline int tb_port_tmu_unidirectional_enable(struct tb_port *port)
  163. {
  164. return tb_port_tmu_set_unidirectional(port, true);
  165. }
  166. static bool tb_port_tmu_is_unidirectional(struct tb_port *port)
  167. {
  168. int ret;
  169. u32 val;
  170. ret = tb_port_read(port, &val, TB_CFG_PORT,
  171. port->cap_tmu + TMU_ADP_CS_3, 1);
  172. if (ret)
  173. return false;
  174. return val & TMU_ADP_CS_3_UDM;
  175. }
  176. static bool tb_port_tmu_is_enhanced(struct tb_port *port)
  177. {
  178. int ret;
  179. u32 val;
  180. ret = tb_port_read(port, &val, TB_CFG_PORT,
  181. port->cap_tmu + TMU_ADP_CS_8, 1);
  182. if (ret)
  183. return false;
  184. return val & TMU_ADP_CS_8_EUDM;
  185. }
  186. /* Can be called to non-v2 lane adapters too */
  187. static int tb_port_tmu_enhanced_enable(struct tb_port *port, bool enable)
  188. {
  189. int ret;
  190. u32 val;
  191. if (!tb_switch_tmu_enhanced_is_supported(port->sw))
  192. return 0;
  193. ret = tb_port_read(port, &val, TB_CFG_PORT,
  194. port->cap_tmu + TMU_ADP_CS_8, 1);
  195. if (ret)
  196. return ret;
  197. if (enable)
  198. val |= TMU_ADP_CS_8_EUDM;
  199. else
  200. val &= ~TMU_ADP_CS_8_EUDM;
  201. return tb_port_write(port, &val, TB_CFG_PORT,
  202. port->cap_tmu + TMU_ADP_CS_8, 1);
  203. }
  204. static int tb_port_set_tmu_mode_params(struct tb_port *port,
  205. enum tb_switch_tmu_mode mode)
  206. {
  207. u32 repl_timeout, repl_threshold, repl_n, dirswitch_n, val;
  208. int ret;
  209. repl_timeout = tmu_params[mode].repl_timeout;
  210. repl_threshold = tmu_params[mode].repl_threshold;
  211. repl_n = tmu_params[mode].repl_n;
  212. dirswitch_n = tmu_params[mode].dirswitch_n;
  213. ret = tb_port_read(port, &val, TB_CFG_PORT,
  214. port->cap_tmu + TMU_ADP_CS_8, 1);
  215. if (ret)
  216. return ret;
  217. val &= ~TMU_ADP_CS_8_REPL_TIMEOUT_MASK;
  218. val &= ~TMU_ADP_CS_8_REPL_THRESHOLD_MASK;
  219. val |= FIELD_PREP(TMU_ADP_CS_8_REPL_TIMEOUT_MASK, repl_timeout);
  220. val |= FIELD_PREP(TMU_ADP_CS_8_REPL_THRESHOLD_MASK, repl_threshold);
  221. ret = tb_port_write(port, &val, TB_CFG_PORT,
  222. port->cap_tmu + TMU_ADP_CS_8, 1);
  223. if (ret)
  224. return ret;
  225. ret = tb_port_read(port, &val, TB_CFG_PORT,
  226. port->cap_tmu + TMU_ADP_CS_9, 1);
  227. if (ret)
  228. return ret;
  229. val &= ~TMU_ADP_CS_9_REPL_N_MASK;
  230. val &= ~TMU_ADP_CS_9_DIRSWITCH_N_MASK;
  231. val |= FIELD_PREP(TMU_ADP_CS_9_REPL_N_MASK, repl_n);
  232. val |= FIELD_PREP(TMU_ADP_CS_9_DIRSWITCH_N_MASK, dirswitch_n);
  233. return tb_port_write(port, &val, TB_CFG_PORT,
  234. port->cap_tmu + TMU_ADP_CS_9, 1);
  235. }
  236. /* Can be called to non-v2 lane adapters too */
  237. static int tb_port_tmu_rate_write(struct tb_port *port, int rate)
  238. {
  239. int ret;
  240. u32 val;
  241. if (!tb_switch_tmu_enhanced_is_supported(port->sw))
  242. return 0;
  243. ret = tb_port_read(port, &val, TB_CFG_PORT,
  244. port->cap_tmu + TMU_ADP_CS_9, 1);
  245. if (ret)
  246. return ret;
  247. val &= ~TMU_ADP_CS_9_ADP_TS_INTERVAL_MASK;
  248. val |= FIELD_PREP(TMU_ADP_CS_9_ADP_TS_INTERVAL_MASK, rate);
  249. return tb_port_write(port, &val, TB_CFG_PORT,
  250. port->cap_tmu + TMU_ADP_CS_9, 1);
  251. }
  252. static int tb_port_tmu_time_sync(struct tb_port *port, bool time_sync)
  253. {
  254. u32 val = time_sync ? TMU_ADP_CS_6_DTS : 0;
  255. return tb_port_tmu_write(port, TMU_ADP_CS_6, TMU_ADP_CS_6_DTS, val);
  256. }
  257. static int tb_port_tmu_time_sync_disable(struct tb_port *port)
  258. {
  259. return tb_port_tmu_time_sync(port, true);
  260. }
  261. static int tb_port_tmu_time_sync_enable(struct tb_port *port)
  262. {
  263. return tb_port_tmu_time_sync(port, false);
  264. }
  265. static int tb_switch_tmu_set_time_disruption(struct tb_switch *sw, bool set)
  266. {
  267. u32 val, offset, bit;
  268. int ret;
  269. if (tb_switch_is_usb4(sw)) {
  270. offset = sw->tmu.cap + TMU_RTR_CS_0;
  271. bit = TMU_RTR_CS_0_TD;
  272. } else {
  273. offset = sw->cap_vsec_tmu + TB_TIME_VSEC_3_CS_26;
  274. bit = TB_TIME_VSEC_3_CS_26_TD;
  275. }
  276. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, offset, 1);
  277. if (ret)
  278. return ret;
  279. if (set)
  280. val |= bit;
  281. else
  282. val &= ~bit;
  283. return tb_sw_write(sw, &val, TB_CFG_SWITCH, offset, 1);
  284. }
  285. static int tmu_mode_init(struct tb_switch *sw)
  286. {
  287. bool enhanced, ucap;
  288. int ret, rate;
  289. ucap = tb_switch_tmu_ucap_is_supported(sw);
  290. if (ucap)
  291. tb_sw_dbg(sw, "TMU: supports uni-directional mode\n");
  292. enhanced = tb_switch_tmu_enhanced_is_supported(sw);
  293. if (enhanced)
  294. tb_sw_dbg(sw, "TMU: supports enhanced uni-directional mode\n");
  295. ret = tb_switch_tmu_rate_read(sw);
  296. if (ret < 0)
  297. return ret;
  298. rate = ret;
  299. /* Off by default */
  300. sw->tmu.mode = TB_SWITCH_TMU_MODE_OFF;
  301. if (tb_route(sw)) {
  302. struct tb_port *up = tb_upstream_port(sw);
  303. if (enhanced && tb_port_tmu_is_enhanced(up)) {
  304. sw->tmu.mode = TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI;
  305. } else if (ucap && tb_port_tmu_is_unidirectional(up)) {
  306. if (tmu_rates[TB_SWITCH_TMU_MODE_LOWRES] == rate)
  307. sw->tmu.mode = TB_SWITCH_TMU_MODE_LOWRES;
  308. else if (tmu_rates[TB_SWITCH_TMU_MODE_HIFI_UNI] == rate)
  309. sw->tmu.mode = TB_SWITCH_TMU_MODE_HIFI_UNI;
  310. } else if (rate) {
  311. sw->tmu.mode = TB_SWITCH_TMU_MODE_HIFI_BI;
  312. }
  313. } else if (rate) {
  314. sw->tmu.mode = TB_SWITCH_TMU_MODE_HIFI_BI;
  315. }
  316. /* Update the initial request to match the current mode */
  317. sw->tmu.mode_request = sw->tmu.mode;
  318. sw->tmu.has_ucap = ucap;
  319. return 0;
  320. }
  321. /**
  322. * tb_switch_tmu_init() - Initialize switch TMU structures
  323. * @sw: Switch to be initialized
  324. *
  325. * This function must be called before other TMU related functions to
  326. * make sure the internal structures are filled in correctly. Does not
  327. * change any hardware configuration.
  328. *
  329. * Return: %0 on success, negative errno otherwise.
  330. */
  331. int tb_switch_tmu_init(struct tb_switch *sw)
  332. {
  333. struct tb_port *port;
  334. int ret;
  335. if (tb_switch_is_icm(sw))
  336. return 0;
  337. ret = tb_switch_find_cap(sw, TB_SWITCH_CAP_TMU);
  338. if (ret > 0)
  339. sw->tmu.cap = ret;
  340. tb_switch_for_each_port(sw, port) {
  341. int cap;
  342. cap = tb_port_find_cap(port, TB_PORT_CAP_TIME1);
  343. if (cap > 0)
  344. port->cap_tmu = cap;
  345. }
  346. ret = tmu_mode_init(sw);
  347. if (ret)
  348. return ret;
  349. tb_sw_dbg(sw, "TMU: current mode: %s\n", tmu_mode_name(sw->tmu.mode));
  350. return 0;
  351. }
  352. /**
  353. * tb_switch_tmu_post_time() - Update switch local time
  354. * @sw: Switch whose time to update
  355. *
  356. * Updates switch local time using time posting procedure.
  357. *
  358. * Return: %0 on success, negative errno otherwise.
  359. */
  360. int tb_switch_tmu_post_time(struct tb_switch *sw)
  361. {
  362. unsigned int post_time_high_offset, post_time_high = 0;
  363. unsigned int post_local_time_offset, post_time_offset;
  364. struct tb_switch *root_switch = sw->tb->root_switch;
  365. u64 hi, mid, lo, local_time, post_time;
  366. int i, ret, retries = 100;
  367. u32 gm_local_time[3];
  368. if (!tb_route(sw))
  369. return 0;
  370. if (!tb_switch_is_usb4(sw))
  371. return 0;
  372. /* Need to be able to read the grand master time */
  373. if (!root_switch->tmu.cap)
  374. return 0;
  375. ret = tb_sw_read(root_switch, gm_local_time, TB_CFG_SWITCH,
  376. root_switch->tmu.cap + TMU_RTR_CS_1,
  377. ARRAY_SIZE(gm_local_time));
  378. if (ret)
  379. return ret;
  380. for (i = 0; i < ARRAY_SIZE(gm_local_time); i++)
  381. tb_sw_dbg(root_switch, "TMU: local_time[%d]=0x%08x\n", i,
  382. gm_local_time[i]);
  383. /* Convert to nanoseconds (drop fractional part) */
  384. hi = gm_local_time[2] & TMU_RTR_CS_3_LOCAL_TIME_NS_MASK;
  385. mid = gm_local_time[1];
  386. lo = (gm_local_time[0] & TMU_RTR_CS_1_LOCAL_TIME_NS_MASK) >>
  387. TMU_RTR_CS_1_LOCAL_TIME_NS_SHIFT;
  388. local_time = hi << 48 | mid << 16 | lo;
  389. /* Tell the switch that time sync is disrupted for a while */
  390. ret = tb_switch_tmu_set_time_disruption(sw, true);
  391. if (ret)
  392. return ret;
  393. post_local_time_offset = sw->tmu.cap + TMU_RTR_CS_22;
  394. post_time_offset = sw->tmu.cap + TMU_RTR_CS_24;
  395. post_time_high_offset = sw->tmu.cap + TMU_RTR_CS_25;
  396. /*
  397. * Write the Grandmaster time to the Post Local Time registers
  398. * of the new switch.
  399. */
  400. ret = tb_sw_write(sw, &local_time, TB_CFG_SWITCH,
  401. post_local_time_offset, 2);
  402. if (ret)
  403. goto out;
  404. /*
  405. * Have the new switch update its local time by:
  406. * 1) writing 0x1 to the Post Time Low register and 0xffffffff to
  407. * Post Time High register.
  408. * 2) write 0 to Post Time High register and then wait for
  409. * the completion of the post_time register becomes 0.
  410. * This means the time has been converged properly.
  411. */
  412. post_time = 0xffffffff00000001ULL;
  413. ret = tb_sw_write(sw, &post_time, TB_CFG_SWITCH, post_time_offset, 2);
  414. if (ret)
  415. goto out;
  416. ret = tb_sw_write(sw, &post_time_high, TB_CFG_SWITCH,
  417. post_time_high_offset, 1);
  418. if (ret)
  419. goto out;
  420. do {
  421. usleep_range(5, 10);
  422. ret = tb_sw_read(sw, &post_time, TB_CFG_SWITCH,
  423. post_time_offset, 2);
  424. if (ret)
  425. goto out;
  426. } while (--retries && post_time);
  427. if (!retries) {
  428. ret = -ETIMEDOUT;
  429. goto out;
  430. }
  431. tb_sw_dbg(sw, "TMU: updated local time to %#llx\n", local_time);
  432. out:
  433. tb_switch_tmu_set_time_disruption(sw, false);
  434. return ret;
  435. }
  436. static int disable_enhanced(struct tb_port *up, struct tb_port *down)
  437. {
  438. int ret;
  439. /*
  440. * Router may already been disconnected so ignore errors on the
  441. * upstream port.
  442. */
  443. tb_port_tmu_rate_write(up, 0);
  444. tb_port_tmu_enhanced_enable(up, false);
  445. ret = tb_port_tmu_rate_write(down, 0);
  446. if (ret)
  447. return ret;
  448. return tb_port_tmu_enhanced_enable(down, false);
  449. }
  450. /**
  451. * tb_switch_tmu_disable() - Disable TMU of a switch
  452. * @sw: Switch whose TMU to disable
  453. *
  454. * Turns off TMU of @sw if it is enabled. If not enabled does nothing.
  455. *
  456. * Return: %0 on success, negative errno otherwise.
  457. */
  458. int tb_switch_tmu_disable(struct tb_switch *sw)
  459. {
  460. /* Already disabled? */
  461. if (sw->tmu.mode == TB_SWITCH_TMU_MODE_OFF)
  462. return 0;
  463. if (tb_route(sw)) {
  464. struct tb_port *down, *up;
  465. int ret;
  466. down = tb_switch_downstream_port(sw);
  467. up = tb_upstream_port(sw);
  468. /*
  469. * In case of uni-directional time sync, TMU handshake is
  470. * initiated by upstream router. In case of bi-directional
  471. * time sync, TMU handshake is initiated by downstream router.
  472. * We change downstream router's rate to off for both uni/bidir
  473. * cases although it is needed only for the bi-directional mode.
  474. * We avoid changing upstream router's mode since it might
  475. * have another downstream router plugged, that is set to
  476. * uni-directional mode and we don't want to change it's TMU
  477. * mode.
  478. */
  479. ret = tb_switch_tmu_rate_write(sw, tmu_rates[TB_SWITCH_TMU_MODE_OFF]);
  480. if (ret)
  481. return ret;
  482. tb_port_tmu_time_sync_disable(up);
  483. ret = tb_port_tmu_time_sync_disable(down);
  484. if (ret)
  485. return ret;
  486. switch (sw->tmu.mode) {
  487. case TB_SWITCH_TMU_MODE_LOWRES:
  488. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  489. /* The switch may be unplugged so ignore any errors */
  490. tb_port_tmu_unidirectional_disable(up);
  491. ret = tb_port_tmu_unidirectional_disable(down);
  492. if (ret)
  493. return ret;
  494. break;
  495. case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI:
  496. ret = disable_enhanced(up, down);
  497. if (ret)
  498. return ret;
  499. break;
  500. default:
  501. break;
  502. }
  503. } else {
  504. tb_switch_tmu_rate_write(sw, tmu_rates[TB_SWITCH_TMU_MODE_OFF]);
  505. }
  506. sw->tmu.mode = TB_SWITCH_TMU_MODE_OFF;
  507. tb_sw_dbg(sw, "TMU: disabled\n");
  508. return 0;
  509. }
  510. /* Called only when there is failure enabling requested mode */
  511. static void tb_switch_tmu_off(struct tb_switch *sw)
  512. {
  513. unsigned int rate = tmu_rates[TB_SWITCH_TMU_MODE_OFF];
  514. struct tb_port *down, *up;
  515. down = tb_switch_downstream_port(sw);
  516. up = tb_upstream_port(sw);
  517. /*
  518. * In case of any failure in one of the steps when setting
  519. * bi-directional or uni-directional TMU mode, get back to the TMU
  520. * configurations in off mode. In case of additional failures in
  521. * the functions below, ignore them since the caller shall already
  522. * report a failure.
  523. */
  524. tb_port_tmu_time_sync_disable(down);
  525. tb_port_tmu_time_sync_disable(up);
  526. switch (sw->tmu.mode_request) {
  527. case TB_SWITCH_TMU_MODE_LOWRES:
  528. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  529. tb_switch_tmu_rate_write(tb_switch_parent(sw), rate);
  530. break;
  531. case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI:
  532. disable_enhanced(up, down);
  533. break;
  534. default:
  535. break;
  536. }
  537. /* Always set the rate to 0 */
  538. tb_switch_tmu_rate_write(sw, rate);
  539. tb_switch_set_tmu_mode_params(sw, sw->tmu.mode);
  540. tb_port_tmu_unidirectional_disable(down);
  541. tb_port_tmu_unidirectional_disable(up);
  542. }
  543. /*
  544. * This function is called when the previous TMU mode was
  545. * TB_SWITCH_TMU_MODE_OFF.
  546. */
  547. static int tb_switch_tmu_enable_bidirectional(struct tb_switch *sw)
  548. {
  549. struct tb_port *up, *down;
  550. int ret;
  551. up = tb_upstream_port(sw);
  552. down = tb_switch_downstream_port(sw);
  553. ret = tb_port_tmu_unidirectional_disable(up);
  554. if (ret)
  555. return ret;
  556. ret = tb_port_tmu_unidirectional_disable(down);
  557. if (ret)
  558. goto out;
  559. ret = tb_switch_tmu_rate_write(sw, tmu_rates[TB_SWITCH_TMU_MODE_HIFI_BI]);
  560. if (ret)
  561. goto out;
  562. ret = tb_port_tmu_time_sync_enable(up);
  563. if (ret)
  564. goto out;
  565. ret = tb_port_tmu_time_sync_enable(down);
  566. if (ret)
  567. goto out;
  568. return 0;
  569. out:
  570. tb_switch_tmu_off(sw);
  571. return ret;
  572. }
  573. /* Only needed for Titan Ridge */
  574. static int tb_switch_tmu_disable_objections(struct tb_switch *sw)
  575. {
  576. struct tb_port *up = tb_upstream_port(sw);
  577. u32 val;
  578. int ret;
  579. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  580. sw->cap_vsec_tmu + TB_TIME_VSEC_3_CS_9, 1);
  581. if (ret)
  582. return ret;
  583. val &= ~TB_TIME_VSEC_3_CS_9_TMU_OBJ_MASK;
  584. ret = tb_sw_write(sw, &val, TB_CFG_SWITCH,
  585. sw->cap_vsec_tmu + TB_TIME_VSEC_3_CS_9, 1);
  586. if (ret)
  587. return ret;
  588. return tb_port_tmu_write(up, TMU_ADP_CS_6,
  589. TMU_ADP_CS_6_DISABLE_TMU_OBJ_MASK,
  590. TMU_ADP_CS_6_DISABLE_TMU_OBJ_CL1 |
  591. TMU_ADP_CS_6_DISABLE_TMU_OBJ_CL2);
  592. }
  593. /*
  594. * This function is called when the previous TMU mode was
  595. * TB_SWITCH_TMU_MODE_OFF.
  596. */
  597. static int tb_switch_tmu_enable_unidirectional(struct tb_switch *sw)
  598. {
  599. struct tb_port *up, *down;
  600. int ret;
  601. up = tb_upstream_port(sw);
  602. down = tb_switch_downstream_port(sw);
  603. ret = tb_switch_tmu_rate_write(tb_switch_parent(sw),
  604. tmu_rates[sw->tmu.mode_request]);
  605. if (ret)
  606. return ret;
  607. ret = tb_switch_set_tmu_mode_params(sw, sw->tmu.mode_request);
  608. if (ret)
  609. return ret;
  610. ret = tb_port_tmu_unidirectional_enable(up);
  611. if (ret)
  612. goto out;
  613. ret = tb_port_tmu_time_sync_enable(up);
  614. if (ret)
  615. goto out;
  616. ret = tb_port_tmu_unidirectional_enable(down);
  617. if (ret)
  618. goto out;
  619. ret = tb_port_tmu_time_sync_enable(down);
  620. if (ret)
  621. goto out;
  622. return 0;
  623. out:
  624. tb_switch_tmu_off(sw);
  625. return ret;
  626. }
  627. /*
  628. * This function is called when the previous TMU mode was
  629. * TB_SWITCH_TMU_RATE_OFF.
  630. */
  631. static int tb_switch_tmu_enable_enhanced(struct tb_switch *sw)
  632. {
  633. unsigned int rate = tmu_rates[sw->tmu.mode_request];
  634. struct tb_port *up, *down;
  635. int ret;
  636. /* Router specific parameters first */
  637. ret = tb_switch_set_tmu_mode_params(sw, sw->tmu.mode_request);
  638. if (ret)
  639. return ret;
  640. up = tb_upstream_port(sw);
  641. down = tb_switch_downstream_port(sw);
  642. ret = tb_port_set_tmu_mode_params(up, sw->tmu.mode_request);
  643. if (ret)
  644. goto out;
  645. ret = tb_port_tmu_rate_write(up, rate);
  646. if (ret)
  647. goto out;
  648. ret = tb_port_tmu_enhanced_enable(up, true);
  649. if (ret)
  650. goto out;
  651. ret = tb_port_set_tmu_mode_params(down, sw->tmu.mode_request);
  652. if (ret)
  653. goto out;
  654. ret = tb_port_tmu_rate_write(down, rate);
  655. if (ret)
  656. goto out;
  657. ret = tb_port_tmu_enhanced_enable(down, true);
  658. if (ret)
  659. goto out;
  660. return 0;
  661. out:
  662. tb_switch_tmu_off(sw);
  663. return ret;
  664. }
  665. static void tb_switch_tmu_change_mode_prev(struct tb_switch *sw)
  666. {
  667. unsigned int rate = tmu_rates[sw->tmu.mode];
  668. struct tb_port *down, *up;
  669. down = tb_switch_downstream_port(sw);
  670. up = tb_upstream_port(sw);
  671. /*
  672. * In case of any failure in one of the steps when change mode,
  673. * get back to the TMU configurations in previous mode.
  674. * In case of additional failures in the functions below,
  675. * ignore them since the caller shall already report a failure.
  676. */
  677. switch (sw->tmu.mode) {
  678. case TB_SWITCH_TMU_MODE_LOWRES:
  679. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  680. tb_port_tmu_set_unidirectional(down, true);
  681. tb_switch_tmu_rate_write(tb_switch_parent(sw), rate);
  682. break;
  683. case TB_SWITCH_TMU_MODE_HIFI_BI:
  684. tb_port_tmu_set_unidirectional(down, false);
  685. tb_switch_tmu_rate_write(sw, rate);
  686. break;
  687. default:
  688. break;
  689. }
  690. tb_switch_set_tmu_mode_params(sw, sw->tmu.mode);
  691. switch (sw->tmu.mode) {
  692. case TB_SWITCH_TMU_MODE_LOWRES:
  693. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  694. tb_port_tmu_set_unidirectional(up, true);
  695. break;
  696. case TB_SWITCH_TMU_MODE_HIFI_BI:
  697. tb_port_tmu_set_unidirectional(up, false);
  698. break;
  699. default:
  700. break;
  701. }
  702. }
  703. static int tb_switch_tmu_change_mode(struct tb_switch *sw)
  704. {
  705. unsigned int rate = tmu_rates[sw->tmu.mode_request];
  706. struct tb_port *up, *down;
  707. int ret;
  708. up = tb_upstream_port(sw);
  709. down = tb_switch_downstream_port(sw);
  710. /* Program the upstream router downstream facing lane adapter */
  711. switch (sw->tmu.mode_request) {
  712. case TB_SWITCH_TMU_MODE_LOWRES:
  713. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  714. ret = tb_port_tmu_set_unidirectional(down, true);
  715. if (ret)
  716. goto out;
  717. ret = tb_switch_tmu_rate_write(tb_switch_parent(sw), rate);
  718. if (ret)
  719. goto out;
  720. break;
  721. case TB_SWITCH_TMU_MODE_HIFI_BI:
  722. ret = tb_port_tmu_set_unidirectional(down, false);
  723. if (ret)
  724. goto out;
  725. ret = tb_switch_tmu_rate_write(sw, rate);
  726. if (ret)
  727. goto out;
  728. break;
  729. default:
  730. /* Not allowed to change modes from other than above */
  731. return -EINVAL;
  732. }
  733. ret = tb_switch_set_tmu_mode_params(sw, sw->tmu.mode_request);
  734. if (ret)
  735. goto out;
  736. /* Program the new mode and the downstream router lane adapter */
  737. switch (sw->tmu.mode_request) {
  738. case TB_SWITCH_TMU_MODE_LOWRES:
  739. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  740. ret = tb_port_tmu_set_unidirectional(up, true);
  741. if (ret)
  742. goto out;
  743. break;
  744. case TB_SWITCH_TMU_MODE_HIFI_BI:
  745. ret = tb_port_tmu_set_unidirectional(up, false);
  746. if (ret)
  747. goto out;
  748. break;
  749. default:
  750. /* Not allowed to change modes from other than above */
  751. return -EINVAL;
  752. }
  753. ret = tb_port_tmu_time_sync_enable(down);
  754. if (ret)
  755. goto out;
  756. ret = tb_port_tmu_time_sync_enable(up);
  757. if (ret)
  758. goto out;
  759. return 0;
  760. out:
  761. tb_switch_tmu_change_mode_prev(sw);
  762. return ret;
  763. }
  764. /**
  765. * tb_switch_tmu_enable() - Enable TMU on a router
  766. * @sw: Router whose TMU to enable
  767. *
  768. * Enables TMU of a router to be in uni-directional Normal/HiFi or
  769. * bi-directional HiFi mode. Calling tb_switch_tmu_configure() is
  770. * required before calling this function.
  771. *
  772. * Return: %0 on success, negative errno otherwise.
  773. */
  774. int tb_switch_tmu_enable(struct tb_switch *sw)
  775. {
  776. int ret;
  777. if (tb_switch_tmu_is_enabled(sw))
  778. return 0;
  779. if (tb_switch_is_titan_ridge(sw) &&
  780. (sw->tmu.mode_request == TB_SWITCH_TMU_MODE_LOWRES ||
  781. sw->tmu.mode_request == TB_SWITCH_TMU_MODE_HIFI_UNI)) {
  782. ret = tb_switch_tmu_disable_objections(sw);
  783. if (ret)
  784. return ret;
  785. }
  786. ret = tb_switch_tmu_set_time_disruption(sw, true);
  787. if (ret)
  788. return ret;
  789. if (tb_route(sw)) {
  790. /*
  791. * The used mode changes are from OFF to
  792. * HiFi-Uni/HiFi-BiDir/Normal-Uni or from Normal-Uni to
  793. * HiFi-Uni.
  794. */
  795. if (sw->tmu.mode == TB_SWITCH_TMU_MODE_OFF) {
  796. switch (sw->tmu.mode_request) {
  797. case TB_SWITCH_TMU_MODE_LOWRES:
  798. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  799. ret = tb_switch_tmu_enable_unidirectional(sw);
  800. break;
  801. case TB_SWITCH_TMU_MODE_HIFI_BI:
  802. ret = tb_switch_tmu_enable_bidirectional(sw);
  803. break;
  804. case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI:
  805. ret = tb_switch_tmu_enable_enhanced(sw);
  806. break;
  807. default:
  808. ret = -EINVAL;
  809. break;
  810. }
  811. } else if (sw->tmu.mode == TB_SWITCH_TMU_MODE_LOWRES ||
  812. sw->tmu.mode == TB_SWITCH_TMU_MODE_HIFI_UNI ||
  813. sw->tmu.mode == TB_SWITCH_TMU_MODE_HIFI_BI) {
  814. ret = tb_switch_tmu_change_mode(sw);
  815. } else {
  816. ret = -EINVAL;
  817. }
  818. } else {
  819. /*
  820. * Host router port configurations are written as
  821. * part of configurations for downstream port of the parent
  822. * of the child node - see above.
  823. * Here only the host router' rate configuration is written.
  824. */
  825. ret = tb_switch_tmu_rate_write(sw, tmu_rates[sw->tmu.mode_request]);
  826. }
  827. if (ret) {
  828. tb_sw_warn(sw, "TMU: failed to enable mode %s: %d\n",
  829. tmu_mode_name(sw->tmu.mode_request), ret);
  830. } else {
  831. sw->tmu.mode = sw->tmu.mode_request;
  832. tb_sw_dbg(sw, "TMU: mode set to: %s\n", tmu_mode_name(sw->tmu.mode));
  833. }
  834. return tb_switch_tmu_set_time_disruption(sw, false);
  835. }
  836. /**
  837. * tb_switch_tmu_configure() - Configure the TMU mode
  838. * @sw: Router whose mode to change
  839. * @mode: Mode to configure
  840. *
  841. * Selects the TMU mode that is enabled when tb_switch_tmu_enable() is
  842. * next called.
  843. *
  844. * Return:
  845. * * %0 - On success.
  846. * * %-EOPNOTSUPP - If the requested mode is not possible (not supported by
  847. * the router and/or topology).
  848. * * Negative errno - Another error occurred.
  849. */
  850. int tb_switch_tmu_configure(struct tb_switch *sw, enum tb_switch_tmu_mode mode)
  851. {
  852. switch (mode) {
  853. case TB_SWITCH_TMU_MODE_OFF:
  854. break;
  855. case TB_SWITCH_TMU_MODE_LOWRES:
  856. case TB_SWITCH_TMU_MODE_HIFI_UNI:
  857. if (!sw->tmu.has_ucap)
  858. return -EOPNOTSUPP;
  859. break;
  860. case TB_SWITCH_TMU_MODE_HIFI_BI:
  861. break;
  862. case TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI: {
  863. const struct tb_switch *parent_sw = tb_switch_parent(sw);
  864. if (!parent_sw || !tb_switch_tmu_enhanced_is_supported(parent_sw))
  865. return -EOPNOTSUPP;
  866. if (!tb_switch_tmu_enhanced_is_supported(sw))
  867. return -EOPNOTSUPP;
  868. break;
  869. }
  870. default:
  871. tb_sw_warn(sw, "TMU: unsupported mode %u\n", mode);
  872. return -EINVAL;
  873. }
  874. if (sw->tmu.mode_request != mode) {
  875. tb_sw_dbg(sw, "TMU: mode change %s -> %s requested\n",
  876. tmu_mode_name(sw->tmu.mode), tmu_mode_name(mode));
  877. sw->tmu.mode_request = mode;
  878. }
  879. return 0;
  880. }