drm/i915: Hook up pfit for DSI
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_dsi_pll.c
index fbd2b51810ca0f2223a0129a3beac9bbb1433c61..1765e6e18f2c6e8aa2dfb2ac4d8f08fb9983dc40 100644 (file)
 #include "i915_drv.h"
 #include "intel_dsi.h"
 
-#define DSI_HSS_PACKET_SIZE            4
-#define DSI_HSE_PACKET_SIZE            4
-#define DSI_HSA_PACKET_EXTRA_SIZE      6
-#define DSI_HBP_PACKET_EXTRA_SIZE      6
-#define DSI_HACTIVE_PACKET_EXTRA_SIZE  6
-#define DSI_HFP_PACKET_EXTRA_SIZE      6
-#define DSI_EOTP_PACKET_SIZE           4
-
-static int dsi_pixel_format_bpp(int pixel_format)
-{
-       int bpp;
-
-       switch (pixel_format) {
-       default:
-       case VID_MODE_FORMAT_RGB888:
-       case VID_MODE_FORMAT_RGB666_LOOSE:
-               bpp = 24;
-               break;
-       case VID_MODE_FORMAT_RGB666:
-               bpp = 18;
-               break;
-       case VID_MODE_FORMAT_RGB565:
-               bpp = 16;
-               break;
-       }
-
-       return bpp;
-}
-
-struct dsi_mnp {
-       u32 dsi_pll_ctrl;
-       u32 dsi_pll_div;
-};
-
-static const u32 lfsr_converts[] = {
+static const u16 lfsr_converts[] = {
        426, 469, 234, 373, 442, 221, 110, 311, 411,            /* 62 - 70 */
        461, 486, 243, 377, 188, 350, 175, 343, 427, 213,       /* 71 - 80 */
        106, 53, 282, 397, 454, 227, 113, 56, 284, 142,         /* 81 - 90 */
        71, 35, 273, 136, 324, 418, 465, 488, 500, 506          /* 91 - 100 */
 };
 
-#ifdef DSI_CLK_FROM_RR
-
-static u32 dsi_rr_formula(const struct drm_display_mode *mode,
-                         int pixel_format, int video_mode_format,
-                         int lane_count, bool eotp)
-{
-       u32 bpp;
-       u32 hactive, vactive, hfp, hsync, hbp, vfp, vsync, vbp;
-       u32 hsync_bytes, hbp_bytes, hactive_bytes, hfp_bytes;
-       u32 bytes_per_line, bytes_per_frame;
-       u32 num_frames;
-       u32 bytes_per_x_frames, bytes_per_x_frames_x_lanes;
-       u32 dsi_bit_clock_hz;
-       u32 dsi_clk;
-
-       bpp = dsi_pixel_format_bpp(pixel_format);
-
-       hactive = mode->hdisplay;
-       vactive = mode->vdisplay;
-       hfp = mode->hsync_start - mode->hdisplay;
-       hsync = mode->hsync_end - mode->hsync_start;
-       hbp = mode->htotal - mode->hsync_end;
-
-       vfp = mode->vsync_start - mode->vdisplay;
-       vsync = mode->vsync_end - mode->vsync_start;
-       vbp = mode->vtotal - mode->vsync_end;
-
-       hsync_bytes = DIV_ROUND_UP(hsync * bpp, 8);
-       hbp_bytes = DIV_ROUND_UP(hbp * bpp, 8);
-       hactive_bytes = DIV_ROUND_UP(hactive * bpp, 8);
-       hfp_bytes = DIV_ROUND_UP(hfp * bpp, 8);
-
-       bytes_per_line = DSI_HSS_PACKET_SIZE + hsync_bytes +
-               DSI_HSA_PACKET_EXTRA_SIZE + DSI_HSE_PACKET_SIZE +
-               hbp_bytes + DSI_HBP_PACKET_EXTRA_SIZE +
-               hactive_bytes + DSI_HACTIVE_PACKET_EXTRA_SIZE +
-               hfp_bytes + DSI_HFP_PACKET_EXTRA_SIZE;
-
-       /*
-        * XXX: Need to accurately calculate LP to HS transition timeout and add
-        * it to bytes_per_line/bytes_per_frame.
-        */
-
-       if (eotp && video_mode_format == VIDEO_MODE_BURST)
-               bytes_per_line += DSI_EOTP_PACKET_SIZE;
-
-       bytes_per_frame = vsync * bytes_per_line + vbp * bytes_per_line +
-               vactive * bytes_per_line + vfp * bytes_per_line;
-
-       if (eotp &&
-           (video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE ||
-            video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS))
-               bytes_per_frame += DSI_EOTP_PACKET_SIZE;
-
-       num_frames = drm_mode_vrefresh(mode);
-       bytes_per_x_frames = num_frames * bytes_per_frame;
-
-       bytes_per_x_frames_x_lanes = bytes_per_x_frames / lane_count;
-
-       /* the dsi clock is divided by 2 in the hardware to get dsi ddr clock */
-       dsi_bit_clock_hz = bytes_per_x_frames_x_lanes * 8;
-       dsi_clk = dsi_bit_clock_hz / 1000;
-
-       if (eotp && video_mode_format == VIDEO_MODE_BURST)
-               dsi_clk *= 2;
-
-       return dsi_clk;
-}
-
-#else
-
 /* Get DSI clock from pixel clock */
-static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
+static u32 dsi_clk_from_pclk(u32 pclk, enum mipi_dsi_pixel_format fmt,
+                            int lane_count)
 {
        u32 dsi_clk_khz;
-       u32 bpp = dsi_pixel_format_bpp(pixel_format);
+       u32 bpp = mipi_dsi_pixel_format_to_bpp(fmt);
 
        /* DSI data rate = pixel clock * bits per pixel / lane count
           pixel clock is converted from KHz to Hz */
@@ -155,10 +51,9 @@ static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
        return dsi_clk_khz;
 }
 
-#endif
-
 static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
-                       struct dsi_mnp *dsi_mnp, int target_dsi_clk)
+                       struct intel_crtc_state *config,
+                       int target_dsi_clk)
 {
        unsigned int calc_m = 0, calc_p = 0;
        unsigned int m_min, m_max, p_min = 2, p_max = 6;
@@ -204,8 +99,8 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
        /* register has log2(N1), this works fine for powers of two */
        n = ffs(n) - 1;
        m_seed = lfsr_converts[calc_m - 62];
-       dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
-       dsi_mnp->dsi_pll_div = n << DSI_PLL_N1_DIV_SHIFT |
+       config->dsi_pll.ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
+       config->dsi_pll.div = n << DSI_PLL_N1_DIV_SHIFT |
                m_seed << DSI_PLL_M1_DIV_SHIFT;
 
        return 0;
@@ -215,54 +110,55 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
  * XXX: The muxing and gating is hard coded for now. Need to add support for
  * sharing PLLs with two DSI outputs.
  */
-static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
+static int vlv_compute_dsi_pll(struct intel_encoder *encoder,
+                              struct intel_crtc_state *config)
 {
        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
        struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
        int ret;
-       struct dsi_mnp dsi_mnp;
        u32 dsi_clk;
 
        dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
                                    intel_dsi->lane_count);
 
-       ret = dsi_calc_mnp(dev_priv, &dsi_mnp, dsi_clk);
+       ret = dsi_calc_mnp(dev_priv, config, dsi_clk);
        if (ret) {
                DRM_DEBUG_KMS("dsi_calc_mnp failed\n");
-               return;
+               return ret;
        }
 
        if (intel_dsi->ports & (1 << PORT_A))
-               dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
+               config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
 
        if (intel_dsi->ports & (1 << PORT_C))
-               dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
+               config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
+
+       config->dsi_pll.ctrl |= DSI_PLL_VCO_EN;
 
        DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
-                     dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl);
+                     config->dsi_pll.div, config->dsi_pll.ctrl);
 
