From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Andy Gross <agross@kernel.org>, Vinod Koul <vkoul@kernel.org>,
Kishon Vijay Abraham I <kishon@ti.com>,
Rob Herring <robh+dt@kernel.org>,
Manu Gautam <mgautam@codeaurora.org>,
Stephen Boyd <sboyd@kernel.org>,
Jonathan Marek <jonathan@marek.ca>,
linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org
Subject: Re: [PATCH v5 3/7] phy: qcom-qmp: move DP functions to callbacks
Date: Mon, 29 Mar 2021 22:28:34 -0500 [thread overview]
Message-ID: <YGKa4rd1GVD8f4Pg@builder.lan> (raw)
In-Reply-To: <20210328205257.3348866-4-dmitry.baryshkov@linaro.org>
On Sun 28 Mar 15:52 CDT 2021, Dmitry Baryshkov wrote:
> In preparation to adding support for V4 DP PHY move DP functions to
> callbacks at struct qmp_phy_cfg.
>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp.c | 438 +++++++++++++++-------------
> 1 file changed, 231 insertions(+), 207 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index 9cdebe7f26cb..4150096fd350 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -2268,6 +2268,8 @@ static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
> QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
> };
>
> +struct qmp_phy;
> +
> /* struct qmp_phy_cfg - per-PHY initialization config */
> struct qmp_phy_cfg {
> /* phy-type - PCIE/UFS/USB */
> @@ -2307,6 +2309,12 @@ struct qmp_phy_cfg {
> const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
> int serdes_tbl_hbr3_num;
>
> + /* DP PHY callbacks */
> + int (*configure_dp_phy)(struct qmp_phy *qphy);
> + void (*configure_dp_tx)(struct qmp_phy *qphy);
> + int (*calibrate_dp_phy)(struct qmp_phy *qphy);
> + void (*dp_aux_init)(struct qmp_phy *qphy);
> +
> /* clock ids to be requested */
> const char * const *clk_list;
> int num_clks;
> @@ -2423,6 +2431,216 @@ struct qcom_qmp {
> struct reset_control *ufs_reset;
> };
>
> +static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
> +{
> + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> + qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + /* Turn on BIAS current for PHY/PLL */
> + writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
> + QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
> + qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
> +
> + writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> + DP_PHY_PD_CTL_LANE_0_1_PWRDN |
> + DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
> + DP_PHY_PD_CTL_DP_CLAMP_EN,
> + qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + writel(QSERDES_V3_COM_BIAS_EN |
> + QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
> + QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
> + QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
> + qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
> +
> + writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG0);
> + writel(0x13, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
> + writel(0x24, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
> + writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG3);
> + writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG4);
> + writel(0x26, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG5);
> + writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG6);
> + writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG7);
> + writel(0xbb, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG8);
> + writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG9);
> + qphy->dp_aux_cfg = 0;
> +
> + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
> + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> + PHY_AUX_REQ_ERR_MASK,
> + qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
> +}
> +
> +static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
> + { 0x00, 0x0c, 0x14, 0x19 },
> + { 0x00, 0x0b, 0x12, 0xff },
> + { 0x00, 0x0b, 0xff, 0xff },
> + { 0x04, 0xff, 0xff, 0xff }
> +};
> +
> +static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
> + { 0x08, 0x0f, 0x16, 0x1f },
> + { 0x11, 0x1e, 0x1f, 0xff },
> + { 0x19, 0x1f, 0xff, 0xff },
> + { 0x1f, 0xff, 0xff, 0xff }
> +};
> +
> +static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
> +{
> + const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
> + unsigned int v_level = 0, p_level = 0;
> + u32 bias_en, drvr_en;
> + u8 voltage_swing_cfg, pre_emphasis_cfg;
> + int i;
> +
> + for (i = 0; i < dp_opts->lanes; i++) {
> + v_level = max(v_level, dp_opts->voltage[i]);
> + p_level = max(p_level, dp_opts->pre[i]);
> + }
> +
> + if (dp_opts->lanes == 1) {
> + bias_en = 0x3e;
> + drvr_en = 0x13;
> + } else {
> + bias_en = 0x3f;
> + drvr_en = 0x10;
> + }
> +
> + voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
> + pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
> +
> + /* TODO: Move check to config check */
> + if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
> + return;
> +
> + /* Enable MUX to use Cursor values from these registers */
> + voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
> + pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
> +
> + writel(voltage_swing_cfg, qphy->tx + QSERDES_V3_TX_TX_DRV_LVL);
> + writel(pre_emphasis_cfg, qphy->tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);
> + writel(voltage_swing_cfg, qphy->tx2 + QSERDES_V3_TX_TX_DRV_LVL);
> + writel(pre_emphasis_cfg, qphy->tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);
> +
> + writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
> + writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
> + writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
> + writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
> +}
> +
> +static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
> +{
> + const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
> + const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
> + u32 val, phy_vco_div, status;
> + unsigned long pixel_freq;
> +
> + val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
> +
> + /*
> + * TODO: Assume orientation is CC1 for now and two lanes, need to
> + * use type-c connector to understand orientation and lanes.
> + *
> + * Otherwise val changes to be like below if this code understood
> + * the orientation of the type-c cable.
> + *
> + * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
> + * val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
> + * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
> + * val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
> + * if (orientation == ORIENTATION_CC2)
> + * writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
> + */
> + val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
> + writel(val, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + writel(0x5c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
> + writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
> + writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
> +
> + switch (dp_opts->link_rate) {
> + case 1620:
> + phy_vco_div = 0x1;
> + pixel_freq = 1620000000UL / 2;
> + break;
> + case 2700:
> + phy_vco_div = 0x1;
> + pixel_freq = 2700000000UL / 2;
> + break;
> + case 5400:
> + phy_vco_div = 0x2;
> + pixel_freq = 5400000000UL / 4;
> + break;
> + case 8100:
> + phy_vco_div = 0x0;
> + pixel_freq = 8100000000UL / 6;
> + break;
> + default:
> + /* Other link rates aren't supported */
> + return -EINVAL;
> + }
> + writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
> +
> + clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
> + clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
> +
> + writel(0x04, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
> + writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> + writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> + writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> + writel(0x09, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> +
> + writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
> +
> + if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
> + status,
> + ((status & BIT(0)) > 0),
> + 500,
> + 10000))
> + return -ETIMEDOUT;
> +
> + writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> +
> + if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
> + status,
> + ((status & BIT(1)) > 0),
> + 500,
> + 10000))
> + return -ETIMEDOUT;
> +
> + writel(0x18, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> + udelay(2000);
> + writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> +
> + return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
> + status,
> + ((status & BIT(1)) > 0),
> + 500,
> + 10000);
> +}
> +
> +/*
> + * We need to calibrate the aux setting here as many times
> + * as the caller tries
> + */
> +static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
> +{
> + static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
> + u8 val;
> +
> + qphy->dp_aux_cfg++;
> + qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
> + val = cfg1_settings[qphy->dp_aux_cfg];
> +
> + writel(val, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
> +
> + return 0;
> +}
> +
> static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
> {
> u32 reg;
> @@ -2871,6 +3089,11 @@ static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
>
> .has_phy_dp_com_ctrl = true,
> .is_dual_lane_phy = true,
> +
> + .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
> + .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
> + .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
> + .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
> };
>
> static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
> @@ -3332,227 +3555,28 @@ static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
> return 0;
> }
>
> -static void qcom_qmp_phy_dp_aux_init(struct qmp_phy *qphy)
> -{
> - writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> - DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> - qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> -
> - /* Turn on BIAS current for PHY/PLL */
> - writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
> - QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
> - qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
> -
> - writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> -
> - writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> - DP_PHY_PD_CTL_LANE_0_1_PWRDN |
> - DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
> - DP_PHY_PD_CTL_DP_CLAMP_EN,
> - qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> -
> - writel(QSERDES_V3_COM_BIAS_EN |
> - QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
> - QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
> - QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
> - qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
> -
> - writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG0);
> - writel(0x13, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
> - writel(0x24, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
> - writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG3);
> - writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG4);
> - writel(0x26, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG5);
> - writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG6);
> - writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG7);
> - writel(0xbb, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG8);
> - writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG9);
> - qphy->dp_aux_cfg = 0;
> -
> - writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
> - PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> - PHY_AUX_REQ_ERR_MASK,
> - qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
> -}
> -
> -static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
> - { 0x00, 0x0c, 0x14, 0x19 },
> - { 0x00, 0x0b, 0x12, 0xff },
> - { 0x00, 0x0b, 0xff, 0xff },
> - { 0x04, 0xff, 0xff, 0xff }
> -};
> -
> -static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
> - { 0x08, 0x0f, 0x16, 0x1f },
> - { 0x11, 0x1e, 0x1f, 0xff },
> - { 0x19, 0x1f, 0xff, 0xff },
> - { 0x1f, 0xff, 0xff, 0xff }
> -};
> -
> -static void qcom_qmp_phy_configure_dp_tx(struct qmp_phy *qphy)
> -{
> - const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
> - unsigned int v_level = 0, p_level = 0;
> - u32 bias_en, drvr_en;
> - u8 voltage_swing_cfg, pre_emphasis_cfg;
> - int i;
> -
> - for (i = 0; i < dp_opts->lanes; i++) {
> - v_level = max(v_level, dp_opts->voltage[i]);
> - p_level = max(p_level, dp_opts->pre[i]);
> - }
> -
> - if (dp_opts->lanes == 1) {
> - bias_en = 0x3e;
> - drvr_en = 0x13;
> - } else {
> - bias_en = 0x3f;
> - drvr_en = 0x10;
> - }
> -
> - voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
> - pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
> -
> - /* TODO: Move check to config check */
> - if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
> - return;
> -
> - /* Enable MUX to use Cursor values from these registers */
> - voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
> - pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
> -
> - writel(voltage_swing_cfg, qphy->tx + QSERDES_V3_TX_TX_DRV_LVL);
> - writel(pre_emphasis_cfg, qphy->tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);
> - writel(voltage_swing_cfg, qphy->tx2 + QSERDES_V3_TX_TX_DRV_LVL);
> - writel(pre_emphasis_cfg, qphy->tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);
> -
> - writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
> - writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
> - writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
> - writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
> -}
> -
> static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> {
> const struct phy_configure_opts_dp *dp_opts = &opts->dp;
> struct qmp_phy *qphy = phy_get_drvdata(phy);
> + const struct qmp_phy_cfg *cfg = qphy->cfg;
>
> memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
> if (qphy->dp_opts.set_voltages) {
> - qcom_qmp_phy_configure_dp_tx(qphy);
> + cfg->configure_dp_tx(qphy);
> qphy->dp_opts.set_voltages = 0;
> }
>
> return 0;
> }
>
> -static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
> -{
> - const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
> - const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
> - u32 val, phy_vco_div, status;
> - unsigned long pixel_freq;
> -
> - val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> - DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
> -
> - /*
> - * TODO: Assume orientation is CC1 for now and two lanes, need to
> - * use type-c connector to understand orientation and lanes.
> - *
> - * Otherwise val changes to be like below if this code understood
> - * the orientation of the type-c cable.
> - *
> - * if (lane_cnt == 4 || orientation == ORIENTATION_CC2)
> - * val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
> - * if (lane_cnt == 4 || orientation == ORIENTATION_CC1)
> - * val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
> - * if (orientation == ORIENTATION_CC2)
> - * writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
> - */
> - val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
> - writel(val, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> -
> - writel(0x5c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
> - writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
> - writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
> -
> - switch (dp_opts->link_rate) {
> - case 1620:
> - phy_vco_div = 0x1;
> - pixel_freq = 1620000000UL / 2;
> - break;
> - case 2700:
> - phy_vco_div = 0x1;
> - pixel_freq = 2700000000UL / 2;
> - break;
> - case 5400:
> - phy_vco_div = 0x2;
> - pixel_freq = 5400000000UL / 4;
> - break;
> - case 8100:
> - phy_vco_div = 0x0;
> - pixel_freq = 8100000000UL / 6;
> - break;
> - default:
> - /* Other link rates aren't supported */
> - return -EINVAL;
> - }
> - writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV);
> -
> - clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
> - clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
> -
> - writel(0x04, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
> - writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> - writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> - writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> - writel(0x09, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> -
> - writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
> -
> - if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS,
> - status,
> - ((status & BIT(0)) > 0),
> - 500,
> - 10000))
> - return -ETIMEDOUT;
> -
> - writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> -
> - if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
> - status,
> - ((status & BIT(1)) > 0),
> - 500,
> - 10000))
> - return -ETIMEDOUT;
> -
> - writel(0x18, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> - udelay(2000);
> - writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
> -
> - return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
> - status,
> - ((status & BIT(1)) > 0),
> - 500,
> - 10000);
> -}
> -
> -/*
> - * We need to calibrate the aux setting here as many times
> - * as the caller tries
> - */
> static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
> {
> struct qmp_phy *qphy = phy_get_drvdata(phy);
> - static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
> - u8 val;
> -
> - qphy->dp_aux_cfg++;
> - qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
> - val = cfg1_settings[qphy->dp_aux_cfg];
> + const struct qmp_phy_cfg *cfg = qphy->cfg;
>
> - writel(val, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
> + if (cfg->calibrate_dp_phy)
> + return cfg->calibrate_dp_phy(qphy);
>
> return 0;
> }
> @@ -3729,7 +3753,7 @@ static int qcom_qmp_phy_init(struct phy *phy)
> return ret;
>
> if (cfg->type == PHY_TYPE_DP)
> - qcom_qmp_phy_dp_aux_init(qphy);
> + cfg->dp_aux_init(qphy);
>
> return 0;
> }
> @@ -3783,7 +3807,7 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
>
> /* Configure special DP tx tunings */
> if (cfg->type == PHY_TYPE_DP)
> - qcom_qmp_phy_configure_dp_tx(qphy);
> + cfg->configure_dp_tx(qphy);
>
> qcom_qmp_phy_configure_lane(rx, cfg->regs,
> cfg->rx_tbl, cfg->rx_tbl_num, 1);
> @@ -3802,7 +3826,7 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
>
> /* Configure link rate, swing, etc. */
> if (cfg->type == PHY_TYPE_DP) {
> - qcom_qmp_phy_configure_dp_phy(qphy);
> + cfg->configure_dp_phy(qphy);
> } else {
> qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
> if (cfg->pcs_tbl_sec)
> --
> 2.30.2
>
next prev parent reply other threads:[~2021-03-30 3:30 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-28 20:52 [PATCH v5 0/7] phy: qcom-qmp: provide DP phy support for sm8250 Dmitry Baryshkov
2021-03-28 20:52 ` [PATCH v5 1/7] dt-bindings: phy: qcom,qmp-usb3-dp-phy: move usb3 compatibles back to qcom,qmp-phy.yaml Dmitry Baryshkov
2021-03-30 3:27 ` Bjorn Andersson
2021-03-28 20:52 ` [PATCH v5 2/7] dt-bindings: phy: qcom,qmp-usb3-dp: Add support for SM8250 Dmitry Baryshkov
2021-03-30 3:28 ` Bjorn Andersson
2021-03-28 20:52 ` [PATCH v5 3/7] phy: qcom-qmp: move DP functions to callbacks Dmitry Baryshkov
2021-03-30 3:28 ` Bjorn Andersson [this message]
2021-03-28 20:52 ` [PATCH v5 4/7] phy: qcom-qmp: rename common registers Dmitry Baryshkov
2021-03-30 3:29 ` Bjorn Andersson
2021-03-28 20:52 ` [PATCH v5 5/7] phy: qcom-qmp: add support for sm8250-usb3-dp phy Dmitry Baryshkov
2021-03-30 3:30 ` Bjorn Andersson
2021-03-28 20:52 ` [PATCH v5 6/7] arm64: dts: qcom: sm8250: switch usb1 qmp phy to USB3+DP mode Dmitry Baryshkov
2021-03-30 3:32 ` Bjorn Andersson
2021-03-28 20:52 ` [PATCH v5 7/7] arm64: dts: qcom: use dp_phy to provide clocks to dispcc Dmitry Baryshkov
2021-03-30 3:33 ` Bjorn Andersson
2021-03-31 12:25 ` [PATCH v5 0/7] phy: qcom-qmp: provide DP phy support for sm8250 Vinod Koul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YGKa4rd1GVD8f4Pg@builder.lan \
--to=bjorn.andersson@linaro.org \
--cc=agross@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.baryshkov@linaro.org \
--cc=jonathan@marek.ca \
--cc=kishon@ti.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgautam@codeaurora.org \
--cc=robh+dt@kernel.org \
--cc=sboyd@kernel.org \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.