phy-rcar-gen3.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Renesas RCar Gen3 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 <linux/bitops.h>
  19. #include <power/regulator.h>
  20. /* USB2.0 Host registers (original offset is +0x200) */
  21. #define USB2_INT_ENABLE 0x000
  22. #define USB2_USBCTR 0x00c
  23. #define USB2_SPD_RSM_TIMSET 0x10c
  24. #define USB2_OC_TIMSET 0x110
  25. #define USB2_COMMCTRL 0x600
  26. #define USB2_OBINTSTA 0x604
  27. #define USB2_OBINTEN 0x608
  28. #define USB2_VBCTRL 0x60c
  29. #define USB2_LINECTRL1 0x610
  30. #define USB2_ADPCTRL 0x630
  31. /* USBCTR */
  32. #define USB2_USBCTR_PLL_RST BIT(1)
  33. /* SPD_RSM_TIMSET */
  34. #define USB2_SPD_RSM_TIMSET_INIT 0x014e029b
  35. /* OC_TIMSET */
  36. #define USB2_OC_TIMSET_INIT 0x000209ab
  37. /* COMMCTRL */
  38. #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */
  39. /* LINECTRL1 */
  40. #define USB2_LINECTRL1_DP_RPD BIT(18)
  41. #define USB2_LINECTRL1_DM_RPD BIT(16)
  42. /* ADPCTRL */
  43. #define USB2_ADPCTRL_DRVVBUS BIT(4)
  44. struct rcar_gen3_phy {
  45. fdt_addr_t regs;
  46. struct clk clk;
  47. struct udevice *vbus_supply;
  48. };
  49. static int rcar_gen3_phy_phy_init(struct phy *phy)
  50. {
  51. struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
  52. /* Initialize USB2 part */
  53. writel(0, priv->regs + USB2_INT_ENABLE);
  54. writel(USB2_SPD_RSM_TIMSET_INIT, priv->regs + USB2_SPD_RSM_TIMSET);
  55. writel(USB2_OC_TIMSET_INIT, priv->regs + USB2_OC_TIMSET);
  56. setbits_le32(priv->regs + USB2_LINECTRL1,
  57. USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
  58. clrbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI);
  59. setbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS);
  60. return 0;
  61. }
  62. static int rcar_gen3_phy_phy_power_on(struct phy *phy)
  63. {
  64. struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
  65. int ret;
  66. if (priv->vbus_supply) {
  67. ret = regulator_set_enable(priv->vbus_supply, true);
  68. if (ret)
  69. return ret;
  70. }
  71. setbits_le32(priv->regs + USB2_USBCTR, USB2_USBCTR_PLL_RST);
  72. clrbits_le32(priv->regs + USB2_USBCTR, USB2_USBCTR_PLL_RST);
  73. return 0;
  74. }
  75. static int rcar_gen3_phy_phy_power_off(struct phy *phy)
  76. {
  77. struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
  78. if (!priv->vbus_supply)
  79. return 0;
  80. return regulator_set_enable(priv->vbus_supply, false);
  81. }
  82. static const struct phy_ops rcar_gen3_phy_phy_ops = {
  83. .init = rcar_gen3_phy_phy_init,
  84. .power_on = rcar_gen3_phy_phy_power_on,
  85. .power_off = rcar_gen3_phy_phy_power_off,
  86. };
  87. static int rcar_gen3_phy_probe(struct udevice *dev)
  88. {
  89. struct rcar_gen3_phy *priv = dev_get_priv(dev);
  90. int ret;
  91. priv->regs = dev_read_addr(dev);
  92. if (priv->regs == FDT_ADDR_T_NONE)
  93. return -EINVAL;
  94. ret = device_get_supply_regulator(dev, "vbus-supply",
  95. &priv->vbus_supply);
  96. if (ret && ret != -ENOENT) {
  97. pr_err("Failed to get PHY regulator\n");
  98. return ret;
  99. }
  100. /* Enable clock */
  101. ret = clk_get_by_index(dev, 0, &priv->clk);
  102. if (ret)
  103. return ret;
  104. ret = clk_enable(&priv->clk);
  105. if (ret)
  106. return ret;
  107. return 0;
  108. }
  109. static int rcar_gen3_phy_remove(struct udevice *dev)
  110. {
  111. struct rcar_gen3_phy *priv = dev_get_priv(dev);
  112. clk_disable(&priv->clk);
  113. clk_free(&priv->clk);
  114. return 0;
  115. }
  116. static const struct udevice_id rcar_gen3_phy_of_match[] = {
  117. { .compatible = "renesas,rcar-gen3-usb2-phy", },
  118. { },
  119. };
  120. U_BOOT_DRIVER(rcar_gen3_phy) = {
  121. .name = "rcar-gen3-phy",
  122. .id = UCLASS_PHY,
  123. .of_match = rcar_gen3_phy_of_match,
  124. .ops = &rcar_gen3_phy_phy_ops,
  125. .probe = rcar_gen3_phy_probe,
  126. .remove = rcar_gen3_phy_remove,
  127. .priv_auto_alloc_size = sizeof(struct rcar_gen3_phy),
  128. };