ehci-pci.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*-
  3. * Copyright (c) 2007-2008, Juniper Networks, Inc.
  4. * All rights reserved.
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <pci.h>
  10. #include <usb.h>
  11. #include <asm/io.h>
  12. #include "ehci.h"
  13. /* Information about a USB port */
  14. struct ehci_pci_priv {
  15. struct ehci_ctrl ehci;
  16. struct phy phy;
  17. };
  18. #if CONFIG_IS_ENABLED(DM_USB)
  19. static int ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr,
  20. struct ehci_hcor **ret_hcor)
  21. {
  22. struct ehci_pci_priv *priv = dev_get_priv(dev);
  23. struct ehci_hccr *hccr;
  24. struct ehci_hcor *hcor;
  25. int ret;
  26. u32 cmd;
  27. ret = ehci_setup_phy(dev, &priv->phy, 0);
  28. if (ret)
  29. return ret;
  30. hccr = (struct ehci_hccr *)dm_pci_map_bar(dev,
  31. PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
  32. hcor = (struct ehci_hcor *)((uintptr_t) hccr +
  33. HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
  34. debug("EHCI-PCI init hccr %#lx and hcor %#lx hc_length %d\n",
  35. (ulong)hccr, (ulong)hcor,
  36. (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
  37. *ret_hccr = hccr;
  38. *ret_hcor = hcor;
  39. /* enable busmaster */
  40. dm_pci_read_config32(dev, PCI_COMMAND, &cmd);
  41. cmd |= PCI_COMMAND_MASTER;
  42. dm_pci_write_config32(dev, PCI_COMMAND, cmd);
  43. return 0;
  44. }
  45. #else
  46. #ifdef CONFIG_PCI_EHCI_DEVICE
  47. static struct pci_device_id ehci_pci_ids[] = {
  48. /* Please add supported PCI EHCI controller ids here */
  49. {0x1033, 0x00E0}, /* NEC */
  50. {0x10B9, 0x5239}, /* ULI1575 PCI EHCI module ids */
  51. {0x12D8, 0x400F}, /* Pericom */
  52. {0, 0}
  53. };
  54. #endif
  55. static void ehci_pci_legacy_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr,
  56. struct ehci_hcor **ret_hcor)
  57. {
  58. struct ehci_hccr *hccr;
  59. struct ehci_hcor *hcor;
  60. u32 cmd;
  61. hccr = (struct ehci_hccr *)pci_map_bar(pdev,
  62. PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
  63. hcor = (struct ehci_hcor *)((uintptr_t) hccr +
  64. HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
  65. debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
  66. (u32)hccr, (u32)hcor,
  67. (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
  68. *ret_hccr = hccr;
  69. *ret_hcor = hcor;
  70. /* enable busmaster */
  71. pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
  72. cmd |= PCI_COMMAND_MASTER;
  73. pci_write_config_dword(pdev, PCI_COMMAND, cmd);
  74. }
  75. /*
  76. * Create the appropriate control structures to manage
  77. * a new EHCI host controller.
  78. */
  79. int ehci_hcd_init(int index, enum usb_init_type init,
  80. struct ehci_hccr **ret_hccr, struct ehci_hcor **ret_hcor)
  81. {
  82. pci_dev_t pdev;
  83. #ifdef CONFIG_PCI_EHCI_DEVICE
  84. pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
  85. #else
  86. pdev = pci_find_class(PCI_CLASS_SERIAL_USB_EHCI, index);
  87. #endif
  88. if (pdev < 0) {
  89. printf("EHCI host controller not found\n");
  90. return -1;
  91. }
  92. ehci_pci_legacy_init(pdev, ret_hccr, ret_hcor);
  93. return 0;
  94. }
  95. /*
  96. * Destroy the appropriate control structures corresponding
  97. * the the EHCI host controller.
  98. */
  99. int ehci_hcd_stop(int index)
  100. {
  101. return 0;
  102. }
  103. #endif /* !CONFIG_IS_ENABLED(DM_USB) */
  104. #if CONFIG_IS_ENABLED(DM_USB)
  105. static int ehci_pci_probe(struct udevice *dev)
  106. {
  107. struct ehci_hccr *hccr;
  108. struct ehci_hcor *hcor;
  109. int ret;
  110. ret = ehci_pci_init(dev, &hccr, &hcor);
  111. if (ret)
  112. return ret;
  113. return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
  114. }
  115. static int ehci_pci_remove(struct udevice *dev)
  116. {
  117. struct ehci_pci_priv *priv = dev_get_priv(dev);
  118. int ret;
  119. ret = ehci_deregister(dev);
  120. if (ret)
  121. return ret;
  122. return ehci_shutdown_phy(dev, &priv->phy);
  123. }
  124. static const struct udevice_id ehci_pci_ids[] = {
  125. { .compatible = "ehci-pci" },
  126. { }
  127. };
  128. U_BOOT_DRIVER(ehci_pci) = {
  129. .name = "ehci_pci",
  130. .id = UCLASS_USB,
  131. .probe = ehci_pci_probe,
  132. .remove = ehci_pci_remove,
  133. .of_match = ehci_pci_ids,
  134. .ops = &ehci_usb_ops,
  135. .platdata_auto_alloc_size = sizeof(struct usb_platdata),
  136. .priv_auto_alloc_size = sizeof(struct ehci_pci_priv),
  137. .flags = DM_FLAG_ALLOC_PRIV_DMA,
  138. };
  139. static struct pci_device_id ehci_pci_supported[] = {
  140. { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0) },
  141. {},
  142. };
  143. U_BOOT_PCI_DEVICE(ehci_pci, ehci_pci_supported);
  144. #endif /* CONFIG_IS_ENABLED(DM_USB) */