-       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
-       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_mnp.dsi_pll_div);
-       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl);
+       return 0;
 }
 
-static void vlv_enable_dsi_pll(struct intel_encoder *encoder)
+static void vlv_enable_dsi_pll(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *config)
 {
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-       u32 tmp;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
        DRM_DEBUG_KMS("\n");
 
        mutex_lock(&dev_priv->sb_lock);
 
-       vlv_configure_dsi_pll(encoder);
+       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
+       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div);
+       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL,
+                     config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN);
 
        /* wait at least 0.5 us after ungating before enabling VCO */
        usleep_range(1, 10);
 
-       tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
-       tmp |= DSI_PLL_VCO_EN;
-       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
+       vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl);
 
        if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
                                                DSI_PLL_LOCK, 20)) {
@@ -278,7 +174,7 @@ static void vlv_enable_dsi_pll(struct intel_encoder *encoder)
 
 static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
 {
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 tmp;
 
        DRM_DEBUG_KMS("\n");
@@ -293,9 +189,39 @@ static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
        mutex_unlock(&dev_priv->sb_lock);
 }
 
+static bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
+{
+       bool enabled;
+       u32 val;
+       u32 mask;
+
+       mask = BXT_DSI_PLL_DO_ENABLE | BXT_DSI_PLL_LOCKED;
+       val = I915_READ(BXT_DSI_PLL_ENABLE);
+       enabled = (val & mask) == mask;
+
+       if (!enabled)
+               return false;
+
+       /*
+        * Both dividers must be programmed with valid values even if only one
+        * of the PLL is used, see BSpec/Broxton Clocks. Check this here for
+        * paranoia, since BIOS is known to misconfigure PLLs in this way at
+        * times, and since accessing DSI registers with invalid dividers
+        * causes a system hang.
+        */
+       val = I915_READ(BXT_DSI_PLL_CTL);
+       if (!(val & BXT_DSIA_16X_MASK) || !(val & BXT_DSIC_16X_MASK)) {
+               DRM_DEBUG_DRIVER("PLL is enabled with invalid divider settings (%08x)\n",
+                                val);
+               enabled = false;
+       }
+
+       return enabled;
+}
+
 static void bxt_disable_dsi_pll(struct intel_encoder *encoder)
 {
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 val;
 
        DRM_DEBUG_KMS("\n");
@@ -313,23 +239,24 @@ static void bxt_disable_dsi_pll(struct intel_encoder *encoder)
                DRM_ERROR("Timeout waiting for PLL lock deassertion\n");
 }
 
-static void assert_bpp_mismatch(int pixel_format, int pipe_bpp)
+static void assert_bpp_mismatch(enum mipi_dsi_pixel_format fmt, int pipe_bpp)
 {
-       int bpp = dsi_pixel_format_bpp(pixel_format);
+       int bpp = mipi_dsi_pixel_format_to_bpp(fmt);
 
        WARN(bpp != pipe_bpp,
             "bpp match assertion failure (expected %d, current %d)\n",
             bpp, pipe_bpp);
 }
 
-u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
+static u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+                           struct intel_crtc_state *config)
 {
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
        u32 dsi_clock, pclk;
        u32 pll_ctl, pll_div;
        u32 m = 0, p = 0, n;
-       int refclk = 25000;
+       int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000;
        int i;
 
        DRM_DEBUG_KMS("\n");
@@ -339,6 +266,9 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
        pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
        mutex_unlock(&dev_priv->sb_lock);
 
+       config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
+       config->dsi_pll.div = pll_div;
+
        /* mask out other bits and extract the P1 divisor */
        pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
        pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
@@ -384,7 +314,8 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
        return pclk;
 }
 
