xhci-pci.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c) 2015, Google, Inc
  3. * Written by Simon Glass <sjg@chromium.org>
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: GPL-2.0
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <errno.h>
  11. #include <pci.h>
  12. #include <usb.h>
  13. #include "xhci.h"
  14. #ifndef CONFIG_DM_USB
  15. /*
  16. * Create the appropriate control structures to manage a new XHCI host
  17. * controller.
  18. */
  19. int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr,
  20. struct xhci_hcor **ret_hcor)
  21. {
  22. struct xhci_hccr *hccr;
  23. struct xhci_hcor *hcor;
  24. pci_dev_t pdev;
  25. uint32_t cmd;
  26. int len;
  27. pdev = pci_find_class(PCI_CLASS_SERIAL_USB_XHCI, index);
  28. if (pdev < 0) {
  29. printf("XHCI host controller not found\n");
  30. return -1;
  31. }
  32. hccr = (struct xhci_hccr *)pci_map_bar(pdev,
  33. PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
  34. len = HC_LENGTH(xhci_readl(&hccr->cr_capbase));
  35. hcor = (struct xhci_hcor *)((uint32_t)hccr + len);
  36. debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
  37. (uint32_t)hccr, (uint32_t)hcor, len);
  38. *ret_hccr = hccr;
  39. *ret_hcor = hcor;
  40. /* enable busmaster */
  41. pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
  42. cmd |= PCI_COMMAND_MASTER;
  43. pci_write_config_dword(pdev, PCI_COMMAND, cmd);
  44. return 0;
  45. }
  46. /*
  47. * Destroy the appropriate control structures corresponding * to the XHCI host
  48. * controller
  49. */
  50. void xhci_hcd_stop(int index)
  51. {
  52. }
  53. #else
  54. struct xhci_pci_priv {
  55. struct xhci_ctrl ctrl; /* Needs to come first in this struct! */
  56. };
  57. static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
  58. struct xhci_hcor **ret_hcor)
  59. {
  60. struct xhci_hccr *hccr;
  61. struct xhci_hcor *hcor;
  62. u32 cmd;
  63. hccr = (struct xhci_hccr *)dm_pci_map_bar(dev,
  64. PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
  65. hcor = (struct xhci_hcor *)((uintptr_t) hccr +
  66. HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
  67. debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
  68. (u32)hccr, (u32)hcor,
  69. (u32)HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
  70. *ret_hccr = hccr;
  71. *ret_hcor = hcor;
  72. /* enable busmaster */
  73. dm_pci_read_config32(dev, PCI_COMMAND, &cmd);
  74. cmd |= PCI_COMMAND_MASTER;
  75. dm_pci_write_config32(dev, PCI_COMMAND, cmd);
  76. }
  77. static int xhci_pci_probe(struct udevice *dev)
  78. {
  79. struct xhci_hccr *hccr;
  80. struct xhci_hcor *hcor;
  81. xhci_pci_init(dev, &hccr, &hcor);
  82. return xhci_register(dev, hccr, hcor);
  83. }
  84. static int xhci_pci_remove(struct udevice *dev)
  85. {
  86. int ret;
  87. ret = xhci_deregister(dev);
  88. if (ret)
  89. return ret;
  90. return 0;
  91. }
  92. static const struct udevice_id xhci_pci_ids[] = {
  93. { .compatible = "xhci-pci" },
  94. { }
  95. };
  96. U_BOOT_DRIVER(xhci_pci) = {
  97. .name = "xhci_pci",
  98. .id = UCLASS_USB,
  99. .probe = xhci_pci_probe,
  100. .remove = xhci_pci_remove,
  101. .of_match = xhci_pci_ids,
  102. .ops = &xhci_usb_ops,
  103. .platdata_auto_alloc_size = sizeof(struct usb_platdata),
  104. .priv_auto_alloc_size = sizeof(struct xhci_pci_priv),
  105. .flags = DM_FLAG_ALLOC_PRIV_DMA,
  106. };
  107. static struct pci_device_id xhci_pci_supported[] = {
  108. { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0) },
  109. {},
  110. };
  111. U_BOOT_PCI_DEVICE(xhci_pci, xhci_pci_supported);
  112. #endif /* CONFIG_DM_USB */