mu3d_hal_usb_drv.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. /* #include "mu3d_hal_osal.h" */
  2. /* #define _MTK_USB_DRV_EXT_ */
  3. #include "mu3d_hal_usb_drv.h"
  4. /* #undef _MTK_USB_DRV_EXT_ */
  5. #include "mu3d_hal_hw.h"
  6. #include "mu3d_hal_qmu_drv.h"
  7. /* #include "./new/mu3d_hal_comm.h" */
  8. /* #include <linux/mu3phy/mtk-phy.h> */
  9. #include "ssusb_io.h"
  10. static struct usb_ep_setting g_u3d_ep_setting[2 * MAX_EP_NUM + 1];
  11. static u32 g_TxFIFOadd;
  12. static u32 g_RxFIFOadd;
  13. int wait_for_value(void __iomem *base, int addr, int msk, int value, int ms_intvl, int count)
  14. {
  15. u32 i;
  16. for (i = 0; i < count; i++) {
  17. if ((mu3d_readl(base, addr) & msk) == value)
  18. return 0;
  19. mdelay(ms_intvl);
  20. }
  21. return -EBUSY;
  22. }
  23. /**
  24. * mu3d_hal_check_clk_sts - check sys125,u3 mac,u2 mac clock status
  25. *
  26. */
  27. int mu3d_hal_check_clk_sts(struct musb *musb)
  28. {
  29. int ret;
  30. mu3d_dbg(K_ERR, "%s\n", __func__);
  31. ret = wait_for_value(musb->sif_base, U3D_SSUSB_IP_PW_STS1, SSUSB_SYS125_RST_B_STS,
  32. SSUSB_SYS125_RST_B_STS, 1, 10);
  33. if (ret)
  34. mu3d_dbg(K_ERR, "SSUSB_SYS125_RST_B_STS NG\n");
  35. /* do not check when SSUSB_U2_PORT_PDN = 1, because U2 port stays in reset state */
  36. if (!(mu3d_readl(musb->sif_base, U3D_SSUSB_U2_CTRL_0P) & SSUSB_U2_PORT_PDN)) {
  37. ret =
  38. wait_for_value(musb->sif_base, U3D_SSUSB_IP_PW_STS2, SSUSB_U2_MAC_SYS_RST_B_STS,
  39. SSUSB_U2_MAC_SYS_RST_B_STS, 1, 10);
  40. if (ret)
  41. mu3d_dbg(K_ERR, "SSUSB_U2_MAC_SYS_RST_B_STS NG\n");
  42. }
  43. #ifdef SUPPORT_U3
  44. /* do not check when SSUSB_U3_PORT_PDN = 1, because U3 port stays in reset state */
  45. if (!(mu3d_readl(musb->sif_base, U3D_SSUSB_U3_CTRL_0P) & SSUSB_U3_PORT_PDN)) {
  46. ret = wait_for_value(musb->sif_base, U3D_SSUSB_IP_PW_STS1, SSUSB_U3_MAC_RST_B_STS,
  47. SSUSB_U3_MAC_RST_B_STS, 1, 10);
  48. if (ret)
  49. mu3d_dbg(K_ERR, "SSUSB_U3_MAC_RST_B_STS NG\n");
  50. }
  51. #endif
  52. mu3d_dbg(K_CRIT, "check clk pass!!\n");
  53. return 0;
  54. }
  55. /**
  56. * mu3d_hal_ssusb_en - disable ssusb power down & enable u2/u3 ports
  57. *
  58. */
  59. void mu3d_hal_ssusb_en(struct musb *musb)
  60. {
  61. void __iomem *sif_base = musb->sif_base;
  62. mu3d_dbg(K_INFO, "%s\n", __func__);
  63. mu3d_clrmsk(sif_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
  64. mu3d_clrmsk(sif_base, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
  65. #ifdef SUPPORT_U3
  66. mu3d_clrmsk(sif_base, U3D_SSUSB_U3_CTRL_0P,
  67. (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_HOST_SEL));
  68. #endif
  69. mu3d_clrmsk(sif_base, U3D_SSUSB_U2_CTRL_0P,
  70. (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_HOST_SEL));
  71. mu3d_dbg(K_INFO, "%s 0x:%x = 0x%x\n", __func__, U3D_SSUSB_U2_CTRL_0P,
  72. mu3d_readl(sif_base, U3D_SSUSB_U2_CTRL_0P));
  73. mu3d_setmsk(sif_base, U3D_SSUSB_REF_CK_CTRL,
  74. (SSUSB_REF_MAC_CK_GATE_EN | SSUSB_REF_PHY_CK_GATE_EN | SSUSB_REF_CK_GATE_EN |
  75. SSUSB_REF_MAC3_CK_GATE_EN));
  76. /* check U3D sys125,u3 mac,u2 mac clock status. */
  77. mu3d_hal_check_clk_sts(musb);
  78. }
  79. void mu3d_hal_ssusb_dis(struct musb *musb)
  80. {
  81. void __iomem *sif_base = musb->sif_base;
  82. mu3d_dbg(K_INFO, "%s\n", __func__);
  83. #ifdef SUPPORT_U3
  84. mu3d_setmsk(sif_base, U3D_SSUSB_U3_CTRL_0P, (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN));
  85. #endif
  86. mu3d_setmsk(sif_base, U3D_SSUSB_U2_CTRL_0P, (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN));
  87. mu3d_setmsk(sif_base, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
  88. mu3d_dbg(K_INFO, "%s 0x:%x = 0x%x\n", __func__, U3D_SSUSB_U2_CTRL_0P,
  89. mu3d_readl(sif_base, U3D_SSUSB_U2_CTRL_0P));
  90. }
  91. /**
  92. * mu3d_hal_rst_dev - reset all device modules
  93. *
  94. */
  95. void mu3d_hal_rst_dev(struct musb *musb)
  96. {
  97. void __iomem *sif_base = musb->sif_base;
  98. int ret;
  99. mu3d_dbg(K_ERR, "%s\n", __func__);
  100. mu3d_writel(sif_base, U3D_SSUSB_DEV_RST_CTRL, SSUSB_DEV_SW_RST);
  101. mu3d_writel(sif_base, U3D_SSUSB_DEV_RST_CTRL, 0);
  102. mu3d_hal_check_clk_sts(musb);
  103. ret = wait_for_value(sif_base, U3D_SSUSB_IP_PW_STS1, SSUSB_DEV_QMU_RST_B_STS,
  104. SSUSB_DEV_QMU_RST_B_STS, 1, 10);
  105. if (ret)
  106. mu3d_dbg(K_ERR, "SSUSB_DEV_QMU_RST_B_STS NG\n");
  107. ret = wait_for_value(sif_base, U3D_SSUSB_IP_PW_STS1, SSUSB_DEV_BMU_RST_B_STS,
  108. SSUSB_DEV_BMU_RST_B_STS, 1, 10);
  109. if (ret)
  110. mu3d_dbg(K_ERR, "SSUSB_DEV_BMU_RST_B_STS NG\n");
  111. ret = wait_for_value(sif_base, U3D_SSUSB_IP_PW_STS1, SSUSB_DEV_RST_B_STS,
  112. SSUSB_DEV_RST_B_STS, 1, 10);
  113. if (ret)
  114. mu3d_dbg(K_ERR, "SSUSB_DEV_RST_B_STS NG\n");
  115. }
  116. #ifdef CONFIG_MTK_FPGA
  117. /**
  118. * mu3d_hal_link_up - u3d link up
  119. *
  120. */
  121. int mu3d_hal_link_up(struct musb *musb, int latch_val)
  122. {
  123. mu3d_hal_ssusb_en(musb);
  124. mu3d_hal_rst_dev(musb);
  125. mdelay(50);
  126. mu3d_writel(musb->mac_base, U3D_USB3_CONFIG, USB3_EN);
  127. mu3d_writel(musb->mac_base, U3D_PIPE_LATCH_SELECT, latch_val); /* set tx/rx latch sel */
  128. return 0;
  129. }
  130. #endif
  131. /**
  132. * mu3d_hal_initr_dis - disable all interrupts
  133. *
  134. */
  135. void mu3d_hal_initr_dis(struct musb *musb)
  136. {
  137. void __iomem *mbase = musb->mac_base;
  138. /* Disable Level 1 interrupts */
  139. mu3d_writel(mbase, U3D_LV1IECR, 0xFFFFFFFF);
  140. /* Disable Endpoint interrupts */
  141. mu3d_writel(mbase, U3D_EPIECR, 0xFFFFFFFF);
  142. /* Disable DMA interrupts */
  143. mu3d_writel(mbase, U3D_DMAIECR, 0xFFFFFFFF);
  144. }
  145. void mu3d_hal_clear_intr(struct musb *musb)
  146. {
  147. void __iomem *mbase = musb->mac_base;
  148. mu3d_dbg(K_ERR, "%s\n", __func__);
  149. /* Clear EP0 and Tx/Rx EPn interrupts status */
  150. mu3d_writel(mbase, U3D_EPISR, 0xFFFFFFFF);
  151. /* Clear EP0 and Tx/Rx EPn DMA interrupts status */
  152. mu3d_writel(mbase, U3D_DMAISR, 0xFFFFFFFF);
  153. /* Clear speed change event */
  154. mu3d_writel(mbase, U3D_DEV_LINK_INTR, 0xFFFFFFFF);
  155. /* Clear U2 USB common interrupt status */
  156. mu3d_writel(mbase, U3D_COMMON_USB_INTR, 0xFFFFFFFF);
  157. /* Clear U3 LTSSM interrupt status */
  158. mu3d_writel(mbase, U3D_LTSSM_INTR, 0xFFFFFFFF);
  159. }
  160. /**
  161. * mu3d_hal_system_intr_en - enable system global interrupt
  162. *
  163. */
  164. void mu3d_hal_system_intr_en(struct musb *musb)
  165. {
  166. void __iomem *mbase = musb->mac_base;
  167. u32 int_en;
  168. #ifdef SUPPORT_U3
  169. u32 ltssm_int_en;
  170. #endif
  171. mu3d_dbg(K_ERR, "%s\n", __func__);
  172. /* Disable All endpoint interrupt */
  173. mu3d_writel(mbase, U3D_EPIECR, mu3d_readl(mbase, U3D_EPIER));
  174. /* Disable All DMA interrput */
  175. mu3d_writel(mbase, U3D_DMAIECR, mu3d_readl(mbase, U3D_DMAIER));
  176. /* Disable U2 common USB interrupts */
  177. mu3d_writel(mbase, U3D_COMMON_USB_INTR_ENABLE, 0x00);
  178. /* Clear U2 common USB interrupts status */
  179. mu3d_writel(mbase, U3D_COMMON_USB_INTR, mu3d_readl(mbase, U3D_COMMON_USB_INTR));
  180. /* Enable U2 common USB interrupt */
  181. int_en = SUSPEND_INTR_EN | RESUME_INTR_EN | RESET_INTR_EN | CONN_INTR_EN | DISCONN_INTR_EN
  182. | VBUSERR_INTR_EN | LPM_INTR_EN | LPM_RESUME_INTR_EN;
  183. mu3d_writel(mbase, U3D_COMMON_USB_INTR_ENABLE, int_en);
  184. #ifdef SUPPORT_U3
  185. /* Disable U3 LTSSM interrupts */
  186. mu3d_writel(mbase, U3D_LTSSM_INTR_ENABLE, 0x00);
  187. mu3d_dbg(K_ERR, "U3D_LTSSM_INTR: %x\n", mu3d_readl(mbase, U3D_LTSSM_INTR));
  188. /* Clear U3 LTSSM interrupts */
  189. mu3d_writel(mbase, U3D_LTSSM_INTR, mu3d_readl(mbase, U3D_LTSSM_INTR));
  190. /* Enable U3 LTSSM interrupts */
  191. ltssm_int_en =
  192. SS_INACTIVE_INTR_EN | SS_DISABLE_INTR_EN | COMPLIANCE_INTR_EN | LOOPBACK_INTR_EN |
  193. HOT_RST_INTR_EN | WARM_RST_INTR_EN | RECOVERY_INTR_EN | ENTER_U0_INTR_EN |
  194. ENTER_U1_INTR_EN | ENTER_U2_INTR_EN | ENTER_U3_INTR_EN | EXIT_U1_INTR_EN |
  195. EXIT_U2_INTR_EN | EXIT_U3_INTR_EN | RXDET_SUCCESS_INTR_EN | VBUS_RISE_INTR_EN |
  196. VBUS_FALL_INTR_EN | U3_LFPS_TMOUT_INTR_EN | U3_RESUME_INTR_EN;
  197. mu3d_writel(mbase, U3D_LTSSM_INTR_ENABLE, ltssm_int_en);
  198. #endif
  199. if (need_vbus_chg_int(musb)) {
  200. mu3d_writel(musb->sif_base, U3D_SSUSB_OTG_INT_EN, 0x0);
  201. mu3d_dbg(K_ERR, "U3D_SSUSB_OTG_STS: %x\n",
  202. mu3d_readl(musb->sif_base, U3D_SSUSB_OTG_STS));
  203. mu3d_writel(musb->sif_base, U3D_SSUSB_OTG_STS_CLR,
  204. mu3d_readl(musb->sif_base, U3D_SSUSB_OTG_STS));
  205. mu3d_writel(musb->sif_base, U3D_SSUSB_OTG_INT_EN, SSUSB_VBUS_CHG_INT_B_EN);
  206. }
  207. #ifdef USE_SSUSB_QMU
  208. /* Enable QMU interrupt. */
  209. mu3d_writel(mbase, U3D_QIESR1, TXQ_EMPTY_IESR | TXQ_CSERR_IESR | TXQ_LENERR_IESR |
  210. RXQ_EMPTY_IESR | RXQ_CSERR_IESR | RXQ_LENERR_IESR | RXQ_ZLPERR_IESR);
  211. #endif
  212. /* Enable EP0 DMA interrupt */
  213. mu3d_writel(mbase, U3D_DMAIESR, EP0DMAIESR);
  214. /* Enable speed change interrupt */
  215. mu3d_writel(mbase, U3D_DEV_LINK_INTR_ENABLE, SSUSB_DEV_SPEED_CHG_INTR_EN);
  216. }
  217. /**
  218. * mu3d_hal_u2dev_connect - u2 device softconnect
  219. *
  220. */
  221. void mu3d_hal_u2dev_connect(struct musb *musb)
  222. {
  223. mu3d_setmsk(musb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN);
  224. mu3d_setmsk(musb->mac_base, U3D_POWER_MANAGEMENT, SUSPENDM_ENABLE);
  225. mu3d_dbg(K_INFO, "SOFTCONN = 1\n");
  226. }
  227. void mu3d_hal_u2dev_disconn(struct musb *musb)
  228. {
  229. mu3d_clrmsk(musb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN);
  230. mu3d_clrmsk(musb->mac_base, U3D_POWER_MANAGEMENT, SUSPENDM_ENABLE);
  231. mu3d_dbg(K_INFO, "SOFTCONN = 0\n");
  232. }
  233. /**
  234. * mu3d_hal_u3dev_en - enable U3D SS dev
  235. *
  236. */
  237. void mu3d_hal_u3dev_en(struct musb *musb)
  238. {
  239. /*
  240. * Enable super speed function.
  241. */
  242. mu3d_writel(musb->mac_base, U3D_USB3_CONFIG, USB3_EN);
  243. mu3d_dbg(K_INFO, "USB3_EN = 1\n");
  244. }
  245. /**
  246. * mu3d_hal_u3dev_dis - disable U3D SS dev
  247. *
  248. */
  249. void mu3d_hal_u3dev_dis(struct musb *musb)
  250. {
  251. /*
  252. * If usb3_en =0 => LTSSM will go to SS.Disable state.
  253. */
  254. mu3d_writel(musb->mac_base, U3D_USB3_CONFIG, 0);
  255. mu3d_dbg(K_INFO, "USB3_EN = 0\n");
  256. }
  257. /**
  258. * mu3d_hal_pdn_cg_en - enable U2/U3 pdn & cg
  259. *@args -
  260. */
  261. /* void mu3d_hal_pdn_cg_en(void) */
  262. /* { */
  263. /* } */
  264. /* void mu3d_hal_pdn_ip_port(u8 on, u8 touch_dis, u8 u3, u8 u2) */
  265. /* { */
  266. /* } */
  267. /**
  268. * mu3d_hal_write_fifo - pio write one packet
  269. *@args - arg1: ep number, arg2: data length, arg3: data buffer, arg4: max packet size
  270. */
  271. int mu3d_hal_write_fifo(struct musb_hw_ep *hw_ep, int ep_num, int length, u8 *buf, int maxp)
  272. {
  273. struct musb *musb = hw_ep->musb;
  274. void __iomem *fifo = hw_ep->fifo;
  275. void __iomem *mbase = musb->mac_base;
  276. u32 residue;
  277. u32 count;
  278. u32 temp;
  279. mu3d_dbg(K_DEBUG, "%s epnum=%d, len=%d, buf=%p, maxp=%d\n", __func__, ep_num, length, buf,
  280. maxp);
  281. count = residue = length;
  282. while (residue > 0) {
  283. if (residue == 1) {
  284. temp = ((*buf) & 0xFF);
  285. mu3d_writeb(fifo, 0, temp);
  286. buf += 1;
  287. residue -= 1;
  288. } else if (residue == 2) {
  289. temp = ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00);
  290. mu3d_writew(fifo, 0, temp);
  291. buf += 2;
  292. residue -= 2;
  293. } else if (residue == 3) {
  294. temp = ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00);
  295. mu3d_writew(fifo, 0, temp);
  296. buf += 2;
  297. temp = ((*buf) & 0xFF);
  298. mu3d_writeb(fifo, 0, temp);
  299. buf += 1;
  300. residue -= 3;
  301. } else {
  302. temp =
  303. ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00) +
  304. (((*(buf + 2)) << 16) & 0xFF0000) + (((*(buf + 3)) << 24) & 0xFF000000);
  305. mu3d_writel(fifo, 0, temp);
  306. buf += 4;
  307. residue -= 4;
  308. }
  309. }
  310. if (ep_num == 0) {
  311. if (count == 0) {
  312. mu3d_dbg(K_DEBUG, "USB_EP0_DATAEND %8X+\n", mu3d_readl(mbase, U3D_EP0CSR));
  313. mu3d_setmsk(mbase, U3D_EP0CSR, EP0_DATAEND | EP0_TXPKTRDY);
  314. mu3d_dbg(K_DEBUG, "USB_EP0_DATAEND %8X-\n", mu3d_readl(mbase, U3D_EP0CSR));
  315. } else {
  316. #ifdef AUTOSET
  317. if (count < maxp) {
  318. mu3d_setmsk(mbase, U3D_EP0CSR, EP0_TXPKTRDY);
  319. mu3d_dbg(K_DEBUG, "EP0_TXPKTRDY\n");
  320. }
  321. #else
  322. mu3d_setmsk(mbase, U3D_EP0CSR, EP0_TXPKTRDY);
  323. #endif
  324. }
  325. } else {
  326. if (count == 0) {
  327. mu3d_setmsk(hw_ep->addr_txcsr0, 0, TX_TXPKTRDY);
  328. } else {
  329. #ifdef AUTOSET
  330. if (count < maxp) {
  331. mu3d_setmsk(hw_ep->addr_txcsr0, 0, TX_TXPKTRDY);
  332. mu3d_dbg(K_DEBUG, "short packet\n");
  333. }
  334. #else
  335. mu3d_setmsk(hw_ep->addr_txcsr0, 0, TX_TXPKTRDY);
  336. #endif
  337. }
  338. }
  339. return count;
  340. }
  341. /**
  342. * mu3d_hal_read_fifo - pio read one packet
  343. *@args - arg1: ep number, arg2: data buffer
  344. */
  345. /* NOTE: The function should not be used to read SETUP */
  346. int mu3d_hal_read_fifo(struct musb_hw_ep *hw_ep, int ep_num, u8 *buf)
  347. {
  348. struct musb *musb = hw_ep->musb;
  349. void __iomem *mbase = musb->mac_base;
  350. u16 count, residue;
  351. u32 temp;
  352. u8 *bp = buf;
  353. if (ep_num == 0)
  354. residue = count = mu3d_readl(mbase, U3D_RXCOUNT0);
  355. else
  356. residue = count = (mu3d_readl(hw_ep->addr_rxcsr3, 0) >> EP_RX_COUNT_OFST);
  357. mu3d_dbg(K_DEBUG, "%s, req->buf=%p, cnt=%d\n", __func__, buf, count);
  358. while (residue > 0) {
  359. temp = mu3d_readl(hw_ep->fifo, 0);
  360. /*Store the first byte */
  361. *bp = temp & 0xFF;
  362. /*Store the 2nd byte, If have */
  363. if (residue > 1)
  364. *(bp + 1) = (temp >> 8) & 0xFF;
  365. /*Store the 3rd byte, If have */
  366. if (residue > 2)
  367. *(bp + 2) = (temp >> 16) & 0xFF;
  368. /*Store the 4th byte, If have */
  369. if (residue > 3)
  370. *(bp + 3) = (temp >> 24) & 0xFF;
  371. if (residue > 4) {
  372. bp = bp + 4;
  373. residue = residue - 4;
  374. } else {
  375. residue = 0;
  376. }
  377. }
  378. #ifdef AUTOCLEAR
  379. if (ep_num == 0) {
  380. if (!count) {
  381. mu3d_setmsk(mbase, U3D_EP0CSR, EP0_RXPKTRDY);
  382. mu3d_dbg(K_DEBUG, "EP0_RXPKTRDY\n");
  383. }
  384. } else {
  385. if (!count) {
  386. mu3d_setmsk(hw_ep->addr_rxcsr0, 0, RX_RXPKTRDY);
  387. mu3d_dbg(K_ALET, "ZLP\n");
  388. }
  389. }
  390. #else
  391. if (ep_num == 0) {
  392. mu3d_setmsk(mbase, U3D_EP0CSR, EP0_RXPKTRDY);
  393. mu3d_dbg(K_DEBUG, "EP0_RXPKTRDY\n");
  394. } else {
  395. mu3d_setmsk(hw_ep->addr_rxcsr0, 0, RX_RXPKTRDY);
  396. mu3d_dbg(K_DEBUG, "RX_RXPKTRDY\n");
  397. }
  398. #endif
  399. return count;
  400. }
  401. /**
  402. * mu3d_hal_unfigured_ep -
  403. *@args -
  404. */
  405. void mu3d_hal_unfigured_ep(struct musb *musb)
  406. {
  407. void __iomem *mbase = musb->mac_base;
  408. u32 i, tx_ep_num, rx_ep_num;
  409. struct usb_ep_setting *ep_setting;
  410. u32 tmp;
  411. g_TxFIFOadd = USB_TX_FIFO_START_ADDRESS;
  412. g_RxFIFOadd = USB_RX_FIFO_START_ADDRESS;
  413. #ifdef HARDCODE_EP
  414. tx_ep_num = MAX_QMU_EP; /* os_readl(U3D_CAP_EPINFO) & CAP_TX_EP_NUM; */
  415. rx_ep_num = MAX_QMU_EP; /* (os_readl(U3D_CAP_EPINFO) & CAP_RX_EP_NUM) >> 8; */
  416. #else
  417. tx_ep_num = mu3d_readl(mbase, U3D_CAP_EPINFO) & CAP_TX_EP_NUM;
  418. rx_ep_num = (mu3d_readl(mbase, U3D_CAP_EPINFO) & CAP_RX_EP_NUM) >> 8;
  419. #endif
  420. for (i = 1; i <= tx_ep_num; i++) {
  421. tmp = mu3d_xcsr_readl(mbase, U3D_TX1CSR0, i);
  422. tmp &= ~TX_TXMAXPKTSZ;
  423. mu3d_xcsr_writel(mbase, U3D_TX1CSR0, i, tmp);
  424. mu3d_xcsr_writel(mbase, U3D_TX1CSR1, i, 0);
  425. mu3d_xcsr_writel(mbase, U3D_TX1CSR2, i, 0);
  426. ep_setting = &g_u3d_ep_setting[i];
  427. ep_setting->fifoaddr = 0;
  428. ep_setting->enabled = 0;
  429. }
  430. for (i = 1; i <= rx_ep_num; i++) {
  431. tmp = mu3d_xcsr_readl(mbase, U3D_RX1CSR0, i);
  432. tmp &= ~RX_RXMAXPKTSZ;
  433. mu3d_xcsr_writel(mbase, U3D_RX1CSR0, i, tmp);
  434. mu3d_xcsr_writel(mbase, U3D_RX1CSR1, i, 0);
  435. mu3d_xcsr_writel(mbase, U3D_RX1CSR2, i, 0);
  436. ep_setting = &g_u3d_ep_setting[i + MAX_EP_NUM];
  437. ep_setting->fifoaddr = 0;
  438. ep_setting->enabled = 0;
  439. }
  440. }
  441. void mu3d_hal_unfigured_ep_num(struct musb *musb, int ep_num, USB_DIR dir)
  442. {
  443. void __iomem *mbase = musb->mac_base;
  444. struct usb_ep_setting *ep_setting;
  445. u32 tmp;
  446. mu3d_dbg(K_INFO, "%s %d\n", __func__, ep_num);
  447. if (dir == USB_TX) {
  448. tmp = mu3d_xcsr_readl(mbase, U3D_TX1CSR0, ep_num);
  449. tmp &= ~TX_TXMAXPKTSZ;
  450. mu3d_xcsr_writel(mbase, U3D_TX1CSR0, ep_num, tmp);
  451. mu3d_xcsr_writel(mbase, U3D_TX1CSR1, ep_num, 0);
  452. mu3d_xcsr_writel(mbase, U3D_TX1CSR2, ep_num, 0);
  453. ep_setting = &g_u3d_ep_setting[ep_num];
  454. /* ep_setting->fifoaddr = 0; */
  455. ep_setting->enabled = 0;
  456. } else {
  457. tmp = mu3d_xcsr_readl(mbase, U3D_RX1CSR0, ep_num);
  458. tmp &= ~RX_RXMAXPKTSZ;
  459. mu3d_xcsr_writel(mbase, U3D_RX1CSR0, ep_num, tmp);
  460. mu3d_xcsr_writel(mbase, U3D_RX1CSR1, ep_num, 0);
  461. mu3d_xcsr_writel(mbase, U3D_RX1CSR2, ep_num, 0);
  462. ep_setting = &g_u3d_ep_setting[ep_num + MAX_EP_NUM];
  463. /* ep_setting->fifoaddr = 0; */
  464. ep_setting->enabled = 0;
  465. }
  466. }
  467. /**
  468. * mu3d_hal_ep_enable - configure ep
  469. *@args - arg1: ep number, arg2: dir, arg3: transfer type, arg4: max packet size, arg5: interval, arg6: slot, arg7: burst, arg8: mult
  470. */
  471. void mu3d_hal_ep_enable(struct musb *musb, int ep_num, USB_DIR dir, TRANSFER_TYPE type, int maxp,
  472. int interval, int slot, int burst, int mult)
  473. {
  474. int ep_index = 0;
  475. int used_before;
  476. u8 fifosz = 0, max_pkt, binterval;
  477. int csr0, csr1, csr2;
  478. struct usb_ep_setting *ep_setting;
  479. void __iomem *mbase = musb->mac_base;
  480. u8 update_FIFOadd = 0;
  481. mu3d_dbg(K_INFO, "%s\n", __func__);
  482. /*TODO: Enable in future. */
  483. /*Enable Burst, NumP=0, EoB */
  484. /* os_writel( U3D_USB3_EPCTRL_CAP, os_readl(U3D_USB3_EPCTRL_CAP) | TX_NUMP_0_EN | SET_EOB_EN | TX_BURST_EN); */
  485. /*
  486. * Default value of U3D_USB3_EPCTRL_CAP
  487. * 1. tx_burst_en 1'b1
  488. * 2. set_eob_en 1'b0
  489. * 3. usb3_iso_crc_chk_dis 1'b1
  490. * 4. send_stall_clr_pp_en 1'b1
  491. * 5. tx_nump_0_en 1'b0
  492. */
  493. if (slot > MAX_SLOT) {
  494. mu3d_dbg(K_ALET, "[ERROR]Configure wrong slot number(MAX=%d, Not=%d)\n", MAX_SLOT,
  495. slot);
  496. slot = MAX_SLOT;
  497. }
  498. if (type == USB_CTRL) {
  499. ep_setting = &g_u3d_ep_setting[0];
  500. ep_setting->fifosz = maxp;
  501. ep_setting->maxp = maxp;
  502. csr0 = mu3d_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
  503. csr0 |= maxp;
  504. mu3d_writel(mbase, U3D_EP0CSR, csr0);
  505. mu3d_setmsk(mbase, U3D_USB2_RX_EP_DATAERR_INTR, BIT16); /* EP0 data error interrupt */
  506. return;
  507. }
  508. if (dir == USB_TX)
  509. ep_index = ep_num;
  510. else if (dir == USB_RX)
  511. ep_index = ep_num + MAX_EP_NUM;
  512. else
  513. BUG_ON(1);
  514. ep_setting = &g_u3d_ep_setting[ep_index];
  515. used_before = ep_setting->fifoaddr;
  516. if (ep_setting->enabled)
  517. return;
  518. binterval = interval;
  519. if (dir == USB_TX) {
  520. if ((g_TxFIFOadd + maxp * (slot + 1) > mu3d_readl(mbase, U3D_CAP_EPNTXFFSZ))
  521. && (!used_before)) {
  522. mu3d_dbg(K_ALET, "mu3d_hal_ep_enable, FAILED: sram exhausted\n");
  523. mu3d_dbg(K_ALET, "g_FIFOadd :%x\n", g_TxFIFOadd);
  524. mu3d_dbg(K_ALET, "maxp :%d\n", maxp);
  525. mu3d_dbg(K_ALET, "mult :%d\n", slot);
  526. BUG_ON(1);
  527. }
  528. } else {
  529. if ((g_RxFIFOadd + maxp * (slot + 1) > mu3d_readl(mbase, U3D_CAP_EPNRXFFSZ))
  530. && (!used_before)) {
  531. mu3d_dbg(K_ALET, "mu3d_hal_ep_enable, FAILED: sram exhausted\n");
  532. mu3d_dbg(K_ALET, "g_FIFOadd :%x\n", g_RxFIFOadd);
  533. mu3d_dbg(K_ALET, "maxp :%d\n", maxp);
  534. mu3d_dbg(K_ALET, "mult :%d\n", slot);
  535. BUG_ON(1);
  536. }
  537. }
  538. ep_setting->transfer_type = type;
  539. if (dir == USB_TX) {
  540. if (!ep_setting->fifoaddr) {
  541. ep_setting->fifoaddr = g_TxFIFOadd;
  542. update_FIFOadd = 1;
  543. }
  544. } else {
  545. if (!ep_setting->fifoaddr) {
  546. ep_setting->fifoaddr = g_RxFIFOadd;
  547. update_FIFOadd = 1;
  548. }
  549. }
  550. ep_setting->fifosz = maxp;
  551. ep_setting->maxp = maxp;
  552. ep_setting->dir = dir;
  553. ep_setting->enabled = 1;
  554. if (maxp <= 16)
  555. fifosz = USB_FIFOSZ_SIZE_16;
  556. else if (maxp <= 32)
  557. fifosz = USB_FIFOSZ_SIZE_32;
  558. else if (maxp <= 64)
  559. fifosz = USB_FIFOSZ_SIZE_64;
  560. else if (maxp <= 128)
  561. fifosz = USB_FIFOSZ_SIZE_128;
  562. else if (maxp <= 256)
  563. fifosz = USB_FIFOSZ_SIZE_256;
  564. else if (maxp <= 512)
  565. fifosz = USB_FIFOSZ_SIZE_512;
  566. else if (maxp <= 32768)
  567. fifosz = USB_FIFOSZ_SIZE_1024;
  568. else {
  569. mu3d_dbg(K_ERR, "%s Wrong MAXP\n", __func__);
  570. fifosz = USB_FIFOSZ_SIZE_1024;
  571. }
  572. if (dir == USB_TX) {
  573. /* CSR0 */
  574. csr0 = mu3d_xcsr_readl(mbase, U3D_TX1CSR0, ep_num);
  575. csr0 &= ~TX_TXMAXPKTSZ;
  576. csr0 |= (maxp & TX_TXMAXPKTSZ);
  577. #ifdef USE_SSUSB_QMU
  578. /* from SSUSB Device Programming Guide(Revision 0.1) page26
  579. * TX EP Setting of QMU
  580. * TXnCSR0.TxMaxPktSz
  581. * TXnCSR1.SS_BURST/TxType/TxSlot
  582. * TXnCSR1.Tx_Max_Pkt/Tx_Mult (ISO Only)
  583. * TXnCSR2.TxFIFOAddr/TxFIFOSegSize
  584. * TXnCSR2.TxBInterval (SS ISO/INT Only)
  585. * TxnCSR0.AutoSet = 0
  586. * TxnCSR0.DMARegEn = 1
  587. */
  588. csr0 &= ~TX_AUTOSET;
  589. csr0 |= TX_DMAREQEN;
  590. #else
  591. #ifdef AUTOSET
  592. csr0 |= TX_AUTOSET;
  593. #endif
  594. /*Disable DMA, Use PIO mode */
  595. csr0 &= ~TX_DMAREQEN;
  596. #endif
  597. /* CSR1 */
  598. max_pkt = (burst + 1) * (mult + 1) - 1;
  599. csr1 = (burst & SS_TX_BURST);
  600. csr1 |= (slot << TX_SLOT_OFST) & TX_SLOT;
  601. csr1 |= (max_pkt << TX_MAX_PKT_OFST) & TX_MAX_PKT;
  602. csr1 |= (mult << TX_MULT_OFST) & TX_MULT;
  603. /* CSR2 */
  604. csr2 = (ep_setting->fifoaddr >> 4) & TXFIFOADDR;
  605. csr2 |= (fifosz << TXFIFOSEGSIZE_OFST) & TXFIFOSEGSIZE;
  606. if (type == USB_BULK) {
  607. csr1 |= TYPE_BULK;
  608. } else if (type == USB_INTR) {
  609. csr1 |= TYPE_INT;
  610. csr2 |= (binterval << TXBINTERVAL_OFST) & TXBINTERVAL;
  611. } else if (type == USB_ISO) {
  612. csr1 |= TYPE_ISO;
  613. csr2 |= (binterval << TXBINTERVAL_OFST) & TXBINTERVAL;
  614. }
  615. #ifdef USE_SSUSB_QMU
  616. /*Disable Endpoint interrupt */
  617. mu3d_setmsk(mbase, U3D_EPIECR, (BIT0 << ep_num));
  618. /* Enable QMU */
  619. mu3d_setmsk(mbase, U3D_QGCSR, QMU_TX_EN(ep_num));
  620. /* Enable QMU Done interrupt */
  621. mu3d_setmsk(mbase, U3D_QIESR0, QMU_TX_EN(ep_num));
  622. #endif
  623. mu3d_xcsr_writel(mbase, U3D_TX1CSR0, ep_num, csr0);
  624. mu3d_xcsr_writel(mbase, U3D_TX1CSR1, ep_num, csr1);
  625. mu3d_xcsr_writel(mbase, U3D_TX1CSR2, ep_num, csr2);
  626. mu3d_dbg(K_DEBUG, "[CSR]U3D_TX%dCSR0 :%x\n", ep_num,
  627. mu3d_xcsr_readl(mbase, U3D_TX1CSR0, ep_num));
  628. mu3d_dbg(K_DEBUG, "[CSR]U3D_TX%dCSR1 :%x\n", ep_num,
  629. mu3d_xcsr_readl(mbase, U3D_TX1CSR1, ep_num));
  630. mu3d_dbg(K_DEBUG, "[CSR]U3D_TX%dCSR2 :%x\n", ep_num,
  631. mu3d_xcsr_readl(mbase, U3D_TX1CSR2, ep_num));
  632. } else if (dir == USB_RX) {
  633. /* CSR0 */
  634. csr0 = mu3d_xcsr_readl(mbase, U3D_RX1CSR0, ep_num);
  635. csr0 &= ~RX_RXMAXPKTSZ;
  636. csr0 |= (maxp & RX_RXMAXPKTSZ);
  637. #ifdef USE_SSUSB_QMU
  638. /* from SSUSB Device Programming Guide(Revision 0.1) page32
  639. * RX EP Setting of QMU
  640. * RXnCSR0.RxMaxPktSz
  641. * RXnCSR1.SS_BURST/RxType/RxSlot
  642. * RXnCSR1.Rx_Max_Pkt/Rx_Mult (ISO Only)
  643. * RXnCSR2.RxFIFOAddr/RxFIFOSegSize
  644. * RXnCSR2.RxBInterval (SS ISO/INT Only)
  645. * RxnCSR0.AutoClear = 0
  646. * RxnCSR0.DMARegEn = 1
  647. */
  648. csr0 &= ~RX_AUTOCLEAR;
  649. csr0 |= RX_DMAREQEN;
  650. #else
  651. #ifdef AUTOCLEAR
  652. csr0 |= RX_AUTOCLEAR;
  653. #endif
  654. /*Disable DMA, Use PIO mode */
  655. csr0 &= ~RX_DMAREQEN;
  656. #endif
  657. /* CSR1 */
  658. max_pkt = (burst + 1) * (mult + 1) - 1;
  659. csr1 = (burst & SS_RX_BURST);
  660. csr1 |= (slot << RX_SLOT_OFST) & RX_SLOT;
  661. csr1 |= (max_pkt << RX_MAX_PKT_OFST) & RX_MAX_PKT;
  662. csr1 |= (mult << RX_MULT_OFST) & RX_MULT;
  663. /* CSR2 */
  664. csr2 = (ep_setting->fifoaddr >> 4) & RXFIFOADDR;
  665. csr2 |= (fifosz << RXFIFOSEGSIZE_OFST) & RXFIFOSEGSIZE;
  666. if (type == USB_BULK) {
  667. csr1 |= TYPE_BULK;
  668. } else if (type == USB_INTR) {
  669. csr1 |= TYPE_INT;
  670. csr2 |= (binterval << RXBINTERVAL_OFST) & RXBINTERVAL;
  671. } else if (type == USB_ISO) {
  672. csr1 |= TYPE_ISO;
  673. csr2 |= (binterval << RXBINTERVAL_OFST) & RXBINTERVAL;
  674. }
  675. #ifdef USE_SSUSB_QMU
  676. /*Disable Endpoint interrupt */
  677. mu3d_setmsk(mbase, U3D_EPIECR, (BIT16 << ep_num));
  678. /* Enable QMU */
  679. mu3d_setmsk(mbase, U3D_QGCSR, QMU_TX_EN(ep_num));
  680. /*Enable QMU Done interrupt */
  681. mu3d_setmsk(mbase, U3D_QIESR0, QMU_RX_EN(ep_num));
  682. #endif
  683. mu3d_xcsr_writel(mbase, U3D_RX1CSR0, ep_num, csr0);
  684. mu3d_xcsr_writel(mbase, U3D_RX1CSR1, ep_num, csr1);
  685. mu3d_xcsr_writel(mbase, U3D_RX1CSR2, ep_num, csr2);
  686. mu3d_dbg(K_DEBUG, "[CSR]U3D_RX%dCSR0 :%x\n", ep_num,
  687. mu3d_xcsr_readl(mbase, U3D_RX1CSR0, ep_num));
  688. mu3d_dbg(K_DEBUG, "[CSR]U3D_RX%dCSR1 :%x\n", ep_num,
  689. mu3d_xcsr_readl(mbase, U3D_RX1CSR1, ep_num));
  690. mu3d_dbg(K_DEBUG, "[CSR]U3D_RX%dCSR2 :%x\n", ep_num,
  691. mu3d_xcsr_readl(mbase, U3D_RX1CSR2, ep_num));
  692. mu3d_setmsk(mbase, U3D_USB2_RX_EP_DATAERR_INTR, BIT16 << ep_num); /* EPn data error interrupt */
  693. } else {
  694. mu3d_dbg(K_ERR, "WHAT THE DIRECTION IS?!?!\n");
  695. BUG_ON(1);
  696. }
  697. if (update_FIFOadd == 1) {
  698. /* The minimum unit of FIFO address is _16_ bytes.
  699. * So let the offset of each EP fifo address aligns _16_ bytes.*/
  700. int fifo_offset = 0;
  701. if ((maxp & 0xF))
  702. fifo_offset = (maxp + 16) & (~0xF);
  703. else
  704. fifo_offset = maxp;
  705. if (dir == USB_TX)
  706. g_TxFIFOadd += (fifo_offset * (slot + 1));
  707. else
  708. g_RxFIFOadd += (fifo_offset * (slot + 1));
  709. }
  710. }