-u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
+static u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+                           struct intel_crtc_state *config)
 {
        u32 pclk;
        u32 dsi_clk;
@@ -398,15 +329,9 @@ u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
                return 0;
        }
 
-       dsi_ratio = I915_READ(BXT_DSI_PLL_CTL) &
-                               BXT_DSI_PLL_RATIO_MASK;
+       config->dsi_pll.ctrl = I915_READ(BXT_DSI_PLL_CTL);
 
-       /* Invalid DSI ratio ? */
-       if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN ||
-                       dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
-               DRM_ERROR("Invalid DSI pll ratio(%u) programmed\n", dsi_ratio);
-               return 0;
-       }
+       dsi_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
 
        dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
 
@@ -419,6 +344,15 @@ u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
        return pclk;
 }
 
+u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+                      struct intel_crtc_state *config)
+{
+       if (IS_BROXTON(encoder->base.dev))
+               return bxt_dsi_get_pclk(encoder, pipe_bpp, config);
+       else
+               return vlv_dsi_get_pclk(encoder, pipe_bpp, config);
+}
+
 static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
 {
        u32 temp;
@@ -433,51 +367,72 @@ static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
 }
 
 /* Program BXT Mipi clocks and dividers */
-static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port)
+static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port,
+                                  const struct intel_crtc_state *config)
 {
-       u32 tmp;
-       u32 divider;
-       u32 dsi_rate;
-       u32 pll_ratio;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 tmp;
+       u32 dsi_rate = 0;
+       u32 pll_ratio = 0;
+       u32 rx_div;
+       u32 tx_div;
+       u32 rx_div_upper;
+       u32 rx_div_lower;
+       u32 mipi_8by3_divider;
 
        /* Clear old configurations */
        tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
        tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port));
