xhci-mtk-power.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #include "xhci.h"
  2. #include "xhci-mtk-power.h"
  3. #include "xhci-mtk-driver.h"
  4. #include <linux/kernel.h> /* printk() */
  5. #include <linux/slab.h>
  6. #include <linux/delay.h>
  7. #include <linux/printk.h>
  8. #include <linux/types.h>
  9. #define mtk_power_log(fmt, args...) \
  10. pr_debug("%s(%d): " fmt, __func__, __LINE__, ##args)
  11. static bool wait_for_value(unsigned long addr, int msk, int value, int ms_intvl, int count)
  12. {
  13. int i;
  14. for (i = 0; i < count; i++) {
  15. if ((readl((void __iomem *)addr) & msk) == value)
  16. return true;
  17. mdelay(ms_intvl);
  18. }
  19. return false;
  20. }
  21. static void mtk_chk_usb_ip_ck_sts(struct xhci_hcd *xhci)
  22. {
  23. int ret;
  24. int num_u3_port;
  25. int num_u2_port;
  26. num_u3_port = SSUSB_U3_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->sif_regs)));
  27. num_u2_port = SSUSB_U2_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->sif_regs)));
  28. ret =
  29. wait_for_value(_SSUSB_IP_PW_STS1(xhci->sif_regs), SSUSB_SYS125_RST_B_STS,
  30. SSUSB_SYS125_RST_B_STS, 1, 10);
  31. if (ret == false)
  32. mtk_power_log("sys125_ck is still active!!!\n");
  33. /* do not check when SSUSB_U2_PORT_PDN = 1, because U2 port stays in reset state */
  34. if (num_u2_port
  35. && !(readl((void __iomem *)_SSUSB_U2_CTRL(xhci->sif_regs, 0)) & SSUSB_U2_PORT_PDN)) {
  36. ret =
  37. wait_for_value(_SSUSB_IP_PW_STS2(xhci->sif_regs), SSUSB_U2_MAC_SYS_RST_B_STS,
  38. SSUSB_U2_MAC_SYS_RST_B_STS, 1, 10);
  39. if (ret == false)
  40. mtk_power_log("mac2_sys_ck is still active!!!\n");
  41. }
  42. /* do not check when SSUSB_U3_PORT_PDN = 1, because U3 port stays in reset state */
  43. if (num_u3_port
  44. && !(readl((void __iomem *)_SSUSB_U3_CTRL(xhci->sif_regs, 0)) & SSUSB_U3_PORT_PDN)) {
  45. ret =
  46. wait_for_value(_SSUSB_IP_PW_STS1(xhci->sif_regs), SSUSB_U3_MAC_RST_B_STS,
  47. SSUSB_U3_MAC_RST_B_STS, 1, 10);
  48. if (ret == false)
  49. mtk_power_log("mac3_mac_ck is still active!!!\n");
  50. }
  51. }
  52. /* set 1 to PORT_POWER of PORT_STATUS register of each port */
  53. void enableXhciAllPortPower(struct xhci_hcd *xhci)
  54. {
  55. int i;
  56. u32 port_id, temp;
  57. u32 __iomem *addr;
  58. int num_u3_port;
  59. int num_u2_port;
  60. num_u3_port = SSUSB_U3_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->sif_regs)));
  61. num_u2_port = SSUSB_U2_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->sif_regs)));
  62. pr_debug("%s(%d): port number, u3-%d, u2-%d\n",
  63. __func__, __LINE__, num_u3_port, num_u2_port);
  64. for (i = 1; i <= num_u3_port; i++) {
  65. port_id = i;
  66. addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * ((port_id - 1) & 0xff);
  67. temp = readl(addr);
  68. temp = xhci_port_state_to_neutral(temp);
  69. temp |= PORT_POWER;
  70. writel(temp, addr);
  71. while (!(readl(addr) & PORT_POWER))
  72. ;
  73. }
  74. for (i = 1; i <= num_u2_port; i++) {
  75. port_id = i + num_u3_port;
  76. addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * ((port_id - 1) & 0xff);
  77. temp = readl(addr);
  78. temp = xhci_port_state_to_neutral(temp);
  79. temp |= PORT_POWER;
  80. writel(temp, addr);
  81. while (!(readl(addr) & PORT_POWER))
  82. ;
  83. }
  84. }
  85. /* set 0 to PORT_POWER of PORT_STATUS register of each port */
  86. void disableXhciAllPortPower(struct xhci_hcd *xhci)
  87. {
  88. int i;
  89. u32 port_id, temp;
  90. void __iomem *addr;
  91. int num_u3_port;
  92. int num_u2_port;
  93. num_u3_port = SSUSB_U3_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->base_regs)));
  94. num_u2_port = SSUSB_U2_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->base_regs)));
  95. mtk_power_log("port number, u3-%d, u2-%d\n", num_u3_port, num_u2_port);
  96. for (i = 1; i <= num_u3_port; i++) {
  97. port_id = i;
  98. addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * ((port_id - 1) & 0xff);
  99. temp = readl(addr);
  100. temp = xhci_port_state_to_neutral(temp);
  101. temp &= ~PORT_POWER;
  102. writel(temp, addr);
  103. while (readl(addr) & PORT_POWER)
  104. ;
  105. }
  106. for (i = 1; i <= num_u2_port; i++) {
  107. port_id = i + num_u3_port;
  108. addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * ((port_id - 1) & 0xff);
  109. temp = readl(addr);
  110. temp = xhci_port_state_to_neutral(temp);
  111. temp &= ~PORT_POWER;
  112. writel(temp, addr);
  113. while (readl(addr) & PORT_POWER)
  114. ;
  115. }
  116. xhci_print_registers(mtk_xhci);
  117. }
  118. void enableAllClockPower(struct xhci_hcd *xhci, bool is_reset)
  119. {
  120. int i;
  121. u32 temp;
  122. int num_u3_port;
  123. int num_u2_port;
  124. num_u3_port = SSUSB_U3_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP(xhci->sif_regs)));
  125. num_u2_port = SSUSB_U2_PORT_NUM(readl((void __iomem *)_SSUSB_IP_CAP((xhci->sif_regs))));
  126. pr_debug("%s(%d): u3 port number = %d\n", __func__, __LINE__, num_u3_port);
  127. pr_debug("%s(%d): u2 port number = %d\n", __func__, __LINE__, num_u2_port);
  128. /* reset whole ip */
  129. if (is_reset) {
  130. writel(readl((void __iomem *)_SSUSB_IP_PW_CTRL(xhci->sif_regs)) | (SSUSB_IP_SW_RST),
  131. (void __iomem *)_SSUSB_IP_PW_CTRL(xhci->sif_regs));
  132. writel(readl((void __iomem *)_SSUSB_IP_PW_CTRL(xhci->sif_regs)) &
  133. (~SSUSB_IP_SW_RST), (void __iomem *)_SSUSB_IP_PW_CTRL(xhci->sif_regs));
  134. }
  135. /* disable ip host power down bit --> power on host ip */
  136. writel(readl((void __iomem *)_SSUSB_IP_PW_CTRL_1(xhci->sif_regs)) & (~SSUSB_IP_PDN),
  137. (void __iomem *)_SSUSB_IP_PW_CTRL_1(xhci->sif_regs));
  138. /* disable all u3 port power down and disable bits --> power on and enable all u3 ports */
  139. for (i = 0; i < num_u3_port; i++) {
  140. temp = readl((void __iomem *)_SSUSB_U3_CTRL(xhci->sif_regs, i));
  141. temp =
  142. (temp & (~SSUSB_U3_PORT_PDN) & (~SSUSB_U3_PORT_DIS)) | (SSUSB_U3_PORT_HOST_SEL);
  143. writel(temp, (void __iomem *)_SSUSB_U3_CTRL(xhci->sif_regs, i));
  144. }
  145. /*
  146. * FIXME: clock is the correct 30MHz, if the U3 device is enabled
  147. */
  148. #if 0
  149. temp = readl(SSUSB_U3_CTRL(0));
  150. temp = temp & (~SSUSB_U3_PORT_PDN) & (~SSUSB_U3_PORT_DIS) & (~SSUSB_U3_PORT_HOST_SEL);
  151. writel(temp, SSUSB_U3_CTRL(0));
  152. #endif
  153. /* disable all u2 port power down and disable bits --> power on and enable all u2 ports */
  154. for (i = 0; i < num_u2_port; i++) {
  155. temp = readl((void __iomem *)_SSUSB_U2_CTRL(xhci->sif_regs, i));
  156. temp =
  157. (temp & (~SSUSB_U2_PORT_PDN) & (~SSUSB_U2_PORT_DIS)) | (SSUSB_U2_PORT_HOST_SEL);
  158. writel(temp, (void __iomem *)_SSUSB_U2_CTRL(xhci->sif_regs, i));
  159. }
  160. /* msleep(100); */
  161. mtk_chk_usb_ip_ck_sts(xhci);
  162. }
  163. #if 0
  164. /* called after HC initiated */
  165. void disableAllClockPower(void)
  166. {
  167. int i;
  168. u32 temp;
  169. int num_u3_port;
  170. int num_u2_port;
  171. num_u3_port = SSUSB_U3_PORT_NUM(readl(SSUSB_IP_CAP));
  172. num_u2_port = SSUSB_U2_PORT_NUM(readl(SSUSB_IP_CAP));
  173. /* disable target ports */
  174. for (i = 0; i < num_u3_port; i++) {
  175. temp = readl((void __iomem *)SSUSB_U3_CTRL(i));
  176. temp = temp | SSUSB_U3_PORT_PDN & (~SSUSB_U3_PORT_HOST_SEL);
  177. writel(temp, (void __iomem *)SSUSB_U3_CTRL(i));
  178. }
  179. for (i = 0; i < num_u2_port; i++) {
  180. temp = readl((void __iomem *)SSUSB_U2_CTRL(i));
  181. temp = temp | SSUSB_U2_PORT_PDN & (~SSUSB_U2_PORT_HOST_SEL);
  182. writel(temp, (void __iomem *)SSUSB_U2_CTRL(i));
  183. }
  184. writel(readl((void __iomem *)SSUSB_IP_PW_CTRL_1) | (SSUSB_IP_PDN),
  185. (void __iomem *)SSUSB_IP_PW_CTRL_1);
  186. /* msleep(100); */
  187. mtk_chk_usb_ip_ck_sts();
  188. }
  189. #endif
  190. #if 0
  191. /* (X)disable clock/power of a port */
  192. /* (X)if all ports are disabled, disable IP ctrl power */
  193. /* disable all ports and IP clock/power, this is just mention HW that the power/clock of port */
  194. /* and IP could be disable if suspended. */
  195. /* If doesn't not disable all ports at first, the IP clock/power will never be disabled */
  196. /* (some U2 and U3 ports are binded to the same connection, that is, they will never enter suspend at the same time */
  197. /* port_index: port number */
  198. /* port_rev: 0x2 - USB2.0, 0x3 - USB3.0 (SuperSpeed) */
  199. void disablePortClockPower(int port_index, int port_rev)
  200. {
  201. u32 temp;
  202. int real_index;
  203. real_index = port_index;
  204. if (port_rev == 0x3) {
  205. temp = readl((void __iomem *)(unsigned long)SSUSB_U3_CTRL(real_index));
  206. temp = temp | (SSUSB_U3_PORT_PDN);
  207. writel(temp, (void __iomem *)(unsigned long)SSUSB_U3_CTRL(real_index));
  208. } else if (port_rev == 0x2) {
  209. temp = readl((void __iomem *)(unsigned long)SSUSB_U2_CTRL(real_index));
  210. temp = temp | (SSUSB_U2_PORT_PDN);
  211. writel(temp, (void __iomem *)(unsigned long)SSUSB_U2_CTRL(real_index));
  212. }
  213. writel(readl((void __iomem *)(unsigned long)SSUSB_IP_PW_CTRL_1) | (SSUSB_IP_PDN),
  214. (void __iomem *)(unsigned long)SSUSB_IP_PW_CTRL_1);
  215. }
  216. /* if IP ctrl power is disabled, enable it */
  217. /* enable clock/power of a port */
  218. /* port_index: port number */
  219. /* port_rev: 0x2 - USB2.0, 0x3 - USB3.0 (SuperSpeed) */
  220. void enablePortClockPower(int port_index, int port_rev)
  221. {
  222. u32 temp;
  223. int real_index;
  224. real_index = port_index;
  225. writel(readl((void __iomem *)SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN),
  226. (void __iomem *)SSUSB_IP_PW_CTRL_1);
  227. if (port_rev == 0x3) {
  228. temp = readl((void __iomem *)(unsigned long)SSUSB_U3_CTRL(real_index));
  229. temp = temp & (~SSUSB_U3_PORT_PDN);
  230. writel(temp, (void __iomem *)(unsigned long)SSUSB_U3_CTRL(real_index));
  231. } else if (port_rev == 0x2) {
  232. temp = readl((void __iomem *)(unsigned long)SSUSB_U2_CTRL(real_index));
  233. temp = temp & (~SSUSB_U2_PORT_PDN);
  234. writel(temp, (void __iomem *)(unsigned long)SSUSB_U2_CTRL(real_index));
  235. }
  236. }
  237. #endif