Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: qcom: edp: Move v4 specific settings to version ops

In order to support different HW versions move everything specific
to v4 into so-called version ops.

Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20240221-phy-qualcomm-edp-x1e80100-v4-2-4e5018877bee@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Abel Vesa and committed by
Vinod Koul
9eb8e3dd 5d560786

+118 -65
+118 -65
drivers/phy/qualcomm/phy-qcom-edp.c
··· 77 77 const u8 (*pre_emphasis_hbr3_hbr2)[4][4]; 78 78 }; 79 79 80 + struct qcom_edp; 81 + 82 + struct phy_ver_ops { 83 + int (*com_power_on)(const struct qcom_edp *edp); 84 + int (*com_resetsm_cntrl)(const struct qcom_edp *edp); 85 + int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp); 86 + int (*com_configure_pll)(const struct qcom_edp *edp); 87 + int (*com_configure_ssc)(const struct qcom_edp *edp); 88 + }; 89 + 80 90 struct qcom_edp_phy_cfg { 81 91 bool is_edp; 82 92 const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg; 93 + const struct phy_ver_ops *ver_ops; 83 94 }; 84 95 85 96 struct qcom_edp { ··· 185 174 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3, 186 175 }; 187 176 188 - static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { 189 - }; 190 - 191 - static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { 192 - .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 193 - }; 194 - 195 - static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = { 196 - .is_edp = true, 197 - .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 198 - }; 199 - 200 177 static int qcom_edp_phy_init(struct phy *phy) 201 178 { 202 179 struct qcom_edp *edp = phy_get_drvdata(phy); ··· 203 204 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 204 205 edp->edp + DP_PHY_PD_CTL); 205 206 206 - /* Turn on BIAS current for PHY/PLL */ 207 - writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 207 + ret = edp->cfg->ver_ops->com_bias_en_clkbuflr(edp); 208 + if (ret) 209 + return ret; 208 210 209 211 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 210 212 msleep(20); ··· 313 313 314 314 static int qcom_edp_configure_ssc(const struct qcom_edp *edp) 315 315 { 316 + return edp->cfg->ver_ops->com_configure_ssc(edp); 317 + } 318 + 319 + static int qcom_edp_configure_pll(const struct qcom_edp *edp) 320 + { 321 + return edp->cfg->ver_ops->com_configure_pll(edp); 322 + } 323 + 324 + static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq) 325 + { 326 + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 327 + u32 vco_div; 328 + 329 + switch (dp_opts->link_rate) { 330 + case 1620: 331 + vco_div = 0x1; 332 + *pixel_freq = 1620000000UL / 2; 333 + break; 334 + 335 + case 2700: 336 + vco_div = 0x1; 337 + *pixel_freq = 2700000000UL / 2; 338 + break; 339 + 340 + case 5400: 341 + vco_div = 0x2; 342 + *pixel_freq = 5400000000UL / 4; 343 + break; 344 + 345 + case 8100: 346 + vco_div = 0x0; 347 + *pixel_freq = 8100000000UL / 6; 348 + break; 349 + 350 + default: 351 + /* Other link rates aren't supported */ 352 + return -EINVAL; 353 + } 354 + 355 + writel(vco_div, edp->edp + DP_PHY_VCO_DIV); 356 + 357 + return 0; 358 + } 359 + 360 + static int qcom_edp_phy_power_on_v4(const struct qcom_edp *edp) 361 + { 362 + u32 val; 363 + 364 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 365 + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 366 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 367 + edp->edp + DP_PHY_PD_CTL); 368 + writel(0xfc, edp->edp + DP_PHY_MODE); 369 + 370 + return readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS, 371 + val, val & BIT(7), 5, 200); 372 + } 373 + 374 + static int qcom_edp_phy_com_resetsm_cntrl_v4(const struct qcom_edp *edp) 375 + { 376 + u32 val; 377 + 378 + writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL); 379 + 380 + return readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS, 381 + val, val & BIT(0), 500, 10000); 382 + } 383 + 384 + static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp) 385 + { 386 + /* Turn on BIAS current for PHY/PLL */ 387 + writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 388 + 389 + return 0; 390 + } 391 + 392 + static int qcom_edp_com_configure_ssc_v4(const struct qcom_edp *edp) 393 + { 316 394 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 317 395 u32 step1; 318 396 u32 step2; ··· 423 345 return 0; 424 346 } 425 347 426 - static int qcom_edp_configure_pll(const struct qcom_edp *edp) 348 + static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp) 427 349 { 428 350 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 429 351 u32 div_frac_start2_mode0; ··· 509 431 return 0; 510 432 } 511 433 512 - static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq) 513 - { 514 - const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 515 - u32 vco_div; 434 + static const struct phy_ver_ops qcom_edp_phy_ops_v4 = { 435 + .com_power_on = qcom_edp_phy_power_on_v4, 436 + .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4, 437 + .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4, 438 + .com_configure_pll = qcom_edp_com_configure_pll_v4, 439 + .com_configure_ssc = qcom_edp_com_configure_ssc_v4, 440 + }; 516 441 517 - switch (dp_opts->link_rate) { 518 - case 1620: 519 - vco_div = 0x1; 520 - *pixel_freq = 1620000000UL / 2; 521 - break; 442 + static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { 443 + .ver_ops = &qcom_edp_phy_ops_v4, 444 + }; 522 445 523 - case 2700: 524 - vco_div = 0x1; 525 - *pixel_freq = 2700000000UL / 2; 526 - break; 446 + static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { 447 + .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 448 + .ver_ops = &qcom_edp_phy_ops_v4, 449 + }; 527 450 528 - case 5400: 529 - vco_div = 0x2; 530 - *pixel_freq = 5400000000UL / 4; 531 - break; 532 - 533 - case 8100: 534 - vco_div = 0x0; 535 - *pixel_freq = 8100000000UL / 6; 536 - break; 537 - 538 - default: 539 - /* Other link rates aren't supported */ 540 - return -EINVAL; 541 - } 542 - 543 - writel(vco_div, edp->edp + DP_PHY_VCO_DIV); 544 - 545 - return 0; 546 - } 451 + static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = { 452 + .is_edp = true, 453 + .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 454 + .ver_ops = &qcom_edp_phy_ops_v4, 455 + }; 547 456 548 457 static int qcom_edp_phy_power_on(struct phy *phy) 549 458 { ··· 538 473 u32 bias0_en, drvr0_en, bias1_en, drvr1_en; 539 474 unsigned long pixel_freq; 540 475 u8 ldo_config = 0x0; 541 - int timeout; 542 476 int ret; 543 477 u32 val; 544 478 u8 cfg1; 545 479 546 - writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 547 - DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 548 - DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 549 - edp->edp + DP_PHY_PD_CTL); 550 - writel(0xfc, edp->edp + DP_PHY_MODE); 551 - 552 - timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS, 553 - val, val & BIT(7), 5, 200); 554 - if (timeout) 555 - return timeout; 556 - 480 + ret = edp->cfg->ver_ops->com_power_on(edp); 481 + if (ret) 482 + return ret; 557 483 558 484 if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp) 559 485 ldo_config = 0x1; ··· 591 535 writel(0x01, edp->edp + DP_PHY_CFG); 592 536 writel(0x09, edp->edp + DP_PHY_CFG); 593 537 594 - writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL); 595 - 596 - timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS, 597 - val, val & BIT(0), 500, 10000); 598 - if (timeout) 599 - return timeout; 538 + ret = edp->cfg->ver_ops->com_resetsm_cntrl(edp); 539 + if (ret) 540 + return ret; 600 541 601 542 writel(0x19, edp->edp + DP_PHY_CFG); 602 543 writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN);