Zynq.UsbEhciPhy.Mod 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. MODULE UsbEhciPhy; (** AUTHOR "Timothée Martiel"; PURPOSE "TUSB1210 USB EHCI PHY Control"; *)
  2. IMPORT SYSTEM, Kernel, KernelLog, Gpio, UsbDebug;
  3. CONST
  4. (* Ulpi Viewport bits *)
  5. UlpiWakeup = 31;
  6. UlpiRun = 30;
  7. UlpiWrite = 29;
  8. UlpiAddressMask = {16 .. 23};
  9. UlpiAddressOfs = 16;
  10. UlpiWriteDataMask = {0 .. 7};
  11. (* ULPI addresses *)
  12. FuncCtrl = 4H;
  13. FuncCtrlSet = 5H;
  14. FuncCtrlClr = 6H;
  15. IfcCtrlSet = 8H;
  16. IfcCtrlClr = 9H;
  17. OtgCtrlSet = 0BH;
  18. OtgCtrlClr = 0CH;
  19. (* Register bits in FuncCtrl *)
  20. Reset = 5;
  21. SuspendM = 6;
  22. Opmode = {3, 4};
  23. OpmodeNorm = {};
  24. XcvrSelect = {0, 1};
  25. XcvrHS = {};
  26. XcvrFS = {0};
  27. XcvrLS = {1};
  28. (* Register bits in OtgCtrl *)
  29. IdPullUp = 0;
  30. DmPullDown = 2;
  31. DpPullDown = 1;
  32. DrvVbus = 5;
  33. DrvVbusExt = 6;
  34. (* Default Timeout. Value comes from Linux implementation *)
  35. Timeout = 2000;
  36. (** Wakeup ULPI *)
  37. PROCEDURE Wakeup (viewport: ADDRESS): BOOLEAN;
  38. VAR
  39. timer: Kernel.MilliTimer;
  40. reg: SET;
  41. BEGIN
  42. Kernel.SetTimer(timer, Timeout);
  43. SYSTEM.PUT32(viewport, {UlpiWakeup});
  44. REPEAT
  45. reg := SYSTEM.VAL(SET, SYSTEM.GET32(viewport))
  46. UNTIL ~(31 IN reg) OR Kernel.Expired(timer);
  47. IF (31 IN reg) & (UsbDebug.Level >= UsbDebug.Errors) THEN
  48. KernelLog.String("TUSB1210 UsbEhciPhy: could not wakeup PHY");
  49. KernelLog.Ln
  50. END;
  51. RETURN ~(31 IN reg)
  52. END Wakeup;
  53. (** Write to ULPI register *)
  54. PROCEDURE Write(viewport, address: ADDRESS; value: SET): BOOLEAN;
  55. VAR
  56. timer: Kernel.MilliTimer;
  57. reg: SET;
  58. BEGIN
  59. IF ~Wakeup(viewport) THEN RETURN FALSE END;
  60. Kernel.SetTimer(timer, Timeout);
  61. SYSTEM.PUT32(viewport, SYSTEM.VAL(SET, value) * UlpiWriteDataMask + SYSTEM.VAL(SET, LSH(address, UlpiAddressOfs)) * UlpiAddressMask + {UlpiWrite, UlpiRun});
  62. REPEAT
  63. SYSTEM.GET(viewport, reg);
  64. UNTIL ~(30 IN reg) OR Kernel.Expired(timer);
  65. IF (30 IN reg) & (UsbDebug.Level >= UsbDebug.Errors) THEN
  66. KernelLog.String("TUSB1210 UsbEhcuPhy: could not write to PHY");
  67. KernelLog.Ln
  68. END;
  69. RETURN ~(30 IN reg)
  70. END Write;
  71. (**
  72. * Inits the ULPI via the Viewport register of the EHCI controller.
  73. * Has to be done when the controller is configured and running.
  74. *
  75. * 'viewport' is the address of the viewport register. 'reset' is the GPIO
  76. * pin to which the full ULPI reset is wired (negative if not available).
  77. *)
  78. PROCEDURE Init * (viewport: ADDRESS; reset: LONGINT): BOOLEAN;
  79. VAR
  80. i: LONGINT;
  81. BEGIN
  82. IF reset >= 0 THEN
  83. Gpio.SetDirection(reset, Gpio.Output);
  84. Gpio.EnableOutput(reset, TRUE);
  85. Gpio.SetData(reset, TRUE);
  86. Gpio.SetData(reset, FALSE);
  87. (*! TODO: Wait 2 us *)
  88. FOR i := 0 TO 1000000 DO END;
  89. Gpio.SetData(reset, TRUE)
  90. ELSE
  91. KernelLog.Enter; KernelLog.String("Skipping GPIO USB reset"); KernelLog.Exit
  92. END;
  93. (* Reset *)
  94. IF viewport # 0 THEN
  95. IF ~Write(viewport, FuncCtrlSet, {Reset}) THEN RETURN FALSE END;
  96. IF ~Write(viewport, OtgCtrlSet, {DmPullDown, DpPullDown, IdPullUp}) THEN RETURN FALSE END;
  97. IF ~Write(viewport, FuncCtrlSet, {2, SuspendM} + OpmodeNorm + XcvrLS) THEN RETURN FALSE END;
  98. IF ~Write(viewport, FuncCtrlClr, {0 .. 6} - OpmodeNorm - XcvrLS - {2, SuspendM}) THEN RETURN FALSE END;
  99. IF ~Write(viewport, OtgCtrlSet, {DrvVbus, DrvVbusExt}) THEN RETURN FALSE END;
  100. IF ~Write(viewport, FuncCtrlClr, {2}) THEN RETURN FALSE END
  101. ELSE
  102. KernelLog.Enter; KernelLog.String("Skipping USB Viewport reset"); KernelLog.Exit
  103. END;
  104. KernelLog.Enter; KernelLog.String("USB PHY Initialized sucessfully"); KernelLog.Exit;
  105. RETURN TRUE
  106. END Init;
  107. END UsbEhciPhy.