ohci-da8xx.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2012 Sughosh Ganu <urwithsughosh@gmail.com>
  4. */
  5. #include <common.h>
  6. #include <malloc.h>
  7. #include <asm/io.h>
  8. #include <clk.h>
  9. #include <dm.h>
  10. #include <dm/device_compat.h>
  11. #include <dm/devres.h>
  12. #include <dm/ofnode.h>
  13. #include <generic-phy.h>
  14. #include <reset.h>
  15. #include "ohci.h"
  16. #include <asm/arch/da8xx-usb.h>
  17. struct da8xx_ohci {
  18. ohci_t ohci;
  19. struct clk *clocks; /* clock list */
  20. struct phy phy;
  21. int clock_count; /* number of clock in clock list */
  22. };
  23. static int usb_phy_on(void)
  24. {
  25. unsigned long timeout;
  26. clrsetbits_le32(&davinci_syscfg_regs->cfgchip2,
  27. (CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN |
  28. CFGCHIP2_OTGPWRDN | CFGCHIP2_OTGMODE |
  29. CFGCHIP2_REFFREQ | CFGCHIP2_USB1PHYCLKMUX),
  30. (CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN |
  31. CFGCHIP2_PHY_PLLON | CFGCHIP2_REFFREQ_24MHZ |
  32. CFGCHIP2_USB2PHYCLKMUX | CFGCHIP2_USB1SUSPENDM));
  33. /* wait until the usb phy pll locks */
  34. timeout = get_timer(0);
  35. while (get_timer(timeout) < 10) {
  36. if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD)
  37. return 1;
  38. }
  39. /* USB phy was not turned on */
  40. return 0;
  41. }
  42. static void usb_phy_off(void)
  43. {
  44. /* Power down the on-chip PHY. */
  45. clrsetbits_le32(&davinci_syscfg_regs->cfgchip2,
  46. CFGCHIP2_PHY_PLLON | CFGCHIP2_USB1SUSPENDM,
  47. CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN |
  48. CFGCHIP2_RESET);
  49. }
  50. int usb_cpu_init(void)
  51. {
  52. /* enable psc for usb2.0 */
  53. lpsc_on(DAVINCI_LPSC_USB20);
  54. /* enable psc for usb1.0 */
  55. lpsc_on(DAVINCI_LPSC_USB11);
  56. /* start the on-chip usb phy and its pll */
  57. if (usb_phy_on())
  58. return 0;
  59. return 1;
  60. }
  61. int usb_cpu_stop(void)
  62. {
  63. usb_phy_off();
  64. /* turn off the usb clock and assert the module reset */
  65. lpsc_disable(DAVINCI_LPSC_USB11);
  66. lpsc_disable(DAVINCI_LPSC_USB20);
  67. return 0;
  68. }
  69. int usb_cpu_init_fail(void)
  70. {
  71. return usb_cpu_stop();
  72. }
  73. #if CONFIG_IS_ENABLED(DM_USB)
  74. static int ohci_da8xx_probe(struct udevice *dev)
  75. {
  76. struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
  77. struct da8xx_ohci *priv = dev_get_priv(dev);
  78. int i, err, ret, clock_nb;
  79. err = 0;
  80. priv->clock_count = 0;
  81. clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
  82. if (clock_nb < 0)
  83. return clock_nb;
  84. if (clock_nb > 0) {
  85. priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
  86. GFP_KERNEL);
  87. if (!priv->clocks)
  88. return -ENOMEM;
  89. for (i = 0; i < clock_nb; i++) {
  90. err = clk_get_by_index(dev, i, &priv->clocks[i]);
  91. if (err < 0)
  92. break;
  93. err = clk_enable(&priv->clocks[i]);
  94. if (err) {
  95. dev_err(dev, "failed to enable clock %d\n", i);
  96. clk_free(&priv->clocks[i]);
  97. goto clk_err;
  98. }
  99. priv->clock_count++;
  100. }
  101. }
  102. err = usb_cpu_init();
  103. if (err)
  104. goto clk_err;
  105. err = ohci_register(dev, regs);
  106. if (err)
  107. goto phy_err;
  108. return 0;
  109. phy_err:
  110. ret = usb_cpu_stop();
  111. if (ret)
  112. dev_err(dev, "failed to shutdown usb phy\n");
  113. clk_err:
  114. ret = clk_release_all(priv->clocks, priv->clock_count);
  115. if (ret)
  116. dev_err(dev, "failed to disable all clocks\n");
  117. return err;
  118. }
  119. static int ohci_da8xx_remove(struct udevice *dev)
  120. {
  121. struct da8xx_ohci *priv = dev_get_priv(dev);
  122. int ret;
  123. ret = ohci_deregister(dev);
  124. if (ret)
  125. return ret;
  126. ret = usb_cpu_stop();
  127. if (ret)
  128. return ret;
  129. return clk_release_all(priv->clocks, priv->clock_count);
  130. }
  131. static const struct udevice_id da8xx_ohci_ids[] = {
  132. { .compatible = "ti,da830-ohci" },
  133. { }
  134. };
  135. U_BOOT_DRIVER(ohci_generic) = {
  136. .name = "ohci-da8xx",
  137. .id = UCLASS_USB,
  138. .of_match = da8xx_ohci_ids,
  139. .probe = ohci_da8xx_probe,
  140. .remove = ohci_da8xx_remove,
  141. .ops = &ohci_usb_ops,
  142. .priv_auto_alloc_size = sizeof(struct da8xx_ohci),
  143. .flags = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_OS_PREPARE,
  144. };
  145. #endif