Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright © 2019 Intel Corporation
0004  */
0005 
0006 #include <linux/util_macros.h>
0007 
0008 #include "intel_ddi.h"
0009 #include "intel_ddi_buf_trans.h"
0010 #include "intel_de.h"
0011 #include "intel_display_types.h"
0012 #include "intel_snps_phy.h"
0013 #include "intel_snps_phy_regs.h"
0014 
0015 /**
0016  * DOC: Synopsis PHY support
0017  *
0018  * Synopsis PHYs are primarily programmed by looking up magic register values
0019  * in tables rather than calculating the necessary values at runtime.
0020  *
0021  * Of special note is that the SNPS PHYs include a dedicated port PLL, known as
0022  * an "MPLLB."  The MPLLB replaces the shared DPLL functionality used on other
0023  * platforms and must be programming directly during the modeset sequence
0024  * since it is not handled by the shared DPLL framework as on other platforms.
0025  */
0026 
0027 void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
0028 {
0029     enum phy phy;
0030 
0031     for_each_phy_masked(phy, ~0) {
0032         if (!intel_phy_is_snps(i915, phy))
0033             continue;
0034 
0035         /*
0036          * If calibration does not complete successfully, we'll remember
0037          * which phy was affected and skip setup of the corresponding
0038          * output later.
0039          */
0040         if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
0041                         DG2_PHY_DP_TX_ACK_MASK, 25))
0042             i915->snps_phy_failed_calibration |= BIT(phy);
0043     }
0044 }
0045 
0046 void intel_snps_phy_update_psr_power_state(struct drm_i915_private *dev_priv,
0047                        enum phy phy, bool enable)
0048 {
0049     u32 val;
0050 
0051     if (!intel_phy_is_snps(dev_priv, phy))
0052         return;
0053 
0054     val = REG_FIELD_PREP(SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR,
0055                  enable ? 2 : 3);
0056     intel_uncore_rmw(&dev_priv->uncore, SNPS_PHY_TX_REQ(phy),
0057              SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, val);
0058 }
0059 
0060 void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder,
0061                       const struct intel_crtc_state *crtc_state)
0062 {
0063     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0064     const struct intel_ddi_buf_trans *trans;
0065     enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
0066     int n_entries, ln;
0067 
0068     trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
0069     if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))
0070         return;
0071 
0072     for (ln = 0; ln < 4; ln++) {
0073         int level = intel_ddi_level(encoder, crtc_state, ln);
0074         u32 val = 0;
0075 
0076         val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, trans->entries[level].snps.vswing);
0077         val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_PRE, trans->entries[level].snps.pre_cursor);
0078         val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, trans->entries[level].snps.post_cursor);
0079 
0080         intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy), val);
0081     }
0082 }
0083 
0084 /*
0085  * Basic DP link rates with 100 MHz reference clock.
0086  */
0087 
0088 static const struct intel_mpllb_state dg2_dp_rbr_100 = {
0089     .clock = 162000,
0090     .ref_control =
0091         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0092     .mpllb_cp =
0093         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0094         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
0095         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0096         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0097     .mpllb_div =
0098         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0099         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
0100         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0101         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0102         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
0103     .mpllb_div2 =
0104         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0105         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 226),
0106     .mpllb_fracn1 =
0107         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0108         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0109         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0110     .mpllb_fracn2 =
0111         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
0112         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 3),
0113 };
0114 
0115 static const struct intel_mpllb_state dg2_dp_hbr1_100 = {
0116     .clock = 270000,
0117     .ref_control =
0118         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0119     .mpllb_cp =
0120         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0121         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
0122         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0123         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0124     .mpllb_div =
0125         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0126         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
0127         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0128         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
0129     .mpllb_div2 =
0130         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0131         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 184),
0132     .mpllb_fracn1 =
0133         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0134         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
0135 };
0136 
0137 static const struct intel_mpllb_state dg2_dp_hbr2_100 = {
0138     .clock = 540000,
0139     .ref_control =
0140         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0141     .mpllb_cp =
0142         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0143         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
0144         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0145         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0146     .mpllb_div =
0147         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0148         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0149         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
0150     .mpllb_div2 =
0151         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0152         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 184),
0153     .mpllb_fracn1 =
0154         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0155         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
0156 };
0157 
0158 static const struct intel_mpllb_state dg2_dp_hbr3_100 = {
0159     .clock = 810000,
0160     .ref_control =
0161         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0162     .mpllb_cp =
0163         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0164         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 19) |
0165         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0166         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0167     .mpllb_div =
0168         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0169         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0170     .mpllb_div2 =
0171         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0172         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 292),
0173     .mpllb_fracn1 =
0174         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0175         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
0176 };
0177 
0178 static const struct intel_mpllb_state dg2_dp_uhbr10_100 = {
0179     .clock = 1000000,
0180     .ref_control =
0181         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0182     .mpllb_cp =
0183         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0184         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 21) |
0185         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0186         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0187     .mpllb_div =
0188         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0189         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) |
0190         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) |
0191         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0192         REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) |
0193         REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) |
0194         REG_FIELD_PREP(SNPS_PHY_MPLLB_SHIM_DIV32_CLK_SEL, 1) |
0195         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0196     .mpllb_div2 =
0197         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0198         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 368),
0199     .mpllb_fracn1 =
0200         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0201         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
0202 
0203     /*
0204      * SSC will be enabled, DP UHBR has a minimum SSC requirement.
0205      */
0206     .mpllb_sscen =
0207         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
0208         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 58982),
0209     .mpllb_sscstep =
0210         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 76101),
0211 };
0212 
0213 static const struct intel_mpllb_state dg2_dp_uhbr13_100 = {
0214     .clock = 1350000,
0215     .ref_control =
0216         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0217     .mpllb_cp =
0218         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
0219         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 45) |
0220         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0221         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0222     .mpllb_div =
0223         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0224         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) |
0225         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) |
0226         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0227         REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) |
0228         REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) |
0229         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 3),
0230     .mpllb_div2 =
0231         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0232         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 508),
0233     .mpllb_fracn1 =
0234         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0235         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
0236 
0237     /*
0238      * SSC will be enabled, DP UHBR has a minimum SSC requirement.
0239      */
0240     .mpllb_sscen =
0241         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
0242         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 79626),
0243     .mpllb_sscstep =
0244         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 102737),
0245 };
0246 
0247 static const struct intel_mpllb_state * const dg2_dp_100_tables[] = {
0248     &dg2_dp_rbr_100,
0249     &dg2_dp_hbr1_100,
0250     &dg2_dp_hbr2_100,
0251     &dg2_dp_hbr3_100,
0252     &dg2_dp_uhbr10_100,
0253     &dg2_dp_uhbr13_100,
0254     NULL,
0255 };
0256 
0257 /*
0258  * eDP link rates with 100 MHz reference clock.
0259  */
0260 
0261 static const struct intel_mpllb_state dg2_edp_r216 = {
0262     .clock = 216000,
0263     .ref_control =
0264         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0265     .mpllb_cp =
0266         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0267         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 19) |
0268         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0269         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0270     .mpllb_div =
0271         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0272         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
0273         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0274         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0275     .mpllb_div2 =
0276         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0277         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 312),
0278     .mpllb_fracn1 =
0279         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0280         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0281         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0282     .mpllb_fracn2 =
0283         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
0284         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 4),
0285     .mpllb_sscen =
0286         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
0287         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 50961),
0288     .mpllb_sscstep =
0289         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 65752),
0290 };
0291 
0292 static const struct intel_mpllb_state dg2_edp_r243 = {
0293     .clock = 243000,
0294     .ref_control =
0295         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0296     .mpllb_cp =
0297         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0298         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
0299         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0300         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0301     .mpllb_div =
0302         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0303         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
0304         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0305         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0306     .mpllb_div2 =
0307         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0308         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 356),
0309     .mpllb_fracn1 =
0310         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0311         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0312         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0313     .mpllb_fracn2 =
0314         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
0315         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
0316     .mpllb_sscen =
0317         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
0318         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 57331),
0319     .mpllb_sscstep =
0320         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 73971),
0321 };
0322 
0323 static const struct intel_mpllb_state dg2_edp_r324 = {
0324     .clock = 324000,
0325     .ref_control =
0326         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0327     .mpllb_cp =
0328         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0329         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
0330         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0331         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0332     .mpllb_div =
0333         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0334         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
0335         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0336         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0337         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
0338     .mpllb_div2 =
0339         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0340         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 226),
0341     .mpllb_fracn1 =
0342         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0343         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0344         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0345     .mpllb_fracn2 =
0346         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
0347         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 3),
0348     .mpllb_sscen =
0349         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
0350         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 38221),
0351     .mpllb_sscstep =
0352         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 49314),
0353 };
0354 
0355 static const struct intel_mpllb_state dg2_edp_r432 = {
0356     .clock = 432000,
0357     .ref_control =
0358         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0359     .mpllb_cp =
0360         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0361         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 19) |
0362         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
0363         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
0364     .mpllb_div =
0365         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0366         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
0367         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0368         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0369     .mpllb_div2 =
0370         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
0371         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 312),
0372     .mpllb_fracn1 =
0373         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0374         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0375         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0376     .mpllb_fracn2 =
0377         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
0378         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 4),
0379     .mpllb_sscen =
0380         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
0381         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 50961),
0382     .mpllb_sscstep =
0383         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 65752),
0384 };
0385 
0386 static const struct intel_mpllb_state * const dg2_edp_tables[] = {
0387     &dg2_dp_rbr_100,
0388     &dg2_edp_r216,
0389     &dg2_edp_r243,
0390     &dg2_dp_hbr1_100,
0391     &dg2_edp_r324,
0392     &dg2_edp_r432,
0393     &dg2_dp_hbr2_100,
0394     &dg2_dp_hbr3_100,
0395     NULL,
0396 };
0397 
0398 /*
0399  * HDMI link rates with 100 MHz reference clock.
0400  */
0401 
0402 static const struct intel_mpllb_state dg2_hdmi_25_175 = {
0403     .clock = 25175,
0404     .ref_control =
0405         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0406     .mpllb_cp =
0407         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
0408         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
0409         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
0410         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
0411     .mpllb_div =
0412         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0413         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
0414         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0415         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0416     .mpllb_div2 =
0417         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
0418         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 128) |
0419         REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
0420     .mpllb_fracn1 =
0421         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0422         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0423         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 143),
0424     .mpllb_fracn2 =
0425         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 36663) |
0426         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 71),
0427     .mpllb_sscen =
0428         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
0429 };
0430 
0431 static const struct intel_mpllb_state dg2_hdmi_27_0 = {
0432     .clock = 27000,
0433     .ref_control =
0434         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0435     .mpllb_cp =
0436         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
0437         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
0438         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
0439         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
0440     .mpllb_div =
0441         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0442         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
0443         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0444         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
0445     .mpllb_div2 =
0446         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
0447         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 140) |
0448         REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
0449     .mpllb_fracn1 =
0450         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0451         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0452         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0453     .mpllb_fracn2 =
0454         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
0455         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
0456     .mpllb_sscen =
0457         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
0458 };
0459 
0460 static const struct intel_mpllb_state dg2_hdmi_74_25 = {
0461     .clock = 74250,
0462     .ref_control =
0463         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0464     .mpllb_cp =
0465         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0466         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
0467         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
0468         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
0469     .mpllb_div =
0470         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0471         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
0472         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0473         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0474         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
0475     .mpllb_div2 =
0476         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
0477         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
0478         REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
0479     .mpllb_fracn1 =
0480         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0481         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0482         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0483     .mpllb_fracn2 =
0484         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
0485         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
0486     .mpllb_sscen =
0487         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
0488 };
0489 
0490 static const struct intel_mpllb_state dg2_hdmi_148_5 = {
0491     .clock = 148500,
0492     .ref_control =
0493         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0494     .mpllb_cp =
0495         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0496         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
0497         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
0498         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
0499     .mpllb_div =
0500         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0501         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
0502         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0503         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0504         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
0505     .mpllb_div2 =
0506         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
0507         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
0508         REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
0509     .mpllb_fracn1 =
0510         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0511         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0512         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0513     .mpllb_fracn2 =
0514         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
0515         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
0516     .mpllb_sscen =
0517         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
0518 };
0519 
0520 /* values in the below table are calculted using the algo */
0521 static const struct intel_mpllb_state dg2_hdmi_297 = {
0522     .clock = 297000,
0523     .ref_control =
0524         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0525     .mpllb_cp =
0526         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
0527         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
0528         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
0529         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
0530     .mpllb_div =
0531         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0532         REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
0533         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0534         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0535         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
0536     .mpllb_div2 =
0537         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
0538         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
0539         REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
0540     .mpllb_fracn1 =
0541         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0542         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0543         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
0544     .mpllb_fracn2 =
0545         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
0546         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
0547     .mpllb_sscen =
0548         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
0549 };
0550 
0551 static const struct intel_mpllb_state dg2_hdmi_594 = {
0552     .clock = 594000,
0553     .ref_control =
0554         REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
0555     .mpllb_cp =
0556         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
0557         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
0558         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
0559         REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
0560     .mpllb_div =
0561         REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
0562         REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
0563         REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
0564         REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
0565     .mpllb_div2 =
0566         REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
0567         REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
0568         REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
0569     .mpllb_fracn1 =
0570         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
0571         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
0572         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
0573     .mpllb_fracn2 =
0574         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
0575         REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
0576     .mpllb_sscen =
0577         REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
0578 };
0579 
0580 static const struct intel_mpllb_state * const dg2_hdmi_tables[] = {
0581     &dg2_hdmi_25_175,
0582     &dg2_hdmi_27_0,
0583     &dg2_hdmi_74_25,
0584     &dg2_hdmi_148_5,
0585     &dg2_hdmi_297,
0586     &dg2_hdmi_594,
0587     NULL,
0588 };
0589 
0590 static const struct intel_mpllb_state * const *
0591 intel_mpllb_tables_get(struct intel_crtc_state *crtc_state,
0592                struct intel_encoder *encoder)
0593 {
0594     if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
0595         return dg2_edp_tables;
0596     } else if (intel_crtc_has_dp_encoder(crtc_state)) {
0597         return dg2_dp_100_tables;
0598     } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
0599         return dg2_hdmi_tables;
0600     }
0601 
0602     MISSING_CASE(encoder->type);
0603     return NULL;
0604 }
0605 
0606 int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
0607                struct intel_encoder *encoder)
0608 {
0609     struct drm_i915_private *i915 = to_i915(encoder->base.dev);
0610     const struct intel_mpllb_state * const *tables;
0611     int i;
0612 
0613     if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
0614         if (intel_snps_phy_check_hdmi_link_rate(crtc_state->port_clock)
0615             != MODE_OK) {
0616             /*
0617              * FIXME: Can only support fixed HDMI frequencies
0618              * until we have a proper algorithm under a valid
0619              * license.
0620              */
0621             drm_dbg_kms(&i915->drm, "Can't support HDMI link rate %d\n",
0622                     crtc_state->port_clock);
0623             return -EINVAL;
0624         }
0625     }
0626 
0627     tables = intel_mpllb_tables_get(crtc_state, encoder);
0628     if (!tables)
0629         return -EINVAL;
0630 
0631     for (i = 0; tables[i]; i++) {
0632         if (crtc_state->port_clock == tables[i]->clock) {
0633             crtc_state->mpllb_state = *tables[i];
0634             return 0;
0635         }
0636     }
0637 
0638     return -EINVAL;
0639 }
0640 
0641 void intel_mpllb_enable(struct intel_encoder *encoder,
0642             const struct intel_crtc_state *crtc_state)
0643 {
0644     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0645     const struct intel_mpllb_state *pll_state = &crtc_state->mpllb_state;
0646     enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
0647     i915_reg_t enable_reg = (phy <= PHY_D ?
0648                  DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
0649 
0650     /*
0651      * 3. Software programs the following PLL registers for the desired
0652      * frequency.
0653      */
0654     intel_de_write(dev_priv, SNPS_PHY_MPLLB_CP(phy), pll_state->mpllb_cp);
0655     intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div);
0656     intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV2(phy), pll_state->mpllb_div2);
0657     intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy), pll_state->mpllb_sscen);
0658     intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy), pll_state->mpllb_sscstep);
0659     intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy), pll_state->mpllb_fracn1);
0660     intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy), pll_state->mpllb_fracn2);
0661 
0662     /*
0663      * 4. If the frequency will result in a change to the voltage
0664      * requirement, follow the Display Voltage Frequency Switching -
0665      * Sequence Before Frequency Change.
0666      *
0667      * We handle this step in bxt_set_cdclk().
0668      */
0669 
0670     /* 5. Software sets DPLL_ENABLE [PLL Enable] to "1". */
0671     intel_uncore_rmw(&dev_priv->uncore, enable_reg, 0, PLL_ENABLE);
0672 
0673     /*
0674      * 9. Software sets SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "1". This
0675      * will keep the PLL running during the DDI lane programming and any
0676      * typeC DP cable disconnect. Do not set the force before enabling the
0677      * PLL because that will start the PLL before it has sampled the
0678      * divider values.
0679      */
0680     intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy),
0681                pll_state->mpllb_div | SNPS_PHY_MPLLB_FORCE_EN);
0682 
0683     /*
0684      * 10. Software polls on register DPLL_ENABLE [PLL Lock] to confirm PLL
0685      * is locked at new settings. This register bit is sampling PHY
0686      * dp_mpllb_state interface signal.
0687      */
0688     if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5))
0689         drm_dbg_kms(&dev_priv->drm, "Port %c PLL not locked\n", phy_name(phy));
0690 
0691     /*
0692      * 11. If the frequency will result in a change to the voltage
0693      * requirement, follow the Display Voltage Frequency Switching -
0694      * Sequence After Frequency Change.
0695      *
0696      * We handle this step in bxt_set_cdclk().
0697      */
0698 }
0699 
0700 void intel_mpllb_disable(struct intel_encoder *encoder)
0701 {
0702     struct drm_i915_private *i915 = to_i915(encoder->base.dev);
0703     enum phy phy = intel_port_to_phy(i915, encoder->port);
0704     i915_reg_t enable_reg = (phy <= PHY_D ?
0705                  DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
0706 
0707     /*
0708      * 1. If the frequency will result in a change to the voltage
0709      * requirement, follow the Display Voltage Frequency Switching -
0710      * Sequence Before Frequency Change.
0711      *
0712      * We handle this step in bxt_set_cdclk().
0713      */
0714 
0715     /* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */
0716     intel_uncore_rmw(&i915->uncore, enable_reg, PLL_ENABLE, 0);
0717 
0718     /*
0719      * 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0".
0720      * This will allow the PLL to stop running.
0721      */
0722     intel_uncore_rmw(&i915->uncore, SNPS_PHY_MPLLB_DIV(phy),
0723              SNPS_PHY_MPLLB_FORCE_EN, 0);
0724 
0725     /*
0726      * 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment
0727      * (dp_txX_ack) that the new transmitter setting request is completed.
0728      */
0729     if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 5))
0730         drm_err(&i915->drm, "Port %c PLL not locked\n", phy_name(phy));
0731 
0732     /*
0733      * 6. If the frequency will result in a change to the voltage
0734      * requirement, follow the Display Voltage Frequency Switching -
0735      * Sequence After Frequency Change.
0736      *
0737      * We handle this step in bxt_set_cdclk().
0738      */
0739 }
0740 
0741 int intel_mpllb_calc_port_clock(struct intel_encoder *encoder,
0742                 const struct intel_mpllb_state *pll_state)
0743 {
0744     unsigned int frac_quot = 0, frac_rem = 0, frac_den = 1;
0745     unsigned int multiplier, tx_clk_div, refclk;
0746     bool frac_en;
0747 
0748     if (0)
0749         refclk = 38400;
0750     else
0751         refclk = 100000;
0752 
0753     refclk >>= REG_FIELD_GET(SNPS_PHY_MPLLB_REF_CLK_DIV, pll_state->mpllb_div2) - 1;
0754 
0755     frac_en = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_EN, pll_state->mpllb_fracn1);
0756 
0757     if (frac_en) {
0758         frac_quot = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_QUOT, pll_state->mpllb_fracn2);
0759         frac_rem = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_REM, pll_state->mpllb_fracn2);
0760         frac_den = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_DEN, pll_state->mpllb_fracn1);
0761     }
0762 
0763     multiplier = REG_FIELD_GET(SNPS_PHY_MPLLB_MULTIPLIER, pll_state->mpllb_div2) / 2 + 16;
0764 
0765     tx_clk_div = REG_FIELD_GET(SNPS_PHY_MPLLB_TX_CLK_DIV, pll_state->mpllb_div);
0766 
0767     return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, (multiplier << 16) + frac_quot) +
0768                      DIV_ROUND_CLOSEST(refclk * frac_rem, frac_den),
0769                      10 << (tx_clk_div + 16));
0770 }
0771 
0772 void intel_mpllb_readout_hw_state(struct intel_encoder *encoder,
0773                   struct intel_mpllb_state *pll_state)
0774 {
0775     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0776     enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
0777 
0778     pll_state->mpllb_cp = intel_de_read(dev_priv, SNPS_PHY_MPLLB_CP(phy));
0779     pll_state->mpllb_div = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV(phy));
0780     pll_state->mpllb_div2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV2(phy));
0781     pll_state->mpllb_sscen = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy));
0782     pll_state->mpllb_sscstep = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy));
0783     pll_state->mpllb_fracn1 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy));
0784     pll_state->mpllb_fracn2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy));
0785 
0786     /*
0787      * REF_CONTROL is under firmware control and never programmed by the
0788      * driver; we read it only for sanity checking purposes.  The bspec
0789      * only tells us the expected value for one field in this register,
0790      * so we'll only read out those specific bits here.
0791      */
0792     pll_state->ref_control = intel_de_read(dev_priv, SNPS_PHY_REF_CONTROL(phy)) &
0793         SNPS_PHY_REF_CONTROL_REF_RANGE;
0794 
0795     /*
0796      * MPLLB_DIV is programmed twice, once with the software-computed
0797      * state, then again with the MPLLB_FORCE_EN bit added.  Drop that
0798      * extra bit during readout so that we return the actual expected
0799      * software state.
0800      */
0801     pll_state->mpllb_div &= ~SNPS_PHY_MPLLB_FORCE_EN;
0802 }
0803 
0804 int intel_snps_phy_check_hdmi_link_rate(int clock)
0805 {
0806     const struct intel_mpllb_state * const *tables = dg2_hdmi_tables;
0807     int i;
0808 
0809     for (i = 0; tables[i]; i++) {
0810         if (clock == tables[i]->clock)
0811             return MODE_OK;
0812     }
0813 
0814     return MODE_CLOCK_RANGE;
0815 }
0816 
0817 void intel_mpllb_state_verify(struct intel_atomic_state *state,
0818                   struct intel_crtc_state *new_crtc_state)
0819 {
0820     struct drm_i915_private *i915 = to_i915(state->base.dev);
0821     struct intel_mpllb_state mpllb_hw_state = { 0 };
0822     struct intel_mpllb_state *mpllb_sw_state = &new_crtc_state->mpllb_state;
0823     struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
0824     struct intel_encoder *encoder;
0825 
0826     if (!IS_DG2(i915))
0827         return;
0828 
0829     if (!new_crtc_state->hw.active)
0830         return;
0831 
0832     encoder = intel_get_crtc_new_encoder(state, new_crtc_state);
0833     intel_mpllb_readout_hw_state(encoder, &mpllb_hw_state);
0834 
0835 #define MPLLB_CHECK(__name)                     \
0836     I915_STATE_WARN(mpllb_sw_state->__name != mpllb_hw_state.__name,    \
0837             "[CRTC:%d:%s] mismatch in MPLLB: %s (expected 0x%08x, found 0x%08x)", \
0838             crtc->base.base.id, crtc->base.name,        \
0839             __stringify(__name),                \
0840             mpllb_sw_state->__name, mpllb_hw_state.__name)
0841 
0842     MPLLB_CHECK(mpllb_cp);
0843     MPLLB_CHECK(mpllb_div);
0844     MPLLB_CHECK(mpllb_div2);
0845     MPLLB_CHECK(mpllb_fracn1);
0846     MPLLB_CHECK(mpllb_fracn2);
0847     MPLLB_CHECK(mpllb_sscen);
0848     MPLLB_CHECK(mpllb_sscstep);
0849 
0850     /*
0851      * ref_control is handled by the hardware/firemware and never
0852      * programmed by the software, but the proper values are supplied
0853      * in the bspec for verification purposes.
0854      */
0855     MPLLB_CHECK(ref_control);
0856 
0857 #undef MPLLB_CHECK
0858 }