xhci-uniphier.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (C) 2015 Panasonic Corporation
  3. * Copyright (C) 2015 Socionext Inc.
  4. * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <linux/err.h>
  10. #include <usb.h>
  11. #include <fdtdec.h>
  12. #include "xhci.h"
  13. static int get_uniphier_xhci_base(int index, struct xhci_hccr **base)
  14. {
  15. DECLARE_GLOBAL_DATA_PTR;
  16. int node_list[2];
  17. fdt_addr_t addr;
  18. int count;
  19. count = fdtdec_find_aliases_for_id(gd->fdt_blob, "usb",
  20. COMPAT_SOCIONEXT_XHCI, node_list,
  21. ARRAY_SIZE(node_list));
  22. if (index >= count)
  23. return -ENODEV;
  24. addr = fdtdec_get_addr(gd->fdt_blob, node_list[index], "reg");
  25. if (addr == FDT_ADDR_T_NONE)
  26. return -ENODEV;
  27. *base = (struct xhci_hccr *)addr;
  28. return 0;
  29. }
  30. #define USB3_RST_CTRL 0x00100040
  31. #define IOMMU_RST_N (1 << 5)
  32. #define LINK_RST_N (1 << 4)
  33. static void uniphier_xhci_reset(void __iomem *base, int on)
  34. {
  35. u32 tmp;
  36. tmp = readl(base + USB3_RST_CTRL);
  37. if (on)
  38. tmp &= ~(IOMMU_RST_N | LINK_RST_N);
  39. else
  40. tmp |= IOMMU_RST_N | LINK_RST_N;
  41. writel(tmp, base + USB3_RST_CTRL);
  42. }
  43. int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
  44. {
  45. int ret;
  46. struct xhci_hccr *cr;
  47. struct xhci_hcor *or;
  48. ret = get_uniphier_xhci_base(index, &cr);
  49. if (ret < 0)
  50. return ret;
  51. uniphier_xhci_reset(cr, 0);
  52. or = (void *)cr + HC_LENGTH(xhci_readl(&cr->cr_capbase));
  53. *hccr = cr;
  54. *hcor = or;
  55. return 0;
  56. }
  57. void xhci_hcd_stop(int index)
  58. {
  59. int ret;
  60. struct xhci_hccr *cr;
  61. ret = get_uniphier_xhci_base(index, &cr);
  62. if (ret < 0)
  63. return;
  64. uniphier_xhci_reset(cr, 1);
  65. }