Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright © 2013 Intel Corporation
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0021  * DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors:
0024  *  Shobhit Kumar <shobhit.kumar@intel.com>
0025  *  Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
0026  */
0027 
0028 #include <linux/kernel.h>
0029 #include <linux/string_helpers.h>
0030 
0031 #include "i915_drv.h"
0032 #include "intel_de.h"
0033 #include "intel_display_types.h"
0034 #include "intel_dsi.h"
0035 #include "vlv_dsi_pll.h"
0036 #include "vlv_dsi_pll_regs.h"
0037 #include "vlv_sideband.h"
0038 
0039 static const u16 lfsr_converts[] = {
0040     426, 469, 234, 373, 442, 221, 110, 311, 411,        /* 62 - 70 */
0041     461, 486, 243, 377, 188, 350, 175, 343, 427, 213,   /* 71 - 80 */
0042     106, 53, 282, 397, 454, 227, 113, 56, 284, 142,     /* 81 - 90 */
0043     71, 35, 273, 136, 324, 418, 465, 488, 500, 506      /* 91 - 100 */
0044 };
0045 
0046 /* Get DSI clock from pixel clock */
0047 static u32 dsi_clk_from_pclk(u32 pclk, enum mipi_dsi_pixel_format fmt,
0048                  int lane_count)
0049 {
0050     u32 dsi_clk_khz;
0051     u32 bpp = mipi_dsi_pixel_format_to_bpp(fmt);
0052 
0053     /* DSI data rate = pixel clock * bits per pixel / lane count
0054        pixel clock is converted from KHz to Hz */
0055     dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, lane_count);
0056 
0057     return dsi_clk_khz;
0058 }
0059 
0060 static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
0061             struct intel_crtc_state *config,
0062             int target_dsi_clk)
0063 {
0064     unsigned int m_min, m_max, p_min = 2, p_max = 6;
0065     unsigned int m, n, p;
0066     unsigned int calc_m, calc_p;
0067     int delta, ref_clk;
0068 
0069     /* target_dsi_clk is expected in kHz */
0070     if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) {
0071         drm_err(&dev_priv->drm, "DSI CLK Out of Range\n");
0072         return -ECHRNG;
0073     }
0074 
0075     if (IS_CHERRYVIEW(dev_priv)) {
0076         ref_clk = 100000;
0077         n = 4;
0078         m_min = 70;
0079         m_max = 96;
0080     } else {
0081         ref_clk = 25000;
0082         n = 1;
0083         m_min = 62;
0084         m_max = 92;
0085     }
0086 
0087     calc_p = p_min;
0088     calc_m = m_min;
0089     delta = abs(target_dsi_clk - (m_min * ref_clk) / (p_min * n));
0090 
0091     for (m = m_min; m <= m_max && delta; m++) {
0092         for (p = p_min; p <= p_max && delta; p++) {
0093             /*
0094              * Find the optimal m and p divisors with minimal delta
0095              * +/- the required clock
0096              */
0097             int calc_dsi_clk = (m * ref_clk) / (p * n);
0098             int d = abs(target_dsi_clk - calc_dsi_clk);
0099             if (d < delta) {
0100                 delta = d;
0101                 calc_m = m;
0102                 calc_p = p;
0103             }
0104         }
0105     }
0106 
0107     /* register has log2(N1), this works fine for powers of two */
0108     config->dsi_pll.ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
0109     config->dsi_pll.div =
0110         (ffs(n) - 1) << DSI_PLL_N1_DIV_SHIFT |
0111         (u32)lfsr_converts[calc_m - 62] << DSI_PLL_M1_DIV_SHIFT;
0112 
0113     return 0;
0114 }
0115 
0116 /*
0117  * XXX: The muxing and gating is hard coded for now. Need to add support for
0118  * sharing PLLs with two DSI outputs.
0119  */
0120 int vlv_dsi_pll_compute(struct intel_encoder *encoder,
0121             struct intel_crtc_state *config)
0122 {
0123     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0124     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
0125     int ret;
0126     u32 dsi_clk;
0127 
0128     dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
0129                     intel_dsi->lane_count);
0130 
0131     ret = dsi_calc_mnp(dev_priv, config, dsi_clk);
0132     if (ret) {
0133         drm_dbg_kms(&dev_priv->drm, "dsi_calc_mnp failed\n");
0134         return ret;
0135     }
0136 
0137     if (intel_dsi->ports & (1 << PORT_A))
0138         config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
0139 
0140     if (intel_dsi->ports & (1 << PORT_C))
0141         config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
0142 
0143     config->dsi_pll.ctrl |= DSI_PLL_VCO_EN;
0144 
0145     drm_dbg_kms(&dev_priv->drm, "dsi pll div %08x, ctrl %08x\n",
0146             config->dsi_pll.div, config->dsi_pll.ctrl);
0147 
0148     return 0;
0149 }
0150 
0151 void vlv_dsi_pll_enable(struct intel_encoder *encoder,
0152             const struct intel_crtc_state *config)
0153 {
0154     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0155 
0156     drm_dbg_kms(&dev_priv->drm, "\n");
0157 
0158     vlv_cck_get(dev_priv);
0159 
0160     vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
0161     vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div);
0162     vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL,
0163               config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN);
0164 
0165     /* wait at least 0.5 us after ungating before enabling VCO,
0166      * allow hrtimer subsystem optimization by relaxing timing
0167      */
0168     usleep_range(10, 50);
0169 
0170     vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl);
0171 
0172     if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
0173                         DSI_PLL_LOCK, 20)) {
0174 
0175         vlv_cck_put(dev_priv);
0176         drm_err(&dev_priv->drm, "DSI PLL lock failed\n");
0177         return;
0178     }
0179     vlv_cck_put(dev_priv);
0180 
0181     drm_dbg_kms(&dev_priv->drm, "DSI PLL locked\n");
0182 }
0183 
0184 void vlv_dsi_pll_disable(struct intel_encoder *encoder)
0185 {
0186     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0187     u32 tmp;
0188 
0189     drm_dbg_kms(&dev_priv->drm, "\n");
0190 
0191     vlv_cck_get(dev_priv);
0192 
0193     tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
0194     tmp &= ~DSI_PLL_VCO_EN;
0195     tmp |= DSI_PLL_LDO_GATE;
0196     vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
0197 
0198     vlv_cck_put(dev_priv);
0199 }
0200 
0201 bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
0202 {
0203     bool enabled;
0204     u32 val;
0205     u32 mask;
0206 
0207     mask = BXT_DSI_PLL_DO_ENABLE | BXT_DSI_PLL_LOCKED;
0208     val = intel_de_read(dev_priv, BXT_DSI_PLL_ENABLE);
0209     enabled = (val & mask) == mask;
0210 
0211     if (!enabled)
0212         return false;
0213 
0214     /*
0215      * Dividers must be programmed with valid values. As per BSEPC, for
0216      * GEMINLAKE only PORT A divider values are checked while for BXT
0217      * both divider values are validated. Check this here for
0218      * paranoia, since BIOS is known to misconfigure PLLs in this way at
0219      * times, and since accessing DSI registers with invalid dividers
0220      * causes a system hang.
0221      */
0222     val = intel_de_read(dev_priv, BXT_DSI_PLL_CTL);
0223     if (IS_GEMINILAKE(dev_priv)) {
0224         if (!(val & BXT_DSIA_16X_MASK)) {
0225             drm_dbg(&dev_priv->drm,
0226                 "Invalid PLL divider (%08x)\n", val);
0227             enabled = false;
0228         }
0229     } else {
0230         if (!(val & BXT_DSIA_16X_MASK) || !(val & BXT_DSIC_16X_MASK)) {
0231             drm_dbg(&dev_priv->drm,
0232                 "Invalid PLL divider (%08x)\n", val);
0233             enabled = false;
0234         }
0235     }
0236 
0237     return enabled;
0238 }
0239 
0240 void bxt_dsi_pll_disable(struct intel_encoder *encoder)
0241 {
0242     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0243     u32 val;
0244 
0245     drm_dbg_kms(&dev_priv->drm, "\n");
0246 
0247     val = intel_de_read(dev_priv, BXT_DSI_PLL_ENABLE);
0248     val &= ~BXT_DSI_PLL_DO_ENABLE;
0249     intel_de_write(dev_priv, BXT_DSI_PLL_ENABLE, val);
0250 
0251     /*
0252      * PLL lock should deassert within 200us.
0253      * Wait up to 1ms before timing out.
0254      */
0255     if (intel_de_wait_for_clear(dev_priv, BXT_DSI_PLL_ENABLE,
0256                     BXT_DSI_PLL_LOCKED, 1))
0257         drm_err(&dev_priv->drm,
0258             "Timeout waiting for PLL lock deassertion\n");
0259 }
0260 
0261 u32 vlv_dsi_get_pclk(struct intel_encoder *encoder,
0262              struct intel_crtc_state *config)
0263 {
0264     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0265     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
0266     int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
0267     u32 dsi_clock, pclk;
0268     u32 pll_ctl, pll_div;
0269     u32 m = 0, p = 0, n;
0270     int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000;
0271     int i;
0272 
0273     drm_dbg_kms(&dev_priv->drm, "\n");
0274 
0275     vlv_cck_get(dev_priv);
0276     pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
0277     pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
0278     vlv_cck_put(dev_priv);
0279 
0280     config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
0281     config->dsi_pll.div = pll_div;
0282 
0283     /* mask out other bits and extract the P1 divisor */
0284     pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
0285     pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
0286 
0287     /* N1 divisor */
0288     n = (pll_div & DSI_PLL_N1_DIV_MASK) >> DSI_PLL_N1_DIV_SHIFT;
0289     n = 1 << n; /* register has log2(N1) */
0290 
0291     /* mask out the other bits and extract the M1 divisor */
0292     pll_div &= DSI_PLL_M1_DIV_MASK;
0293     pll_div = pll_div >> DSI_PLL_M1_DIV_SHIFT;
0294 
0295     while (pll_ctl) {
0296         pll_ctl = pll_ctl >> 1;
0297         p++;
0298     }
0299     p--;
0300 
0301     if (!p) {
0302         drm_err(&dev_priv->drm, "wrong P1 divisor\n");
0303         return 0;
0304     }
0305 
0306     for (i = 0; i < ARRAY_SIZE(lfsr_converts); i++) {
0307         if (lfsr_converts[i] == pll_div)
0308             break;
0309     }
0310 
0311     if (i == ARRAY_SIZE(lfsr_converts)) {
0312         drm_err(&dev_priv->drm, "wrong m_seed programmed\n");
0313         return 0;
0314     }
0315 
0316     m = i + 62;
0317 
0318     dsi_clock = (m * refclk) / (p * n);
0319 
0320     pclk = DIV_ROUND_CLOSEST(dsi_clock * intel_dsi->lane_count, bpp);
0321 
0322     return pclk;
0323 }
0324 
0325 u32 bxt_dsi_get_pclk(struct intel_encoder *encoder,
0326              struct intel_crtc_state *config)
0327 {
0328     u32 pclk;
0329     u32 dsi_clk;
0330     u32 dsi_ratio;
0331     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
0332     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0333     int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
0334 
0335     config->dsi_pll.ctrl = intel_de_read(dev_priv, BXT_DSI_PLL_CTL);
0336 
0337     dsi_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
0338 
0339     dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
0340 
0341     pclk = DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, bpp);
0342 
0343     drm_dbg(&dev_priv->drm, "Calculated pclk=%u\n", pclk);
0344     return pclk;
0345 }
0346 
0347 void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
0348 {
0349     u32 temp;
0350     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0351     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
0352 
0353     temp = intel_de_read(dev_priv, MIPI_CTRL(port));
0354     temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
0355     intel_de_write(dev_priv, MIPI_CTRL(port),
0356                temp | intel_dsi->escape_clk_div << ESCAPE_CLOCK_DIVIDER_SHIFT);
0357 }
0358 
0359 static void glk_dsi_program_esc_clock(struct drm_device *dev,
0360                    const struct intel_crtc_state *config)
0361 {
0362     struct drm_i915_private *dev_priv = to_i915(dev);
0363     u32 dsi_rate = 0;
0364     u32 pll_ratio = 0;
0365     u32 ddr_clk = 0;
0366     u32 div1_value = 0;
0367     u32 div2_value = 0;
0368     u32 txesc1_div = 0;
0369     u32 txesc2_div = 0;
0370 
0371     pll_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
0372 
0373     dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
0374 
0375     ddr_clk = dsi_rate / 2;
0376 
0377     /* Variable divider value */
0378     div1_value = DIV_ROUND_CLOSEST(ddr_clk, 20000);
0379 
0380     /* Calculate TXESC1 divider */
0381     if (div1_value <= 10)
0382         txesc1_div = div1_value;
0383     else if ((div1_value > 10) && (div1_value <= 20))
0384         txesc1_div = DIV_ROUND_UP(div1_value, 2);
0385     else if ((div1_value > 20) && (div1_value <= 30))
0386         txesc1_div = DIV_ROUND_UP(div1_value, 4);
0387     else if ((div1_value > 30) && (div1_value <= 40))
0388         txesc1_div = DIV_ROUND_UP(div1_value, 6);
0389     else if ((div1_value > 40) && (div1_value <= 50))
0390         txesc1_div = DIV_ROUND_UP(div1_value, 8);
0391     else
0392         txesc1_div = 10;
0393 
0394     /* Calculate TXESC2 divider */
0395     div2_value = DIV_ROUND_UP(div1_value, txesc1_div);
0396 
0397     txesc2_div = min_t(u32, div2_value, 10);
0398 
0399     intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV1,
0400                (1 << (txesc1_div - 1)) & GLK_TX_ESC_CLK_DIV1_MASK);
0401     intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV2,
0402                (1 << (txesc2_div - 1)) & GLK_TX_ESC_CLK_DIV2_MASK);
0403 }
0404 
0405 /* Program BXT Mipi clocks and dividers */
0406 static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port,
0407                    const struct intel_crtc_state *config)
0408 {
0409     struct drm_i915_private *dev_priv = to_i915(dev);
0410     u32 tmp;
0411     u32 dsi_rate = 0;
0412     u32 pll_ratio = 0;
0413     u32 rx_div;
0414     u32 tx_div;
0415     u32 rx_div_upper;
0416     u32 rx_div_lower;
0417     u32 mipi_8by3_divider;
0418 
0419     /* Clear old configurations */
0420     tmp = intel_de_read(dev_priv, BXT_MIPI_CLOCK_CTL);
0421     tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
0422     tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
0423     tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
0424     tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
0425 
0426     /* Get the current DSI rate(actual) */
0427     pll_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
0428     dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
0429 
0430     /*
0431      * tx clock should be <= 20MHz and the div value must be
0432      * subtracted by 1 as per bspec
0433      */
0434     tx_div = DIV_ROUND_UP(dsi_rate, 20000) - 1;
0435     /*
0436      * rx clock should be <= 150MHz and the div value must be
0437      * subtracted by 1 as per bspec
0438      */
0439     rx_div = DIV_ROUND_UP(dsi_rate, 150000) - 1;
0440 
0441     /*
0442      * rx divider value needs to be updated in the
0443      * two differnt bit fields in the register hence splitting the
0444      * rx divider value accordingly
0445      */
0446     rx_div_lower = rx_div & RX_DIVIDER_BIT_1_2;
0447     rx_div_upper = (rx_div & RX_DIVIDER_BIT_3_4) >> 2;
0448 
0449     mipi_8by3_divider = 0x2;
0450 
0451     tmp |= BXT_MIPI_8X_BY3_DIVIDER(port, mipi_8by3_divider);
0452     tmp |= BXT_MIPI_TX_ESCLK_DIVIDER(port, tx_div);
0453     tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower);
0454     tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper);
0455 
0456     intel_de_write(dev_priv, BXT_MIPI_CLOCK_CTL, tmp);
0457 }
0458 
0459 int bxt_dsi_pll_compute(struct intel_encoder *encoder,
0460             struct intel_crtc_state *config)
0461 {
0462     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0463     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
0464     u8 dsi_ratio, dsi_ratio_min, dsi_ratio_max;
0465     u32 dsi_clk;
0466 
0467     dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
0468                     intel_dsi->lane_count);
0469 
0470     /*
0471      * From clock diagram, to get PLL ratio divider, divide double of DSI
0472      * link rate (i.e., 2*8x=16x frequency value) by ref clock. Make sure to
0473      * round 'up' the result
0474      */
0475     dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ);
0476 
0477     if (IS_BROXTON(dev_priv)) {
0478         dsi_ratio_min = BXT_DSI_PLL_RATIO_MIN;
0479         dsi_ratio_max = BXT_DSI_PLL_RATIO_MAX;
0480     } else {
0481         dsi_ratio_min = GLK_DSI_PLL_RATIO_MIN;
0482         dsi_ratio_max = GLK_DSI_PLL_RATIO_MAX;
0483     }
0484 
0485     if (dsi_ratio < dsi_ratio_min || dsi_ratio > dsi_ratio_max) {
0486         drm_err(&dev_priv->drm,
0487             "Can't get a suitable ratio from DSI PLL ratios\n");
0488         return -ECHRNG;
0489     } else
0490         drm_dbg_kms(&dev_priv->drm, "DSI PLL calculation is Done!!\n");
0491 
0492     /*
0493      * Program DSI ratio and Select MIPIC and MIPIA PLL output as 8x
0494      * Spec says both have to be programmed, even if one is not getting
0495      * used. Configure MIPI_CLOCK_CTL dividers in modeset
0496      */
0497     config->dsi_pll.ctrl = dsi_ratio | BXT_DSIA_16X_BY2 | BXT_DSIC_16X_BY2;
0498 
0499     /* As per recommendation from hardware team,
0500      * Prog PVD ratio =1 if dsi ratio <= 50
0501      */
0502     if (IS_BROXTON(dev_priv) && dsi_ratio <= 50)
0503         config->dsi_pll.ctrl |= BXT_DSI_PLL_PVD_RATIO_1;
0504 
0505     return 0;
0506 }
0507 
0508 void bxt_dsi_pll_enable(struct intel_encoder *encoder,
0509             const struct intel_crtc_state *config)
0510 {
0511     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0512     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
0513     enum port port;
0514     u32 val;
0515 
0516     drm_dbg_kms(&dev_priv->drm, "\n");
0517 
0518     /* Configure PLL vales */
0519     intel_de_write(dev_priv, BXT_DSI_PLL_CTL, config->dsi_pll.ctrl);
0520     intel_de_posting_read(dev_priv, BXT_DSI_PLL_CTL);
0521 
0522     /* Program TX, RX, Dphy clocks */
0523     if (IS_BROXTON(dev_priv)) {
0524         for_each_dsi_port(port, intel_dsi->ports)
0525             bxt_dsi_program_clocks(encoder->base.dev, port, config);
0526     } else {
0527         glk_dsi_program_esc_clock(encoder->base.dev, config);
0528     }
0529 
0530     /* Enable DSI PLL */
0531     val = intel_de_read(dev_priv, BXT_DSI_PLL_ENABLE);
0532     val |= BXT_DSI_PLL_DO_ENABLE;
0533     intel_de_write(dev_priv, BXT_DSI_PLL_ENABLE, val);
0534 
0535     /* Timeout and fail if PLL not locked */
0536     if (intel_de_wait_for_set(dev_priv, BXT_DSI_PLL_ENABLE,
0537                   BXT_DSI_PLL_LOCKED, 1)) {
0538         drm_err(&dev_priv->drm,
0539             "Timed out waiting for DSI PLL to lock\n");
0540         return;
0541     }
0542 
0543     drm_dbg_kms(&dev_priv->drm, "DSI PLL locked\n");
0544 }
0545 
0546 void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
0547 {
0548     u32 tmp;
0549     struct drm_device *dev = encoder->base.dev;
0550     struct drm_i915_private *dev_priv = to_i915(dev);
0551 
0552     /* Clear old configurations */
0553     if (IS_BROXTON(dev_priv)) {
0554         tmp = intel_de_read(dev_priv, BXT_MIPI_CLOCK_CTL);
0555         tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
0556         tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
0557         tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
0558         tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
0559         intel_de_write(dev_priv, BXT_MIPI_CLOCK_CTL, tmp);
0560     } else {
0561         tmp = intel_de_read(dev_priv, MIPIO_TXESC_CLK_DIV1);
0562         tmp &= ~GLK_TX_ESC_CLK_DIV1_MASK;
0563         intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV1, tmp);
0564 
0565         tmp = intel_de_read(dev_priv, MIPIO_TXESC_CLK_DIV2);
0566         tmp &= ~GLK_TX_ESC_CLK_DIV2_MASK;
0567         intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV2, tmp);
0568     }
0569     intel_de_write(dev_priv, MIPI_EOT_DISABLE(port), CLOCKSTOP);
0570 }
0571 
0572 static void assert_dsi_pll(struct drm_i915_private *i915, bool state)
0573 {
0574     bool cur_state;
0575 
0576     vlv_cck_get(i915);
0577     cur_state = vlv_cck_read(i915, CCK_REG_DSI_PLL_CONTROL) & DSI_PLL_VCO_EN;
0578     vlv_cck_put(i915);
0579 
0580     I915_STATE_WARN(cur_state != state,
0581             "DSI PLL state assertion failure (expected %s, current %s)\n",
0582             str_on_off(state), str_on_off(cur_state));
0583 }
0584 
0585 void assert_dsi_pll_enabled(struct drm_i915_private *i915)
0586 {
0587     assert_dsi_pll(i915, true);
0588 }
0589 
0590 void assert_dsi_pll_disabled(struct drm_i915_private *i915)
0591 {
0592     assert_dsi_pll(i915, false);
0593 }