-       tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
+       tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
 
        /* Get the current DSI rate(actual) */
-       pll_ratio = I915_READ(BXT_DSI_PLL_CTL) &
-                               BXT_DSI_PLL_RATIO_MASK;
+       pll_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
        dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
 
-       /* Max possible output of clock is 39.5 MHz, program value -1 */
-       divider = (dsi_rate / BXT_MAX_VAR_OUTPUT_KHZ) - 1;
-       tmp |= BXT_MIPI_ESCLK_VAR_DIV(port, divider);
+       /*
+        * tx clock should be <= 20MHz and the div value must be
+        * subtracted by 1 as per bspec
+        */
+       tx_div = DIV_ROUND_UP(dsi_rate, 20000) - 1;
+       /*
+        * rx clock should be <= 150MHz and the div value must be
+        * subtracted by 1 as per bspec
+        */
+       rx_div = DIV_ROUND_UP(dsi_rate, 150000) - 1;
 
        /*
-        * Tx escape clock must be as close to 20MHz possible, but should
-        * not exceed it. Hence select divide by 2
+        * rx divider value needs to be updated in the
+        * two differnt bit fields in the register hence splitting the
+        * rx divider value accordingly
         */
-       tmp |= BXT_MIPI_TX_ESCLK_8XDIV_BY2(port);
+       rx_div_lower = rx_div & RX_DIVIDER_BIT_1_2;
+       rx_div_upper = (rx_div & RX_DIVIDER_BIT_3_4) >> 2;
 
-       tmp |= BXT_MIPI_RX_ESCLK_8X_BY3(port);
+       /* As per bpsec program the 8/3X clock divider to the below value */
+       if (dev_priv->vbt.dsi.config->is_cmd_mode)
+               mipi_8by3_divider = 0x2;
+       else
+               mipi_8by3_divider = 0x3;
+
+       tmp |= BXT_MIPI_8X_BY3_DIVIDER(port, mipi_8by3_divider);
+       tmp |= BXT_MIPI_TX_ESCLK_DIVIDER(port, tx_div);
+       tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower);
+       tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper);
 
        I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
 }
 
-static bool bxt_configure_dsi_pll(struct intel_encoder *encoder)
+static int bxt_compute_dsi_pll(struct intel_encoder *encoder,
+                              struct intel_crtc_state *config)
 {
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
        struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
        u8 dsi_ratio;
        u32 dsi_clk;
-       u32 val;
 
        dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
-                       intel_dsi->lane_count);
+                                   intel_dsi->lane_count);
 
        /*
         * From clock diagram, to get PLL ratio divider, divide double of DSI
@@ -486,9 +441,9 @@ static bool bxt_configure_dsi_pll(struct intel_encoder *encoder)
         */
        dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ);
        if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN ||
-                       dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
+           dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
                DRM_ERROR("Cant get a suitable ratio from DSI PLL ratios\n");
-               return false;
+               return -ECHRNG;
        }
 
        /*
@@ -496,27 +451,19 @@ static bool bxt_configure_dsi_pll(struct intel_encoder *encoder)
         * Spec says both have to be programmed, even if one is not getting
         * used. Configure MIPI_CLOCK_CTL dividers in modeset
         */
