1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2025, The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/clk-provider.h> 8 #include <linux/delay.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/module.h> 13 #include <linux/of_device.h> 14 #include <linux/of.h> 15 #include <linux/phy/phy.h> 16 #include <linux/platform_device.h> 17 #include <linux/regmap.h> 18 #include <linux/reset.h> 19 #include <linux/units.h> 20 21 #define RST_ASSERT_DELAY_MIN_US 100 22 #define RST_ASSERT_DELAY_MAX_US 150 23 #define PIPE_CLK_DELAY_MIN_US 5000 24 #define PIPE_CLK_DELAY_MAX_US 5100 25 #define CLK_EN_DELAY_MIN_US 30 26 #define CLK_EN_DELAY_MAX_US 50 27 #define CDR_CTRL_REG_1 0x80 28 #define CDR_CTRL_REG_2 0x84 29 #define CDR_CTRL_REG_3 0x88 30 #define CDR_CTRL_REG_4 0x8c 31 #define CDR_CTRL_REG_5 0x90 32 #define CDR_CTRL_REG_6 0x94 33 #define CDR_CTRL_REG_7 0x98 34 #define SSCG_CTRL_REG_1 0x9c 35 #define SSCG_CTRL_REG_2 0xa0 36 #define SSCG_CTRL_REG_3 0xa4 37 #define SSCG_CTRL_REG_4 0xa8 38 #define SSCG_CTRL_REG_5 0xac 39 #define SSCG_CTRL_REG_6 0xb0 40 #define PCS_INTERNAL_CONTROL_2 0x2d8 41 42 #define PHY_CFG_PLLCFG 0x220 43 #define PHY_CFG_EIOS_DTCT_REG 0x3e4 44 #define PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME 0x3e8 45 46 enum qcom_uniphy_pcie_type { 47 PHY_TYPE_PCIE = 1, 48 PHY_TYPE_PCIE_GEN2, 49 PHY_TYPE_PCIE_GEN3, 50 }; 51 52 struct qcom_uniphy_pcie_regs { 53 u32 offset; 54 u32 val; 55 }; 56 57 struct qcom_uniphy_pcie_data { 58 int lane_offset; /* offset between the lane register bases */ 59 u32 phy_type; 60 const struct qcom_uniphy_pcie_regs *init_seq; 61 u32 init_seq_num; 62 u32 pipe_clk_rate; 63 }; 64 65 struct qcom_uniphy_pcie { 66 struct phy phy; 67 struct device *dev; 68 const struct qcom_uniphy_pcie_data *data; 69 struct clk_bulk_data *clks; 70 int num_clks; 71 struct reset_control *resets; 72 void __iomem *base; 73 int lanes; 74 }; 75 76 #define phy_to_dw_phy(x) container_of((x), struct qca_uni_pcie_phy, phy) 77 78 static const struct qcom_uniphy_pcie_regs ipq5018_regs[] = { 79 { 80 .offset = SSCG_CTRL_REG_4, 81 .val = 0x1cb9, 82 }, { 83 .offset = SSCG_CTRL_REG_5, 84 .val = 0x023a, 85 }, { 86 .offset = SSCG_CTRL_REG_3, 87 .val = 0xd360, 88 }, { 89 .offset = SSCG_CTRL_REG_1, 90 .val = 0x1, 91 }, { 92 .offset = SSCG_CTRL_REG_2, 93 .val = 0xeb, 94 }, { 95 .offset = CDR_CTRL_REG_4, 96 .val = 0x3f9, 97 }, { 98 .offset = CDR_CTRL_REG_5, 99 .val = 0x1c9, 100 }, { 101 .offset = CDR_CTRL_REG_2, 102 .val = 0x419, 103 }, { 104 .offset = CDR_CTRL_REG_1, 105 .val = 0x200, 106 }, { 107 .offset = PCS_INTERNAL_CONTROL_2, 108 .val = 0xf101, 109 }, 110 }; 111 112 static const struct qcom_uniphy_pcie_regs ipq5332_regs[] = { 113 { 114 .offset = PHY_CFG_PLLCFG, 115 .val = 0x30, 116 }, { 117 .offset = PHY_CFG_EIOS_DTCT_REG, 118 .val = 0x53ef, 119 }, { 120 .offset = PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME, 121 .val = 0xcf, 122 }, 123 }; 124 125 static const struct qcom_uniphy_pcie_data ipq5018_data = { 126 .lane_offset = 0x800, 127 .phy_type = PHY_TYPE_PCIE_GEN2, 128 .init_seq = ipq5018_regs, 129 .init_seq_num = ARRAY_SIZE(ipq5018_regs), 130 .pipe_clk_rate = 125 * MEGA, 131 }; 132 133 static const struct qcom_uniphy_pcie_data ipq5332_data = { 134 .lane_offset = 0x800, 135 .phy_type = PHY_TYPE_PCIE_GEN3, 136 .init_seq = ipq5332_regs, 137 .init_seq_num = ARRAY_SIZE(ipq5332_regs), 138 .pipe_clk_rate = 250 * MEGA, 139 }; 140 141 static void qcom_uniphy_pcie_init(struct qcom_uniphy_pcie *phy) 142 { 143 const struct qcom_uniphy_pcie_data *data = phy->data; 144 const struct qcom_uniphy_pcie_regs *init_seq; 145 void __iomem *base = phy->base; 146 int lane, i; 147 148 for (lane = 0; lane < phy->lanes; lane++) { 149 init_seq = data->init_seq; 150 151 for (i = 0; i < data->init_seq_num; i++) 152 writel(init_seq[i].val, base + init_seq[i].offset); 153 154 base += data->lane_offset; 155 } 156 } 157 158 static int qcom_uniphy_pcie_power_off(struct phy *x) 159 { 160 struct qcom_uniphy_pcie *phy = phy_get_drvdata(x); 161 162 clk_bulk_disable_unprepare(phy->num_clks, phy->clks); 163 164 return reset_control_assert(phy->resets); 165 } 166 167 static int qcom_uniphy_pcie_power_on(struct phy *x) 168 { 169 struct qcom_uniphy_pcie *phy = phy_get_drvdata(x); 170 int ret; 171 172 ret = reset_control_assert(phy->resets); 173 if (ret) { 174 dev_err(phy->dev, "reset assert failed (%d)\n", ret); 175 return ret; 176 } 177 178 usleep_range(RST_ASSERT_DELAY_MIN_US, RST_ASSERT_DELAY_MAX_US); 179 180 ret = reset_control_deassert(phy->resets); 181 if (ret) { 182 dev_err(phy->dev, "reset deassert failed (%d)\n", ret); 183 return ret; 184 } 185 186 usleep_range(PIPE_CLK_DELAY_MIN_US, PIPE_CLK_DELAY_MAX_US); 187 188 ret = clk_bulk_prepare_enable(phy->num_clks, phy->clks); 189 if (ret) { 190 dev_err(phy->dev, "clk prepare and enable failed %d\n", ret); 191 return ret; 192 } 193 194 usleep_range(CLK_EN_DELAY_MIN_US, CLK_EN_DELAY_MAX_US); 195 196 qcom_uniphy_pcie_init(phy); 197 198 return 0; 199 } 200 201 static inline int qcom_uniphy_pcie_get_resources(struct platform_device *pdev, 202 struct qcom_uniphy_pcie *phy) 203 { 204 struct resource *res; 205 206 phy->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 207 if (IS_ERR(phy->base)) 208 return PTR_ERR(phy->base); 209 210 phy->num_clks = devm_clk_bulk_get_all(phy->dev, &phy->clks); 211 if (phy->num_clks < 0) 212 return phy->num_clks; 213 214 phy->resets = devm_reset_control_array_get_exclusive(phy->dev); 215 if (IS_ERR(phy->resets)) 216 return PTR_ERR(phy->resets); 217 218 return 0; 219 } 220 221 /* 222 * Register a fixed rate pipe clock. 223 * 224 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate 225 * controls it. The <s>_pipe_clk coming out of the GCC is requested 226 * by the PHY driver for its operations. 227 * We register the <s>_pipe_clksrc here. The gcc driver takes care 228 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk. 229 * Below picture shows this relationship. 230 * 231 * +---------------+ 232 * | PHY block |<<---------------------------------------+ 233 * | | | 234 * | +-------+ | +-----+ | 235 * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+ 236 * clk | +-------+ | +-----+ 237 * +---------------+ 238 */ 239 static inline int phy_pipe_clk_register(struct qcom_uniphy_pcie *phy, int id) 240 { 241 const struct qcom_uniphy_pcie_data *data = phy->data; 242 struct clk_hw *hw; 243 char name[64]; 244 245 snprintf(name, sizeof(name), "phy%d_pipe_clk_src", id); 246 hw = devm_clk_hw_register_fixed_rate(phy->dev, name, NULL, 0, 247 data->pipe_clk_rate); 248 if (IS_ERR(hw)) 249 return dev_err_probe(phy->dev, PTR_ERR(hw), 250 "Unable to register %s\n", name); 251 252 return devm_of_clk_add_hw_provider(phy->dev, of_clk_hw_simple_get, hw); 253 } 254 255 static const struct of_device_id qcom_uniphy_pcie_id_table[] = { 256 { 257 .compatible = "qcom,ipq5018-uniphy-pcie-phy", 258 .data = &ipq5018_data, 259 }, { 260 .compatible = "qcom,ipq5332-uniphy-pcie-phy", 261 .data = &ipq5332_data, 262 }, { 263 /* Sentinel */ 264 }, 265 }; 266 MODULE_DEVICE_TABLE(of, qcom_uniphy_pcie_id_table); 267 268 static const struct phy_ops pcie_ops = { 269 .power_on = qcom_uniphy_pcie_power_on, 270 .power_off = qcom_uniphy_pcie_power_off, 271 .owner = THIS_MODULE, 272 }; 273 274 static int qcom_uniphy_pcie_probe(struct platform_device *pdev) 275 { 276 struct phy_provider *phy_provider; 277 struct device *dev = &pdev->dev; 278 struct qcom_uniphy_pcie *phy; 279 struct phy *generic_phy; 280 int ret; 281 282 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 283 if (!phy) 284 return -ENOMEM; 285 286 platform_set_drvdata(pdev, phy); 287 phy->dev = &pdev->dev; 288 289 phy->data = of_device_get_match_data(dev); 290 if (!phy->data) 291 return -EINVAL; 292 293 ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &phy->lanes); 294 if (ret) 295 return dev_err_probe(dev, ret, "Couldn't read num-lanes\n"); 296 297 ret = qcom_uniphy_pcie_get_resources(pdev, phy); 298 if (ret < 0) 299 return dev_err_probe(&pdev->dev, ret, 300 "failed to get resources: %d\n", ret); 301 302 generic_phy = devm_phy_create(phy->dev, NULL, &pcie_ops); 303 if (IS_ERR(generic_phy)) 304 return PTR_ERR(generic_phy); 305 306 phy_set_drvdata(generic_phy, phy); 307 308 ret = phy_pipe_clk_register(phy, generic_phy->id); 309 if (ret) 310 dev_err(&pdev->dev, "failed to register phy pipe clk\n"); 311 312 phy_provider = devm_of_phy_provider_register(phy->dev, 313 of_phy_simple_xlate); 314 if (IS_ERR(phy_provider)) 315 return PTR_ERR(phy_provider); 316 317 return 0; 318 } 319 320 static struct platform_driver qcom_uniphy_pcie_driver = { 321 .probe = qcom_uniphy_pcie_probe, 322 .driver = { 323 .name = "qcom-uniphy-pcie", 324 .of_match_table = qcom_uniphy_pcie_id_table, 325 }, 326 }; 327 328 module_platform_driver(qcom_uniphy_pcie_driver); 329 330 MODULE_DESCRIPTION("PCIE QCOM UNIPHY driver"); 331 MODULE_LICENSE("GPL"); 332