ulpi.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
  4. * Copyright (C) 2011 CompuLab, Ltd. <www.compulab.co.il>
  5. *
  6. * Authors: Jana Rapava <fermata7@gmail.com>
  7. * Igor Grinberg <grinberg@compulab.co.il>
  8. *
  9. * Based on:
  10. * linux/drivers/usb/otg/ulpi.c
  11. * Generic ULPI USB transceiver support
  12. *
  13. * Original Copyright follow:
  14. * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
  15. *
  16. * Based on sources from
  17. *
  18. * Sascha Hauer <s.hauer@pengutronix.de>
  19. * Freescale Semiconductors
  20. */
  21. #include <common.h>
  22. #include <exports.h>
  23. #include <usb/ulpi.h>
  24. #define ULPI_ID_REGS_COUNT 4
  25. #define ULPI_TEST_VALUE 0x55 /* 0x55 == 0b01010101 */
  26. static struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
  27. static int ulpi_integrity_check(struct ulpi_viewport *ulpi_vp)
  28. {
  29. u32 val, tval = ULPI_TEST_VALUE;
  30. int err, i;
  31. /* Use the 'special' test value to check all bits */
  32. for (i = 0; i < 2; i++, tval <<= 1) {
  33. err = ulpi_write(ulpi_vp, &ulpi->scratch, tval);
  34. if (err)
  35. return err;
  36. val = ulpi_read(ulpi_vp, &ulpi->scratch);
  37. if (val != tval) {
  38. printf("ULPI integrity check failed\n");
  39. return val;
  40. }
  41. }
  42. return 0;
  43. }
  44. int ulpi_init(struct ulpi_viewport *ulpi_vp)
  45. {
  46. u32 val, id = 0;
  47. u8 *reg = &ulpi->product_id_high;
  48. int i;
  49. /* Assemble ID from four ULPI ID registers (8 bits each). */
  50. for (i = 0; i < ULPI_ID_REGS_COUNT; i++) {
  51. val = ulpi_read(ulpi_vp, reg - i);
  52. if (val == ULPI_ERROR)
  53. return val;
  54. id = (id << 8) | val;
  55. }
  56. /* Split ID into vendor and product ID. */
  57. debug("ULPI transceiver ID 0x%04x:0x%04x\n", id >> 16, id & 0xffff);
  58. return ulpi_integrity_check(ulpi_vp);
  59. }
  60. int ulpi_select_transceiver(struct ulpi_viewport *ulpi_vp, unsigned speed)
  61. {
  62. u32 tspeed = ULPI_FC_FULL_SPEED;
  63. u32 val;
  64. switch (speed) {
  65. case ULPI_FC_HIGH_SPEED:
  66. case ULPI_FC_FULL_SPEED:
  67. case ULPI_FC_LOW_SPEED:
  68. case ULPI_FC_FS4LS:
  69. tspeed = speed;
  70. break;
  71. default:
  72. printf("ULPI: %s: wrong transceiver speed specified: %u, "
  73. "falling back to full speed\n", __func__, speed);
  74. }
  75. val = ulpi_read(ulpi_vp, &ulpi->function_ctrl);
  76. if (val == ULPI_ERROR)
  77. return val;
  78. /* clear the previous speed setting */
  79. val = (val & ~ULPI_FC_XCVRSEL_MASK) | tspeed;
  80. return ulpi_write(ulpi_vp, &ulpi->function_ctrl, val);
  81. }
  82. int ulpi_set_vbus(struct ulpi_viewport *ulpi_vp, int on, int ext_power)
  83. {
  84. u32 flags = ULPI_OTG_DRVVBUS;
  85. u8 *reg = on ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear;
  86. if (ext_power)
  87. flags |= ULPI_OTG_DRVVBUS_EXT;
  88. return ulpi_write(ulpi_vp, reg, flags);
  89. }
  90. int ulpi_set_vbus_indicator(struct ulpi_viewport *ulpi_vp, int external,
  91. int passthu, int complement)
  92. {
  93. u32 flags, val;
  94. u8 *reg;
  95. reg = external ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear;
  96. val = ulpi_write(ulpi_vp, reg, ULPI_OTG_EXTVBUSIND);
  97. if (val)
  98. return val;
  99. flags = passthu ? ULPI_IFACE_PASSTHRU : 0;
  100. flags |= complement ? ULPI_IFACE_EXTVBUS_COMPLEMENT : 0;
  101. val = ulpi_read(ulpi_vp, &ulpi->iface_ctrl);
  102. if (val == ULPI_ERROR)
  103. return val;
  104. val = val & ~(ULPI_IFACE_PASSTHRU & ULPI_IFACE_EXTVBUS_COMPLEMENT);
  105. val |= flags;
  106. val = ulpi_write(ulpi_vp, &ulpi->iface_ctrl, val);
  107. if (val)
  108. return val;
  109. return 0;
  110. }
  111. int ulpi_set_pd(struct ulpi_viewport *ulpi_vp, int enable)
  112. {
  113. u32 val = ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN;
  114. u8 *reg = enable ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear;
  115. return ulpi_write(ulpi_vp, reg, val);
  116. }
  117. int ulpi_opmode_sel(struct ulpi_viewport *ulpi_vp, unsigned opmode)
  118. {
  119. u32 topmode = ULPI_FC_OPMODE_NORMAL;
  120. u32 val;
  121. switch (opmode) {
  122. case ULPI_FC_OPMODE_NORMAL:
  123. case ULPI_FC_OPMODE_NONDRIVING:
  124. case ULPI_FC_OPMODE_DISABLE_NRZI:
  125. case ULPI_FC_OPMODE_NOSYNC_NOEOP:
  126. topmode = opmode;
  127. break;
  128. default:
  129. printf("ULPI: %s: wrong OpMode specified: %u, "
  130. "falling back to OpMode Normal\n", __func__, opmode);
  131. }
  132. val = ulpi_read(ulpi_vp, &ulpi->function_ctrl);
  133. if (val == ULPI_ERROR)
  134. return val;
  135. /* clear the previous opmode setting */
  136. val = (val & ~ULPI_FC_OPMODE_MASK) | topmode;
  137. return ulpi_write(ulpi_vp, &ulpi->function_ctrl, val);
  138. }
  139. int ulpi_serial_mode_enable(struct ulpi_viewport *ulpi_vp, unsigned smode)
  140. {
  141. switch (smode) {
  142. case ULPI_IFACE_6_PIN_SERIAL_MODE:
  143. case ULPI_IFACE_3_PIN_SERIAL_MODE:
  144. break;
  145. default:
  146. printf("ULPI: %s: unrecognized Serial Mode specified: %u\n",
  147. __func__, smode);
  148. return ULPI_ERROR;
  149. }
  150. return ulpi_write(ulpi_vp, &ulpi->iface_ctrl_set, smode);
  151. }
  152. int ulpi_suspend(struct ulpi_viewport *ulpi_vp)
  153. {
  154. int err;
  155. err = ulpi_write(ulpi_vp, &ulpi->function_ctrl_clear,
  156. ULPI_FC_SUSPENDM);
  157. if (err)
  158. printf("ULPI: %s: failed writing the suspend bit\n", __func__);
  159. return err;
  160. }
  161. /*
  162. * Wait for ULPI PHY reset to complete.
  163. * Actual wait for reset must be done in a view port specific way,
  164. * because it involves checking the DIR line.
  165. */
  166. static int __ulpi_reset_wait(struct ulpi_viewport *ulpi_vp)
  167. {
  168. u32 val;
  169. int timeout = CONFIG_USB_ULPI_TIMEOUT;
  170. /* Wait for the RESET bit to become zero */
  171. while (--timeout) {
  172. /*
  173. * This function is generic and suppose to work
  174. * with any viewport, so we cheat here and don't check
  175. * for the error of ulpi_read(), if there is one, then
  176. * there will be a timeout.
  177. */
  178. val = ulpi_read(ulpi_vp, &ulpi->function_ctrl);
  179. if (!(val & ULPI_FC_RESET))
  180. return 0;
  181. udelay(1);
  182. }
  183. printf("ULPI: %s: reset timed out\n", __func__);
  184. return ULPI_ERROR;
  185. }
  186. int ulpi_reset_wait(struct ulpi_viewport *ulpi_vp)
  187. __attribute__((weak, alias("__ulpi_reset_wait")));
  188. int ulpi_reset(struct ulpi_viewport *ulpi_vp)
  189. {
  190. int err;
  191. err = ulpi_write(ulpi_vp,
  192. &ulpi->function_ctrl_set, ULPI_FC_RESET);
  193. if (err) {
  194. printf("ULPI: %s: failed writing reset bit\n", __func__);
  195. return err;
  196. }
  197. return ulpi_reset_wait(ulpi_vp);
  198. }