ehci.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
  3. * Copyright (C) 2010 Freescale Semiconductor, Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #include <linux/platform_device.h>
  16. #include <linux/io.h>
  17. #include <mach/hardware.h>
  18. #include <mach/mxc_ehci.h>
  19. #define MXC_OTG_OFFSET 0
  20. #define MXC_H1_OFFSET 0x200
  21. #define MXC_H2_OFFSET 0x400
  22. /* USB_CTRL */
  23. #define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
  24. #define MXC_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */
  25. #define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */
  26. #define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */
  27. #define MXC_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */
  28. /* USB_PHY_CTRL_FUNC */
  29. #define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
  30. #define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
  31. /* USBH2CTRL */
  32. #define MXC_H2_UCTRL_H2UIE_BIT (1 << 8)
  33. #define MXC_H2_UCTRL_H2WIE_BIT (1 << 7)
  34. #define MXC_H2_UCTRL_H2PM_BIT (1 << 4)
  35. #define MXC_USBCMD_OFFSET 0x140
  36. /* USBCMD */
  37. #define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */
  38. int mx51_initialize_usb_hw(int port, unsigned int flags)
  39. {
  40. unsigned int v;
  41. void __iomem *usb_base;
  42. void __iomem *usbotg_base;
  43. void __iomem *usbother_base;
  44. int ret = 0;
  45. usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
  46. if (!usb_base) {
  47. printk(KERN_ERR "%s(): ioremap failed\n", __func__);
  48. return -ENOMEM;
  49. }
  50. switch (port) {
  51. case 0: /* OTG port */
  52. usbotg_base = usb_base + MXC_OTG_OFFSET;
  53. break;
  54. case 1: /* Host 1 port */
  55. usbotg_base = usb_base + MXC_H1_OFFSET;
  56. break;
  57. case 2: /* Host 2 port */
  58. usbotg_base = usb_base + MXC_H2_OFFSET;
  59. break;
  60. default:
  61. printk(KERN_ERR"%s no such port %d\n", __func__, port);
  62. ret = -ENOENT;
  63. goto error;
  64. }
  65. usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
  66. switch (port) {
  67. case 0: /*OTG port */
  68. if (flags & MXC_EHCI_INTERNAL_PHY) {
  69. v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
  70. if (flags & MXC_EHCI_POWER_PINS_ENABLED) {
  71. /* OC/USBPWR is not used */
  72. v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
  73. } else {
  74. /* OC/USBPWR is used */
  75. v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
  76. }
  77. __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
  78. v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
  79. if (flags & MXC_EHCI_WAKEUP_ENABLED)
  80. v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
  81. else
  82. v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
  83. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  84. v |= MXC_OTG_UCTRL_OPM_BIT;
  85. else
  86. v &= ~MXC_OTG_UCTRL_OPM_BIT;
  87. __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
  88. }
  89. break;
  90. case 1: /* Host 1 */
  91. /*Host ULPI */
  92. v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
  93. if (flags & MXC_EHCI_WAKEUP_ENABLED) {
  94. /* HOST1 wakeup/ULPI intr enable */
  95. v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
  96. } else {
  97. /* HOST1 wakeup/ULPI intr disable */
  98. v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
  99. }
  100. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  101. v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
  102. else
  103. v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
  104. __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
  105. v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
  106. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  107. v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
  108. else
  109. v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
  110. __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
  111. v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET);
  112. if (flags & MXC_EHCI_ITC_NO_THRESHOLD)
  113. /* Interrupt Threshold Control:Immediate (no threshold) */
  114. v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
  115. __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
  116. break;
  117. case 2: /* Host 2 ULPI */
  118. v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
  119. if (flags & MXC_EHCI_WAKEUP_ENABLED) {
  120. /* HOST1 wakeup/ULPI intr enable */
  121. v |= (MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
  122. } else {
  123. /* HOST1 wakeup/ULPI intr disable */
  124. v &= ~(MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
  125. }
  126. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  127. v &= ~MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
  128. else
  129. v |= MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
  130. __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
  131. break;
  132. }
  133. error:
  134. iounmap(usb_base);
  135. return ret;
  136. }