phy-rcar-gen2.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Renesas RCar Gen2 USB PHY driver
  4. *
  5. * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  6. */
  7. #include <common.h>
  8. #include <clk.h>
  9. #include <div64.h>
  10. #include <dm.h>
  11. #include <fdtdec.h>
  12. #include <generic-phy.h>
  13. #include <reset.h>
  14. #include <syscon.h>
  15. #include <usb.h>
  16. #include <asm/io.h>
  17. #include <linux/bitops.h>
  18. #include <power/regulator.h>
  19. #define USBHS_LPSTS 0x02
  20. #define USBHS_UGCTRL 0x80
  21. #define USBHS_UGCTRL2 0x84
  22. #define USBHS_UGSTS 0x88 /* From technical update */
  23. /* Low Power Status register (LPSTS) */
  24. #define USBHS_LPSTS_SUSPM 0x4000
  25. /* USB General control register (UGCTRL) */
  26. #define USBHS_UGCTRL_CONNECT BIT(2)
  27. #define USBHS_UGCTRL_PLLRESET BIT(0)
  28. /* USB General control register 2 (UGCTRL2) */
  29. #define USBHS_UGCTRL2_USB2SEL 0x80000000
  30. #define USBHS_UGCTRL2_USB2SEL_PCI 0x00000000
  31. #define USBHS_UGCTRL2_USB2SEL_USB30 0x80000000
  32. #define USBHS_UGCTRL2_USB0SEL 0x00000030
  33. #define USBHS_UGCTRL2_USB0SEL_PCI 0x00000010
  34. #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030
  35. /* USB General status register (UGSTS) */
  36. #define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */
  37. #define PHYS_PER_CHANNEL 2
  38. struct rcar_gen2_phy {
  39. fdt_addr_t regs;
  40. struct clk clk;
  41. };
  42. static int rcar_gen2_phy_phy_init(struct phy *phy)
  43. {
  44. struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
  45. u16 chan = phy->id & 0xffff;
  46. u16 mode = (phy->id >> 16) & 0xffff;
  47. u32 clrmask, setmask;
  48. if (chan == 0) {
  49. clrmask = USBHS_UGCTRL2_USB0SEL;
  50. setmask = mode ? USBHS_UGCTRL2_USB0SEL_HS_USB :
  51. USBHS_UGCTRL2_USB0SEL_PCI;
  52. } else {
  53. clrmask = USBHS_UGCTRL2_USB2SEL;
  54. setmask = mode ? USBHS_UGCTRL2_USB2SEL_USB30 :
  55. USBHS_UGCTRL2_USB2SEL_PCI;
  56. }
  57. clrsetbits_le32(priv->regs + USBHS_UGCTRL2, clrmask, setmask);
  58. return 0;
  59. }
  60. static int rcar_gen2_phy_phy_power_on(struct phy *phy)
  61. {
  62. struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
  63. int i;
  64. u32 value;
  65. /* Power on USBHS PHY */
  66. clrbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_PLLRESET);
  67. setbits_le16(priv->regs + USBHS_LPSTS, USBHS_LPSTS_SUSPM);
  68. for (i = 0; i < 20; i++) {
  69. value = readl(priv->regs + USBHS_UGSTS);
  70. if ((value & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) {
  71. setbits_le32(priv->regs + USBHS_UGCTRL,
  72. USBHS_UGCTRL_CONNECT);
  73. return 0;
  74. }
  75. udelay(1);
  76. }
  77. return -ETIMEDOUT;
  78. }
  79. static int rcar_gen2_phy_phy_power_off(struct phy *phy)
  80. {
  81. struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
  82. /* Power off USBHS PHY */
  83. clrbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_CONNECT);
  84. clrbits_le16(priv->regs + USBHS_LPSTS, USBHS_LPSTS_SUSPM);
  85. setbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_PLLRESET);
  86. return 0;
  87. }
  88. static int rcar_gen2_phy_of_xlate(struct phy *phy,
  89. struct ofnode_phandle_args *args)
  90. {
  91. if (args->args_count != 2) {
  92. dev_err(phy->dev, "Invalid DT PHY argument count: %d\n",
  93. args->args_count);
  94. return -EINVAL;
  95. }
  96. if (args->args[0] != 0 && args->args[0] != 2) {
  97. dev_err(phy->dev, "Invalid DT PHY channel: %d\n",
  98. args->args[0]);
  99. return -EINVAL;
  100. }
  101. if (args->args[1] != 0 && args->args[1] != 1) {
  102. dev_err(phy->dev, "Invalid DT PHY mode: %d\n",
  103. args->args[1]);
  104. return -EINVAL;
  105. }
  106. if (args->args_count)
  107. phy->id = args->args[0] | (args->args[1] << 16);
  108. else
  109. phy->id = 0;
  110. return 0;
  111. }
  112. static const struct phy_ops rcar_gen2_phy_phy_ops = {
  113. .init = rcar_gen2_phy_phy_init,
  114. .power_on = rcar_gen2_phy_phy_power_on,
  115. .power_off = rcar_gen2_phy_phy_power_off,
  116. .of_xlate = rcar_gen2_phy_of_xlate,
  117. };
  118. static int rcar_gen2_phy_probe(struct udevice *dev)
  119. {
  120. struct rcar_gen2_phy *priv = dev_get_priv(dev);
  121. int ret;
  122. priv->regs = dev_read_addr(dev);
  123. if (priv->regs == FDT_ADDR_T_NONE)
  124. return -EINVAL;
  125. /* Enable clock */
  126. ret = clk_get_by_index(dev, 0, &priv->clk);
  127. if (ret)
  128. return ret;
  129. ret = clk_enable(&priv->clk);
  130. if (ret)
  131. return ret;
  132. return 0;
  133. }
  134. static int rcar_gen2_phy_remove(struct udevice *dev)
  135. {
  136. struct rcar_gen2_phy *priv = dev_get_priv(dev);
  137. clk_disable(&priv->clk);
  138. clk_free(&priv->clk);
  139. return 0;
  140. }
  141. static const struct udevice_id rcar_gen2_phy_of_match[] = {
  142. { .compatible = "renesas,rcar-gen2-usb-phy", },
  143. { },
  144. };
  145. U_BOOT_DRIVER(rcar_gen2_phy) = {
  146. .name = "rcar-gen2-phy",
  147. .id = UCLASS_PHY,
  148. .of_match = rcar_gen2_phy_of_match,
  149. .ops = &rcar_gen2_phy_phy_ops,
  150. .probe = rcar_gen2_phy_probe,
  151. .remove = rcar_gen2_phy_remove,
  152. .priv_auto_alloc_size = sizeof(struct rcar_gen2_phy),
  153. };