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

phy: qcom: edp: Add v6 specific ops and X1E80100 platform support

Add v6 HW support by implementing the version ops. Add the X1E80100
compatible and match config as it is v6.

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-3-4e5018877bee@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Abel Vesa and committed by
Vinod Koul
db83c107 9eb8e3dd

+180
+180
drivers/phy/qualcomm/phy-qcom-edp.c
··· 24 24 25 25 #include "phy-qcom-qmp-dp-phy.h" 26 26 #include "phy-qcom-qmp-qserdes-com-v4.h" 27 + #include "phy-qcom-qmp-qserdes-com-v6.h" 27 28 28 29 /* EDP_PHY registers */ 29 30 #define DP_PHY_CFG 0x0010 ··· 533 532 .ver_ops = &qcom_edp_phy_ops_v4, 534 533 }; 535 534 535 + static int qcom_edp_phy_power_on_v6(const struct qcom_edp *edp) 536 + { 537 + u32 val; 538 + 539 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 540 + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 541 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 542 + edp->edp + DP_PHY_PD_CTL); 543 + writel(0xfc, edp->edp + DP_PHY_MODE); 544 + 545 + return readl_poll_timeout(edp->pll + QSERDES_V6_COM_CMN_STATUS, 546 + val, val & BIT(7), 5, 200); 547 + } 548 + 549 + static int qcom_edp_phy_com_resetsm_cntrl_v6(const struct qcom_edp *edp) 550 + { 551 + u32 val; 552 + 553 + writel(0x20, edp->pll + QSERDES_V6_COM_RESETSM_CNTRL); 554 + 555 + return readl_poll_timeout(edp->pll + QSERDES_V6_COM_C_READY_STATUS, 556 + val, val & BIT(0), 500, 10000); 557 + } 558 + 559 + static int qcom_edp_com_bias_en_clkbuflr_v6(const struct qcom_edp *edp) 560 + { 561 + /* Turn on BIAS current for PHY/PLL */ 562 + writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN); 563 + 564 + return 0; 565 + } 566 + 567 + static int qcom_edp_com_configure_ssc_v6(const struct qcom_edp *edp) 568 + { 569 + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 570 + u32 step1; 571 + u32 step2; 572 + 573 + switch (dp_opts->link_rate) { 574 + case 1620: 575 + case 2700: 576 + case 8100: 577 + step1 = 0x92; 578 + step2 = 0x01; 579 + break; 580 + 581 + case 5400: 582 + step1 = 0x18; 583 + step2 = 0x02; 584 + break; 585 + 586 + default: 587 + /* Other link rates aren't supported */ 588 + return -EINVAL; 589 + } 590 + 591 + writel(0x01, edp->pll + QSERDES_V6_COM_SSC_EN_CENTER); 592 + writel(0x00, edp->pll + QSERDES_V6_COM_SSC_ADJ_PER1); 593 + writel(0x36, edp->pll + QSERDES_V6_COM_SSC_PER1); 594 + writel(0x01, edp->pll + QSERDES_V6_COM_SSC_PER2); 595 + writel(step1, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0); 596 + writel(step2, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0); 597 + 598 + return 0; 599 + } 600 + 601 + static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp) 602 + { 603 + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 604 + u32 div_frac_start2_mode0; 605 + u32 div_frac_start3_mode0; 606 + u32 dec_start_mode0; 607 + u32 lock_cmp1_mode0; 608 + u32 lock_cmp2_mode0; 609 + u32 code1_mode0; 610 + u32 code2_mode0; 611 + u32 hsclk_sel; 612 + 613 + switch (dp_opts->link_rate) { 614 + case 1620: 615 + hsclk_sel = 0x5; 616 + dec_start_mode0 = 0x34; 617 + div_frac_start2_mode0 = 0xc0; 618 + div_frac_start3_mode0 = 0x0b; 619 + lock_cmp1_mode0 = 0x37; 620 + lock_cmp2_mode0 = 0x04; 621 + code1_mode0 = 0x71; 622 + code2_mode0 = 0x0c; 623 + break; 624 + 625 + case 2700: 626 + hsclk_sel = 0x3; 627 + dec_start_mode0 = 0x34; 628 + div_frac_start2_mode0 = 0xc0; 629 + div_frac_start3_mode0 = 0x0b; 630 + lock_cmp1_mode0 = 0x07; 631 + lock_cmp2_mode0 = 0x07; 632 + code1_mode0 = 0x71; 633 + code2_mode0 = 0x0c; 634 + break; 635 + 636 + case 5400: 637 + hsclk_sel = 0x1; 638 + dec_start_mode0 = 0x46; 639 + div_frac_start2_mode0 = 0x00; 640 + div_frac_start3_mode0 = 0x05; 641 + lock_cmp1_mode0 = 0x0f; 642 + lock_cmp2_mode0 = 0x0e; 643 + code1_mode0 = 0x97; 644 + code2_mode0 = 0x10; 645 + break; 646 + 647 + case 8100: 648 + hsclk_sel = 0x0; 649 + dec_start_mode0 = 0x34; 650 + div_frac_start2_mode0 = 0xc0; 651 + div_frac_start3_mode0 = 0x0b; 652 + lock_cmp1_mode0 = 0x17; 653 + lock_cmp2_mode0 = 0x15; 654 + code1_mode0 = 0x71; 655 + code2_mode0 = 0x0c; 656 + break; 657 + 658 + default: 659 + /* Other link rates aren't supported */ 660 + return -EINVAL; 661 + } 662 + 663 + writel(0x01, edp->pll + QSERDES_V6_COM_SVS_MODE_CLK_SEL); 664 + writel(0x0b, edp->pll + QSERDES_V6_COM_SYSCLK_EN_SEL); 665 + writel(0x02, edp->pll + QSERDES_V6_COM_SYS_CLK_CTRL); 666 + writel(0x0c, edp->pll + QSERDES_V6_COM_CLK_ENABLE1); 667 + writel(0x06, edp->pll + QSERDES_V6_COM_SYSCLK_BUF_ENABLE); 668 + writel(0x30, edp->pll + QSERDES_V6_COM_CLK_SELECT); 669 + writel(hsclk_sel, edp->pll + QSERDES_V6_COM_HSCLK_SEL_1); 670 + writel(0x07, edp->pll + QSERDES_V6_COM_PLL_IVCO); 671 + writel(0x08, edp->pll + QSERDES_V6_COM_LOCK_CMP_EN); 672 + writel(0x36, edp->pll + QSERDES_V6_COM_PLL_CCTRL_MODE0); 673 + writel(0x16, edp->pll + QSERDES_V6_COM_PLL_RCTRL_MODE0); 674 + writel(0x06, edp->pll + QSERDES_V6_COM_CP_CTRL_MODE0); 675 + writel(dec_start_mode0, edp->pll + QSERDES_V6_COM_DEC_START_MODE0); 676 + writel(0x00, edp->pll + QSERDES_V6_COM_DIV_FRAC_START1_MODE0); 677 + writel(div_frac_start2_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START2_MODE0); 678 + writel(div_frac_start3_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START3_MODE0); 679 + writel(0x12, edp->pll + QSERDES_V6_COM_CMN_CONFIG_1); 680 + writel(0x3f, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0); 681 + writel(0x00, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0); 682 + writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_MAP); 683 + writel(lock_cmp1_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP1_MODE0); 684 + writel(lock_cmp2_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP2_MODE0); 685 + 686 + writel(0x0a, edp->pll + QSERDES_V6_COM_BG_TIMER); 687 + writel(0x14, edp->pll + QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0); 688 + writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_CTRL); 689 + writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN); 690 + writel(0x0f, edp->pll + QSERDES_V6_COM_CORE_CLK_EN); 691 + writel(0xa0, edp->pll + QSERDES_V6_COM_VCO_TUNE1_MODE0); 692 + writel(0x03, edp->pll + QSERDES_V6_COM_VCO_TUNE2_MODE0); 693 + 694 + writel(code1_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0); 695 + writel(code2_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0); 696 + 697 + return 0; 698 + } 699 + 700 + static const struct phy_ver_ops qcom_edp_phy_ops_v6 = { 701 + .com_power_on = qcom_edp_phy_power_on_v6, 702 + .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6, 703 + .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6, 704 + .com_configure_pll = qcom_edp_com_configure_pll_v6, 705 + .com_configure_ssc = qcom_edp_com_configure_ssc_v6, 706 + }; 707 + 708 + static struct qcom_edp_phy_cfg x1e80100_phy_cfg = { 709 + .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 710 + .ver_ops = &qcom_edp_phy_ops_v6, 711 + }; 712 + 536 713 static int qcom_edp_phy_power_on(struct phy *phy) 537 714 { 538 715 const struct qcom_edp *edp = phy_get_drvdata(phy); ··· 1112 933 { .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, }, 1113 934 { .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, }, 1114 935 { .compatible = "qcom,sc8280xp-edp-phy", .data = &sc8280xp_edp_phy_cfg, }, 936 + { .compatible = "qcom,x1e80100-dp-phy", .data = &x1e80100_phy_cfg, }, 1115 937 { } 1116 938 }; 1117 939 MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);