usb_phy.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016 - 2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include <usb/include/usb.h>
  31. #include "fsl_device_registers.h"
  32. #include <usb/phy/usb_phy.h>
  33. void *USB_EhciPhyGetBase(uint8_t controllerId)
  34. {
  35. void *usbPhyBase = NULL;
  36. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  37. uint32_t instance;
  38. uint32_t newinstance = 0;
  39. uint32_t usbphy_base_temp[] = USBPHY_BASE_ADDRS;
  40. uint32_t usbphy_base[] = USBPHY_BASE_ADDRS;
  41. uint32_t *temp;
  42. if (controllerId < (uint8_t)kUSB_ControllerEhci0)
  43. {
  44. return NULL;
  45. }
  46. if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
  47. {
  48. controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
  49. }
  50. else if ((controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs0) ||
  51. (controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs1))
  52. {
  53. controllerId = controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0;
  54. }
  55. else if ((controllerId == (uint8_t)kUSB_ControllerIp3516Hs0) || (controllerId == (uint8_t)kUSB_ControllerIp3516Hs1))
  56. {
  57. controllerId = controllerId - (uint8_t)kUSB_ControllerIp3516Hs0;
  58. }
  59. else
  60. {
  61. /*no action*/
  62. }
  63. for (instance = 0; instance < (sizeof(usbphy_base_temp) / sizeof(usbphy_base_temp[0])); instance++)
  64. {
  65. if (0U != usbphy_base_temp[instance])
  66. {
  67. usbphy_base[newinstance++] = usbphy_base_temp[instance];
  68. }
  69. }
  70. if (controllerId > newinstance)
  71. {
  72. return NULL;
  73. }
  74. temp = (uint32_t *)usbphy_base[controllerId];
  75. usbPhyBase = (void *)temp;
  76. #endif
  77. return usbPhyBase;
  78. }
  79. /*!
  80. * @brief ehci phy initialization.
  81. *
  82. * This function initialize ehci phy IP.
  83. *
  84. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  85. * @param[in] freq the external input clock.
  86. * for example: if the external input clock is 16M, the parameter freq should be 16000000.
  87. *
  88. * @retval kStatus_USB_Success cancel successfully.
  89. * @retval kStatus_USB_Error the freq value is incorrect.
  90. */
  91. uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
  92. {
  93. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  94. USBPHY_Type *usbPhyBase;
  95. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  96. if (NULL == usbPhyBase)
  97. {
  98. return (uint8_t)kStatus_USB_Error;
  99. }
  100. #if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U))
  101. ANATOP->HW_ANADIG_REG_3P0.RW =
  102. (ANATOP->HW_ANADIG_REG_3P0.RW &
  103. (~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) |
  104. ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK;
  105. ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET =
  106. ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK;
  107. #endif
  108. #if (defined USB_ANALOG)
  109. USB_ANALOG->INSTANCE[controllerId - (uint8_t)kUSB_ControllerEhci0].CHRG_DETECT_SET =
  110. USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1);
  111. #endif
  112. #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
  113. usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
  114. #endif
  115. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
  116. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
  117. /* PWD register provides overall control of the PHY power state */
  118. usbPhyBase->PWD = 0U;
  119. if (((uint8_t)kUSB_ControllerIp3516Hs0 == controllerId) || ((uint8_t)kUSB_ControllerIp3516Hs1 == controllerId) ||
  120. ((uint8_t)kUSB_ControllerLpcIp3511Hs0 == controllerId) ||
  121. ((uint8_t)kUSB_ControllerLpcIp3511Hs1 == controllerId))
  122. {
  123. usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK;
  124. usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK;
  125. }
  126. if (NULL != phyConfig)
  127. {
  128. /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
  129. usbPhyBase->TX =
  130. ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
  131. (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
  132. USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
  133. }
  134. #endif
  135. return (uint8_t)kStatus_USB_Success;
  136. }
  137. /*!
  138. * @brief ehci phy initialization for suspend and resume.
  139. *
  140. * This function initialize ehci phy IP for suspend and resume.
  141. *
  142. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  143. * @param[in] freq the external input clock.
  144. * for example: if the external input clock is 16M, the parameter freq should be 16000000.
  145. *
  146. * @retval kStatus_USB_Success cancel successfully.
  147. * @retval kStatus_USB_Error the freq value is incorrect.
  148. */
  149. uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
  150. {
  151. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  152. USBPHY_Type *usbPhyBase;
  153. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  154. if (NULL == usbPhyBase)
  155. {
  156. return (uint8_t)kStatus_USB_Error;
  157. }
  158. #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
  159. usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
  160. #endif
  161. #if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U))
  162. usbPhyBase->CTRL_CLR |= USBPHY_CTRL_AUTORESUME_EN_MASK;
  163. #else
  164. usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK;
  165. #endif
  166. usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK;
  167. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
  168. usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
  169. /* PWD register provides overall control of the PHY power state */
  170. usbPhyBase->PWD = 0U;
  171. #if (defined USBPHY_ANACTRL_PFD_CLKGATE_MASK)
  172. /* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD
  173. * pfd clock = 480MHz*18/N, where N=18~35
  174. * Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode
  175. */
  176. usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */
  177. usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */
  178. usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK;
  179. usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK;
  180. while (0U == (usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK))
  181. {
  182. }
  183. #endif
  184. if (NULL != phyConfig)
  185. {
  186. /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
  187. usbPhyBase->TX =
  188. ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
  189. (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
  190. USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
  191. }
  192. #endif
  193. return (uint8_t)kStatus_USB_Success;
  194. }
  195. /*!
  196. * @brief ehci phy de-initialization.
  197. *
  198. * This function de-initialize ehci phy IP.
  199. *
  200. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  201. */
  202. void USB_EhciPhyDeinit(uint8_t controllerId)
  203. {
  204. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  205. USBPHY_Type *usbPhyBase;
  206. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  207. if (NULL == usbPhyBase)
  208. {
  209. return;
  210. }
  211. #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
  212. usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */
  213. usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */
  214. #endif
  215. usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */
  216. #endif
  217. }
  218. /*!
  219. * @brief ehci phy disconnect detection enable or disable.
  220. *
  221. * This function enable/disable host ehci disconnect detection.
  222. *
  223. * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
  224. * @param[in] enable
  225. * 1U - enable;
  226. * 0U - disable;
  227. */
  228. void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable)
  229. {
  230. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  231. USBPHY_Type *usbPhyBase;
  232. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  233. if (NULL == usbPhyBase)
  234. {
  235. return;
  236. }
  237. if (0U != enable)
  238. {
  239. usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
  240. }
  241. else
  242. {
  243. usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK);
  244. }
  245. #endif
  246. }
  247. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  248. #if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U))
  249. void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable)
  250. {
  251. USBPHY_Type *usbPhyBase;
  252. usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  253. if (NULL == usbPhyBase)
  254. {
  255. return;
  256. }
  257. if (0U != enable)
  258. {
  259. uint32_t delay = 1000000;
  260. usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
  261. while ((0U != (usbPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK)) && (0U != delay))
  262. {
  263. delay--;
  264. }
  265. usbPhyBase->USB1_LOOPBACK_SET = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
  266. }
  267. else
  268. {
  269. usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
  270. usbPhyBase->USB1_LOOPBACK_CLR = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
  271. }
  272. }
  273. #endif
  274. #endif