2
0

002-6.2-phy-freescale-imx8m-pcie-Refine-i.MX8MM-PCIe-PHY-dri.patch 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. From fb681544808b85c0cdf41a627401e5d470633914 Mon Sep 17 00:00:00 2001
  2. From: Richard Zhu <[email protected]>
  3. Date: Thu, 13 Oct 2022 09:47:01 +0800
  4. Subject: [PATCH 2/3] phy: freescale: imx8m-pcie: Refine i.MX8MM PCIe PHY
  5. driver
  6. To make it more flexible and easy to expand. Refine i.MX8MM PCIe PHY
  7. driver.
  8. - Use gpr compatible string to avoid the codes duplications when add
  9. another platform PCIe PHY support.
  10. - Re-arrange the codes to let it more flexible and easy to expand.
  11. No functional change. Re-arrange the TX tuning, since internal registers
  12. can be wrote through APB interface before assertion of CMN_RST.
  13. Signed-off-by: Richard Zhu <[email protected]>
  14. Signed-off-by: Lucas Stach <[email protected]>
  15. Tested-by: Marek Vasut <[email protected]>
  16. Tested-by: Richard Leitner <[email protected]>
  17. Tested-by: Alexander Stein <[email protected]>
  18. Reviewed-by: Lucas Stach <[email protected]>
  19. Reviewed-by: Ahmad Fatoum <[email protected]>
  20. ---
  21. drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 106 +++++++++++++--------
  22. 1 file changed, 66 insertions(+), 40 deletions(-)
  23. --- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
  24. +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
  25. @@ -11,6 +11,7 @@
  26. #include <linux/mfd/syscon.h>
  27. #include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
  28. #include <linux/module.h>
  29. +#include <linux/of_device.h>
  30. #include <linux/phy/phy.h>
  31. #include <linux/platform_device.h>
  32. #include <linux/regmap.h>
  33. @@ -45,6 +46,15 @@
  34. #define IMX8MM_GPR_PCIE_SSC_EN BIT(16)
  35. #define IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE BIT(9)
  36. +enum imx8_pcie_phy_type {
  37. + IMX8MM,
  38. +};
  39. +
  40. +struct imx8_pcie_phy_drvdata {
  41. + const char *gpr;
  42. + enum imx8_pcie_phy_type variant;
  43. +};
  44. +
  45. struct imx8_pcie_phy {
  46. void __iomem *base;
  47. struct clk *clk;
  48. @@ -55,6 +65,7 @@ struct imx8_pcie_phy {
  49. u32 tx_deemph_gen1;
  50. u32 tx_deemph_gen2;
  51. bool clkreq_unused;
  52. + const struct imx8_pcie_phy_drvdata *drvdata;
  53. };
  54. static int imx8_pcie_phy_power_on(struct phy *phy)
  55. @@ -66,31 +77,17 @@ static int imx8_pcie_phy_power_on(struct
  56. reset_control_assert(imx8_phy->reset);
  57. pad_mode = imx8_phy->refclk_pad_mode;
  58. - /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */
  59. - regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  60. - IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE,
  61. - imx8_phy->clkreq_unused ?
  62. - 0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
  63. - regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  64. - IMX8MM_GPR_PCIE_AUX_EN,
  65. - IMX8MM_GPR_PCIE_AUX_EN);
  66. - regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  67. - IMX8MM_GPR_PCIE_POWER_OFF, 0);
  68. - regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  69. - IMX8MM_GPR_PCIE_SSC_EN, 0);
  70. -
  71. - regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  72. - IMX8MM_GPR_PCIE_REF_CLK_SEL,
  73. - pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
  74. - IMX8MM_GPR_PCIE_REF_CLK_EXT :
  75. - IMX8MM_GPR_PCIE_REF_CLK_PLL);
  76. - usleep_range(100, 200);
  77. -
  78. - /* Do the PHY common block reset */
  79. - regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  80. - IMX8MM_GPR_PCIE_CMN_RST,
  81. - IMX8MM_GPR_PCIE_CMN_RST);
  82. - usleep_range(200, 500);
  83. + switch (imx8_phy->drvdata->variant) {
  84. + case IMX8MM:
  85. + /* Tune PHY de-emphasis setting to pass PCIe compliance. */
  86. + if (imx8_phy->tx_deemph_gen1)
  87. + writel(imx8_phy->tx_deemph_gen1,
  88. + imx8_phy->base + PCIE_PHY_TRSV_REG5);
  89. + if (imx8_phy->tx_deemph_gen2)
  90. + writel(imx8_phy->tx_deemph_gen2,
  91. + imx8_phy->base + PCIE_PHY_TRSV_REG6);
  92. + break;
  93. + }
  94. if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ||
  95. pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) {
  96. @@ -118,15 +115,37 @@ static int imx8_pcie_phy_power_on(struct
  97. imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG065);
  98. }
  99. - /* Tune PHY de-emphasis setting to pass PCIe compliance. */
  100. - if (imx8_phy->tx_deemph_gen1)
  101. - writel(imx8_phy->tx_deemph_gen1,
  102. - imx8_phy->base + PCIE_PHY_TRSV_REG5);
  103. - if (imx8_phy->tx_deemph_gen2)
  104. - writel(imx8_phy->tx_deemph_gen2,
  105. - imx8_phy->base + PCIE_PHY_TRSV_REG6);
  106. + /* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */
  107. + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  108. + IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE,
  109. + imx8_phy->clkreq_unused ?
  110. + 0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
  111. + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  112. + IMX8MM_GPR_PCIE_AUX_EN,
  113. + IMX8MM_GPR_PCIE_AUX_EN);
  114. + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  115. + IMX8MM_GPR_PCIE_POWER_OFF, 0);
  116. + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  117. + IMX8MM_GPR_PCIE_SSC_EN, 0);
  118. - reset_control_deassert(imx8_phy->reset);
  119. + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  120. + IMX8MM_GPR_PCIE_REF_CLK_SEL,
  121. + pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
  122. + IMX8MM_GPR_PCIE_REF_CLK_EXT :
  123. + IMX8MM_GPR_PCIE_REF_CLK_PLL);
  124. + usleep_range(100, 200);
  125. +
  126. + /* Do the PHY common block reset */
  127. + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
  128. + IMX8MM_GPR_PCIE_CMN_RST,
  129. + IMX8MM_GPR_PCIE_CMN_RST);
  130. +
  131. + switch (imx8_phy->drvdata->variant) {
  132. + case IMX8MM:
  133. + reset_control_deassert(imx8_phy->reset);
  134. + usleep_range(200, 500);
  135. + break;
  136. + }
  137. /* Polling to check the phy is ready or not. */
  138. ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075,
  139. @@ -157,6 +176,17 @@ static const struct phy_ops imx8_pcie_ph
  140. .owner = THIS_MODULE,
  141. };
  142. +static const struct imx8_pcie_phy_drvdata imx8mm_drvdata = {
  143. + .gpr = "fsl,imx8mm-iomuxc-gpr",
  144. + .variant = IMX8MM,
  145. +};
  146. +
  147. +static const struct of_device_id imx8_pcie_phy_of_match[] = {
  148. + {.compatible = "fsl,imx8mm-pcie-phy", .data = &imx8mm_drvdata, },
  149. + { },
  150. +};
  151. +MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
  152. +
  153. static int imx8_pcie_phy_probe(struct platform_device *pdev)
  154. {
  155. struct phy_provider *phy_provider;
  156. @@ -169,6 +199,8 @@ static int imx8_pcie_phy_probe(struct pl
  157. if (!imx8_phy)
  158. return -ENOMEM;
  159. + imx8_phy->drvdata = of_device_get_match_data(dev);
  160. +
  161. /* get PHY refclk pad mode */
  162. of_property_read_u32(np, "fsl,refclk-pad-mode",
  163. &imx8_phy->refclk_pad_mode);
  164. @@ -194,7 +226,7 @@ static int imx8_pcie_phy_probe(struct pl
  165. /* Grab GPR config register range */
  166. imx8_phy->iomuxc_gpr =
  167. - syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  168. + syscon_regmap_lookup_by_compatible(imx8_phy->drvdata->gpr);
  169. if (IS_ERR(imx8_phy->iomuxc_gpr)) {
  170. dev_err(dev, "unable to find iomuxc registers\n");
  171. return PTR_ERR(imx8_phy->iomuxc_gpr);
  172. @@ -222,12 +254,6 @@ static int imx8_pcie_phy_probe(struct pl
  173. return PTR_ERR_OR_ZERO(phy_provider);
  174. }
  175. -static const struct of_device_id imx8_pcie_phy_of_match[] = {
  176. - {.compatible = "fsl,imx8mm-pcie-phy",},
  177. - { },
  178. -};
  179. -MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
  180. -
  181. static struct platform_driver imx8_pcie_phy_driver = {
  182. .probe = imx8_pcie_phy_probe,
  183. .driver = {