1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021, Linaro Ltd. 5 */ 6 7 #include <linux/clk.h> 8 #include <linux/clk-provider.h> 9 #include <linux/delay.h> 10 #include <linux/err.h> 11 #include <linux/io.h> 12 #include <linux/iopoll.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/phy/phy.h> 17 #include <linux/phy/phy-dp.h> 18 #include <linux/platform_device.h> 19 #include <linux/regulator/consumer.h> 20 #include <linux/reset.h> 21 #include <linux/slab.h> 22 23 #include <dt-bindings/phy/phy.h> 24 25 #include "phy-qcom-qmp-dp-phy.h" 26 #include "phy-qcom-qmp-qserdes-com-v4.h" 27 #include "phy-qcom-qmp-qserdes-com-v6.h" 28 29 #include "phy-qcom-qmp-qserdes-dp-com-v8.h" 30 31 /* EDP_PHY registers */ 32 #define DP_PHY_CFG 0x0010 33 #define DP_PHY_CFG_1 0x0014 34 #define DP_PHY_PD_CTL 0x001c 35 #define DP_PHY_MODE 0x0020 36 37 #define DP_AUX_CFG_SIZE 13 38 #define DP_PHY_AUX_CFG(n) (0x24 + (0x04 * (n))) 39 40 #define DP_PHY_AUX_INTERRUPT_MASK 0x0058 41 42 #define DP_PHY_VCO_DIV 0x0074 43 #define DP_PHY_TX0_TX1_LANE_CTL 0x007c 44 #define DP_PHY_TX2_TX3_LANE_CTL 0x00a0 45 46 #define DP_PHY_STATUS 0x00e0 47 48 /* LANE_TXn registers */ 49 #define TXn_CLKBUF_ENABLE 0x0000 50 #define TXn_TX_EMP_POST1_LVL 0x0004 51 52 #define TXn_TX_DRV_LVL 0x0014 53 #define TXn_TX_DRV_LVL_OFFSET 0x0018 54 #define TXn_RESET_TSYNC_EN 0x001c 55 #define TXn_LDO_CONFIG 0x0084 56 #define TXn_TX_BAND 0x0028 57 58 #define TXn_RES_CODE_LANE_OFFSET_TX0 0x0044 59 #define TXn_RES_CODE_LANE_OFFSET_TX1 0x0048 60 61 #define TXn_TRANSCEIVER_BIAS_EN 0x0054 62 #define TXn_HIGHZ_DRVR_EN 0x0058 63 #define TXn_TX_POL_INV 0x005c 64 #define TXn_LANE_MODE_1 0x0064 65 66 #define TXn_TRAN_DRVR_EMP_EN 0x0078 67 68 struct qcom_edp_swing_pre_emph_cfg { 69 const u8 (*swing_hbr_rbr)[4][4]; 70 const u8 (*swing_hbr3_hbr2)[4][4]; 71 const u8 (*pre_emphasis_hbr_rbr)[4][4]; 72 const u8 (*pre_emphasis_hbr3_hbr2)[4][4]; 73 }; 74 75 struct qcom_edp; 76 77 struct phy_ver_ops { 78 int (*com_power_on)(const struct qcom_edp *edp); 79 int (*com_resetsm_cntrl)(const struct qcom_edp *edp); 80 int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp); 81 int (*com_clk_fwd_cfg)(const struct qcom_edp *edp); 82 int (*com_configure_pll)(const struct qcom_edp *edp); 83 int (*com_configure_ssc)(const struct qcom_edp *edp); 84 int (*com_ldo_config)(const struct qcom_edp *edp); 85 }; 86 87 struct qcom_edp_phy_cfg { 88 bool is_edp; 89 const u8 *aux_cfg; 90 const u8 *vco_div_cfg; 91 const struct qcom_edp_swing_pre_emph_cfg *dp_swing_pre_emph_cfg; 92 const struct qcom_edp_swing_pre_emph_cfg *edp_swing_pre_emph_cfg; 93 const struct phy_ver_ops *ver_ops; 94 }; 95 96 struct qcom_edp { 97 struct device *dev; 98 const struct qcom_edp_phy_cfg *cfg; 99 100 struct phy *phy; 101 102 void __iomem *edp; 103 void __iomem *tx0; 104 void __iomem *tx1; 105 void __iomem *pll; 106 107 struct clk_hw dp_link_hw; 108 struct clk_hw dp_pixel_hw; 109 110 struct phy_configure_opts_dp dp_opts; 111 112 struct clk_bulk_data *clks; 113 int num_clks; 114 115 struct regulator_bulk_data supplies[2]; 116 117 bool is_edp; 118 }; 119 120 static const u8 dp_swing_hbr_rbr[4][4] = { 121 { 0x07, 0x0f, 0x16, 0x1f }, 122 { 0x11, 0x1e, 0x1f, 0xff }, 123 { 0x16, 0x1f, 0xff, 0xff }, 124 { 0x1f, 0xff, 0xff, 0xff } 125 }; 126 127 static const u8 dp_pre_emp_hbr_rbr[4][4] = { 128 { 0x00, 0x0e, 0x15, 0x1a }, 129 { 0x00, 0x0e, 0x15, 0xff }, 130 { 0x00, 0x0e, 0xff, 0xff }, 131 { 0x04, 0xff, 0xff, 0xff } 132 }; 133 134 static const u8 dp_swing_hbr2_hbr3[4][4] = { 135 { 0x02, 0x12, 0x16, 0x1a }, 136 { 0x09, 0x19, 0x1f, 0xff }, 137 { 0x10, 0x1f, 0xff, 0xff }, 138 { 0x1f, 0xff, 0xff, 0xff } 139 }; 140 141 static const u8 dp_pre_emp_hbr2_hbr3[4][4] = { 142 { 0x00, 0x0c, 0x15, 0x1b }, 143 { 0x02, 0x0e, 0x16, 0xff }, 144 { 0x02, 0x11, 0xff, 0xff }, 145 { 0x04, 0xff, 0xff, 0xff } 146 }; 147 148 static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg = { 149 .swing_hbr_rbr = &dp_swing_hbr_rbr, 150 .swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3, 151 .pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr, 152 .pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3, 153 }; 154 155 static const u8 dp_pre_emp_hbr_rbr_v8[4][4] = { 156 { 0x00, 0x0e, 0x15, 0x1a }, 157 { 0x00, 0x0e, 0x15, 0xff }, 158 { 0x00, 0x0e, 0xff, 0xff }, 159 { 0x00, 0xff, 0xff, 0xff } 160 }; 161 162 static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg_v8 = { 163 .swing_hbr_rbr = &dp_swing_hbr_rbr, 164 .swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3, 165 .pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr_v8, 166 .pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3, 167 }; 168 169 static const u8 dp_swing_hbr2_hbr3_v2[4][4] = { 170 { 0x27, 0x2f, 0x36, 0xff }, 171 { 0x31, 0x3e, 0x3f, 0xff }, 172 { 0x3a, 0x3f, 0xff, 0xff }, 173 { 0xff, 0xff, 0xff, 0xff } 174 }; 175 176 static const u8 dp_pre_emp_hbr2_hbr3_v2[4][4] = { 177 { 0x20, 0x2e, 0x35, 0xff }, 178 { 0x20, 0x2e, 0x35, 0xff }, 179 { 0x20, 0x2e, 0xff, 0xff }, 180 { 0xff, 0xff, 0xff, 0xff } 181 }; 182 183 static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg_v2 = { 184 /* 185 * NOTE: The HPG does not specify a separate swing_hbr_rbr table. 186 * Reuse the HBR2/HBR3 table for now. 187 * 188 * TODO: Update this once the HPG explicitly defines RBR/HBR swing values. 189 */ 190 .swing_hbr_rbr = &dp_swing_hbr2_hbr3_v2, 191 .swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3_v2, 192 .pre_emphasis_hbr_rbr = &dp_pre_emp_hbr2_hbr3_v2, 193 .pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3_v2, 194 }; 195 196 static const u8 edp_swing_hbr_rbr[4][4] = { 197 { 0x07, 0x0f, 0x16, 0x1f }, 198 { 0x0d, 0x16, 0x1e, 0xff }, 199 { 0x11, 0x1b, 0xff, 0xff }, 200 { 0x16, 0xff, 0xff, 0xff } 201 }; 202 203 static const u8 edp_pre_emp_hbr_rbr[4][4] = { 204 { 0x05, 0x11, 0x17, 0x1d }, 205 { 0x05, 0x11, 0x18, 0xff }, 206 { 0x06, 0x11, 0xff, 0xff }, 207 { 0x00, 0xff, 0xff, 0xff } 208 }; 209 210 static const u8 edp_swing_hbr2_hbr3[4][4] = { 211 { 0x0b, 0x11, 0x17, 0x1c }, 212 { 0x10, 0x19, 0x1f, 0xff }, 213 { 0x19, 0x1f, 0xff, 0xff }, 214 { 0x1f, 0xff, 0xff, 0xff } 215 }; 216 217 static const u8 edp_pre_emp_hbr2_hbr3[4][4] = { 218 { 0x0c, 0x15, 0x19, 0x1e }, 219 { 0x0b, 0x15, 0x19, 0xff }, 220 { 0x0e, 0x14, 0xff, 0xff }, 221 { 0x0d, 0xff, 0xff, 0xff } 222 }; 223 224 static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = { 225 .swing_hbr_rbr = &edp_swing_hbr_rbr, 226 .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3, 227 .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr, 228 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3, 229 }; 230 231 static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = { 232 0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00, 233 }; 234 235 static const u8 edp_phy_vco_div_cfg_v4[4] = { 236 0x01, 0x01, 0x02, 0x00, 237 }; 238 239 static const u8 edp_pre_emp_hbr_rbr_v2[4][4] = { 240 { 0x05, 0x12, 0x17, 0x1d }, 241 { 0x05, 0x11, 0x18, 0xff }, 242 { 0x06, 0x11, 0xff, 0xff }, 243 { 0x00, 0xff, 0xff, 0xff } 244 }; 245 246 static const u8 edp_pre_emp_hbr2_hbr3_v2[4][4] = { 247 { 0x0c, 0x15, 0x19, 0x1e }, 248 { 0x08, 0x15, 0x19, 0xff }, 249 { 0x0e, 0x14, 0xff, 0xff }, 250 { 0x0d, 0xff, 0xff, 0xff } 251 }; 252 253 static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v2 = { 254 .swing_hbr_rbr = &edp_swing_hbr_rbr, 255 .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3, 256 .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v2, 257 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v2, 258 }; 259 260 static const u8 edp_swing_hbr2_hbr3_v3[4][4] = { 261 { 0x06, 0x11, 0x16, 0x1b }, 262 { 0x0b, 0x19, 0x1f, 0xff }, 263 { 0x18, 0x1f, 0xff, 0xff }, 264 { 0x1f, 0xff, 0xff, 0xff } 265 }; 266 267 static const u8 edp_pre_emp_hbr2_hbr3_v3[4][4] = { 268 { 0x0c, 0x15, 0x19, 0x1e }, 269 { 0x09, 0x14, 0x19, 0xff }, 270 { 0x0f, 0x14, 0xff, 0xff }, 271 { 0x0d, 0xff, 0xff, 0xff } 272 }; 273 274 static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v3 = { 275 .swing_hbr_rbr = &edp_swing_hbr_rbr, 276 .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3_v3, 277 .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr, 278 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v3, 279 }; 280 281 static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = { 282 0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00, 283 }; 284 285 static const u8 edp_phy_aux_cfg_v8[DP_AUX_CFG_SIZE] = { 286 0x00, 0x00, 0xa0, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x04, 287 }; 288 289 static const u8 edp_phy_vco_div_cfg_v8[4] = { 290 0x00, 0x00, 0x02, 0x01, 291 }; 292 293 static int qcom_edp_phy_init(struct phy *phy) 294 { 295 struct qcom_edp *edp = phy_get_drvdata(phy); 296 u8 aux_cfg[DP_AUX_CFG_SIZE]; 297 int ret; 298 299 ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies); 300 if (ret) 301 return ret; 302 303 ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks); 304 if (ret) 305 goto out_disable_supplies; 306 307 memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg)); 308 309 ret = edp->cfg->ver_ops->com_clk_fwd_cfg(edp); 310 if (ret) 311 return ret; 312 313 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 314 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 315 edp->edp + DP_PHY_PD_CTL); 316 317 ret = edp->cfg->ver_ops->com_bias_en_clkbuflr(edp); 318 if (ret) 319 return ret; 320 321 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 322 msleep(20); 323 324 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 325 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 326 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 327 edp->edp + DP_PHY_PD_CTL); 328 329 if (!edp->is_edp) 330 aux_cfg[8] = 0xb7; 331 332 writel(0xfc, edp->edp + DP_PHY_MODE); 333 334 for (int i = 0; i < DP_AUX_CFG_SIZE; i++) 335 writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i)); 336 337 writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | 338 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | 339 PHY_AUX_REQ_ERR_MASK, edp->edp + DP_PHY_AUX_INTERRUPT_MASK); 340 341 msleep(20); 342 343 return 0; 344 345 out_disable_supplies: 346 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 347 348 return ret; 349 } 350 351 static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts) 352 { 353 const struct qcom_edp_swing_pre_emph_cfg *cfg; 354 unsigned int v_level = 0; 355 unsigned int p_level = 0; 356 int ret; 357 u8 swing; 358 u8 emph; 359 int i; 360 361 if (edp->is_edp) 362 cfg = edp->cfg->edp_swing_pre_emph_cfg; 363 else 364 cfg = edp->cfg->dp_swing_pre_emph_cfg; 365 366 for (i = 0; i < dp_opts->lanes; i++) { 367 v_level = max(v_level, dp_opts->voltage[i]); 368 p_level = max(p_level, dp_opts->pre[i]); 369 } 370 371 if (dp_opts->link_rate <= 2700) { 372 swing = (*cfg->swing_hbr_rbr)[v_level][p_level]; 373 emph = (*cfg->pre_emphasis_hbr_rbr)[v_level][p_level]; 374 } else { 375 swing = (*cfg->swing_hbr3_hbr2)[v_level][p_level]; 376 emph = (*cfg->pre_emphasis_hbr3_hbr2)[v_level][p_level]; 377 } 378 379 if (swing == 0xff || emph == 0xff) 380 return -EINVAL; 381 382 ret = edp->cfg->ver_ops->com_ldo_config(edp); 383 if (ret) 384 return ret; 385 386 writel(swing, edp->tx0 + TXn_TX_DRV_LVL); 387 writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL); 388 389 writel(swing, edp->tx1 + TXn_TX_DRV_LVL); 390 writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL); 391 392 return 0; 393 } 394 395 static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts) 396 { 397 const struct phy_configure_opts_dp *dp_opts = &opts->dp; 398 struct qcom_edp *edp = phy_get_drvdata(phy); 399 int ret = 0; 400 401 memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts)); 402 403 if (dp_opts->set_voltages) 404 ret = qcom_edp_set_voltages(edp, dp_opts); 405 406 return ret; 407 } 408 409 static int qcom_edp_configure_ssc(const struct qcom_edp *edp) 410 { 411 return edp->cfg->ver_ops->com_configure_ssc(edp); 412 } 413 414 static int qcom_edp_configure_pll(const struct qcom_edp *edp) 415 { 416 return edp->cfg->ver_ops->com_configure_pll(edp); 417 } 418 419 static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq) 420 { 421 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 422 u32 vco_div; 423 424 switch (dp_opts->link_rate) { 425 case 1620: 426 vco_div = edp->cfg->vco_div_cfg[0]; 427 *pixel_freq = 1620000000UL / 2; 428 break; 429 430 case 2700: 431 vco_div = edp->cfg->vco_div_cfg[1]; 432 *pixel_freq = 2700000000UL / 2; 433 break; 434 435 case 5400: 436 vco_div = edp->cfg->vco_div_cfg[2]; 437 *pixel_freq = 5400000000UL / 4; 438 break; 439 440 case 8100: 441 vco_div = edp->cfg->vco_div_cfg[3]; 442 *pixel_freq = 8100000000UL / 6; 443 break; 444 445 default: 446 /* Other link rates aren't supported */ 447 return -EINVAL; 448 } 449 450 writel(vco_div, edp->edp + DP_PHY_VCO_DIV); 451 452 return 0; 453 } 454 455 static int qcom_edp_phy_power_on_v4(const struct qcom_edp *edp) 456 { 457 u32 val; 458 459 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 460 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 461 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 462 edp->edp + DP_PHY_PD_CTL); 463 writel(0xfc, edp->edp + DP_PHY_MODE); 464 465 return readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS, 466 val, val & BIT(7), 5, 200); 467 } 468 469 static int qcom_edp_phy_com_resetsm_cntrl_v4(const struct qcom_edp *edp) 470 { 471 u32 val; 472 473 writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL); 474 475 return readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS, 476 val, val & BIT(0), 500, 10000); 477 } 478 479 static int qcom_edp_com_clk_fwd_cfg_v4(const struct qcom_edp *edp) 480 { 481 return 0; 482 } 483 484 static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp) 485 { 486 /* Turn on BIAS current for PHY/PLL */ 487 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 488 489 return 0; 490 } 491 492 static int qcom_edp_com_configure_ssc_v4(const struct qcom_edp *edp) 493 { 494 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 495 u32 step1; 496 u32 step2; 497 498 switch (dp_opts->link_rate) { 499 case 1620: 500 case 2700: 501 case 8100: 502 step1 = 0x45; 503 step2 = 0x06; 504 break; 505 506 case 5400: 507 step1 = 0x5c; 508 step2 = 0x08; 509 break; 510 511 default: 512 /* Other link rates aren't supported */ 513 return -EINVAL; 514 } 515 516 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_EN_CENTER); 517 writel(0x00, edp->pll + QSERDES_V4_COM_SSC_ADJ_PER1); 518 writel(0x36, edp->pll + QSERDES_V4_COM_SSC_PER1); 519 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_PER2); 520 writel(step1, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0); 521 writel(step2, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0); 522 523 return 0; 524 } 525 526 static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp) 527 { 528 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 529 u32 div_frac_start2_mode0; 530 u32 div_frac_start3_mode0; 531 u32 dec_start_mode0; 532 u32 lock_cmp1_mode0; 533 u32 lock_cmp2_mode0; 534 u32 hsclk_sel; 535 536 switch (dp_opts->link_rate) { 537 case 1620: 538 hsclk_sel = 0x5; 539 dec_start_mode0 = 0x69; 540 div_frac_start2_mode0 = 0x80; 541 div_frac_start3_mode0 = 0x07; 542 lock_cmp1_mode0 = 0x6f; 543 lock_cmp2_mode0 = 0x08; 544 break; 545 546 case 2700: 547 hsclk_sel = 0x3; 548 dec_start_mode0 = 0x69; 549 div_frac_start2_mode0 = 0x80; 550 div_frac_start3_mode0 = 0x07; 551 lock_cmp1_mode0 = 0x0f; 552 lock_cmp2_mode0 = 0x0e; 553 break; 554 555 case 5400: 556 hsclk_sel = 0x1; 557 dec_start_mode0 = 0x8c; 558 div_frac_start2_mode0 = 0x00; 559 div_frac_start3_mode0 = 0x0a; 560 lock_cmp1_mode0 = 0x1f; 561 lock_cmp2_mode0 = 0x1c; 562 break; 563 564 case 8100: 565 hsclk_sel = 0x0; 566 dec_start_mode0 = 0x69; 567 div_frac_start2_mode0 = 0x80; 568 div_frac_start3_mode0 = 0x07; 569 lock_cmp1_mode0 = 0x2f; 570 lock_cmp2_mode0 = 0x2a; 571 break; 572 573 default: 574 /* Other link rates aren't supported */ 575 return -EINVAL; 576 } 577 578 writel(0x01, edp->pll + QSERDES_V4_COM_SVS_MODE_CLK_SEL); 579 writel(0x0b, edp->pll + QSERDES_V4_COM_SYSCLK_EN_SEL); 580 writel(0x02, edp->pll + QSERDES_V4_COM_SYS_CLK_CTRL); 581 writel(0x0c, edp->pll + QSERDES_V4_COM_CLK_ENABLE1); 582 writel(0x06, edp->pll + QSERDES_V4_COM_SYSCLK_BUF_ENABLE); 583 writel(0x30, edp->pll + QSERDES_V4_COM_CLK_SELECT); 584 writel(hsclk_sel, edp->pll + QSERDES_V4_COM_HSCLK_SEL); 585 writel(0x0f, edp->pll + QSERDES_V4_COM_PLL_IVCO); 586 writel(0x08, edp->pll + QSERDES_V4_COM_LOCK_CMP_EN); 587 writel(0x36, edp->pll + QSERDES_V4_COM_PLL_CCTRL_MODE0); 588 writel(0x16, edp->pll + QSERDES_V4_COM_PLL_RCTRL_MODE0); 589 writel(0x06, edp->pll + QSERDES_V4_COM_CP_CTRL_MODE0); 590 writel(dec_start_mode0, edp->pll + QSERDES_V4_COM_DEC_START_MODE0); 591 writel(0x00, edp->pll + QSERDES_V4_COM_DIV_FRAC_START1_MODE0); 592 writel(div_frac_start2_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START2_MODE0); 593 writel(div_frac_start3_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START3_MODE0); 594 writel(0x02, edp->pll + QSERDES_V4_COM_CMN_CONFIG); 595 writel(0x3f, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0); 596 writel(0x00, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0); 597 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_MAP); 598 writel(lock_cmp1_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP1_MODE0); 599 writel(lock_cmp2_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP2_MODE0); 600 601 writel(0x0a, edp->pll + QSERDES_V4_COM_BG_TIMER); 602 writel(0x14, edp->pll + QSERDES_V4_COM_CORECLK_DIV_MODE0); 603 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_CTRL); 604 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 605 writel(0x0f, edp->pll + QSERDES_V4_COM_CORE_CLK_EN); 606 writel(0xa0, edp->pll + QSERDES_V4_COM_VCO_TUNE1_MODE0); 607 writel(0x03, edp->pll + QSERDES_V4_COM_VCO_TUNE2_MODE0); 608 609 return 0; 610 } 611 612 static int qcom_edp_ldo_config_v3(const struct qcom_edp *edp) 613 { 614 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 615 u32 ldo_config; 616 617 if (!edp->is_edp) 618 ldo_config = 0x0; 619 else if (dp_opts->link_rate <= 2700) 620 ldo_config = 0x81; 621 else 622 ldo_config = 0x41; 623 624 writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG); 625 writel(dp_opts->lanes > 2 ? ldo_config : 0x00, edp->tx1 + TXn_LDO_CONFIG); 626 627 return 0; 628 } 629 630 static int qcom_edp_ldo_config_v4(const struct qcom_edp *edp) 631 { 632 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 633 u32 ldo_config; 634 635 if (!edp->is_edp) 636 ldo_config = 0x0; 637 else if (dp_opts->link_rate <= 2700) 638 ldo_config = 0xc1; 639 else 640 ldo_config = 0x81; 641 642 writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG); 643 writel(dp_opts->lanes > 2 ? ldo_config : 0x00, edp->tx1 + TXn_LDO_CONFIG); 644 645 return 0; 646 } 647 648 static const struct phy_ver_ops qcom_edp_phy_ops_v3 = { 649 .com_power_on = qcom_edp_phy_power_on_v4, 650 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4, 651 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4, 652 .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, 653 .com_configure_pll = qcom_edp_com_configure_pll_v4, 654 .com_configure_ssc = qcom_edp_com_configure_ssc_v4, 655 .com_ldo_config = qcom_edp_ldo_config_v3, 656 }; 657 658 static const struct phy_ver_ops qcom_edp_phy_ops_v4 = { 659 .com_power_on = qcom_edp_phy_power_on_v4, 660 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4, 661 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4, 662 .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, 663 .com_configure_pll = qcom_edp_com_configure_pll_v4, 664 .com_configure_ssc = qcom_edp_com_configure_ssc_v4, 665 .com_ldo_config = qcom_edp_ldo_config_v4, 666 }; 667 668 static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = { 669 .is_edp = false, 670 .aux_cfg = edp_phy_aux_cfg_v5, 671 .vco_div_cfg = edp_phy_vco_div_cfg_v4, 672 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 673 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 674 .ver_ops = &qcom_edp_phy_ops_v4, 675 }; 676 677 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { 678 .aux_cfg = edp_phy_aux_cfg_v4, 679 .vco_div_cfg = edp_phy_vco_div_cfg_v4, 680 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 681 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v3, 682 .ver_ops = &qcom_edp_phy_ops_v3, 683 }; 684 685 static const struct qcom_edp_phy_cfg sc8180x_dp_phy_cfg = { 686 .aux_cfg = edp_phy_aux_cfg_v4, 687 .vco_div_cfg = edp_phy_vco_div_cfg_v4, 688 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg_v2, 689 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v2, 690 .ver_ops = &qcom_edp_phy_ops_v3, 691 }; 692 693 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { 694 .aux_cfg = edp_phy_aux_cfg_v4, 695 .vco_div_cfg = edp_phy_vco_div_cfg_v4, 696 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 697 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 698 .ver_ops = &qcom_edp_phy_ops_v4, 699 }; 700 701 static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = { 702 .is_edp = true, 703 .aux_cfg = edp_phy_aux_cfg_v4, 704 .vco_div_cfg = edp_phy_vco_div_cfg_v4, 705 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 706 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 707 .ver_ops = &qcom_edp_phy_ops_v4, 708 }; 709 710 static int qcom_edp_phy_power_on_v6(const struct qcom_edp *edp) 711 { 712 u32 val; 713 714 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 715 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 716 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 717 edp->edp + DP_PHY_PD_CTL); 718 writel(0xfc, edp->edp + DP_PHY_MODE); 719 720 return readl_poll_timeout(edp->pll + QSERDES_V6_COM_CMN_STATUS, 721 val, val & BIT(7), 5, 200); 722 } 723 724 static int qcom_edp_phy_com_resetsm_cntrl_v6(const struct qcom_edp *edp) 725 { 726 u32 val; 727 728 writel(0x20, edp->pll + QSERDES_V6_COM_RESETSM_CNTRL); 729 730 return readl_poll_timeout(edp->pll + QSERDES_V6_COM_C_READY_STATUS, 731 val, val & BIT(0), 500, 10000); 732 } 733 734 static int qcom_edp_com_bias_en_clkbuflr_v6(const struct qcom_edp *edp) 735 { 736 /* Turn on BIAS current for PHY/PLL */ 737 writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN); 738 739 return 0; 740 } 741 742 static int qcom_edp_com_configure_ssc_v6(const struct qcom_edp *edp) 743 { 744 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 745 u32 step1; 746 u32 step2; 747 748 switch (dp_opts->link_rate) { 749 case 1620: 750 case 2700: 751 case 8100: 752 step1 = 0x92; 753 step2 = 0x01; 754 break; 755 756 case 5400: 757 step1 = 0x18; 758 step2 = 0x02; 759 break; 760 761 default: 762 /* Other link rates aren't supported */ 763 return -EINVAL; 764 } 765 766 writel(0x01, edp->pll + QSERDES_V6_COM_SSC_EN_CENTER); 767 writel(0x00, edp->pll + QSERDES_V6_COM_SSC_ADJ_PER1); 768 writel(0x36, edp->pll + QSERDES_V6_COM_SSC_PER1); 769 writel(0x01, edp->pll + QSERDES_V6_COM_SSC_PER2); 770 writel(step1, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0); 771 writel(step2, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0); 772 773 return 0; 774 } 775 776 static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp) 777 { 778 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 779 u32 div_frac_start2_mode0; 780 u32 div_frac_start3_mode0; 781 u32 dec_start_mode0; 782 u32 lock_cmp1_mode0; 783 u32 lock_cmp2_mode0; 784 u32 code1_mode0; 785 u32 code2_mode0; 786 u32 hsclk_sel; 787 788 switch (dp_opts->link_rate) { 789 case 1620: 790 hsclk_sel = 0x5; 791 dec_start_mode0 = 0x34; 792 div_frac_start2_mode0 = 0xc0; 793 div_frac_start3_mode0 = 0x0b; 794 lock_cmp1_mode0 = 0x37; 795 lock_cmp2_mode0 = 0x04; 796 code1_mode0 = 0x71; 797 code2_mode0 = 0x0c; 798 break; 799 800 case 2700: 801 hsclk_sel = 0x3; 802 dec_start_mode0 = 0x34; 803 div_frac_start2_mode0 = 0xc0; 804 div_frac_start3_mode0 = 0x0b; 805 lock_cmp1_mode0 = 0x07; 806 lock_cmp2_mode0 = 0x07; 807 code1_mode0 = 0x71; 808 code2_mode0 = 0x0c; 809 break; 810 811 case 5400: 812 hsclk_sel = 0x1; 813 dec_start_mode0 = 0x46; 814 div_frac_start2_mode0 = 0x00; 815 div_frac_start3_mode0 = 0x05; 816 lock_cmp1_mode0 = 0x0f; 817 lock_cmp2_mode0 = 0x0e; 818 code1_mode0 = 0x97; 819 code2_mode0 = 0x10; 820 break; 821 822 case 8100: 823 hsclk_sel = 0x0; 824 dec_start_mode0 = 0x34; 825 div_frac_start2_mode0 = 0xc0; 826 div_frac_start3_mode0 = 0x0b; 827 lock_cmp1_mode0 = 0x17; 828 lock_cmp2_mode0 = 0x15; 829 code1_mode0 = 0x71; 830 code2_mode0 = 0x0c; 831 break; 832 833 default: 834 /* Other link rates aren't supported */ 835 return -EINVAL; 836 } 837 838 writel(0x01, edp->pll + QSERDES_V6_COM_SVS_MODE_CLK_SEL); 839 writel(0x0b, edp->pll + QSERDES_V6_COM_SYSCLK_EN_SEL); 840 writel(0x02, edp->pll + QSERDES_V6_COM_SYS_CLK_CTRL); 841 writel(0x0c, edp->pll + QSERDES_V6_COM_CLK_ENABLE1); 842 writel(0x06, edp->pll + QSERDES_V6_COM_SYSCLK_BUF_ENABLE); 843 writel(0x30, edp->pll + QSERDES_V6_COM_CLK_SELECT); 844 writel(hsclk_sel, edp->pll + QSERDES_V6_COM_HSCLK_SEL_1); 845 writel(0x07, edp->pll + QSERDES_V6_COM_PLL_IVCO); 846 writel(0x08, edp->pll + QSERDES_V6_COM_LOCK_CMP_EN); 847 writel(0x36, edp->pll + QSERDES_V6_COM_PLL_CCTRL_MODE0); 848 writel(0x16, edp->pll + QSERDES_V6_COM_PLL_RCTRL_MODE0); 849 writel(0x06, edp->pll + QSERDES_V6_COM_CP_CTRL_MODE0); 850 writel(dec_start_mode0, edp->pll + QSERDES_V6_COM_DEC_START_MODE0); 851 writel(0x00, edp->pll + QSERDES_V6_COM_DIV_FRAC_START1_MODE0); 852 writel(div_frac_start2_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START2_MODE0); 853 writel(div_frac_start3_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START3_MODE0); 854 writel(0x12, edp->pll + QSERDES_V6_COM_CMN_CONFIG_1); 855 writel(0x3f, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0); 856 writel(0x00, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0); 857 writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_MAP); 858 writel(lock_cmp1_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP1_MODE0); 859 writel(lock_cmp2_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP2_MODE0); 860 861 writel(0x0a, edp->pll + QSERDES_V6_COM_BG_TIMER); 862 writel(0x14, edp->pll + QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0); 863 writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_CTRL); 864 writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN); 865 writel(0x0f, edp->pll + QSERDES_V6_COM_CORE_CLK_EN); 866 writel(0xa0, edp->pll + QSERDES_V6_COM_VCO_TUNE1_MODE0); 867 writel(0x03, edp->pll + QSERDES_V6_COM_VCO_TUNE2_MODE0); 868 869 writel(code1_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0); 870 writel(code2_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0); 871 872 return 0; 873 } 874 875 static int qcom_edp_ldo_config_v6(const struct qcom_edp *edp) 876 { 877 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 878 u32 ldo_config; 879 880 if (!edp->is_edp) 881 ldo_config = 0x0; 882 else if (dp_opts->link_rate <= 2700) 883 ldo_config = 0x51; 884 else 885 ldo_config = 0x91; 886 887 writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG); 888 writel(dp_opts->lanes > 2 ? ldo_config : 0x00, edp->tx1 + TXn_LDO_CONFIG); 889 890 return 0; 891 } 892 893 static const struct phy_ver_ops qcom_edp_phy_ops_v6 = { 894 .com_power_on = qcom_edp_phy_power_on_v6, 895 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6, 896 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6, 897 .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, 898 .com_configure_pll = qcom_edp_com_configure_pll_v6, 899 .com_configure_ssc = qcom_edp_com_configure_ssc_v6, 900 .com_ldo_config = qcom_edp_ldo_config_v6, 901 }; 902 903 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = { 904 .aux_cfg = edp_phy_aux_cfg_v4, 905 .vco_div_cfg = edp_phy_vco_div_cfg_v4, 906 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 907 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 908 .ver_ops = &qcom_edp_phy_ops_v6, 909 }; 910 911 static int qcom_edp_com_configure_ssc_v8(const struct qcom_edp *edp) 912 { 913 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 914 u32 step1; 915 u32 step2; 916 917 switch (dp_opts->link_rate) { 918 case 1620: 919 case 2700: 920 case 8100: 921 step1 = 0x5b; 922 step2 = 0x02; 923 break; 924 925 case 5400: 926 step1 = 0x5b; 927 step2 = 0x02; 928 break; 929 930 default: 931 /* Other link rates aren't supported */ 932 return -EINVAL; 933 } 934 935 writel(0x01, edp->pll + DP_QSERDES_V8_COM_SSC_EN_CENTER); 936 writel(0x00, edp->pll + DP_QSERDES_V8_COM_SSC_ADJ_PER1); 937 writel(0x6b, edp->pll + DP_QSERDES_V8_COM_SSC_PER1); 938 writel(0x02, edp->pll + DP_QSERDES_V8_COM_SSC_PER2); 939 writel(step1, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0); 940 writel(step2, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0); 941 942 return 0; 943 } 944 945 static int qcom_edp_com_configure_pll_v8(const struct qcom_edp *edp) 946 { 947 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 948 u32 div_frac_start2_mode0; 949 u32 div_frac_start3_mode0; 950 u32 dec_start_mode0; 951 u32 lock_cmp1_mode0; 952 u32 lock_cmp2_mode0; 953 u32 code1_mode0; 954 u32 code2_mode0; 955 u32 hsclk_sel; 956 957 switch (dp_opts->link_rate) { 958 case 1620: 959 hsclk_sel = 0x5; 960 dec_start_mode0 = 0x34; 961 div_frac_start2_mode0 = 0xc0; 962 div_frac_start3_mode0 = 0x0b; 963 lock_cmp1_mode0 = 0x37; 964 lock_cmp2_mode0 = 0x04; 965 code1_mode0 = 0x71; 966 code2_mode0 = 0x0c; 967 break; 968 969 case 2700: 970 hsclk_sel = 0x3; 971 dec_start_mode0 = 0x34; 972 div_frac_start2_mode0 = 0xc0; 973 div_frac_start3_mode0 = 0x0b; 974 lock_cmp1_mode0 = 0x07; 975 lock_cmp2_mode0 = 0x07; 976 code1_mode0 = 0x71; 977 code2_mode0 = 0x0c; 978 break; 979 980 case 5400: 981 case 8100: 982 hsclk_sel = 0x2; 983 dec_start_mode0 = 0x4f; 984 div_frac_start2_mode0 = 0xa0; 985 div_frac_start3_mode0 = 0x01; 986 lock_cmp1_mode0 = 0x18; 987 lock_cmp2_mode0 = 0x15; 988 code1_mode0 = 0x14; 989 code2_mode0 = 0x25; 990 break; 991 992 default: 993 /* Other link rates aren't supported */ 994 return -EINVAL; 995 } 996 997 writel(0x01, edp->pll + DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL); 998 writel(0x3b, edp->pll + DP_QSERDES_V8_COM_SYSCLK_EN_SEL); 999 writel(0x02, edp->pll + DP_QSERDES_V8_COM_SYS_CLK_CTRL); 1000 writel(0x0c, edp->pll + DP_QSERDES_V8_COM_CLK_ENABLE1); 1001 writel(0x06, edp->pll + DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE); 1002 writel(0x30, edp->pll + DP_QSERDES_V8_COM_CLK_SELECT); 1003 writel(hsclk_sel, edp->pll + DP_QSERDES_V8_COM_HSCLK_SEL_1); 1004 writel(0x07, edp->pll + DP_QSERDES_V8_COM_PLL_IVCO); 1005 writel(0x00, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP_EN); 1006 writel(0x36, edp->pll + DP_QSERDES_V8_COM_PLL_CCTRL_MODE0); 1007 writel(0x16, edp->pll + DP_QSERDES_V8_COM_PLL_RCTRL_MODE0); 1008 writel(0x06, edp->pll + DP_QSERDES_V8_COM_CP_CTRL_MODE0); 1009 writel(dec_start_mode0, edp->pll + DP_QSERDES_V8_COM_DEC_START_MODE0); 1010 writel(0x00, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0); 1011 writel(div_frac_start2_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0); 1012 writel(div_frac_start3_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0); 1013 writel(0x96, edp->pll + DP_QSERDES_V8_COM_CMN_CONFIG_1); 1014 writel(0x3f, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0); 1015 writel(0x00, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0); 1016 writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_MAP); 1017 writel(lock_cmp1_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP1_MODE0); 1018 writel(lock_cmp2_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP2_MODE0); 1019 1020 writel(0x0a, edp->pll + DP_QSERDES_V8_COM_BG_TIMER); 1021 writel(0x0a, edp->pll + DP_QSERDES_V8_COM_CORECLK_DIV_MODE0); 1022 writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_CTRL); 1023 writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN); 1024 writel(0x00, edp->pll + DP_QSERDES_V8_COM_CORE_CLK_EN); 1025 writel(0xa0, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE1_MODE0); 1026 writel(0x01, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE2_MODE0); 1027 1028 writel(code1_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0); 1029 writel(code2_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0); 1030 1031 return 0; 1032 } 1033 1034 1035 static int qcom_edp_phy_com_resetsm_cntrl_v8(const struct qcom_edp *edp) 1036 { 1037 u32 val; 1038 1039 writel(0x20, edp->pll + DP_QSERDES_V8_COM_RESETSM_CNTRL); 1040 1041 return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_C_READY_STATUS, 1042 val, val & BIT(0), 500, 10000); 1043 } 1044 1045 static int qcom_edp_com_clk_fwd_cfg_v8(const struct qcom_edp *edp) 1046 { 1047 writel(0x3f, edp->pll + DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1); 1048 1049 return 0; 1050 } 1051 1052 static int qcom_edp_com_bias_en_clkbuflr_v8(const struct qcom_edp *edp) 1053 { 1054 /* Turn on BIAS current for PHY/PLL */ 1055 writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN); 1056 1057 return 0; 1058 } 1059 1060 static int qcom_edp_phy_power_on_v8(const struct qcom_edp *edp) 1061 { 1062 u32 val; 1063 1064 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 1065 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 1066 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 1067 edp->edp + DP_PHY_PD_CTL); 1068 writel(0xfc, edp->edp + DP_PHY_MODE); 1069 1070 return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_CMN_STATUS, 1071 val, val & BIT(7), 5, 200); 1072 } 1073 1074 static const struct phy_ver_ops qcom_edp_phy_ops_v8 = { 1075 .com_power_on = qcom_edp_phy_power_on_v8, 1076 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v8, 1077 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v8, 1078 .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v8, 1079 .com_configure_pll = qcom_edp_com_configure_pll_v8, 1080 .com_configure_ssc = qcom_edp_com_configure_ssc_v8, 1081 .com_ldo_config = qcom_edp_ldo_config_v6, 1082 }; 1083 1084 static struct qcom_edp_phy_cfg glymur_phy_cfg = { 1085 .aux_cfg = edp_phy_aux_cfg_v8, 1086 .vco_div_cfg = edp_phy_vco_div_cfg_v8, 1087 .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg_v8, 1088 .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 1089 .ver_ops = &qcom_edp_phy_ops_v8, 1090 }; 1091 1092 static int qcom_edp_phy_power_on(struct phy *phy) 1093 { 1094 const struct qcom_edp *edp = phy_get_drvdata(phy); 1095 u32 bias0_en, drvr0_en, bias1_en, drvr1_en; 1096 unsigned long pixel_freq; 1097 int ret; 1098 u32 val; 1099 u8 cfg1; 1100 1101 ret = edp->cfg->ver_ops->com_power_on(edp); 1102 if (ret) 1103 return ret; 1104 1105 ret = edp->cfg->ver_ops->com_ldo_config(edp); 1106 if (ret) 1107 return ret; 1108 1109 writel(0x00, edp->tx0 + TXn_LANE_MODE_1); 1110 writel(0x00, edp->tx1 + TXn_LANE_MODE_1); 1111 1112 if (edp->dp_opts.ssc) { 1113 ret = qcom_edp_configure_ssc(edp); 1114 if (ret) 1115 return ret; 1116 } 1117 1118 ret = qcom_edp_configure_pll(edp); 1119 if (ret) 1120 return ret; 1121 1122 /* TX Lane configuration */ 1123 writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL); 1124 writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL); 1125 1126 /* TX-0 register configuration */ 1127 writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN); 1128 writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE); 1129 writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN); 1130 writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN); 1131 writel(0x04, edp->tx0 + TXn_TX_BAND); 1132 1133 /* TX-1 register configuration */ 1134 writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN); 1135 writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE); 1136 writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN); 1137 writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN); 1138 writel(0x04, edp->tx1 + TXn_TX_BAND); 1139 1140 ret = qcom_edp_set_vco_div(edp, &pixel_freq); 1141 if (ret) 1142 return ret; 1143 1144 writel(0x01, edp->edp + DP_PHY_CFG); 1145 writel(0x05, edp->edp + DP_PHY_CFG); 1146 writel(0x01, edp->edp + DP_PHY_CFG); 1147 writel(0x09, edp->edp + DP_PHY_CFG); 1148 1149 ret = edp->cfg->ver_ops->com_resetsm_cntrl(edp); 1150 if (ret) 1151 return ret; 1152 1153 writel(0x19, edp->edp + DP_PHY_CFG); 1154 writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN); 1155 writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN); 1156 writel(0x00, edp->tx0 + TXn_TX_POL_INV); 1157 writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN); 1158 writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN); 1159 writel(0x00, edp->tx1 + TXn_TX_POL_INV); 1160 writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET); 1161 writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET); 1162 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0); 1163 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1); 1164 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0); 1165 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1); 1166 1167 writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL); 1168 writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL); 1169 writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL); 1170 writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL); 1171 1172 if (edp->dp_opts.lanes == 1) { 1173 bias0_en = 0x01; 1174 bias1_en = 0x00; 1175 drvr0_en = 0x06; 1176 drvr1_en = 0x07; 1177 cfg1 = 0x1; 1178 } else if (edp->dp_opts.lanes == 2) { 1179 bias0_en = 0x03; 1180 bias1_en = 0x00; 1181 drvr0_en = 0x04; 1182 drvr1_en = 0x07; 1183 cfg1 = 0x3; 1184 } else { 1185 bias0_en = 0x03; 1186 bias1_en = 0x03; 1187 drvr0_en = 0x04; 1188 drvr1_en = 0x04; 1189 cfg1 = 0xf; 1190 } 1191 1192 writel(drvr0_en, edp->tx0 + TXn_HIGHZ_DRVR_EN); 1193 writel(bias0_en, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN); 1194 writel(drvr1_en, edp->tx1 + TXn_HIGHZ_DRVR_EN); 1195 writel(bias1_en, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN); 1196 writel(cfg1, edp->edp + DP_PHY_CFG_1); 1197 1198 writel(0x18, edp->edp + DP_PHY_CFG); 1199 usleep_range(100, 1000); 1200 1201 writel(0x19, edp->edp + DP_PHY_CFG); 1202 1203 ret = readl_poll_timeout(edp->edp + DP_PHY_STATUS, 1204 val, val & BIT(1), 500, 10000); 1205 if (ret) 1206 return ret; 1207 1208 clk_set_rate(edp->dp_link_hw.clk, edp->dp_opts.link_rate * 100000); 1209 clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq); 1210 1211 return 0; 1212 } 1213 1214 static int qcom_edp_phy_power_off(struct phy *phy) 1215 { 1216 const struct qcom_edp *edp = phy_get_drvdata(phy); 1217 1218 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 1219 1220 return 0; 1221 } 1222 1223 static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1224 { 1225 struct qcom_edp *edp = phy_get_drvdata(phy); 1226 1227 if (mode != PHY_MODE_DP) 1228 return -EINVAL; 1229 1230 edp->is_edp = submode == PHY_SUBMODE_EDP; 1231 1232 return 0; 1233 } 1234 1235 static int qcom_edp_phy_exit(struct phy *phy) 1236 { 1237 struct qcom_edp *edp = phy_get_drvdata(phy); 1238 1239 clk_bulk_disable_unprepare(edp->num_clks, edp->clks); 1240 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 1241 1242 return 0; 1243 } 1244 1245 static const struct phy_ops qcom_edp_ops = { 1246 .init = qcom_edp_phy_init, 1247 .configure = qcom_edp_phy_configure, 1248 .power_on = qcom_edp_phy_power_on, 1249 .power_off = qcom_edp_phy_power_off, 1250 .set_mode = qcom_edp_phy_set_mode, 1251 .exit = qcom_edp_phy_exit, 1252 .owner = THIS_MODULE, 1253 }; 1254 1255 /* 1256 * Embedded Display Port PLL driver block diagram for branch clocks 1257 * 1258 * +------------------------------+ 1259 * | EDP_VCO_CLK | 1260 * | | 1261 * | +-------------------+ | 1262 * | | (EDP PLL/VCO) | | 1263 * | +---------+---------+ | 1264 * | v | 1265 * | +----------+-----------+ | 1266 * | | hsclk_divsel_clk_src | | 1267 * | +----------+-----------+ | 1268 * +------------------------------+ 1269 * | 1270 * +---------<---------v------------>----------+ 1271 * | | 1272 * +--------v----------------+ | 1273 * | edp_phy_pll_link_clk | | 1274 * | link_clk | | 1275 * +--------+----------------+ | 1276 * | | 1277 * | | 1278 * v v 1279 * Input to DISPCC block | 1280 * for link clk, crypto clk | 1281 * and interface clock | 1282 * | 1283 * | 1284 * +--------<------------+-----------------+---<---+ 1285 * | | | 1286 * +----v---------+ +--------v-----+ +--------v------+ 1287 * | vco_divided | | vco_divided | | vco_divided | 1288 * | _clk_src | | _clk_src | | _clk_src | 1289 * | | | | | | 1290 * |divsel_six | | divsel_two | | divsel_four | 1291 * +-------+------+ +-----+--------+ +--------+------+ 1292 * | | | 1293 * v---->----------v-------------<------v 1294 * | 1295 * +----------+-----------------+ 1296 * | edp_phy_pll_vco_div_clk | 1297 * +---------+------------------+ 1298 * | 1299 * v 1300 * Input to DISPCC block 1301 * for EDP pixel clock 1302 * 1303 */ 1304 static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw, 1305 struct clk_rate_request *req) 1306 { 1307 switch (req->rate) { 1308 case 1620000000UL / 2: 1309 case 2700000000UL / 2: 1310 /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */ 1311 return 0; 1312 1313 default: 1314 return -EINVAL; 1315 } 1316 } 1317 1318 static unsigned long 1319 qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 1320 { 1321 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw); 1322 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 1323 1324 switch (dp_opts->link_rate) { 1325 case 1620: 1326 return 1620000000UL / 2; 1327 case 2700: 1328 return 2700000000UL / 2; 1329 case 5400: 1330 return 5400000000UL / 4; 1331 case 8100: 1332 return 8100000000UL / 6; 1333 default: 1334 return 0; 1335 } 1336 } 1337 1338 static const struct clk_ops qcom_edp_dp_pixel_clk_ops = { 1339 .determine_rate = qcom_edp_dp_pixel_clk_determine_rate, 1340 .recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate, 1341 }; 1342 1343 static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw, 1344 struct clk_rate_request *req) 1345 { 1346 switch (req->rate) { 1347 case 162000000: 1348 case 270000000: 1349 case 540000000: 1350 case 810000000: 1351 return 0; 1352 1353 default: 1354 return -EINVAL; 1355 } 1356 } 1357 1358 static unsigned long 1359 qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 1360 { 1361 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw); 1362 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 1363 1364 switch (dp_opts->link_rate) { 1365 case 1620: 1366 case 2700: 1367 case 5400: 1368 case 8100: 1369 return dp_opts->link_rate * 100000; 1370 1371 default: 1372 return 0; 1373 } 1374 } 1375 1376 static const struct clk_ops qcom_edp_dp_link_clk_ops = { 1377 .determine_rate = qcom_edp_dp_link_clk_determine_rate, 1378 .recalc_rate = qcom_edp_dp_link_clk_recalc_rate, 1379 }; 1380 1381 static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np) 1382 { 1383 struct clk_hw_onecell_data *data; 1384 struct clk_init_data init = { }; 1385 char name[64]; 1386 int ret; 1387 1388 data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL); 1389 if (!data) 1390 return -ENOMEM; 1391 data->num = 2; 1392 1393 snprintf(name, sizeof(name), "%s::link_clk", dev_name(edp->dev)); 1394 init.ops = &qcom_edp_dp_link_clk_ops; 1395 init.name = name; 1396 edp->dp_link_hw.init = &init; 1397 ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw); 1398 if (ret) 1399 return ret; 1400 1401 snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(edp->dev)); 1402 init.ops = &qcom_edp_dp_pixel_clk_ops; 1403 init.name = name; 1404 edp->dp_pixel_hw.init = &init; 1405 ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw); 1406 if (ret) 1407 return ret; 1408 1409 data->hws[0] = &edp->dp_link_hw; 1410 data->hws[1] = &edp->dp_pixel_hw; 1411 1412 return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data); 1413 } 1414 1415 static int qcom_edp_phy_probe(struct platform_device *pdev) 1416 { 1417 struct phy_provider *phy_provider; 1418 struct device *dev = &pdev->dev; 1419 struct qcom_edp *edp; 1420 int ret; 1421 1422 edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL); 1423 if (!edp) 1424 return -ENOMEM; 1425 1426 edp->dev = dev; 1427 edp->cfg = of_device_get_match_data(&pdev->dev); 1428 edp->is_edp = edp->cfg->is_edp; 1429 1430 edp->edp = devm_platform_ioremap_resource(pdev, 0); 1431 if (IS_ERR(edp->edp)) 1432 return PTR_ERR(edp->edp); 1433 1434 edp->tx0 = devm_platform_ioremap_resource(pdev, 1); 1435 if (IS_ERR(edp->tx0)) 1436 return PTR_ERR(edp->tx0); 1437 1438 edp->tx1 = devm_platform_ioremap_resource(pdev, 2); 1439 if (IS_ERR(edp->tx1)) 1440 return PTR_ERR(edp->tx1); 1441 1442 edp->pll = devm_platform_ioremap_resource(pdev, 3); 1443 if (IS_ERR(edp->pll)) 1444 return PTR_ERR(edp->pll); 1445 1446 edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks); 1447 if (edp->num_clks < 0) 1448 return dev_err_probe(dev, edp->num_clks, "failed to get clocks\n"); 1449 1450 edp->supplies[0].supply = "vdda-phy"; 1451 edp->supplies[1].supply = "vdda-pll"; 1452 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), edp->supplies); 1453 if (ret) 1454 return ret; 1455 1456 ret = regulator_set_load(edp->supplies[0].consumer, 21800); /* 1.2 V vdda-phy */ 1457 if (ret) { 1458 dev_err(dev, "failed to set load at %s\n", edp->supplies[0].supply); 1459 return ret; 1460 } 1461 1462 ret = regulator_set_load(edp->supplies[1].consumer, 36000); /* 0.9 V vdda-pll */ 1463 if (ret) { 1464 dev_err(dev, "failed to set load at %s\n", edp->supplies[1].supply); 1465 return ret; 1466 } 1467 1468 ret = qcom_edp_clks_register(edp, pdev->dev.of_node); 1469 if (ret) 1470 return ret; 1471 1472 edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops); 1473 if (IS_ERR(edp->phy)) { 1474 dev_err(dev, "failed to register phy\n"); 1475 return PTR_ERR(edp->phy); 1476 } 1477 1478 phy_set_drvdata(edp->phy, edp); 1479 1480 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1481 return PTR_ERR_OR_ZERO(phy_provider); 1482 } 1483 1484 static const struct of_device_id qcom_edp_phy_match_table[] = { 1485 { .compatible = "qcom,glymur-dp-phy", .data = &glymur_phy_cfg, }, 1486 { .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, }, 1487 { .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, }, 1488 { .compatible = "qcom,sc8180x-edp-phy", .data = &sc8180x_dp_phy_cfg, }, 1489 { .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, }, 1490 { .compatible = "qcom,sc8280xp-edp-phy", .data = &sc8280xp_edp_phy_cfg, }, 1491 { .compatible = "qcom,x1e80100-dp-phy", .data = &x1e80100_phy_cfg, }, 1492 { } 1493 }; 1494 MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table); 1495 1496 static struct platform_driver qcom_edp_phy_driver = { 1497 .probe = qcom_edp_phy_probe, 1498 .driver = { 1499 .name = "qcom-edp-phy", 1500 .of_match_table = qcom_edp_phy_match_table, 1501 }, 1502 }; 1503 1504 module_platform_driver(qcom_edp_phy_driver); 1505 1506 MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>"); 1507 MODULE_DESCRIPTION("Qualcomm eDP QMP PHY driver"); 1508 MODULE_LICENSE("GPL v2"); 1509