ehci-generic.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <clk.h>
  8. #include <dm/ofnode.h>
  9. #include <generic-phy.h>
  10. #include <reset.h>
  11. #include <asm/io.h>
  12. #include <dm.h>
  13. #include "ehci.h"
  14. /*
  15. * Even though here we don't explicitly use "struct ehci_ctrl"
  16. * ehci_register() expects it to be the first thing that resides in
  17. * device's private data.
  18. */
  19. struct generic_ehci {
  20. struct ehci_ctrl ctrl;
  21. struct clk *clocks;
  22. struct reset_ctl *resets;
  23. struct phy phy;
  24. int clock_count;
  25. int reset_count;
  26. };
  27. static int ehci_usb_probe(struct udevice *dev)
  28. {
  29. struct generic_ehci *priv = dev_get_priv(dev);
  30. struct ehci_hccr *hccr;
  31. struct ehci_hcor *hcor;
  32. int i, err, ret, clock_nb, reset_nb;
  33. err = 0;
  34. priv->clock_count = 0;
  35. clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
  36. "#clock-cells");
  37. if (clock_nb > 0) {
  38. priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
  39. GFP_KERNEL);
  40. if (!priv->clocks)
  41. return -ENOMEM;
  42. for (i = 0; i < clock_nb; i++) {
  43. err = clk_get_by_index(dev, i, &priv->clocks[i]);
  44. if (err < 0)
  45. break;
  46. err = clk_enable(&priv->clocks[i]);
  47. if (err) {
  48. error("failed to enable clock %d\n", i);
  49. clk_free(&priv->clocks[i]);
  50. goto clk_err;
  51. }
  52. priv->clock_count++;
  53. }
  54. } else {
  55. if (clock_nb != -ENOENT) {
  56. error("failed to get clock phandle(%d)\n", clock_nb);
  57. return clock_nb;
  58. }
  59. }
  60. priv->reset_count = 0;
  61. reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
  62. "#reset-cells");
  63. if (reset_nb > 0) {
  64. priv->resets = devm_kcalloc(dev, reset_nb,
  65. sizeof(struct reset_ctl),
  66. GFP_KERNEL);
  67. if (!priv->resets)
  68. return -ENOMEM;
  69. for (i = 0; i < reset_nb; i++) {
  70. err = reset_get_by_index(dev, i, &priv->resets[i]);
  71. if (err < 0)
  72. break;
  73. if (reset_deassert(&priv->resets[i])) {
  74. error("failed to deassert reset %d\n", i);
  75. reset_free(&priv->resets[i]);
  76. goto reset_err;
  77. }
  78. priv->reset_count++;
  79. }
  80. } else {
  81. if (reset_nb != -ENOENT) {
  82. error("failed to get reset phandle(%d)\n", reset_nb);
  83. goto clk_err;
  84. }
  85. }
  86. err = generic_phy_get_by_index(dev, 0, &priv->phy);
  87. if (err) {
  88. if (err != -ENOENT) {
  89. error("failed to get usb phy\n");
  90. goto reset_err;
  91. }
  92. } else {
  93. err = generic_phy_init(&priv->phy);
  94. if (err) {
  95. error("failed to init usb phy\n");
  96. goto reset_err;
  97. }
  98. }
  99. hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
  100. hcor = (struct ehci_hcor *)((uintptr_t)hccr +
  101. HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
  102. err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
  103. if (err)
  104. goto phy_err;
  105. return 0;
  106. phy_err:
  107. if (generic_phy_valid(&priv->phy)) {
  108. ret = generic_phy_exit(&priv->phy);
  109. if (ret)
  110. error("failed to release phy\n");
  111. }
  112. reset_err:
  113. ret = reset_release_all(priv->resets, priv->reset_count);
  114. if (ret)
  115. error("failed to assert all resets\n");
  116. clk_err:
  117. ret = clk_release_all(priv->clocks, priv->clock_count);
  118. if (ret)
  119. error("failed to disable all clocks\n");
  120. return err;
  121. }
  122. static int ehci_usb_remove(struct udevice *dev)
  123. {
  124. struct generic_ehci *priv = dev_get_priv(dev);
  125. int ret;
  126. ret = ehci_deregister(dev);
  127. if (ret)
  128. return ret;
  129. if (generic_phy_valid(&priv->phy)) {
  130. ret = generic_phy_exit(&priv->phy);
  131. if (ret)
  132. return ret;
  133. }
  134. ret = reset_release_all(priv->resets, priv->reset_count);
  135. if (ret)
  136. return ret;
  137. return clk_release_all(priv->clocks, priv->clock_count);
  138. }
  139. static const struct udevice_id ehci_usb_ids[] = {
  140. { .compatible = "generic-ehci" },
  141. { }
  142. };
  143. U_BOOT_DRIVER(ehci_generic) = {
  144. .name = "ehci_generic",
  145. .id = UCLASS_USB,
  146. .of_match = ehci_usb_ids,
  147. .probe = ehci_usb_probe,
  148. .remove = ehci_usb_remove,
  149. .ops = &ehci_usb_ops,
  150. .priv_auto_alloc_size = sizeof(struct generic_ehci),
  151. .flags = DM_FLAG_ALLOC_PRIV_DMA,
  152. };