phy-qcom-pcie2.c (8799B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2019, Linaro Ltd. 5 */ 6 7#include <linux/clk-provider.h> 8#include <linux/clk.h> 9#include <linux/iopoll.h> 10#include <linux/module.h> 11#include <linux/phy/phy.h> 12#include <linux/platform_device.h> 13#include <linux/reset.h> 14#include <linux/slab.h> 15 16#include <dt-bindings/phy/phy.h> 17 18#define PCIE20_PARF_PHY_STTS 0x3c 19#define PCIE2_PHY_RESET_CTRL 0x44 20#define PCIE20_PARF_PHY_REFCLK_CTRL2 0xa0 21#define PCIE20_PARF_PHY_REFCLK_CTRL3 0xa4 22#define PCIE20_PARF_PCS_SWING_CTRL1 0x88 23#define PCIE20_PARF_PCS_SWING_CTRL2 0x8c 24#define PCIE20_PARF_PCS_DEEMPH1 0x74 25#define PCIE20_PARF_PCS_DEEMPH2 0x78 26#define PCIE20_PARF_PCS_DEEMPH3 0x7c 27#define PCIE20_PARF_CONFIGBITS 0x84 28#define PCIE20_PARF_PHY_CTRL3 0x94 29#define PCIE20_PARF_PCS_CTRL 0x80 30 31#define TX_AMP_VAL 120 32#define PHY_RX0_EQ_GEN1_VAL 0 33#define PHY_RX0_EQ_GEN2_VAL 4 34#define TX_DEEMPH_GEN1_VAL 24 35#define TX_DEEMPH_GEN2_3_5DB_VAL 26 36#define TX_DEEMPH_GEN2_6DB_VAL 36 37#define PHY_TX0_TERM_OFFST_VAL 0 38 39struct qcom_phy { 40 struct device *dev; 41 void __iomem *base; 42 43 struct regulator_bulk_data vregs[2]; 44 45 struct reset_control *phy_reset; 46 struct reset_control *pipe_reset; 47 struct clk *pipe_clk; 48}; 49 50static int qcom_pcie2_phy_init(struct phy *phy) 51{ 52 struct qcom_phy *qphy = phy_get_drvdata(phy); 53 int ret; 54 55 ret = reset_control_deassert(qphy->phy_reset); 56 if (ret) { 57 dev_err(qphy->dev, "cannot deassert pipe reset\n"); 58 return ret; 59 } 60 61 ret = regulator_bulk_enable(ARRAY_SIZE(qphy->vregs), qphy->vregs); 62 if (ret) 63 reset_control_assert(qphy->phy_reset); 64 65 return ret; 66} 67 68static int qcom_pcie2_phy_power_on(struct phy *phy) 69{ 70 struct qcom_phy *qphy = phy_get_drvdata(phy); 71 int ret; 72 u32 val; 73 74 /* Program REF_CLK source */ 75 val = readl(qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2); 76 val &= ~BIT(1); 77 writel(val, qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2); 78 79 usleep_range(1000, 2000); 80 81 /* Don't use PAD for refclock */ 82 val = readl(qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2); 83 val &= ~BIT(0); 84 writel(val, qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2); 85 86 /* Program SSP ENABLE */ 87 val = readl(qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL3); 88 val |= BIT(0); 89 writel(val, qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL3); 90 91 usleep_range(1000, 2000); 92 93 /* Assert Phy SW Reset */ 94 val = readl(qphy->base + PCIE2_PHY_RESET_CTRL); 95 val |= BIT(0); 96 writel(val, qphy->base + PCIE2_PHY_RESET_CTRL); 97 98 /* Program Tx Amplitude */ 99 val = readl(qphy->base + PCIE20_PARF_PCS_SWING_CTRL1); 100 val &= ~0x7f; 101 val |= TX_AMP_VAL; 102 writel(val, qphy->base + PCIE20_PARF_PCS_SWING_CTRL1); 103 104 val = readl(qphy->base + PCIE20_PARF_PCS_SWING_CTRL2); 105 val &= ~0x7f; 106 val |= TX_AMP_VAL; 107 writel(val, qphy->base + PCIE20_PARF_PCS_SWING_CTRL2); 108 109 /* Program De-Emphasis */ 110 val = readl(qphy->base + PCIE20_PARF_PCS_DEEMPH1); 111 val &= ~0x3f; 112 val |= TX_DEEMPH_GEN2_6DB_VAL; 113 writel(val, qphy->base + PCIE20_PARF_PCS_DEEMPH1); 114 115 val = readl(qphy->base + PCIE20_PARF_PCS_DEEMPH2); 116 val &= ~0x3f; 117 val |= TX_DEEMPH_GEN2_3_5DB_VAL; 118 writel(val, qphy->base + PCIE20_PARF_PCS_DEEMPH2); 119 120 val = readl(qphy->base + PCIE20_PARF_PCS_DEEMPH3); 121 val &= ~0x3f; 122 val |= TX_DEEMPH_GEN1_VAL; 123 writel(val, qphy->base + PCIE20_PARF_PCS_DEEMPH3); 124 125 /* Program Rx_Eq */ 126 val = readl(qphy->base + PCIE20_PARF_CONFIGBITS); 127 val &= ~0x7; 128 val |= PHY_RX0_EQ_GEN2_VAL; 129 writel(val, qphy->base + PCIE20_PARF_CONFIGBITS); 130 131 /* Program Tx0_term_offset */ 132 val = readl(qphy->base + PCIE20_PARF_PHY_CTRL3); 133 val &= ~0x1f; 134 val |= PHY_TX0_TERM_OFFST_VAL; 135 writel(val, qphy->base + PCIE20_PARF_PHY_CTRL3); 136 137 /* disable Tx2Rx Loopback */ 138 val = readl(qphy->base + PCIE20_PARF_PCS_CTRL); 139 val &= ~BIT(1); 140 writel(val, qphy->base + PCIE20_PARF_PCS_CTRL); 141 142 /* De-assert Phy SW Reset */ 143 val = readl(qphy->base + PCIE2_PHY_RESET_CTRL); 144 val &= ~BIT(0); 145 writel(val, qphy->base + PCIE2_PHY_RESET_CTRL); 146 147 usleep_range(1000, 2000); 148 149 ret = reset_control_deassert(qphy->pipe_reset); 150 if (ret) { 151 dev_err(qphy->dev, "cannot deassert pipe reset\n"); 152 goto out; 153 } 154 155 clk_set_rate(qphy->pipe_clk, 250000000); 156 157 ret = clk_prepare_enable(qphy->pipe_clk); 158 if (ret) { 159 dev_err(qphy->dev, "failed to enable pipe clock\n"); 160 goto out; 161 } 162 163 ret = readl_poll_timeout(qphy->base + PCIE20_PARF_PHY_STTS, val, 164 !(val & BIT(0)), 1000, 10); 165 if (ret) 166 dev_err(qphy->dev, "phy initialization failed\n"); 167 168out: 169 return ret; 170} 171 172static int qcom_pcie2_phy_power_off(struct phy *phy) 173{ 174 struct qcom_phy *qphy = phy_get_drvdata(phy); 175 u32 val; 176 177 val = readl(qphy->base + PCIE2_PHY_RESET_CTRL); 178 val |= BIT(0); 179 writel(val, qphy->base + PCIE2_PHY_RESET_CTRL); 180 181 clk_disable_unprepare(qphy->pipe_clk); 182 reset_control_assert(qphy->pipe_reset); 183 184 return 0; 185} 186 187static int qcom_pcie2_phy_exit(struct phy *phy) 188{ 189 struct qcom_phy *qphy = phy_get_drvdata(phy); 190 191 regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs); 192 reset_control_assert(qphy->phy_reset); 193 194 return 0; 195} 196 197static const struct phy_ops qcom_pcie2_ops = { 198 .init = qcom_pcie2_phy_init, 199 .power_on = qcom_pcie2_phy_power_on, 200 .power_off = qcom_pcie2_phy_power_off, 201 .exit = qcom_pcie2_phy_exit, 202 .owner = THIS_MODULE, 203}; 204 205/* 206 * Register a fixed rate pipe clock. 207 * 208 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate 209 * controls it. The <s>_pipe_clk coming out of the GCC is requested 210 * by the PHY driver for its operations. 211 * We register the <s>_pipe_clksrc here. The gcc driver takes care 212 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk. 213 * Below picture shows this relationship. 214 * 215 * +---------------+ 216 * | PHY block |<<---------------------------------------+ 217 * | | | 218 * | +-------+ | +-----+ | 219 * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+ 220 * clk | +-------+ | +-----+ 221 * +---------------+ 222 */ 223static int phy_pipe_clksrc_register(struct qcom_phy *qphy) 224{ 225 struct device_node *np = qphy->dev->of_node; 226 struct clk_fixed_rate *fixed; 227 struct clk_init_data init = { }; 228 int ret; 229 230 ret = of_property_read_string(np, "clock-output-names", &init.name); 231 if (ret) { 232 dev_err(qphy->dev, "%s: No clock-output-names\n", np->name); 233 return ret; 234 } 235 236 fixed = devm_kzalloc(qphy->dev, sizeof(*fixed), GFP_KERNEL); 237 if (!fixed) 238 return -ENOMEM; 239 240 init.ops = &clk_fixed_rate_ops; 241 242 /* controllers using QMP phys use 250MHz pipe clock interface */ 243 fixed->fixed_rate = 250000000; 244 fixed->hw.init = &init; 245 246 return devm_clk_hw_register(qphy->dev, &fixed->hw); 247} 248 249static int qcom_pcie2_phy_probe(struct platform_device *pdev) 250{ 251 struct phy_provider *phy_provider; 252 struct qcom_phy *qphy; 253 struct device *dev = &pdev->dev; 254 struct phy *phy; 255 int ret; 256 257 qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL); 258 if (!qphy) 259 return -ENOMEM; 260 261 qphy->dev = dev; 262 qphy->base = devm_platform_ioremap_resource(pdev, 0); 263 if (IS_ERR(qphy->base)) 264 return PTR_ERR(qphy->base); 265 266 ret = phy_pipe_clksrc_register(qphy); 267 if (ret) { 268 dev_err(dev, "failed to register pipe_clk\n"); 269 return ret; 270 } 271 272 qphy->vregs[0].supply = "vdda-vp"; 273 qphy->vregs[1].supply = "vdda-vph"; 274 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(qphy->vregs), qphy->vregs); 275 if (ret < 0) 276 return ret; 277 278 qphy->pipe_clk = devm_clk_get(dev, NULL); 279 if (IS_ERR(qphy->pipe_clk)) { 280 dev_err(dev, "failed to acquire pipe clock\n"); 281 return PTR_ERR(qphy->pipe_clk); 282 } 283 284 qphy->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); 285 if (IS_ERR(qphy->phy_reset)) { 286 dev_err(dev, "failed to acquire phy reset\n"); 287 return PTR_ERR(qphy->phy_reset); 288 } 289 290 qphy->pipe_reset = devm_reset_control_get_exclusive(dev, "pipe"); 291 if (IS_ERR(qphy->pipe_reset)) { 292 dev_err(dev, "failed to acquire pipe reset\n"); 293 return PTR_ERR(qphy->pipe_reset); 294 } 295 296 phy = devm_phy_create(dev, dev->of_node, &qcom_pcie2_ops); 297 if (IS_ERR(phy)) { 298 dev_err(dev, "failed to create phy\n"); 299 return PTR_ERR(phy); 300 } 301 302 phy_set_drvdata(phy, qphy); 303 304 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 305 if (IS_ERR(phy_provider)) 306 dev_err(dev, "failed to register phy provider\n"); 307 308 return PTR_ERR_OR_ZERO(phy_provider); 309} 310 311static const struct of_device_id qcom_pcie2_phy_match_table[] = { 312 { .compatible = "qcom,pcie2-phy" }, 313 {} 314}; 315MODULE_DEVICE_TABLE(of, qcom_pcie2_phy_match_table); 316 317static struct platform_driver qcom_pcie2_phy_driver = { 318 .probe = qcom_pcie2_phy_probe, 319 .driver = { 320 .name = "phy-qcom-pcie2", 321 .of_match_table = qcom_pcie2_phy_match_table, 322 }, 323}; 324 325module_platform_driver(qcom_pcie2_phy_driver); 326 327MODULE_DESCRIPTION("Qualcomm PCIe PHY driver"); 328MODULE_LICENSE("GPL v2");