xhci-fsl.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright 2015 Freescale Semiconductor, Inc.
  3. *
  4. * FSL USB HOST xHCI Controller
  5. *
  6. * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
  7. *
  8. * SPDX-License-Identifier: GPL-2.0+
  9. */
  10. #include <common.h>
  11. #include <usb.h>
  12. #include <asm-generic/errno.h>
  13. #include <linux/compat.h>
  14. #include <linux/usb/xhci-fsl.h>
  15. #include <linux/usb/dwc3.h>
  16. #include "xhci.h"
  17. /* Declare global data pointer */
  18. DECLARE_GLOBAL_DATA_PTR;
  19. static struct fsl_xhci fsl_xhci;
  20. unsigned long ctr_addr[] = FSL_USB_XHCI_ADDR;
  21. __weak int __board_usb_init(int index, enum usb_init_type init)
  22. {
  23. return 0;
  24. }
  25. static int fsl_xhci_core_init(struct fsl_xhci *fsl_xhci)
  26. {
  27. int ret = 0;
  28. ret = dwc3_core_init(fsl_xhci->dwc3_reg);
  29. if (ret) {
  30. debug("%s:failed to initialize core\n", __func__);
  31. return ret;
  32. }
  33. /* We are hard-coding DWC3 core to Host Mode */
  34. dwc3_set_mode(fsl_xhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
  35. /* Set GFLADJ_30MHZ as 20h as per XHCI spec default value */
  36. dwc3_set_fladj(fsl_xhci->dwc3_reg, GFLADJ_30MHZ_DEFAULT);
  37. return ret;
  38. }
  39. static int fsl_xhci_core_exit(struct fsl_xhci *fsl_xhci)
  40. {
  41. /*
  42. * Currently fsl socs do not support PHY shutdown from
  43. * sw. But this support may be added in future socs.
  44. */
  45. return 0;
  46. }
  47. int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
  48. {
  49. struct fsl_xhci *ctx = &fsl_xhci;
  50. int ret = 0;
  51. ctx->hcd = (struct xhci_hccr *)ctr_addr[index];
  52. ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
  53. ret = board_usb_init(index, USB_INIT_HOST);
  54. if (ret != 0) {
  55. puts("Failed to initialize board for USB\n");
  56. return ret;
  57. }
  58. ret = fsl_xhci_core_init(ctx);
  59. if (ret < 0) {
  60. puts("Failed to initialize xhci\n");
  61. return ret;
  62. }
  63. *hccr = (struct xhci_hccr *)ctx->hcd;
  64. *hcor = (struct xhci_hcor *)((uintptr_t) *hccr
  65. + HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));
  66. debug("fsl-xhci: init hccr %lx and hcor %lx hc_length %lx\n",
  67. (uintptr_t)*hccr, (uintptr_t)*hcor,
  68. (uintptr_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));
  69. return ret;
  70. }
  71. void xhci_hcd_stop(int index)
  72. {
  73. struct fsl_xhci *ctx = &fsl_xhci;
  74. fsl_xhci_core_exit(ctx);
  75. }