phy-exynos-pcie.c 8.8 KB

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