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 11 #include <linux/delay.h> 12 #include <linux/io.h> 13 #include <linux/iopoll.h> 14 #include <linux/init.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/of.h> 17 #include <linux/of_address.h> 18 #include <linux/of_platform.h> 19 #include <linux/platform_device.h> 20 #include <linux/phy/phy.h> 21 #include <linux/regmap.h> 22 23 /* PCIe Purple registers */ 24 #define PCIE_PHY_GLOBAL_RESET 0x000 25 #define PCIE_PHY_COMMON_RESET 0x004 26 #define PCIE_PHY_CMN_REG 0x008 27 #define PCIE_PHY_MAC_RESET 0x00c 28 #define PCIE_PHY_PLL_LOCKED 0x010 29 #define PCIE_PHY_TRSVREG_RESET 0x020 30 #define PCIE_PHY_TRSV_RESET 0x024 31 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 62 struct exynos_pcie_phy_data { 63 const struct phy_ops *ops; 64 }; 65 66 /* For Exynos pcie phy */ 67 struct exynos_pcie_phy { 68 const struct exynos_pcie_phy_data *drv_data; 69 void __iomem *phy_base; 70 void __iomem *blk_base; /* For exynos5440 */ 71 }; 72 73 static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset) 74 { 75 writel(val, base + offset); 76 } 77 78 static u32 exynos_pcie_phy_readl(void __iomem *base, u32 offset) 79 { 80 return readl(base + offset); 81 } 82 83 /* For Exynos5440 specific functions */ 84 static int exynos5440_pcie_phy_init(struct phy *phy) 85 { 86 struct exynos_pcie_phy *ep = phy_get_drvdata(phy); 87 88 /* DCC feedback control off */ 89 exynos_pcie_phy_writel(ep->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK); 90 91 /* set TX/RX impedance */ 92 exynos_pcie_phy_writel(ep->phy_base, 0xd5, PCIE_PHY_IMPEDANCE); 93 94 /* set 50Mhz PHY clock */ 95 exynos_pcie_phy_writel(ep->phy_base, 0x14, PCIE_PHY_PLL_DIV_0); 96 exynos_pcie_phy_writel(ep->phy_base, 0x12, PCIE_PHY_PLL_DIV_1); 97 98 /* set TX Differential output for lane 0 */ 99 exynos_pcie_phy_writel(ep->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL); 100 101 /* set TX Pre-emphasis Level Control for lane 0 to minimum */ 102 exynos_pcie_phy_writel(ep->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL); 103 104 /* set RX clock and data recovery bandwidth */ 105 exynos_pcie_phy_writel(ep->phy_base, 0xe7, PCIE_PHY_PLL_BIAS); 106 exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR); 107 exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR); 108 exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR); 109 exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR); 110 111 /* change TX Pre-emphasis Level Control for lanes */ 112 exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL); 113 exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL); 114 exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL); 115 exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL); 116 117 /* set LVCC */ 118 exynos_pcie_phy_writel(ep->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC); 119 exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC); 120 exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC); 121 exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC); 122 123 /* pulse for common reset */ 124 exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_COMMON_RESET); 125 udelay(500); 126 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET); 127 128 return 0; 129 } 130 131 static int exynos5440_pcie_phy_power_on(struct phy *phy) 132 { 133 struct exynos_pcie_phy *ep = phy_get_drvdata(phy); 134 u32 val; 135 136 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET); 137 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_CMN_REG); 138 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSVREG_RESET); 139 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSV_RESET); 140 141 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER); 142 val &= ~PCIE_PHY_COMMON_PD_CMN; 143 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER); 144 145 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER); 146 val &= ~PCIE_PHY_TRSV0_PD_TSV; 147 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER); 148 149 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER); 150 val &= ~PCIE_PHY_TRSV1_PD_TSV; 151 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER); 152 153 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER); 154 val &= ~PCIE_PHY_TRSV2_PD_TSV; 155 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER); 156 157 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER); 158 val &= ~PCIE_PHY_TRSV3_PD_TSV; 159 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER); 160 161 return 0; 162 } 163 164 static int exynos5440_pcie_phy_power_off(struct phy *phy) 165 { 166 struct exynos_pcie_phy *ep = phy_get_drvdata(phy); 167 u32 val; 168 169 if (readl_poll_timeout(ep->phy_base + PCIE_PHY_PLL_LOCKED, val, 170 (val != 0), 1, 500)) { 171 dev_err(&phy->dev, "PLL Locked: 0x%x\n", val); 172 return -ETIMEDOUT; 173 } 174 175 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER); 176 val |= PCIE_PHY_COMMON_PD_CMN; 177 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER); 178 179 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER); 180 val |= PCIE_PHY_TRSV0_PD_TSV; 181 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER); 182 183 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER); 184 val |= PCIE_PHY_TRSV1_PD_TSV; 185 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER); 186 187 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER); 188 val |= PCIE_PHY_TRSV2_PD_TSV; 189 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER); 190 191 val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER); 192 val |= PCIE_PHY_TRSV3_PD_TSV; 193 exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER); 194 195 return 0; 196 } 197 198 static int exynos5440_pcie_phy_reset(struct phy *phy) 199 { 200 struct exynos_pcie_phy *ep = phy_get_drvdata(phy); 201 202 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_MAC_RESET); 203 exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_GLOBAL_RESET); 204 exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_GLOBAL_RESET); 205 206 return 0; 207 } 208 209 static const struct phy_ops exynos5440_phy_ops = { 210 .init = exynos5440_pcie_phy_init, 211 .power_on = exynos5440_pcie_phy_power_on, 212 .power_off = exynos5440_pcie_phy_power_off, 213 .reset = exynos5440_pcie_phy_reset, 214 .owner = THIS_MODULE, 215 }; 216 217 static const struct exynos_pcie_phy_data exynos5440_pcie_phy_data = { 218 .ops = &exynos5440_phy_ops, 219 }; 220 221 static const struct of_device_id exynos_pcie_phy_match[] = { 222 { 223 .compatible = "samsung,exynos5440-pcie-phy", 224 .data = &exynos5440_pcie_phy_data, 225 }, 226 {}, 227 }; 228 229 static int exynos_pcie_phy_probe(struct platform_device *pdev) 230 { 231 struct device *dev = &pdev->dev; 232 struct exynos_pcie_phy *exynos_phy; 233 struct phy *generic_phy; 234 struct phy_provider *phy_provider; 235 struct resource *res; 236 const struct exynos_pcie_phy_data *drv_data; 237 238 drv_data = of_device_get_match_data(dev); 239 if (!drv_data) 240 return -ENODEV; 241 242 exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL); 243 if (!exynos_phy) 244 return -ENOMEM; 245 246 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 247 exynos_phy->phy_base = devm_ioremap_resource(dev, res); 248 if (IS_ERR(exynos_phy->phy_base)) 249 return PTR_ERR(exynos_phy->phy_base); 250 251 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 252 exynos_phy->blk_base = devm_ioremap_resource(dev, res); 253 if (IS_ERR(exynos_phy->blk_base)) 254 return PTR_ERR(exynos_phy->blk_base); 255 256 exynos_phy->drv_data = drv_data; 257 258 generic_phy = devm_phy_create(dev, dev->of_node, drv_data->ops); 259 if (IS_ERR(generic_phy)) { 260 dev_err(dev, "failed to create PHY\n"); 261 return PTR_ERR(generic_phy); 262 } 263 264 phy_set_drvdata(generic_phy, exynos_phy); 265 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 266 267 return PTR_ERR_OR_ZERO(phy_provider); 268 } 269 270 static struct platform_driver exynos_pcie_phy_driver = { 271 .probe = exynos_pcie_phy_probe, 272 .driver = { 273 .of_match_table = exynos_pcie_phy_match, 274 .name = "exynos_pcie_phy", 275 .suppress_bind_attrs = true, 276 } 277 }; 278 279 builtin_platform_driver(exynos_pcie_phy_driver); 280