ehci-zynq.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Timothee: I found this in:
  2. * http://lists.denx.de/pipermail/u-boot/2014-April/178227.html
  3. * It is an old (and more simple version of the Xilinx linux USB driver.
  4. * Overview of the commit diff:
  5. *
  6. * arch/arm/cpu/armv7/zynq/slcr.c | 24 +++++++
  7. * arch/arm/include/asm/arch-zynq/hardware.h | 2 +
  8. * drivers/usb/host/Makefile | 1 +
  9. * drivers/usb/host/ehci-zynq.c | 104 ++++++++++++++++++++++++++++++
  10. * 4 files changed, 131 insertions(+)
  11. * create mode 100644 drivers/usb/host/ehci-zynq.c
  12. */
  13. /*
  14. * (C) Copyright 2014, Xilinx, Inc
  15. *
  16. * USB Low level initialization(Specific to zynq)
  17. *
  18. * SPDX-License-Identifier: GPL-2.0+
  19. */
  20. #include <common.h>
  21. #include <asm/arch/hardware.h>
  22. #include <asm/arch/sys_proto.h>
  23. #include <asm/io.h>
  24. #include <usb.h>
  25. #include <usb/ehci-fsl.h>
  26. #include <usb/ulpi.h>
  27. #include "ehci.h"
  28. #define ZYNQ_USB_USBCMD_RST 0x0000002
  29. #define ZYNQ_USB_USBCMD_STOP 0x0000000
  30. #define ZYNQ_USB_NUM_MIO 12
  31. /*
  32. * Create the appropriate control structures to manage
  33. * a new EHCI host controller.
  34. */
  35. int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
  36. struct ehci_hcor **hcor)
  37. {
  38. struct usb_ehci *ehci;
  39. struct ulpi_viewport ulpi_vp;
  40. int ret, mio_usb;
  41. /* Used for writing the ULPI data address */
  42. struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
  43. if (!index) {
  44. mio_usb = zynq_slcr_get_mio_pin_status("usb0");
  45. if (mio_usb != ZYNQ_USB_NUM_MIO) {
  46. printf("usb0 wrong num MIO: %d, Index %d\n", mio_usb,
  47. index);
  48. return -1;
  49. }
  50. ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0;
  51. } else {
  52. mio_usb = zynq_slcr_get_mio_pin_status("usb1");
  53. if (mio_usb != ZYNQ_USB_NUM_MIO) {
  54. printf("usb1 wrong num MIO: %d, Index %d\n", mio_usb,
  55. index);
  56. return -1;
  57. }
  58. ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1;
  59. }
  60. *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
  61. *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
  62. HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
  63. ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
  64. ulpi_vp.port_num = 0;
  65. ret = ulpi_init(&ulpi_vp);
  66. if (ret) {
  67. puts("zynq ULPI viewport init failed\n");
  68. return -1;
  69. }
  70. /* ULPI set flags */
  71. ulpi_write(&ulpi_vp, &ulpi->otg_ctrl,
  72. ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN |
  73. ULPI_OTG_EXTVBUSIND);
  74. ulpi_write(&ulpi_vp, &ulpi->function_ctrl,
  75. ULPI_FC_FULL_SPEED | ULPI_FC_OPMODE_NORMAL |
  76. ULPI_FC_SUSPENDM);
  77. ulpi_write(&ulpi_vp, &ulpi->iface_ctrl, 0);
  78. /* Set VBus */
  79. ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set,
  80. ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
  81. return 0;
  82. }
  83. /*
  84. * Destroy the appropriate control structures corresponding
  85. * the the EHCI host controller.
  86. */
  87. int ehci_hcd_stop(int index)
  88. {
  89. struct usb_ehci *ehci;
  90. if (!index)
  91. ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0;
  92. else
  93. ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1;
  94. /* Stop controller */
  95. writel(ZYNQ_USB_USBCMD_STOP, &ehci->usbcmd);
  96. udelay(1000);
  97. /* Initiate controller reset */
  98. writel(ZYNQ_USB_USBCMD_RST, &ehci->usbcmd);
  99. return 0;
  100. }