phy-exynos-pcie.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Samsung Exynos SoC series PCIe PHY driver
  4. *
  5. * Phy provider for PCIe controller on Exynos SoC series
  6. *
  7. * Copyright (C) 2017 Samsung Electronics Co., Ltd.
  8. * Jaehoon Chung <jh80.chung@samsung.com>
  9. */
  10. #include <linux/delay.h>
  11. #include <linux/io.h>
  12. #include <linux/iopoll.h>
  13. #include <linux/init.h>
  14. #include <linux/mfd/syscon.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_platform.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/phy/phy.h>
  20. #include <linux/regmap.h>
  21. /* PCIe Purple registers */
  22. #define PCIE_PHY_GLOBAL_RESET 0x000
  23. #define PCIE_PHY_COMMON_RESET 0x004
  24. #define PCIE_PHY_CMN_REG 0x008
  25. #define PCIE_PHY_MAC_RESET 0x00c
  26. #define PCIE_PHY_PLL_LOCKED 0x010
  27. #define PCIE_PHY_TRSVREG_RESET 0x020
  28. #define PCIE_PHY_TRSV_RESET 0x024
  29. /* PCIe PHY registers */
  30. #define PCIE_PHY_IMPEDANCE 0x004
  31. #define PCIE_PHY_PLL_DIV_0 0x008
  32. #define PCIE_PHY_PLL_BIAS 0x00c
  33. #define PCIE_PHY_DCC_FEEDBACK 0x014
  34. #define PCIE_PHY_PLL_DIV_1 0x05c
  35. #define PCIE_PHY_COMMON_POWER 0x064
  36. #define PCIE_PHY_COMMON_PD_CMN BIT(3)
  37. #define PCIE_PHY_TRSV0_EMP_LVL 0x084
  38. #define PCIE_PHY_TRSV0_DRV_LVL 0x088
  39. #define PCIE_PHY_TRSV0_RXCDR 0x0ac
  40. #define PCIE_PHY_TRSV0_POWER 0x0c4
  41. #define PCIE_PHY_TRSV0_PD_TSV BIT(7)
  42. #define PCIE_PHY_TRSV0_LVCC 0x0dc
  43. #define PCIE_PHY_TRSV1_EMP_LVL 0x144
  44. #define PCIE_PHY_TRSV1_RXCDR 0x16c
  45. #define PCIE_PHY_TRSV1_POWER 0x184
  46. #define PCIE_PHY_TRSV1_PD_TSV BIT(7)
  47. #define PCIE_PHY_TRSV1_LVCC 0x19c
  48. #define PCIE_PHY_TRSV2_EMP_LVL 0x204
  49. #define PCIE_PHY_TRSV2_RXCDR 0x22c
  50. #define PCIE_PHY_TRSV2_POWER 0x244
  51. #define PCIE_PHY_TRSV2_PD_TSV BIT(7)
  52. #define PCIE_PHY_TRSV2_LVCC 0x25c
  53. #define PCIE_PHY_TRSV3_EMP_LVL 0x2c4
  54. #define PCIE_PHY_TRSV3_RXCDR 0x2ec
  55. #define PCIE_PHY_TRSV3_POWER 0x304
  56. #define PCIE_PHY_TRSV3_PD_TSV BIT(7)
  57. #define PCIE_PHY_TRSV3_LVCC 0x31c
  58. struct exynos_pcie_phy_data {
  59. const struct phy_ops *ops;
  60. };
  61. /* For Exynos pcie phy */
  62. struct exynos_pcie_phy {
  63. const struct exynos_pcie_phy_data *drv_data;
  64. void __iomem *phy_base;
  65. void __iomem *blk_base; /* For exynos5440 */
  66. };
  67. static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset)
  68. {
  69. writel(val, base + offset);
  70. }
  71. static u32 exynos_pcie_phy_readl(void __iomem *base, u32 offset)
  72. {
  73. return readl(base + offset);
  74. }
  75. /* For Exynos5440 specific functions */
  76. static int exynos5440_pcie_phy_init(struct phy *phy)
  77. {
  78. struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
  79. /* DCC feedback control off */
  80. exynos_pcie_phy_writel(ep->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK);
  81. /* set TX/RX impedance */
  82. exynos_pcie_phy_writel(ep->phy_base, 0xd5, PCIE_PHY_IMPEDANCE);
  83. /* set 50Mhz PHY clock */
  84. exynos_pcie_phy_writel(ep->phy_base, 0x14, PCIE_PHY_PLL_DIV_0);
  85. exynos_pcie_phy_writel(ep->phy_base, 0x12, PCIE_PHY_PLL_DIV_1);
  86. /* set TX Differential output for lane 0 */
  87. exynos_pcie_phy_writel(ep->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL);
  88. /* set TX Pre-emphasis Level Control for lane 0 to minimum */
  89. exynos_pcie_phy_writel(ep->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL);
  90. /* set RX clock and data recovery bandwidth */
  91. exynos_pcie_phy_writel(ep->phy_base, 0xe7, PCIE_PHY_PLL_BIAS);
  92. exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR);
  93. exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR);
  94. exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR);
  95. exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR);
  96. /* change TX Pre-emphasis Level Control for lanes */
  97. exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL);
  98. exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL);
  99. exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL);
  100. exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL);
  101. /* set LVCC */
  102. exynos_pcie_phy_writel(ep->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC);
  103. exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC);
  104. exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC);
  105. exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC);
  106. /* pulse for common reset */
  107. exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_COMMON_RESET);
  108. udelay(500);
  109. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET);
  110. return 0;
  111. }
  112. static int exynos5440_pcie_phy_power_on(struct phy *phy)
  113. {
  114. struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
  115. u32 val;
  116. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET);
  117. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_CMN_REG);
  118. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSVREG_RESET);
  119. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSV_RESET);
  120. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER);
  121. val &= ~PCIE_PHY_COMMON_PD_CMN;
  122. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER);
  123. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER);
  124. val &= ~PCIE_PHY_TRSV0_PD_TSV;
  125. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER);
  126. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER);
  127. val &= ~PCIE_PHY_TRSV1_PD_TSV;
  128. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER);
  129. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER);
  130. val &= ~PCIE_PHY_TRSV2_PD_TSV;
  131. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER);
  132. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER);
  133. val &= ~PCIE_PHY_TRSV3_PD_TSV;
  134. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER);
  135. return 0;
  136. }
  137. static int exynos5440_pcie_phy_power_off(struct phy *phy)
  138. {
  139. struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
  140. u32 val;
  141. if (readl_poll_timeout(ep->phy_base + PCIE_PHY_PLL_LOCKED, val,
  142. (val != 0), 1, 500)) {
  143. dev_err(&phy->dev, "PLL Locked: 0x%x\n", val);
  144. return -ETIMEDOUT;
  145. }
  146. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER);
  147. val |= PCIE_PHY_COMMON_PD_CMN;
  148. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER);
  149. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER);
  150. val |= PCIE_PHY_TRSV0_PD_TSV;
  151. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER);
  152. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER);
  153. val |= PCIE_PHY_TRSV1_PD_TSV;
  154. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER);
  155. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER);
  156. val |= PCIE_PHY_TRSV2_PD_TSV;
  157. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER);
  158. val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER);
  159. val |= PCIE_PHY_TRSV3_PD_TSV;
  160. exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER);
  161. return 0;
  162. }
  163. static int exynos5440_pcie_phy_reset(struct phy *phy)
  164. {
  165. struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
  166. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_MAC_RESET);
  167. exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_GLOBAL_RESET);
  168. exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_GLOBAL_RESET);
  169. return 0;
  170. }
  171. static const struct phy_ops exynos5440_phy_ops = {
  172. .init = exynos5440_pcie_phy_init,
  173. .power_on = exynos5440_pcie_phy_power_on,
  174. .power_off = exynos5440_pcie_phy_power_off,
  175. .reset = exynos5440_pcie_phy_reset,
  176. .owner = THIS_MODULE,
  177. };
  178. static const struct exynos_pcie_phy_data exynos5440_pcie_phy_data = {
  179. .ops = &exynos5440_phy_ops,
  180. };
  181. static const struct of_device_id exynos_pcie_phy_match[] = {
  182. {
  183. .compatible = "samsung,exynos5440-pcie-phy",
  184. .data = &exynos5440_pcie_phy_data,
  185. },
  186. {},
  187. };
  188. static int exynos_pcie_phy_probe(struct platform_device *pdev)
  189. {
  190. struct device *dev = &pdev->dev;
  191. struct exynos_pcie_phy *exynos_phy;
  192. struct phy *generic_phy;
  193. struct phy_provider *phy_provider;
  194. struct resource *res;
  195. const struct exynos_pcie_phy_data *drv_data;
  196. drv_data = of_device_get_match_data(dev);
  197. if (!drv_data)
  198. return -ENODEV;
  199. exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL);
  200. if (!exynos_phy)
  201. return -ENOMEM;
  202. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  203. exynos_phy->phy_base = devm_ioremap_resource(dev, res);
  204. if (IS_ERR(exynos_phy->phy_base))
  205. return PTR_ERR(exynos_phy->phy_base);
  206. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  207. exynos_phy->blk_base = devm_ioremap_resource(dev, res);
  208. if (IS_ERR(exynos_phy->blk_base))
  209. return PTR_ERR(exynos_phy->blk_base);
  210. exynos_phy->drv_data = drv_data;
  211. generic_phy = devm_phy_create(dev, dev->of_node, drv_data->ops);
  212. if (IS_ERR(generic_phy)) {
  213. dev_err(dev, "failed to create PHY\n");
  214. return PTR_ERR(generic_phy);
  215. }
  216. phy_set_drvdata(generic_phy, exynos_phy);
  217. phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
  218. return PTR_ERR_OR_ZERO(phy_provider);
  219. }
  220. static struct platform_driver exynos_pcie_phy_driver = {
  221. .probe = exynos_pcie_phy_probe,
  222. .driver = {
  223. .of_match_table = exynos_pcie_phy_match,
  224. .name = "exynos_pcie_phy",
  225. .suppress_bind_attrs = true,
  226. }
  227. };
  228. builtin_platform_driver(exynos_pcie_phy_driver);