lc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Thunderbolt link controller support
  4. *
  5. * Copyright (C) 2019, Intel Corporation
  6. * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
  7. */
  8. #include <linux/delay.h>
  9. #include "tb.h"
  10. /**
  11. * tb_lc_read_uuid() - Read switch UUID from link controller common register
  12. * @sw: Switch whose UUID is read
  13. * @uuid: UUID is placed here
  14. *
  15. * Return: %0 on success, negative errno otherwise.
  16. */
  17. int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid)
  18. {
  19. if (!sw->cap_lc)
  20. return -EINVAL;
  21. return tb_sw_read(sw, uuid, TB_CFG_SWITCH, sw->cap_lc + TB_LC_FUSE, 4);
  22. }
  23. static int read_lc_desc(struct tb_switch *sw, u32 *desc)
  24. {
  25. if (!sw->cap_lc)
  26. return -EINVAL;
  27. return tb_sw_read(sw, desc, TB_CFG_SWITCH, sw->cap_lc + TB_LC_DESC, 1);
  28. }
  29. static int find_port_lc_cap(struct tb_port *port)
  30. {
  31. struct tb_switch *sw = port->sw;
  32. int start, phys, ret, size;
  33. u32 desc;
  34. ret = read_lc_desc(sw, &desc);
  35. if (ret)
  36. return ret;
  37. /* Start of port LC registers */
  38. start = (desc & TB_LC_DESC_SIZE_MASK) >> TB_LC_DESC_SIZE_SHIFT;
  39. size = (desc & TB_LC_DESC_PORT_SIZE_MASK) >> TB_LC_DESC_PORT_SIZE_SHIFT;
  40. phys = tb_phy_port_from_link(port->port);
  41. return sw->cap_lc + start + phys * size;
  42. }
  43. /**
  44. * tb_lc_reset_port() - Trigger downstream port reset through LC
  45. * @port: Port that is reset
  46. *
  47. * Triggers downstream port reset through link controller registers.
  48. * Only supports non-USB4 routers with link controller (that's
  49. * Thunderbolt 2 and Thunderbolt 3).
  50. *
  51. * Return: %0 on success, negative errno otherwise.
  52. */
  53. int tb_lc_reset_port(struct tb_port *port)
  54. {
  55. struct tb_switch *sw = port->sw;
  56. int cap, ret;
  57. u32 mode;
  58. if (sw->generation < 2)
  59. return -EINVAL;
  60. cap = find_port_lc_cap(port);
  61. if (cap < 0)
  62. return cap;
  63. ret = tb_sw_read(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
  64. if (ret)
  65. return ret;
  66. mode |= TB_LC_PORT_MODE_DPR;
  67. ret = tb_sw_write(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
  68. if (ret)
  69. return ret;
  70. fsleep(10000);
  71. ret = tb_sw_read(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
  72. if (ret)
  73. return ret;
  74. mode &= ~TB_LC_PORT_MODE_DPR;
  75. return tb_sw_write(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
  76. }
  77. static int tb_lc_set_port_configured(struct tb_port *port, bool configured)
  78. {
  79. bool upstream = tb_is_upstream_port(port);
  80. struct tb_switch *sw = port->sw;
  81. u32 ctrl, lane;
  82. int cap, ret;
  83. if (sw->generation < 2)
  84. return 0;
  85. cap = find_port_lc_cap(port);
  86. if (cap < 0)
  87. return cap;
  88. ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
  89. if (ret)
  90. return ret;
  91. /* Resolve correct lane */
  92. if (port->port % 2)
  93. lane = TB_LC_SX_CTRL_L1C;
  94. else
  95. lane = TB_LC_SX_CTRL_L2C;
  96. if (configured) {
  97. ctrl |= lane;
  98. if (upstream)
  99. ctrl |= TB_LC_SX_CTRL_UPSTREAM;
  100. } else {
  101. ctrl &= ~lane;
  102. if (upstream)
  103. ctrl &= ~TB_LC_SX_CTRL_UPSTREAM;
  104. }
  105. return tb_sw_write(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
  106. }
  107. /**
  108. * tb_lc_configure_port() - Let LC know about configured port
  109. * @port: Port that is set as configured
  110. *
  111. * Sets the port configured for power management purposes.
  112. *
  113. * Return: %0 on success, negative errno otherwise.
  114. */
  115. int tb_lc_configure_port(struct tb_port *port)
  116. {
  117. return tb_lc_set_port_configured(port, true);
  118. }
  119. /**
  120. * tb_lc_unconfigure_port() - Let LC know about unconfigured port
  121. * @port: Port that is set as configured
  122. *
  123. * Sets the port unconfigured for power management purposes.
  124. *
  125. * Return: %0 on success, negative errno otherwise.
  126. */
  127. void tb_lc_unconfigure_port(struct tb_port *port)
  128. {
  129. tb_lc_set_port_configured(port, false);
  130. }
  131. static int tb_lc_set_xdomain_configured(struct tb_port *port, bool configure)
  132. {
  133. struct tb_switch *sw = port->sw;
  134. u32 ctrl, lane;
  135. int cap, ret;
  136. if (sw->generation < 2)
  137. return 0;
  138. cap = find_port_lc_cap(port);
  139. if (cap < 0)
  140. return cap;
  141. ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
  142. if (ret)
  143. return ret;
  144. /* Resolve correct lane */
  145. if (port->port % 2)
  146. lane = TB_LC_SX_CTRL_L1D;
  147. else
  148. lane = TB_LC_SX_CTRL_L2D;
  149. if (configure)
  150. ctrl |= lane;
  151. else
  152. ctrl &= ~lane;
  153. return tb_sw_write(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
  154. }
  155. /**
  156. * tb_lc_configure_xdomain() - Inform LC that the link is XDomain
  157. * @port: Switch downstream port connected to another host
  158. *
  159. * Sets the lane configured for XDomain accordingly so that LC knows
  160. * about this.
  161. *
  162. * Return: %0 on success, negative errno otherwise.
  163. */
  164. int tb_lc_configure_xdomain(struct tb_port *port)
  165. {
  166. return tb_lc_set_xdomain_configured(port, true);
  167. }
  168. /**
  169. * tb_lc_unconfigure_xdomain() - Unconfigure XDomain from port
  170. * @port: Switch downstream port that was connected to another host
  171. *
  172. * Unsets the lane XDomain configuration.
  173. */
  174. void tb_lc_unconfigure_xdomain(struct tb_port *port)
  175. {
  176. tb_lc_set_xdomain_configured(port, false);
  177. }
  178. /**
  179. * tb_lc_start_lane_initialization() - Start lane initialization
  180. * @port: Device router lane 0 adapter
  181. *
  182. * Starts lane initialization for @port after the router resumed from
  183. * sleep. Should be called for those downstream lane adapters that were
  184. * not connected (tb_lc_configure_port() was not called) before sleep.
  185. *
  186. * Return: %0 on success, negative errno otherwise.
  187. */
  188. int tb_lc_start_lane_initialization(struct tb_port *port)
  189. {
  190. struct tb_switch *sw = port->sw;
  191. int ret, cap;
  192. u32 ctrl;
  193. if (!tb_route(sw))
  194. return 0;
  195. if (sw->generation < 2)
  196. return 0;
  197. cap = find_port_lc_cap(port);
  198. if (cap < 0)
  199. return cap;
  200. ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
  201. if (ret)
  202. return ret;
  203. ctrl |= TB_LC_SX_CTRL_SLI;
  204. return tb_sw_write(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
  205. }
  206. /**
  207. * tb_lc_is_clx_supported() - Check whether CLx is supported by the lane adapter
  208. * @port: Lane adapter
  209. *
  210. * TB_LC_LINK_ATTR_CPS bit reflects if the link supports CLx including
  211. * active cables (if connected on the link).
  212. *
  213. * Return: %true if CLx is supported, %false otherwise.
  214. */
  215. bool tb_lc_is_clx_supported(struct tb_port *port)
  216. {
  217. struct tb_switch *sw = port->sw;
  218. int cap, ret;
  219. u32 val;
  220. cap = find_port_lc_cap(port);
  221. if (cap < 0)
  222. return false;
  223. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_ATTR, 1);
  224. if (ret)
  225. return false;
  226. return !!(val & TB_LC_LINK_ATTR_CPS);
  227. }
  228. /**
  229. * tb_lc_is_usb_plugged() - Is there USB device connected to port
  230. * @port: Device router lane 0 adapter
  231. *
  232. * Return: %true if the @port has USB Type-C device connected, %false
  233. * otherwise.
  234. */
  235. bool tb_lc_is_usb_plugged(struct tb_port *port)
  236. {
  237. struct tb_switch *sw = port->sw;
  238. int cap, ret;
  239. u32 val;
  240. if (sw->generation != 3)
  241. return false;
  242. cap = find_port_lc_cap(port);
  243. if (cap < 0)
  244. return false;
  245. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_CS_42, 1);
  246. if (ret)
  247. return false;
  248. return !!(val & TB_LC_CS_42_USB_PLUGGED);
  249. }
  250. /**
  251. * tb_lc_is_xhci_connected() - Is the internal xHCI connected
  252. * @port: Device router lane 0 adapter
  253. *
  254. * Return: %true if the internal xHCI has been connected to
  255. * @port, %false otherwise.
  256. */
  257. bool tb_lc_is_xhci_connected(struct tb_port *port)
  258. {
  259. struct tb_switch *sw = port->sw;
  260. int cap, ret;
  261. u32 val;
  262. if (sw->generation != 3)
  263. return false;
  264. cap = find_port_lc_cap(port);
  265. if (cap < 0)
  266. return false;
  267. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_REQ, 1);
  268. if (ret)
  269. return false;
  270. return !!(val & TB_LC_LINK_REQ_XHCI_CONNECT);
  271. }
  272. static int __tb_lc_xhci_connect(struct tb_port *port, bool connect)
  273. {
  274. struct tb_switch *sw = port->sw;
  275. int cap, ret;
  276. u32 val;
  277. if (sw->generation != 3)
  278. return -EINVAL;
  279. cap = find_port_lc_cap(port);
  280. if (cap < 0)
  281. return cap;
  282. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_REQ, 1);
  283. if (ret)
  284. return ret;
  285. if (connect)
  286. val |= TB_LC_LINK_REQ_XHCI_CONNECT;
  287. else
  288. val &= ~TB_LC_LINK_REQ_XHCI_CONNECT;
  289. return tb_sw_write(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_REQ, 1);
  290. }
  291. /**
  292. * tb_lc_xhci_connect() - Connect internal xHCI
  293. * @port: Device router lane 0 adapter
  294. *
  295. * Tells LC to connect the internal xHCI to @port. Can be called for
  296. * Thunderbolt 3 routers only.
  297. *
  298. * Return: %0 on success, negative errno otherwise.
  299. */
  300. int tb_lc_xhci_connect(struct tb_port *port)
  301. {
  302. int ret;
  303. ret = __tb_lc_xhci_connect(port, true);
  304. if (ret)
  305. return ret;
  306. tb_port_dbg(port, "xHCI connected\n");
  307. return 0;
  308. }
  309. /**
  310. * tb_lc_xhci_disconnect() - Disconnect internal xHCI
  311. * @port: Device router lane 0 adapter
  312. *
  313. * Tells LC to disconnect the internal xHCI from @port. Can be called
  314. * for Thunderbolt 3 routers only.
  315. */
  316. void tb_lc_xhci_disconnect(struct tb_port *port)
  317. {
  318. __tb_lc_xhci_connect(port, false);
  319. tb_port_dbg(port, "xHCI disconnected\n");
  320. }
  321. static int tb_lc_set_wake_one(struct tb_switch *sw, unsigned int offset,
  322. unsigned int flags)
  323. {
  324. u32 ctrl;
  325. int ret;
  326. /*
  327. * Enable wake on PCIe and USB4 (wake coming from another
  328. * router).
  329. */
  330. ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH,
  331. offset + TB_LC_SX_CTRL, 1);
  332. if (ret)
  333. return ret;
  334. ctrl &= ~(TB_LC_SX_CTRL_WOC | TB_LC_SX_CTRL_WOD | TB_LC_SX_CTRL_WODPC |
  335. TB_LC_SX_CTRL_WODPD | TB_LC_SX_CTRL_WOP | TB_LC_SX_CTRL_WOU4);
  336. if (flags & TB_WAKE_ON_CONNECT)
  337. ctrl |= TB_LC_SX_CTRL_WOC | TB_LC_SX_CTRL_WOD;
  338. if (flags & TB_WAKE_ON_USB4)
  339. ctrl |= TB_LC_SX_CTRL_WOU4;
  340. if (flags & TB_WAKE_ON_PCIE)
  341. ctrl |= TB_LC_SX_CTRL_WOP;
  342. if (flags & TB_WAKE_ON_DP)
  343. ctrl |= TB_LC_SX_CTRL_WODPC | TB_LC_SX_CTRL_WODPD;
  344. return tb_sw_write(sw, &ctrl, TB_CFG_SWITCH, offset + TB_LC_SX_CTRL, 1);
  345. }
  346. /**
  347. * tb_lc_set_wake() - Enable/disable wake
  348. * @sw: Switch whose wakes to configure
  349. * @flags: Wakeup flags (%0 to disable)
  350. *
  351. * For each LC sets wake bits accordingly.
  352. *
  353. * Return: %0 on success, negative errno otherwise.
  354. */
  355. int tb_lc_set_wake(struct tb_switch *sw, unsigned int flags)
  356. {
  357. int start, size, nlc, ret, i;
  358. u32 desc;
  359. if (sw->generation < 2)
  360. return 0;
  361. if (!tb_route(sw))
  362. return 0;
  363. ret = read_lc_desc(sw, &desc);
  364. if (ret)
  365. return ret;
  366. /* Figure out number of link controllers */
  367. nlc = desc & TB_LC_DESC_NLC_MASK;
  368. start = (desc & TB_LC_DESC_SIZE_MASK) >> TB_LC_DESC_SIZE_SHIFT;
  369. size = (desc & TB_LC_DESC_PORT_SIZE_MASK) >> TB_LC_DESC_PORT_SIZE_SHIFT;
  370. /* For each link controller set sleep bit */
  371. for (i = 0; i < nlc; i++) {
  372. unsigned int offset = sw->cap_lc + start + i * size;
  373. ret = tb_lc_set_wake_one(sw, offset, flags);
  374. if (ret)
  375. return ret;
  376. }
  377. return 0;
  378. }
  379. /**
  380. * tb_lc_set_sleep() - Inform LC that the switch is going to sleep
  381. * @sw: Switch to set sleep
  382. *
  383. * Let the switch link controllers know that the switch is going to
  384. * sleep.
  385. *
  386. * Return: %0 on success, negative errno otherwise.
  387. */
  388. int tb_lc_set_sleep(struct tb_switch *sw)
  389. {
  390. int start, size, nlc, ret, i;
  391. u32 desc;
  392. if (sw->generation < 2)
  393. return 0;
  394. ret = read_lc_desc(sw, &desc);
  395. if (ret)
  396. return ret;
  397. /* Figure out number of link controllers */
  398. nlc = desc & TB_LC_DESC_NLC_MASK;
  399. start = (desc & TB_LC_DESC_SIZE_MASK) >> TB_LC_DESC_SIZE_SHIFT;
  400. size = (desc & TB_LC_DESC_PORT_SIZE_MASK) >> TB_LC_DESC_PORT_SIZE_SHIFT;
  401. /* For each link controller set sleep bit */
  402. for (i = 0; i < nlc; i++) {
  403. unsigned int offset = sw->cap_lc + start + i * size;
  404. u32 ctrl;
  405. ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH,
  406. offset + TB_LC_SX_CTRL, 1);
  407. if (ret)
  408. return ret;
  409. ctrl |= TB_LC_SX_CTRL_SLP;
  410. ret = tb_sw_write(sw, &ctrl, TB_CFG_SWITCH,
  411. offset + TB_LC_SX_CTRL, 1);
  412. if (ret)
  413. return ret;
  414. }
  415. return 0;
  416. }
  417. /**
  418. * tb_lc_lane_bonding_possible() - Is lane bonding possible towards switch
  419. * @sw: Switch to check
  420. *
  421. * Checks whether conditions for lane bonding from parent to @sw are
  422. * possible.
  423. *
  424. * Return: %true if lane bonding is possible, %false otherwise.
  425. */
  426. bool tb_lc_lane_bonding_possible(struct tb_switch *sw)
  427. {
  428. struct tb_port *up;
  429. int cap, ret;
  430. u32 val;
  431. if (sw->generation < 2)
  432. return false;
  433. up = tb_upstream_port(sw);
  434. cap = find_port_lc_cap(up);
  435. if (cap < 0)
  436. return false;
  437. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_PORT_ATTR, 1);
  438. if (ret)
  439. return false;
  440. return !!(val & TB_LC_PORT_ATTR_BE);
  441. }
  442. static int tb_lc_dp_sink_from_port(const struct tb_switch *sw,
  443. struct tb_port *in)
  444. {
  445. struct tb_port *port;
  446. /* The first DP IN port is sink 0 and second is sink 1 */
  447. tb_switch_for_each_port(sw, port) {
  448. if (tb_port_is_dpin(port))
  449. return in != port;
  450. }
  451. return -EINVAL;
  452. }
  453. static int tb_lc_dp_sink_available(struct tb_switch *sw, int sink)
  454. {
  455. u32 val, alloc;
  456. int ret;
  457. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  458. sw->cap_lc + TB_LC_SNK_ALLOCATION, 1);
  459. if (ret)
  460. return ret;
  461. /*
  462. * Sink is available for CM/SW to use if the allocation value is
  463. * either 0 or 1.
  464. */
  465. if (!sink) {
  466. alloc = val & TB_LC_SNK_ALLOCATION_SNK0_MASK;
  467. if (!alloc || alloc == TB_LC_SNK_ALLOCATION_SNK0_CM)
  468. return 0;
  469. } else {
  470. alloc = (val & TB_LC_SNK_ALLOCATION_SNK1_MASK) >>
  471. TB_LC_SNK_ALLOCATION_SNK1_SHIFT;
  472. if (!alloc || alloc == TB_LC_SNK_ALLOCATION_SNK1_CM)
  473. return 0;
  474. }
  475. return -EBUSY;
  476. }
  477. /**
  478. * tb_lc_dp_sink_query() - Is DP sink available for DP IN port
  479. * @sw: Switch whose DP sink is queried
  480. * @in: DP IN port to check
  481. *
  482. * Queries through LC SNK_ALLOCATION registers whether DP sink is available
  483. * for the given DP IN port or not.
  484. *
  485. * Return: %true if DP sink is available, %false otherwise.
  486. */
  487. bool tb_lc_dp_sink_query(struct tb_switch *sw, struct tb_port *in)
  488. {
  489. int sink;
  490. /*
  491. * For older generations sink is always available as there is no
  492. * allocation mechanism.
  493. */
  494. if (sw->generation < 3)
  495. return true;
  496. sink = tb_lc_dp_sink_from_port(sw, in);
  497. if (sink < 0)
  498. return false;
  499. return !tb_lc_dp_sink_available(sw, sink);
  500. }
  501. /**
  502. * tb_lc_dp_sink_alloc() - Allocate DP sink
  503. * @sw: Switch whose DP sink is allocated
  504. * @in: DP IN port the DP sink is allocated for
  505. *
  506. * Allocate DP sink for @in via LC SNK_ALLOCATION registers.
  507. *
  508. * Return:
  509. * * %0 - If the resource is available and allocation is successful.
  510. * * %-EBUSY - If resource is not available.
  511. * * Negative errno - Another error occurred.
  512. */
  513. int tb_lc_dp_sink_alloc(struct tb_switch *sw, struct tb_port *in)
  514. {
  515. int ret, sink;
  516. u32 val;
  517. if (sw->generation < 3)
  518. return 0;
  519. sink = tb_lc_dp_sink_from_port(sw, in);
  520. if (sink < 0)
  521. return sink;
  522. ret = tb_lc_dp_sink_available(sw, sink);
  523. if (ret)
  524. return ret;
  525. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  526. sw->cap_lc + TB_LC_SNK_ALLOCATION, 1);
  527. if (ret)
  528. return ret;
  529. if (!sink) {
  530. val &= ~TB_LC_SNK_ALLOCATION_SNK0_MASK;
  531. val |= TB_LC_SNK_ALLOCATION_SNK0_CM;
  532. } else {
  533. val &= ~TB_LC_SNK_ALLOCATION_SNK1_MASK;
  534. val |= TB_LC_SNK_ALLOCATION_SNK1_CM <<
  535. TB_LC_SNK_ALLOCATION_SNK1_SHIFT;
  536. }
  537. ret = tb_sw_write(sw, &val, TB_CFG_SWITCH,
  538. sw->cap_lc + TB_LC_SNK_ALLOCATION, 1);
  539. if (ret)
  540. return ret;
  541. tb_port_dbg(in, "sink %d allocated\n", sink);
  542. return 0;
  543. }
  544. /**
  545. * tb_lc_dp_sink_dealloc() - De-allocate DP sink
  546. * @sw: Switch whose DP sink is de-allocated
  547. * @in: DP IN port whose DP sink is de-allocated
  548. *
  549. * De-allocate DP sink from @in using LC SNK_ALLOCATION registers.
  550. *
  551. * Return: %0 on success, negative errno otherwise.
  552. */
  553. int tb_lc_dp_sink_dealloc(struct tb_switch *sw, struct tb_port *in)
  554. {
  555. int ret, sink;
  556. u32 val;
  557. if (sw->generation < 3)
  558. return 0;
  559. sink = tb_lc_dp_sink_from_port(sw, in);
  560. if (sink < 0)
  561. return sink;
  562. /* Needs to be owned by CM/SW */
  563. ret = tb_lc_dp_sink_available(sw, sink);
  564. if (ret)
  565. return ret;
  566. ret = tb_sw_read(sw, &val, TB_CFG_SWITCH,
  567. sw->cap_lc + TB_LC_SNK_ALLOCATION, 1);
  568. if (ret)
  569. return ret;
  570. if (!sink)
  571. val &= ~TB_LC_SNK_ALLOCATION_SNK0_MASK;
  572. else
  573. val &= ~TB_LC_SNK_ALLOCATION_SNK1_MASK;
  574. ret = tb_sw_write(sw, &val, TB_CFG_SWITCH,
  575. sw->cap_lc + TB_LC_SNK_ALLOCATION, 1);
  576. if (ret)
  577. return ret;
  578. tb_port_dbg(in, "sink %d de-allocated\n", sink);
  579. return 0;
  580. }
  581. /**
  582. * tb_lc_force_power() - Forces LC to be powered on
  583. * @sw: Thunderbolt switch
  584. *
  585. * This is useful to let authentication cycle pass even without
  586. * a Thunderbolt link present.
  587. *
  588. * Return: %0 on success, negative errno otherwise.
  589. */
  590. int tb_lc_force_power(struct tb_switch *sw)
  591. {
  592. u32 in = 0xffff;
  593. return tb_sw_write(sw, &in, TB_CFG_SWITCH, TB_LC_POWER, 1);
  594. }