phy-rcar-gen2.c 4.4 KB

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