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-2020 Samsung Electronics Co., Ltd. 8 * Jaehoon Chung <jh80.chung@samsung.com> 9 */ 10 11 #include <linux/io.h> 12 #include <linux/mfd/syscon.h> 13 #include <linux/of_platform.h> 14 #include <linux/platform_device.h> 15 #include <linux/phy/phy.h> 16 #include <linux/regmap.h> 17 18 #define PCIE_PHY_OFFSET(x) ((x) * 0x4) 19 20 /* Sysreg FSYS register offsets and bits for Exynos5433 */ 21 #define PCIE_EXYNOS5433_PHY_MAC_RESET 0x0208 22 #define PCIE_MAC_RESET_MASK 0xFF 23 #define PCIE_MAC_RESET BIT(4) 24 #define PCIE_EXYNOS5433_PHY_L1SUB_CM_CON 0x1010 25 #define PCIE_REFCLK_GATING_EN BIT(0) 26 #define PCIE_EXYNOS5433_PHY_COMMON_RESET 0x1020 27 #define PCIE_PHY_RESET BIT(0) 28 #define PCIE_EXYNOS5433_PHY_GLOBAL_RESET 0x1040 29 #define PCIE_GLOBAL_RESET BIT(0) 30 #define PCIE_REFCLK BIT(1) 31 #define PCIE_REFCLK_MASK 0x16 32 #define PCIE_APP_REQ_EXIT_L1_MODE BIT(5) 33 34 /* PMU PCIE PHY isolation control */ 35 #define EXYNOS5433_PMU_PCIE_PHY_OFFSET 0x730 36 37 /* For Exynos pcie phy */ 38 struct exynos_pcie_phy { 39 void __iomem *base; 40 struct regmap *pmureg; 41 struct regmap *fsysreg; 42 }; 43 44 static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset) 45 { 46 writel(val, base + offset); 47 } 48 49 /* Exynos5433 specific functions */ 50 static int exynos5433_pcie_phy_init(struct phy *phy) 51 { 52 struct exynos_pcie_phy *ep = phy_get_drvdata(phy); 53 54 regmap_update_bits(ep->pmureg, EXYNOS5433_PMU_PCIE_PHY_OFFSET, 55 BIT(0), 1); 56 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET, 57 PCIE_APP_REQ_EXIT_L1_MODE, 0); 58 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_L1SUB_CM_CON, 59 PCIE_REFCLK_GATING_EN, 0); 60 61 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_COMMON_RESET, 62 PCIE_PHY_RESET, 1); 63 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_MAC_RESET, 64 PCIE_MAC_RESET, 0); 65 66 /* PHY refclk 24MHz */ 67 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET, 68 PCIE_REFCLK_MASK, PCIE_REFCLK); 69 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET, 70 PCIE_GLOBAL_RESET, 0); 71 72 73 exynos_pcie_phy_writel(ep->base, 0x11, PCIE_PHY_OFFSET(0x3)); 74 75 /* band gap reference on */ 76 exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x20)); 77 exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x4b)); 78 79 /* jitter tuning */ 80 exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x4)); 81 exynos_pcie_phy_writel(ep->base, 0x02, PCIE_PHY_OFFSET(0x7)); 82 exynos_pcie_phy_writel(ep->base, 0x41, PCIE_PHY_OFFSET(0x21)); 83 exynos_pcie_phy_writel(ep->base, 0x7F, PCIE_PHY_OFFSET(0x14)); 84 exynos_pcie_phy_writel(ep->base, 0xC0, PCIE_PHY_OFFSET(0x15)); 85 exynos_pcie_phy_writel(ep->base, 0x61, PCIE_PHY_OFFSET(0x36)); 86 87 /* D0 uninit.. */ 88 exynos_pcie_phy_writel(ep->base, 0x44, PCIE_PHY_OFFSET(0x3D)); 89 90 /* 24MHz */ 91 exynos_pcie_phy_writel(ep->base, 0x94, PCIE_PHY_OFFSET(0x8)); 92 exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x9)); 93 exynos_pcie_phy_writel(ep->base, 0x93, PCIE_PHY_OFFSET(0xA)); 94 exynos_pcie_phy_writel(ep->base, 0x6B, PCIE_PHY_OFFSET(0xC)); 95 exynos_pcie_phy_writel(ep->base, 0xA5, PCIE_PHY_OFFSET(0xF)); 96 exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x16)); 97 exynos_pcie_phy_writel(ep->base, 0xA3, PCIE_PHY_OFFSET(0x17)); 98 exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x1A)); 99 exynos_pcie_phy_writel(ep->base, 0x71, PCIE_PHY_OFFSET(0x23)); 100 exynos_pcie_phy_writel(ep->base, 0x4C, PCIE_PHY_OFFSET(0x24)); 101 102 exynos_pcie_phy_writel(ep->base, 0x0E, PCIE_PHY_OFFSET(0x26)); 103 exynos_pcie_phy_writel(ep->base, 0x14, PCIE_PHY_OFFSET(0x7)); 104 exynos_pcie_phy_writel(ep->base, 0x48, PCIE_PHY_OFFSET(0x43)); 105 exynos_pcie_phy_writel(ep->base, 0x44, PCIE_PHY_OFFSET(0x44)); 106 exynos_pcie_phy_writel(ep->base, 0x03, PCIE_PHY_OFFSET(0x45)); 107 exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x48)); 108 exynos_pcie_phy_writel(ep->base, 0x13, PCIE_PHY_OFFSET(0x54)); 109 exynos_pcie_phy_writel(ep->base, 0x04, PCIE_PHY_OFFSET(0x31)); 110 exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x32)); 111 112 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_COMMON_RESET, 113 PCIE_PHY_RESET, 0); 114 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_MAC_RESET, 115 PCIE_MAC_RESET_MASK, PCIE_MAC_RESET); 116 return 0; 117 } 118 119 static int exynos5433_pcie_phy_exit(struct phy *phy) 120 { 121 struct exynos_pcie_phy *ep = phy_get_drvdata(phy); 122 123 regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_L1SUB_CM_CON, 124 PCIE_REFCLK_GATING_EN, PCIE_REFCLK_GATING_EN); 125 regmap_update_bits(ep->pmureg, EXYNOS5433_PMU_PCIE_PHY_OFFSET, 126 BIT(0), 0); 127 return 0; 128 } 129 130 static const struct phy_ops exynos5433_phy_ops = { 131 .init = exynos5433_pcie_phy_init, 132 .exit = exynos5433_pcie_phy_exit, 133 .owner = THIS_MODULE, 134 }; 135 136 static const struct of_device_id exynos_pcie_phy_match[] = { 137 { 138 .compatible = "samsung,exynos5433-pcie-phy", 139 }, 140 {}, 141 }; 142 143 static int exynos_pcie_phy_probe(struct platform_device *pdev) 144 { 145 struct device *dev = &pdev->dev; 146 struct exynos_pcie_phy *exynos_phy; 147 struct phy *generic_phy; 148 struct phy_provider *phy_provider; 149 150 exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL); 151 if (!exynos_phy) 152 return -ENOMEM; 153 154 exynos_phy->base = devm_platform_ioremap_resource(pdev, 0); 155 if (IS_ERR(exynos_phy->base)) 156 return PTR_ERR(exynos_phy->base); 157 158 exynos_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, 159 "samsung,pmu-syscon"); 160 if (IS_ERR(exynos_phy->pmureg)) { 161 dev_err(&pdev->dev, "PMU regmap lookup failed.\n"); 162 return PTR_ERR(exynos_phy->pmureg); 163 } 164 165 exynos_phy->fsysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 166 "samsung,fsys-sysreg"); 167 if (IS_ERR(exynos_phy->fsysreg)) { 168 dev_err(&pdev->dev, "FSYS sysreg regmap lookup failed.\n"); 169 return PTR_ERR(exynos_phy->fsysreg); 170 } 171 172 generic_phy = devm_phy_create(dev, dev->of_node, &exynos5433_phy_ops); 173 if (IS_ERR(generic_phy)) { 174 dev_err(dev, "failed to create PHY\n"); 175 return PTR_ERR(generic_phy); 176 } 177 178 phy_set_drvdata(generic_phy, exynos_phy); 179 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 180 181 return PTR_ERR_OR_ZERO(phy_provider); 182 } 183 184 static struct platform_driver exynos_pcie_phy_driver = { 185 .probe = exynos_pcie_phy_probe, 186 .driver = { 187 .of_match_table = exynos_pcie_phy_match, 188 .name = "exynos_pcie_phy", 189 .suppress_bind_attrs = true, 190 } 191 }; 192 builtin_platform_driver(exynos_pcie_phy_driver); 193