usb_phy.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016 - 2017 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "usb.h"
  9. #include "fsl_device_registers.h"
  10. #include "usb_phy.h"
  11. void *USB_EhciPhyGetBase(uint8_t controllerId)
  12. {
  13. void *usbPhyBase = NULL;
  14. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  15. #if defined(USBPHY_STACK_BASE_ADDRS)
  16. uint32_t usbphy_base[] = USBPHY_STACK_BASE_ADDRS;
  17. #else
  18. uint32_t usbphy_base[] = USBPHY_BASE_ADDRS;
  19. #endif
  20. uint32_t *temp;
  21. if (controllerId < (uint8_t)kUSB_ControllerEhci0)
  22. {
  23. return NULL;
  24. }
  25. if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
  26. {
  27. controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
  28. }
  29. else if ((controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs0) ||
  30. (controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs1))
  31. {
  32. controllerId = controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0;
  33. }
  34. else if ((controllerId == (uint8_t)kUSB_ControllerIp3516Hs0) || (controllerId == (uint8_t)kUSB_ControllerIp3516Hs1))
  35. {
  36. controllerId = controllerId - (uint8_t)kUSB_ControllerIp3516Hs0;
  37. }
  38. else
  39. {
  40. return NULL;
  41. }
  42. if (controllerId < (sizeof(usbphy_base) / sizeof(usbphy_base[0])))
  43. {
  44. temp = (uint32_t *)usbphy_base[controllerId];
  45. usbPhyBase = (void *)temp;
  46. }
  47. else
  48. {
  49. return NULL;
  50. }
  51. #endif
  52. return usbPhyBase;
  53. }
  54. /*!
  55. * @brief ehci phy initialization.
  56. *
  57. * This function initialize ehci phy IP.
  58. *
  59. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  60. * @param[in] freq the external input clock.
  61. * for example: if the external input clock is 16M, the parameter freq should be 16000000.
  62. *
  63. * @retval kStatus_USB_Success cancel successfully.
  64. * @retval kStatus_USB_Error the freq value is incorrect.
  65. */
  66. uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
  67. {
  68. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  69. USBPHY_Type *usbPhyBase;
  70. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  71. if (NULL == usbPhyBase)
  72. {
  73. return (uint8_t)kStatus_USB_Error;
  74. }
  75. #if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U))
  76. ANATOP->HW_ANADIG_REG_3P0.RW =
  77. (ANATOP->HW_ANADIG_REG_3P0.RW &
  78. (~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) |
  79. ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK;
  80. ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET =
  81. ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK;
  82. #endif
  83. #if (defined USB_ANALOG)
  84. USB_ANALOG->INSTANCE[controllerId - (uint8_t)kUSB_ControllerEhci0].CHRG_DETECT_SET =
  85. USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1);
  86. #endif
  87. #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
  88. usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
  89. #endif
  90. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
  91. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
  92. /* PWD register provides overall control of the PHY power state */
  93. usbPhyBase->PWD = 0U;
  94. if (((uint8_t)kUSB_ControllerIp3516Hs0 == controllerId) || ((uint8_t)kUSB_ControllerIp3516Hs1 == controllerId) ||
  95. ((uint8_t)kUSB_ControllerLpcIp3511Hs0 == controllerId) ||
  96. ((uint8_t)kUSB_ControllerLpcIp3511Hs1 == controllerId))
  97. {
  98. usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK;
  99. usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK;
  100. }
  101. if (NULL != phyConfig)
  102. {
  103. /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
  104. usbPhyBase->TX =
  105. ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
  106. (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
  107. USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
  108. }
  109. #endif
  110. return (uint8_t)kStatus_USB_Success;
  111. }
  112. /*!
  113. * @brief ehci phy initialization for suspend and resume.
  114. *
  115. * This function initialize ehci phy IP for suspend and resume.
  116. *
  117. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  118. * @param[in] freq the external input clock.
  119. * for example: if the external input clock is 16M, the parameter freq should be 16000000.
  120. *
  121. * @retval kStatus_USB_Success cancel successfully.
  122. * @retval kStatus_USB_Error the freq value is incorrect.
  123. */
  124. uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
  125. {
  126. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  127. USBPHY_Type *usbPhyBase;
  128. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  129. if (NULL == usbPhyBase)
  130. {
  131. return (uint8_t)kStatus_USB_Error;
  132. }
  133. #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
  134. usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
  135. #endif
  136. #if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U))
  137. usbPhyBase->CTRL_CLR |= USBPHY_CTRL_AUTORESUME_EN_MASK;
  138. #else
  139. usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK;
  140. #endif
  141. usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK;
  142. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
  143. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
  144. /* PWD register provides overall control of the PHY power state */
  145. usbPhyBase->PWD = 0U;
  146. #if (defined USBPHY_ANACTRL_PFD_CLKGATE_MASK)
  147. /* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD
  148. * pfd clock = 480MHz*18/N, where N=18~35
  149. * Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode
  150. */
  151. usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */
  152. usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */
  153. usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK;
  154. usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK;
  155. while (0U == (usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK))
  156. {
  157. }
  158. #endif
  159. if (NULL != phyConfig)
  160. {
  161. /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
  162. usbPhyBase->TX =
  163. ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
  164. (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
  165. USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
  166. }
  167. #endif
  168. return (uint8_t)kStatus_USB_Success;
  169. }
  170. /*!
  171. * @brief ehci phy de-initialization.
  172. *
  173. * This function de-initialize ehci phy IP.
  174. *
  175. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  176. */
  177. void USB_EhciPhyDeinit(uint8_t controllerId)
  178. {
  179. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  180. USBPHY_Type *usbPhyBase;
  181. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  182. if (NULL == usbPhyBase)
  183. {
  184. return;
  185. }
  186. #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
  187. usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */
  188. usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */
  189. #endif
  190. usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */
  191. #endif
  192. }
  193. /*!
  194. * @brief ehci phy disconnect detection enable or disable.
  195. *
  196. * This function enable/disable host ehci disconnect detection.
  197. *
  198. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  199. * @param[in] enable
  200. * 1U - enable;
  201. * 0U - disable;
  202. */
  203. void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable)
  204. {
  205. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  206. USBPHY_Type *usbPhyBase;
  207. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  208. if (NULL == usbPhyBase)
  209. {
  210. return;
  211. }
  212. if (0U != enable)
  213. {
  214. usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
  215. }
  216. else
  217. {
  218. usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK);
  219. }
  220. #endif
  221. }
  222. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  223. #if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U))
  224. void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable)
  225. {
  226. USBPHY_Type *usbPhyBase;
  227. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  228. if (NULL == usbPhyBase)
  229. {
  230. return;
  231. }
  232. if (0U != enable)
  233. {
  234. uint32_t delay = 1000000;
  235. usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
  236. while ((0U != (usbPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK)) && (0U != delay))
  237. {
  238. delay--;
  239. }
  240. usbPhyBase->USB1_LOOPBACK_SET = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
  241. }
  242. else
  243. {
  244. usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
  245. usbPhyBase->USB1_LOOPBACK_CLR = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
  246. }
  247. }
  248. #endif
  249. #endif