tmu.c 8.4 KB

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