xhci-mtk.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. * Mediatek XHCI driver for SSUSB.
  3. *
  4. * Copyright (C) 2015 Mediatek Inc.
  5. *
  6. * Author: Arvin Wang <arvin.wang@mediatek.com>,
  7. * Macpaul Lin <macpaul.lin@mediatek.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/kernel.h>
  15. #include <linux/sched.h>
  16. #include <linux/slab.h>
  17. #include <linux/init.h>
  18. #include <linux/list.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/io.h>
  21. #include <xhci-mtk.h>
  22. static struct sch_ep **ss_out_eps[MAX_EP_NUM];
  23. static struct sch_ep **ss_in_eps[MAX_EP_NUM];
  24. static struct sch_ep **hs_eps[MAX_EP_NUM]; /* including tt isoc */
  25. static struct sch_ep **tt_intr_eps[MAX_EP_NUM];
  26. int mtk_xhci_scheduler_init(void)
  27. {
  28. int i;
  29. for (i = 0; i < MAX_EP_NUM; i++)
  30. ss_out_eps[i] = NULL;
  31. for (i = 0; i < MAX_EP_NUM; i++)
  32. ss_in_eps[i] = NULL;
  33. for (i = 0; i < MAX_EP_NUM; i++)
  34. hs_eps[i] = NULL;
  35. for (i = 0; i < MAX_EP_NUM; i++)
  36. tt_intr_eps[i] = NULL;
  37. return 0;
  38. }
  39. int add_sch_ep(int dev_speed, int is_in, int isTT, int ep_type, int maxp,
  40. int interval, int burst, int mult, int offset, int repeat,
  41. int pkts, int cs_count, int burst_mode, int bw_cost,
  42. mtk_u32 *ep, struct sch_ep *tmp_ep)
  43. {
  44. struct sch_ep **ep_array;
  45. int i;
  46. if (is_in && dev_speed == USB_SPEED_SUPER)
  47. ep_array = (struct sch_ep **)ss_in_eps;
  48. else if (dev_speed == USB_SPEED_SUPER)
  49. ep_array = (struct sch_ep **)ss_out_eps;
  50. else if (dev_speed == USB_SPEED_HIGH || (isTT && ep_type == USB_EP_ISOC))
  51. ep_array = (struct sch_ep **)hs_eps;
  52. else
  53. ep_array = (struct sch_ep **)tt_intr_eps;
  54. for (i = 0; i < MAX_EP_NUM; i++) {
  55. if (ep_array[i] == NULL) {
  56. tmp_ep->dev_speed = dev_speed;
  57. tmp_ep->isTT = isTT;
  58. tmp_ep->is_in = is_in;
  59. tmp_ep->ep_type = ep_type;
  60. tmp_ep->maxp = maxp;
  61. tmp_ep->interval = interval;
  62. tmp_ep->burst = burst;
  63. tmp_ep->mult = mult;
  64. tmp_ep->offset = offset;
  65. tmp_ep->repeat = repeat;
  66. tmp_ep->pkts = pkts;
  67. tmp_ep->cs_count = cs_count;
  68. tmp_ep->burst_mode = burst_mode;
  69. tmp_ep->bw_cost = bw_cost;
  70. tmp_ep->ep = ep;
  71. ep_array[i] = tmp_ep;
  72. return SCH_SUCCESS;
  73. }
  74. }
  75. return SCH_FAIL;
  76. }
  77. int count_ss_bw(int is_in, int ep_type, int maxp, int interval, int burst,
  78. int mult, int offset, int repeat, int td_size)
  79. {
  80. int i, j, k;
  81. int bw_required[3];
  82. int final_bw_required;
  83. int bw_required_per_repeat;
  84. int tmp_bw_required;
  85. struct sch_ep *cur_sch_ep;
  86. struct sch_ep **ep_array;
  87. int cur_offset;
  88. int cur_ep_offset;
  89. int tmp_offset;
  90. int tmp_interval;
  91. int ep_offset;
  92. int ep_interval;
  93. int ep_repeat;
  94. int ep_mult;
  95. if (is_in)
  96. ep_array = (struct sch_ep **)ss_in_eps;
  97. else
  98. ep_array = (struct sch_ep **)ss_out_eps;
  99. bw_required[0] = 0;
  100. bw_required[1] = 0;
  101. bw_required[2] = 0;
  102. if (repeat == 0) {
  103. final_bw_required = 0;
  104. for (i = 0; i < MAX_EP_NUM; i++) {
  105. cur_sch_ep = ep_array[i];
  106. if (cur_sch_ep == NULL)
  107. continue;
  108. ep_interval = cur_sch_ep->interval;
  109. ep_offset = cur_sch_ep->offset;
  110. if (cur_sch_ep->repeat == 0) {
  111. if (ep_interval >= interval) {
  112. tmp_offset = ep_offset + ep_interval - offset;
  113. tmp_interval = interval;
  114. } else {
  115. tmp_offset = offset + interval - ep_offset;
  116. tmp_interval = ep_interval;
  117. }
  118. if (tmp_offset % tmp_interval == 0)
  119. final_bw_required += cur_sch_ep->bw_cost;
  120. } else {
  121. ep_repeat = cur_sch_ep->repeat;
  122. ep_mult = cur_sch_ep->mult;
  123. for (k = 0; k <= ep_mult; k++) {
  124. cur_ep_offset = ep_offset + (k * ep_mult);
  125. if (ep_interval >= interval) {
  126. tmp_offset = cur_ep_offset + ep_interval - offset;
  127. tmp_interval = interval;
  128. } else {
  129. tmp_offset = offset + interval - cur_ep_offset;
  130. tmp_interval = ep_interval;
  131. }
  132. if (tmp_offset % tmp_interval == 0) {
  133. final_bw_required += cur_sch_ep->bw_cost;
  134. break;
  135. }
  136. }
  137. }
  138. }
  139. final_bw_required += td_size;
  140. } else {
  141. bw_required_per_repeat = maxp * (burst + 1);
  142. for (j = 0; j <= mult; j++) {
  143. tmp_bw_required = 0;
  144. cur_offset = offset + (j * repeat);
  145. for (i = 0; i < MAX_EP_NUM; i++) {
  146. cur_sch_ep = ep_array[i];
  147. if (cur_sch_ep == NULL)
  148. continue;
  149. ep_interval = cur_sch_ep->interval;
  150. ep_offset = cur_sch_ep->offset;
  151. if (cur_sch_ep->repeat == 0) {
  152. if (ep_interval >= interval) {
  153. tmp_offset = ep_offset + ep_interval - cur_offset;
  154. tmp_interval = interval;
  155. } else {
  156. tmp_offset = cur_offset + interval - ep_offset;
  157. tmp_interval = ep_interval;
  158. }
  159. if (tmp_offset % tmp_interval == 0)
  160. tmp_bw_required += cur_sch_ep->bw_cost;
  161. } else {
  162. ep_repeat = cur_sch_ep->repeat;
  163. ep_mult = cur_sch_ep->mult;
  164. for (k = 0; k <= ep_mult; k++) {
  165. cur_ep_offset = ep_offset + (k * ep_repeat);
  166. if (ep_interval >= interval) {
  167. tmp_offset = cur_ep_offset + ep_interval - cur_offset;
  168. tmp_interval = interval;
  169. } else {
  170. tmp_offset = cur_offset + interval - cur_ep_offset;
  171. tmp_interval = ep_interval;
  172. }
  173. if (tmp_offset % tmp_interval == 0) {
  174. tmp_bw_required += cur_sch_ep->bw_cost;
  175. break;
  176. }
  177. }
  178. }
  179. }
  180. bw_required[j] = tmp_bw_required;
  181. }
  182. final_bw_required = SS_BW_BOUND;
  183. for (j = 0; j <= mult; j++) {
  184. if (bw_required[j] < final_bw_required)
  185. final_bw_required = bw_required[j];
  186. }
  187. final_bw_required += bw_required_per_repeat;
  188. }
  189. return final_bw_required;
  190. }
  191. int count_hs_bw(int ep_type, int maxp, int interval, int offset, int td_size)
  192. {
  193. int i;
  194. int bw_required;
  195. struct sch_ep *cur_sch_ep;
  196. int tmp_offset;
  197. int tmp_interval;
  198. int ep_offset;
  199. int ep_interval;
  200. int cur_tt_isoc_interval; /* for isoc tt check */
  201. bw_required = 0;
  202. for (i = 0; i < MAX_EP_NUM; i++) {
  203. cur_sch_ep = (struct sch_ep *)hs_eps[i];
  204. if (cur_sch_ep == NULL)
  205. continue;
  206. ep_offset = cur_sch_ep->offset;
  207. ep_interval = cur_sch_ep->interval;
  208. if (cur_sch_ep->isTT && cur_sch_ep->ep_type == USB_EP_ISOC) {
  209. cur_tt_isoc_interval = ep_interval << 3;
  210. if (ep_interval >= interval) {
  211. tmp_offset = ep_offset + cur_tt_isoc_interval - offset;
  212. tmp_interval = interval;
  213. } else {
  214. tmp_offset = offset + interval - ep_offset;
  215. tmp_interval = cur_tt_isoc_interval;
  216. }
  217. if (cur_sch_ep->is_in) {
  218. if ((tmp_offset % tmp_interval >= 2)
  219. && (tmp_offset % tmp_interval <= cur_sch_ep->cs_count)) {
  220. bw_required += 188;
  221. }
  222. } else {
  223. if (tmp_offset % tmp_interval <= cur_sch_ep->cs_count)
  224. bw_required += 188;
  225. }
  226. } else {
  227. if (ep_interval >= interval) {
  228. tmp_offset = ep_offset + ep_interval - offset;
  229. tmp_interval = interval;
  230. } else {
  231. tmp_offset = offset + interval - ep_offset;
  232. tmp_interval = ep_interval;
  233. }
  234. if (tmp_offset % tmp_interval == 0)
  235. bw_required += cur_sch_ep->bw_cost;
  236. }
  237. }
  238. bw_required += td_size;
  239. return bw_required;
  240. }
  241. int count_tt_isoc_bw(int is_in, int maxp, int interval, int offset, int td_size)
  242. {
  243. char is_cs;
  244. int s_frame, s_mframe, cur_mframe;
  245. int bw_required, max_bw;
  246. int ss_cs_count;
  247. int cs_mframe;
  248. int i, j;
  249. struct sch_ep *cur_sch_ep;
  250. int ep_offset;
  251. int ep_interval;
  252. int tt_isoc_interval; /* for isoc tt check */
  253. int cur_tt_isoc_interval; /* for isoc tt check */
  254. int tmp_offset;
  255. int tmp_interval;
  256. is_cs = 0;
  257. tt_isoc_interval = interval << 3; /* frame to mframe */
  258. if (is_in)
  259. is_cs = 1;
  260. s_frame = offset / 8;
  261. s_mframe = offset % 8;
  262. ss_cs_count = (maxp + (188 - 1)) / 188;
  263. if (is_cs) {
  264. cs_mframe = offset % 8 + 2 + ss_cs_count;
  265. if (cs_mframe <= 6)
  266. ss_cs_count += 2;
  267. else if (cs_mframe == 7)
  268. ss_cs_count++;
  269. else if (cs_mframe > 8)
  270. return -1;
  271. }
  272. max_bw = 0;
  273. if (is_in)
  274. i = 2;
  275. for (cur_mframe = offset + i; i < ss_cs_count; cur_mframe++, i++) {
  276. bw_required = 0;
  277. for (j = 0; j < MAX_EP_NUM; j++) {
  278. cur_sch_ep = (struct sch_ep *)hs_eps[j];
  279. if (cur_sch_ep == NULL)
  280. continue;
  281. ep_offset = cur_sch_ep->offset;
  282. ep_interval = cur_sch_ep->interval;
  283. if (cur_sch_ep->isTT && cur_sch_ep->ep_type == USB_EP_ISOC) {
  284. /* isoc tt */
  285. /* check if mframe offset overlap */
  286. /* if overlap, add 188 to the bw */
  287. cur_tt_isoc_interval = ep_interval << 3;
  288. if (cur_tt_isoc_interval >= tt_isoc_interval) {
  289. tmp_offset =
  290. (ep_offset + cur_tt_isoc_interval) - cur_mframe;
  291. tmp_interval = tt_isoc_interval;
  292. } else {
  293. tmp_offset = (cur_mframe + tt_isoc_interval) - ep_offset;
  294. tmp_interval = cur_tt_isoc_interval;
  295. }
  296. if (cur_sch_ep->is_in) {
  297. if ((tmp_offset % tmp_interval >= 2)
  298. && (tmp_offset % tmp_interval <= cur_sch_ep->cs_count)) {
  299. bw_required += 188;
  300. }
  301. } else {
  302. if (tmp_offset % tmp_interval <= cur_sch_ep->cs_count)
  303. bw_required += 188;
  304. }
  305. } else if (cur_sch_ep->ep_type == USB_EP_INT
  306. || cur_sch_ep->ep_type == USB_EP_ISOC) {
  307. /* check if mframe */
  308. if (ep_interval >= tt_isoc_interval) {
  309. tmp_offset = (ep_offset + ep_interval) - cur_mframe;
  310. tmp_interval = tt_isoc_interval;
  311. } else {
  312. tmp_offset = (cur_mframe + tt_isoc_interval) - ep_offset;
  313. tmp_interval = ep_interval;
  314. }
  315. if (tmp_offset % tmp_interval == 0)
  316. bw_required += cur_sch_ep->bw_cost;
  317. }
  318. }
  319. bw_required += 188;
  320. if (bw_required > max_bw)
  321. max_bw = bw_required;
  322. }
  323. return max_bw;
  324. }
  325. int count_tt_intr_bw(int interval, int frame_offset)
  326. {
  327. /* check all eps in tt_intr_eps */
  328. int ret;
  329. int i;
  330. int ep_offset;
  331. int ep_interval;
  332. int tmp_offset;
  333. int tmp_interval;
  334. struct sch_ep *cur_sch_ep;
  335. ret = SCH_SUCCESS;
  336. for (i = 0; i < MAX_EP_NUM; i++) {
  337. cur_sch_ep = (struct sch_ep *)tt_intr_eps[i];
  338. if (cur_sch_ep == NULL)
  339. continue;
  340. ep_offset = cur_sch_ep->offset;
  341. ep_interval = cur_sch_ep->interval;
  342. if (ep_interval >= interval) {
  343. tmp_offset = ep_offset + ep_interval - frame_offset;
  344. tmp_interval = interval;
  345. } else {
  346. tmp_offset = frame_offset + interval - ep_offset;
  347. tmp_interval = ep_interval;
  348. }
  349. if (tmp_offset % tmp_interval == 0)
  350. return SCH_FAIL;
  351. }
  352. return SCH_SUCCESS;
  353. }
  354. struct sch_ep *mtk_xhci_scheduler_remove_ep(int dev_speed, int is_in, int isTT,
  355. int ep_type, mtk_u32 *ep)
  356. {
  357. int i;
  358. struct sch_ep **ep_array;
  359. struct sch_ep *cur_ep;
  360. if (is_in && dev_speed == USB_SPEED_SUPER)
  361. ep_array = (struct sch_ep **)ss_in_eps;
  362. else if (dev_speed == USB_SPEED_SUPER)
  363. ep_array = (struct sch_ep **)ss_out_eps;
  364. else if (dev_speed == USB_SPEED_HIGH || (isTT && ep_type == USB_EP_ISOC))
  365. ep_array = (struct sch_ep **)hs_eps;
  366. else
  367. ep_array = (struct sch_ep **)tt_intr_eps;
  368. for (i = 0; i < MAX_EP_NUM; i++) {
  369. cur_ep = (struct sch_ep *)ep_array[i];
  370. if (cur_ep != NULL && cur_ep->ep == ep) {
  371. ep_array[i] = NULL;
  372. return cur_ep;
  373. }
  374. }
  375. return NULL;
  376. }
  377. int mtk_xhci_scheduler_add_ep(int dev_speed, int is_in, int isTT, int ep_type,
  378. int maxp, int interval, int burst, int mult,
  379. mtk_u32 *ep, mtk_u32 *ep_ctx,
  380. struct sch_ep *sch_ep)
  381. {
  382. mtk_u32 bPkts = 0;
  383. mtk_u32 bCsCount = 0;
  384. mtk_u32 bBm = 1;
  385. mtk_u32 bOffset = 0;
  386. mtk_u32 bRepeat = 0;
  387. int ret;
  388. struct mtk_xhci_ep_ctx *temp_ep_ctx;
  389. int td_size;
  390. int mframe_idx, frame_idx;
  391. int bw_cost;
  392. int cur_bw, best_bw, best_bw_idx, repeat, max_repeat, best_bw_repeat;
  393. int cur_offset, cs_mframe;
  394. int break_out;
  395. int frame_interval;
  396. best_bw_repeat = 0;
  397. pr_debug("add_ep parameters, dev_speed : %d\n"
  398. "is_in : %d\n"
  399. "isTT : %d\n"
  400. "ep_type : %d\n"
  401. "maxp : %d\n"
  402. "interval: %d\n"
  403. "burst : %d\n"
  404. "mult : %d\n"
  405. "ep : 0x%p\n"
  406. "ep_ctx : 0x%p\n"
  407. "sch_ep : 0x%p\n",
  408. dev_speed, is_in, isTT, ep_type,
  409. maxp, interval, burst, mult,
  410. ep, ep_ctx, sch_ep);
  411. if (isTT && ep_type == USB_EP_INT
  412. && ((dev_speed == USB_SPEED_LOW) || (dev_speed == USB_SPEED_FULL))) {
  413. frame_interval = interval >> 3;
  414. for (frame_idx = 0; frame_idx < frame_interval; frame_idx++) {
  415. pr_debug("check tt_intr_bw interval %d, frame_idx %d\n",
  416. frame_interval, frame_idx);
  417. if (count_tt_intr_bw(frame_interval, frame_idx) == SCH_SUCCESS) {
  418. pr_debug("check OK............\n");
  419. bOffset = frame_idx << 3;
  420. bPkts = 1;
  421. bCsCount = 3;
  422. bw_cost = maxp;
  423. bRepeat = 0;
  424. if (add_sch_ep
  425. (dev_speed, is_in, isTT, ep_type, maxp, frame_interval, burst,
  426. mult, bOffset, bRepeat, bPkts, bCsCount, bBm, maxp, ep,
  427. sch_ep) == SCH_FAIL) {
  428. return SCH_FAIL;
  429. }
  430. ret = SCH_SUCCESS;
  431. break;
  432. }
  433. }
  434. } else if (isTT && ep_type == USB_EP_ISOC) {
  435. best_bw = HS_BW_BOUND;
  436. best_bw_idx = -1;
  437. cur_bw = 0;
  438. td_size = maxp;
  439. break_out = 0;
  440. frame_interval = interval >> 3;
  441. for (frame_idx = 0; frame_idx < frame_interval && !break_out; frame_idx++) {
  442. for (mframe_idx = 0; mframe_idx < 8; mframe_idx++) {
  443. cur_offset = (frame_idx * 8) + mframe_idx;
  444. cur_bw =
  445. count_tt_isoc_bw(is_in, maxp, frame_interval, cur_offset,
  446. td_size);
  447. if (cur_bw > 0 && cur_bw < best_bw) {
  448. best_bw_idx = cur_offset;
  449. best_bw = cur_bw;
  450. if (cur_bw == td_size || cur_bw < (HS_BW_BOUND >> 1)) {
  451. break_out = 1;
  452. break;
  453. }
  454. }
  455. }
  456. }
  457. if (best_bw_idx == -1)
  458. return SCH_FAIL;
  459. bOffset = best_bw_idx;
  460. bPkts = 1;
  461. bCsCount = maxp + (188 - 1) / 188;
  462. if (is_in) {
  463. cs_mframe = bOffset % 8 + 2 + bCsCount;
  464. if (cs_mframe <= 6)
  465. bCsCount += 2;
  466. else if (cs_mframe == 7)
  467. bCsCount++;
  468. }
  469. bw_cost = 188;
  470. bRepeat = 0;
  471. if (add_sch_ep
  472. (dev_speed, is_in, isTT, ep_type, maxp, interval, burst, mult, bOffset,
  473. bRepeat, bPkts, bCsCount, bBm, bw_cost, ep, sch_ep) == SCH_FAIL) {
  474. return SCH_FAIL;
  475. }
  476. ret = SCH_SUCCESS;
  477. } else if ((dev_speed == USB_SPEED_FULL || dev_speed == USB_SPEED_LOW)
  478. && ep_type == USB_EP_INT) {
  479. bPkts = 1;
  480. ret = SCH_SUCCESS;
  481. } else if (dev_speed == USB_SPEED_FULL && ep_type == USB_EP_ISOC) {
  482. bPkts = 1;
  483. ret = SCH_SUCCESS;
  484. } else if (dev_speed == USB_SPEED_HIGH && (ep_type == USB_EP_INT || ep_type == USB_EP_ISOC)) {
  485. best_bw = HS_BW_BOUND;
  486. best_bw_idx = -1;
  487. cur_bw = 0;
  488. td_size = maxp * (burst + 1);
  489. for (cur_offset = 0; cur_offset < interval; cur_offset++) {
  490. cur_bw = count_hs_bw(ep_type, maxp, interval, cur_offset, td_size);
  491. if (cur_bw > 0 && cur_bw < best_bw) {
  492. best_bw_idx = cur_offset;
  493. best_bw = cur_bw;
  494. if (cur_bw == td_size || cur_bw < (HS_BW_BOUND >> 1))
  495. break;
  496. }
  497. }
  498. if (best_bw_idx == -1)
  499. return SCH_FAIL;
  500. bOffset = best_bw_idx;
  501. bPkts = burst + 1;
  502. bCsCount = 0;
  503. bw_cost = td_size;
  504. bRepeat = 0;
  505. if (add_sch_ep
  506. (dev_speed, is_in, isTT, ep_type, maxp, interval, burst, mult, bOffset,
  507. bRepeat, bPkts, bCsCount, bBm, bw_cost, ep, sch_ep) == SCH_FAIL) {
  508. return SCH_FAIL;
  509. }
  510. ret = SCH_SUCCESS;
  511. } else if (dev_speed == USB_SPEED_SUPER
  512. && (ep_type == USB_EP_INT || ep_type == USB_EP_ISOC)) {
  513. best_bw = SS_BW_BOUND;
  514. best_bw_idx = -1;
  515. cur_bw = 0;
  516. td_size = maxp * (mult + 1) * (burst + 1);
  517. if (mult == 0)
  518. max_repeat = 0;
  519. else
  520. max_repeat = (interval - 1) / (mult + 1);
  521. break_out = 0;
  522. for (frame_idx = 0; (frame_idx < interval) && !break_out; frame_idx++) {
  523. for (repeat = max_repeat; repeat >= 0; repeat--) {
  524. cur_bw =
  525. count_ss_bw(is_in, ep_type, maxp, interval, burst, mult,
  526. frame_idx, repeat, td_size);
  527. pr_debug
  528. ("count_ss_bw, frame_idx %d, repeat %d, td_size %d, result bw %d\n",
  529. frame_idx, repeat, td_size, cur_bw);
  530. if (cur_bw > 0 && cur_bw < best_bw) {
  531. best_bw_idx = frame_idx;
  532. best_bw_repeat = repeat;
  533. best_bw = cur_bw;
  534. if (cur_bw <= td_size || cur_bw < (HS_BW_BOUND >> 1)) {
  535. break_out = 1;
  536. break;
  537. }
  538. }
  539. }
  540. }
  541. pr_debug("final best idx %d, best repeat %d\n", best_bw_idx, best_bw_repeat);
  542. if (best_bw_idx == -1)
  543. return SCH_FAIL;
  544. bOffset = best_bw_idx;
  545. bCsCount = 0;
  546. bRepeat = best_bw_repeat;
  547. if (bRepeat == 0) {
  548. bw_cost = (burst + 1) * (mult + 1) * maxp;
  549. bPkts = (burst + 1) * (mult + 1);
  550. } else {
  551. bw_cost = (burst + 1) * maxp;
  552. bPkts = (burst + 1);
  553. }
  554. if (add_sch_ep
  555. (dev_speed, is_in, isTT, ep_type, maxp, interval, burst, mult, bOffset,
  556. bRepeat, bPkts, bCsCount, bBm, bw_cost, ep, sch_ep) == SCH_FAIL) {
  557. return SCH_FAIL;
  558. }
  559. ret = SCH_SUCCESS;
  560. } else {
  561. bPkts = 1;
  562. ret = SCH_SUCCESS;
  563. }
  564. if (ret == SCH_SUCCESS) {
  565. temp_ep_ctx = (struct mtk_xhci_ep_ctx *)ep_ctx;
  566. temp_ep_ctx->reserved[0] |= (BPKTS(bPkts) | BCSCOUNT(bCsCount) | BBM(bBm));
  567. temp_ep_ctx->reserved[1] |= (BOFFSET(bOffset) | BREPEAT(bRepeat));
  568. pr_debug("[DBG] BPKTS: %x, BCSCOUNT: %x, BBM: %x\n", (unsigned int)bPkts,
  569. (unsigned int)bCsCount, (unsigned int)bBm);
  570. pr_debug("[DBG] BOFFSET: %x, BREPEAT: %x\n", (unsigned int)bOffset,
  571. (unsigned int)bRepeat);
  572. return SCH_SUCCESS;
  573. } else {
  574. return SCH_FAIL;
  575. }
  576. }
  577. void mtk_xhci_vbus_on(struct platform_device *pdev)
  578. {
  579. struct pinctrl *pinctrl;
  580. struct pinctrl_state *pinctrl_drvvbus_high;
  581. pinctrl = devm_pinctrl_get(&pdev->dev);
  582. if (IS_ERR(pinctrl)) {
  583. dev_err(&pdev->dev, "Cannot find usb pinctrl!\n");
  584. return;
  585. }
  586. pinctrl_drvvbus_high = pinctrl_lookup_state(pinctrl, "drvvbus_high");
  587. if (IS_ERR(pinctrl_drvvbus_high)) {
  588. dev_err(&pdev->dev, "Cannot find usb pinctrl drvvbus_high\n");
  589. return;
  590. }
  591. pinctrl_select_state(pinctrl, pinctrl_drvvbus_high);
  592. }
  593. void mtk_xhci_vbus_off(struct platform_device *pdev)
  594. {
  595. struct pinctrl *pinctrl;
  596. struct pinctrl_state *pinctrl_drvvbus_low;
  597. pinctrl = devm_pinctrl_get(&pdev->dev);
  598. if (IS_ERR(pinctrl)) {
  599. dev_err(&pdev->dev, "Cannot find usb pinctrl!\n");
  600. return;
  601. }
  602. pinctrl_drvvbus_low = pinctrl_lookup_state(pinctrl, "drvvbus_low");
  603. if (IS_ERR(pinctrl_drvvbus_low)) {
  604. dev_err(&pdev->dev, "Cannot find usb pinctrl drvvbus_low\n");
  605. return;
  606. }
  607. pinctrl_select_state(pinctrl, pinctrl_drvvbus_low);
  608. }
  609. MODULE_DESCRIPTION(DRIVER_DESC);
  610. MODULE_AUTHOR("Arvin Wang <arvin.wang@mediatek.com>");
  611. MODULE_AUTHOR("Macpaul Lin <macpaul.lin@mediatek.com>");
  612. MODULE_LICENSE("GPL");