phy-jh7110-dphy-rx.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * StarFive JH7110 DPHY RX driver
  4. *
  5. * Copyright (C) 2023 StarFive Technology Co., Ltd.
  6. * Author: Jack Zhu <jack.zhu@starfivetech.com>
  7. * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
  8. */
  9. #include <linux/bitfield.h>
  10. #include <linux/bitops.h>
  11. #include <linux/clk.h>
  12. #include <linux/io.h>
  13. #include <linux/module.h>
  14. #include <linux/of.h>
  15. #include <linux/phy/phy.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/pm_runtime.h>
  18. #include <linux/reset.h>
  19. #define STF_DPHY_APBCFGSAIF_SYSCFG(x) (x)
  20. #define STF_DPHY_ENABLE_CLK BIT(6)
  21. #define STF_DPHY_ENABLE_CLK1 BIT(7)
  22. #define STF_DPHY_ENABLE_LAN0 BIT(8)
  23. #define STF_DPHY_ENABLE_LAN1 BIT(9)
  24. #define STF_DPHY_ENABLE_LAN2 BIT(10)
  25. #define STF_DPHY_ENABLE_LAN3 BIT(11)
  26. #define STF_DPHY_LANE_SWAP_CLK GENMASK(22, 20)
  27. #define STF_DPHY_LANE_SWAP_CLK1 GENMASK(25, 23)
  28. #define STF_DPHY_LANE_SWAP_LAN0 GENMASK(28, 26)
  29. #define STF_DPHY_LANE_SWAP_LAN1 GENMASK(31, 29)
  30. #define STF_DPHY_LANE_SWAP_LAN2 GENMASK(2, 0)
  31. #define STF_DPHY_LANE_SWAP_LAN3 GENMASK(5, 3)
  32. #define STF_DPHY_PLL_CLK_SEL GENMASK(21, 12)
  33. #define STF_DPHY_PRECOUNTER_IN_CLK GENMASK(29, 22)
  34. #define STF_DPHY_PRECOUNTER_IN_CLK1 GENMASK(7, 0)
  35. #define STF_DPHY_PRECOUNTER_IN_LAN0 GENMASK(15, 8)
  36. #define STF_DPHY_PRECOUNTER_IN_LAN1 GENMASK(23, 16)
  37. #define STF_DPHY_PRECOUNTER_IN_LAN2 GENMASK(31, 24)
  38. #define STF_DPHY_PRECOUNTER_IN_LAN3 GENMASK(7, 0)
  39. #define STF_DPHY_RX_1C2C_SEL BIT(8)
  40. #define STF_MAP_LANES_NUM 6
  41. struct stf_dphy_info {
  42. /**
  43. * @maps:
  44. *
  45. * Physical lanes and logic lanes mapping table.
  46. *
  47. * The default order is:
  48. * [clk lane0, data lane 0, data lane 1, data lane 2, date lane 3, clk lane 1]
  49. */
  50. u8 maps[STF_MAP_LANES_NUM];
  51. };
  52. struct stf_dphy {
  53. struct device *dev;
  54. void __iomem *regs;
  55. struct clk *cfg_clk;
  56. struct clk *ref_clk;
  57. struct clk *tx_clk;
  58. struct reset_control *rstc;
  59. struct regulator *mipi_0p9;
  60. struct phy *phy;
  61. const struct stf_dphy_info *info;
  62. };
  63. static int stf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
  64. {
  65. struct stf_dphy *dphy = phy_get_drvdata(phy);
  66. const struct stf_dphy_info *info = dphy->info;
  67. writel(FIELD_PREP(STF_DPHY_ENABLE_CLK, 1) |
  68. FIELD_PREP(STF_DPHY_ENABLE_CLK1, 1) |
  69. FIELD_PREP(STF_DPHY_ENABLE_LAN0, 1) |
  70. FIELD_PREP(STF_DPHY_ENABLE_LAN1, 1) |
  71. FIELD_PREP(STF_DPHY_ENABLE_LAN2, 1) |
  72. FIELD_PREP(STF_DPHY_ENABLE_LAN3, 1) |
  73. FIELD_PREP(STF_DPHY_LANE_SWAP_CLK, info->maps[0]) |
  74. FIELD_PREP(STF_DPHY_LANE_SWAP_CLK1, info->maps[5]) |
  75. FIELD_PREP(STF_DPHY_LANE_SWAP_LAN0, info->maps[1]) |
  76. FIELD_PREP(STF_DPHY_LANE_SWAP_LAN1, info->maps[2]),
  77. dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(188));
  78. writel(FIELD_PREP(STF_DPHY_LANE_SWAP_LAN2, info->maps[3]) |
  79. FIELD_PREP(STF_DPHY_LANE_SWAP_LAN3, info->maps[4]) |
  80. FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK, 8),
  81. dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(192));
  82. writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK1, 8) |
  83. FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN0, 7) |
  84. FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN1, 7) |
  85. FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN2, 7),
  86. dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(196));
  87. writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN3, 7),
  88. dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(200));
  89. return 0;
  90. }
  91. static int stf_dphy_power_on(struct phy *phy)
  92. {
  93. struct stf_dphy *dphy = phy_get_drvdata(phy);
  94. int ret;
  95. ret = pm_runtime_resume_and_get(dphy->dev);
  96. if (ret < 0)
  97. return ret;
  98. ret = regulator_enable(dphy->mipi_0p9);
  99. if (ret) {
  100. pm_runtime_put(dphy->dev);
  101. return ret;
  102. }
  103. clk_set_rate(dphy->cfg_clk, 99000000);
  104. clk_set_rate(dphy->ref_clk, 49500000);
  105. clk_set_rate(dphy->tx_clk, 19800000);
  106. reset_control_deassert(dphy->rstc);
  107. return 0;
  108. }
  109. static int stf_dphy_power_off(struct phy *phy)
  110. {
  111. struct stf_dphy *dphy = phy_get_drvdata(phy);
  112. reset_control_assert(dphy->rstc);
  113. regulator_disable(dphy->mipi_0p9);
  114. pm_runtime_put_sync(dphy->dev);
  115. return 0;
  116. }
  117. static const struct phy_ops stf_dphy_ops = {
  118. .configure = stf_dphy_configure,
  119. .power_on = stf_dphy_power_on,
  120. .power_off = stf_dphy_power_off,
  121. };
  122. static int stf_dphy_probe(struct platform_device *pdev)
  123. {
  124. struct phy_provider *phy_provider;
  125. struct stf_dphy *dphy;
  126. dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
  127. if (!dphy)
  128. return -ENOMEM;
  129. dphy->info = of_device_get_match_data(&pdev->dev);
  130. dev_set_drvdata(&pdev->dev, dphy);
  131. dphy->dev = &pdev->dev;
  132. dphy->regs = devm_platform_ioremap_resource(pdev, 0);
  133. if (IS_ERR(dphy->regs))
  134. return PTR_ERR(dphy->regs);
  135. dphy->cfg_clk = devm_clk_get(&pdev->dev, "cfg");
  136. if (IS_ERR(dphy->cfg_clk))
  137. return PTR_ERR(dphy->cfg_clk);
  138. dphy->ref_clk = devm_clk_get(&pdev->dev, "ref");
  139. if (IS_ERR(dphy->ref_clk))
  140. return PTR_ERR(dphy->ref_clk);
  141. dphy->tx_clk = devm_clk_get(&pdev->dev, "tx");
  142. if (IS_ERR(dphy->tx_clk))
  143. return PTR_ERR(dphy->tx_clk);
  144. dphy->rstc = devm_reset_control_array_get_exclusive(&pdev->dev);
  145. if (IS_ERR(dphy->rstc))
  146. return PTR_ERR(dphy->rstc);
  147. dphy->mipi_0p9 = devm_regulator_get(&pdev->dev, "mipi_0p9");
  148. if (IS_ERR(dphy->mipi_0p9))
  149. return PTR_ERR(dphy->mipi_0p9);
  150. dphy->phy = devm_phy_create(&pdev->dev, NULL, &stf_dphy_ops);
  151. if (IS_ERR(dphy->phy)) {
  152. dev_err(&pdev->dev, "Failed to create PHY\n");
  153. return PTR_ERR(dphy->phy);
  154. }
  155. pm_runtime_enable(&pdev->dev);
  156. phy_set_drvdata(dphy->phy, dphy);
  157. phy_provider = devm_of_phy_provider_register(&pdev->dev,
  158. of_phy_simple_xlate);
  159. return PTR_ERR_OR_ZERO(phy_provider);
  160. }
  161. static const struct stf_dphy_info starfive_dphy_info = {
  162. .maps = {4, 0, 1, 2, 3, 5},
  163. };
  164. static const struct of_device_id stf_dphy_dt_ids[] = {
  165. {
  166. .compatible = "starfive,jh7110-dphy-rx",
  167. .data = &starfive_dphy_info,
  168. },
  169. { /* sentinel */ },
  170. };
  171. MODULE_DEVICE_TABLE(of, stf_dphy_dt_ids);
  172. static struct platform_driver stf_dphy_driver = {
  173. .probe = stf_dphy_probe,
  174. .driver = {
  175. .name = "starfive-dphy-rx",
  176. .of_match_table = stf_dphy_dt_ids,
  177. },
  178. };
  179. module_platform_driver(stf_dphy_driver);
  180. MODULE_AUTHOR("Jack Zhu <jack.zhu@starfivetech.com>");
  181. MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
  182. MODULE_DESCRIPTION("StarFive JH7110 DPHY RX driver");
  183. MODULE_LICENSE("GPL");