-       val = I915_READ(BXT_DSI_PLL_CTL);
-       val &= ~BXT_DSI_PLL_PVD_RATIO_MASK;
-       val &= ~BXT_DSI_FREQ_SEL_MASK;
-       val &= ~BXT_DSI_PLL_RATIO_MASK;
-       val |= (dsi_ratio | BXT_DSIA_16X_BY2 | BXT_DSIC_16X_BY2);
+       config->dsi_pll.ctrl = dsi_ratio | BXT_DSIA_16X_BY2 | BXT_DSIC_16X_BY2;
 
        /* As per recommendation from hardware team,
         * Prog PVD ratio =1 if dsi ratio <= 50
         */
-       if (dsi_ratio <= 50) {
-               val &= ~BXT_DSI_PLL_PVD_RATIO_MASK;
-               val |= BXT_DSI_PLL_PVD_RATIO_1;
-       }
-
-       I915_WRITE(BXT_DSI_PLL_CTL, val);
-       POSTING_READ(BXT_DSI_PLL_CTL);
+       if (dsi_ratio <= 50)
+               config->dsi_pll.ctrl |= BXT_DSI_PLL_PVD_RATIO_1;
 
-       return true;
+       return 0;
 }
 
-static void bxt_enable_dsi_pll(struct intel_encoder *encoder)
+static void bxt_enable_dsi_pll(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *config)
 {
        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
        struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
@@ -525,23 +472,13 @@ static void bxt_enable_dsi_pll(struct intel_encoder *encoder)
 
        DRM_DEBUG_KMS("\n");
 
-       val = I915_READ(BXT_DSI_PLL_ENABLE);
-
-       if (val & BXT_DSI_PLL_DO_ENABLE) {
-               WARN(1, "DSI PLL already enabled. Disabling it.\n");
-               val &= ~BXT_DSI_PLL_DO_ENABLE;
-               I915_WRITE(BXT_DSI_PLL_ENABLE, val);
-       }
-
        /* Configure PLL vales */
-       if (!bxt_configure_dsi_pll(encoder)) {
-               DRM_ERROR("Configure DSI PLL failed, abort PLL enable\n");
-               return;
-       }
+       I915_WRITE(BXT_DSI_PLL_CTL, config->dsi_pll.ctrl);
+       POSTING_READ(BXT_DSI_PLL_CTL);
 
        /* Program TX, RX, Dphy clocks */
        for_each_dsi_port(port, intel_dsi->ports)
-               bxt_dsi_program_clocks(encoder->base.dev, port);
+               bxt_dsi_program_clocks(encoder->base.dev, port, config);
 
        /* Enable DSI PLL */
        val = I915_READ(BXT_DSI_PLL_ENABLE);
@@ -557,14 +494,38 @@ static void bxt_enable_dsi_pll(struct intel_encoder *encoder)
        DRM_DEBUG_KMS("DSI PLL locked\n");
 }
 
-void intel_enable_dsi_pll(struct intel_encoder *encoder)
+bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
+{
+       if (IS_BROXTON(dev_priv))
+               return bxt_dsi_pll_is_enabled(dev_priv);
+
+       MISSING_CASE(INTEL_DEVID(dev_priv));
+
+       return false;
+}
+
+int intel_compute_dsi_pll(struct intel_encoder *encoder,
+                         struct intel_crtc_state *config)
+{
+       struct drm_device *dev = encoder->base.dev;
+
+       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+               return vlv_compute_dsi_pll(encoder, config);
+       else if (IS_BROXTON(dev))
+               return bxt_compute_dsi_pll(encoder, config);
+
+       return -ENODEV;
+}
+
+void intel_enable_dsi_pll(struct intel_encoder *encoder,
+                         const struct intel_crtc_state *config)
 {
        struct drm_device *dev = encoder->base.dev;
 
        if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
-               vlv_enable_dsi_pll(encoder);
+               vlv_enable_dsi_pll(encoder, config);
        else if (IS_BROXTON(dev))
-               bxt_enable_dsi_pll(encoder);
+               bxt_enable_dsi_pll(encoder, config);
 }
 
 void intel_disable_dsi_pll(struct intel_encoder *encoder)
@@ -586,9 +547,9 @@ static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
        /* Clear old configurations */
        tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
        tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port));
-       tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
+       tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
        I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
        I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
 }
This page took 0.033034 seconds and 5 git commands to generate.