drm/i915: ValleyView mode setting limits and PLL functions
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_display.c
index ee61ad1e642b06848f537fb6000b3d83c3bf1be1..7794c1a630c0e0150093388d2b96820369ec1a79 100644 (file)
@@ -98,6 +98,11 @@ intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
                           int target, int refclk, intel_clock_t *match_clock,
                           intel_clock_t *best_clock);
 
+static bool
+intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
+                       int target, int refclk, intel_clock_t *match_clock,
+                       intel_clock_t *best_clock);
+
 static inline u32 /* units of 100MHz */
 intel_fdi_link_freq(struct drm_device *dev)
 {
@@ -359,6 +364,48 @@ static const intel_limit_t intel_limits_ironlake_display_port = {
        .find_pll = intel_find_pll_ironlake_dp,
 };
 
+static const intel_limit_t intel_limits_vlv_dac = {
+       .dot = { .min = 25000, .max = 270000 },
+       .vco = { .min = 4000000, .max = 6000000 },
+       .n = { .min = 1, .max = 7 },
+       .m = { .min = 22, .max = 450 }, /* guess */
+       .m1 = { .min = 2, .max = 3 },
+       .m2 = { .min = 11, .max = 156 },
+       .p = { .min = 10, .max = 30 },
+       .p1 = { .min = 2, .max = 3 },
+       .p2 = { .dot_limit = 270000,
+               .p2_slow = 2, .p2_fast = 20 },
+       .find_pll = intel_vlv_find_best_pll,
+};
+
+static const intel_limit_t intel_limits_vlv_hdmi = {
+       .dot = { .min = 20000, .max = 165000 },
+       .vco = { .min = 5994000, .max = 4000000 },
+       .n = { .min = 1, .max = 7 },
+       .m = { .min = 60, .max = 300 }, /* guess */
+       .m1 = { .min = 2, .max = 3 },
+       .m2 = { .min = 11, .max = 156 },
+       .p = { .min = 10, .max = 30 },
+       .p1 = { .min = 2, .max = 3 },
+       .p2 = { .dot_limit = 270000,
+               .p2_slow = 2, .p2_fast = 20 },
+       .find_pll = intel_vlv_find_best_pll,
+};
+
+static const intel_limit_t intel_limits_vlv_dp = {
+       .dot = { .min = 162000, .max = 270000 },
+       .vco = { .min = 5994000, .max = 4000000 },
+       .n = { .min = 1, .max = 7 },
+       .m = { .min = 60, .max = 300 }, /* guess */
+       .m1 = { .min = 2, .max = 3 },
+       .m2 = { .min = 11, .max = 156 },
+       .p = { .min = 10, .max = 30 },
+       .p1 = { .min = 2, .max = 3 },
+       .p2 = { .dot_limit = 270000,
+               .p2_slow = 2, .p2_fast = 20 },
+       .find_pll = intel_vlv_find_best_pll,
+};
+
 u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg)
 {
        unsigned long flags;
@@ -384,6 +431,28 @@ out_unlock:
        return val;
 }
 
+static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
+                            u32 val)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev_priv->dpio_lock, flags);
+       if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
+               DRM_ERROR("DPIO idle wait timed out\n");
+               goto out_unlock;
+       }
+
+       I915_WRITE(DPIO_DATA, val);
+       I915_WRITE(DPIO_REG, reg);
+       I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID |
+                  DPIO_BYTE);
+       if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100))
+               DRM_ERROR("DPIO write wait timed out\n");
+
+out_unlock:
+       spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
+}
+
 static void vlv_init_dpio(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -434,7 +503,7 @@ static bool is_dual_link_lvds(struct drm_i915_private *dev_priv,
                 * register is uninitialized.
                 */
                val = I915_READ(reg);
-               if (!(val & ~LVDS_DETECTED))
+               if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
                        val = dev_priv->bios_lvds_val;
                dev_priv->lvds_val = val;
        }
@@ -510,6 +579,13 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk)
                        limit = &intel_limits_pineview_lvds;
                else
                        limit = &intel_limits_pineview_sdvo;
+       } else if (IS_VALLEYVIEW(dev)) {
+               if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG))
+                       limit = &intel_limits_vlv_dac;
+               else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
+                       limit = &intel_limits_vlv_hdmi;
+               else
+                       limit = &intel_limits_vlv_dp;
        } else if (!IS_GEN2(dev)) {
                if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
                        limit = &intel_limits_i9xx_lvds;
@@ -783,6 +859,73 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
        memcpy(best_clock, &clock, sizeof(intel_clock_t));
        return true;
 }
+static bool
+intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
+                       int target, int refclk, intel_clock_t *match_clock,
+                       intel_clock_t *best_clock)
+{
+       u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2;
+       u32 m, n, fastclk;
+       u32 updrate, minupdate, fracbits, p;
+       unsigned long bestppm, ppm, absppm;
+       int dotclk, flag;
+
+       dotclk = target * 1000;
+       bestppm = 1000000;
+       ppm = absppm = 0;
+       fastclk = dotclk / (2*100);
+       updrate = 0;
+       minupdate = 19200;
+       fracbits = 1;
+       n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0;
+       bestm1 = bestm2 = bestp1 = bestp2 = 0;
+
+       /* based on hardware requirement, prefer smaller n to precision */
+       for (n = limit->n.min; n <= ((refclk) / minupdate); n++) {
+               updrate = refclk / n;
+               for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) {
+                       for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) {
+                               if (p2 > 10)
+                                       p2 = p2 - 1;
+                               p = p1 * p2;
+                               /* based on hardware requirement, prefer bigger m1,m2 values */
+                               for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) {
+                                       m2 = (((2*(fastclk * p * n / m1 )) +
+                                              refclk) / (2*refclk));
+                                       m = m1 * m2;
+                                       vco = updrate * m;
+                                       if (vco >= limit->vco.min && vco < limit->vco.max) {
+                                               ppm = 1000000 * ((vco / p) - fastclk) / fastclk;
+                                               absppm = (ppm > 0) ? ppm : (-ppm);
+                                               if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) {
+                                                       bestppm = 0;
+                                                       flag = 1;
+                                               }
+                                               if (absppm < bestppm - 10) {
+                                                       bestppm = absppm;
+                                                       flag = 1;
+                                               }
+                                               if (flag) {
+                                                       bestn = n;
+                                                       bestm1 = m1;
+                                                       bestm2 = m2;
+                                                       bestp1 = p1;
+                                                       bestp2 = p2;
+                                                       flag = 0;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       best_clock->n = bestn;
+       best_clock->m1 = bestm1;
+       best_clock->m2 = bestm2;
+       best_clock->p1 = bestp1;
+       best_clock->p2 = bestp2;
+
+       return true;
+}
 
 static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe)
 {
@@ -910,9 +1053,10 @@ static void assert_pll(struct drm_i915_private *dev_priv,
 
 /* For ILK+ */
 static void assert_pch_pll(struct drm_i915_private *dev_priv,
-                          struct intel_crtc *intel_crtc, bool state)
+                          struct intel_pch_pll *pll,
+                          struct intel_crtc *crtc,
+                          bool state)
 {
-       int reg;
        u32 val;
        bool cur_state;
 
@@ -921,30 +1065,37 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv,
                return;
        }
 
-       if (!intel_crtc->pch_pll) {
-               WARN(1, "asserting PCH PLL enabled with no PLL\n");
+       if (WARN (!pll,
+                 "asserting PCH PLL %s with no PLL\n", state_string(state)))
                return;
-       }
 
-       if (HAS_PCH_CPT(dev_priv->dev)) {
+       val = I915_READ(pll->pll_reg);
+       cur_state = !!(val & DPLL_VCO_ENABLE);
+       WARN(cur_state != state,
+            "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n",
+            pll->pll_reg, state_string(state), state_string(cur_state), val);
+
+       /* Make sure the selected PLL is correctly attached to the transcoder */
+       if (crtc && HAS_PCH_CPT(dev_priv->dev)) {
                u32 pch_dpll;
 
                pch_dpll = I915_READ(PCH_DPLL_SEL);
-
-               /* Make sure the selected PLL is enabled to the transcoder */
-               WARN(!((pch_dpll >> (4 * intel_crtc->pipe)) & 8),
-                    "transcoder %d PLL not enabled\n", intel_crtc->pipe);
+               cur_state = pll->pll_reg == _PCH_DPLL_B;
+               if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state,
+                         "PLL[%d] not attached to this transcoder %d: %08x\n",
+                         cur_state, crtc->pipe, pch_dpll)) {
+                       cur_state = !!(val >> (4*crtc->pipe + 3));
+                       WARN(cur_state != state,
+                            "PLL[%d] not %s on this transcoder %d: %08x\n",
+                            pll->pll_reg == _PCH_DPLL_B,
+                            state_string(state),
+                            crtc->pipe,
+                            val);
+               }
        }
-
-       reg = intel_crtc->pch_pll->pll_reg;
-       val = I915_READ(reg);
-       cur_state = !!(val & DPLL_VCO_ENABLE);
-       WARN(cur_state != state,
-            "PCH PLL state assertion failure (expected %s, current %s)\n",
-            state_string(state), state_string(cur_state));
 }
-#define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, true)
-#define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, false)
+#define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true)
+#define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false)
 
 static void assert_fdi_tx(struct drm_i915_private *dev_priv,
                          enum pipe pipe, bool state)
@@ -1224,6 +1375,9 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
        WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
             "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
             reg, pipe_name(pipe));
+
+       WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT),
+            "IBX PCH dp port still using transcoder B\n");
 }
 
 static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
@@ -1233,6 +1387,9 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
        WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
             "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
             reg, pipe_name(pipe));
+
+       WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT),
+            "IBX PCH hdmi port still using transcoder B\n");
 }
 
 static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
@@ -1279,7 +1436,7 @@ static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
        u32 val;
 
        /* No really, not for ILK+ */
-       BUG_ON(dev_priv->info->gen >= 5);
+       BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5);
 
        /* PLL is protected by panel, make sure we can write it */
        if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev))
@@ -1336,7 +1493,7 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value)
        unsigned long flags;
 
        spin_lock_irqsave(&dev_priv->dpio_lock, flags);
-       if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0,
+       if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to become ready\n");
                goto out_unlock;
@@ -1350,7 +1507,7 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value)
                        SBI_BUSY |
                        SBI_CTL_OP_CRWR);
 
-       if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0,
+       if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
                goto out_unlock;
@@ -1364,10 +1521,10 @@ static u32
 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg)
 {
        unsigned long flags;
-       u32 value;
+       u32 value = 0;
 
        spin_lock_irqsave(&dev_priv->dpio_lock, flags);
-       if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0,
+       if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to become ready\n");
                goto out_unlock;
@@ -1379,7 +1536,7 @@ intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg)
                        SBI_BUSY |
                        SBI_CTL_OP_CRRD);
 
-       if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0,
+       if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
                goto out_unlock;
@@ -1424,7 +1581,7 @@ static void intel_enable_pch_pll(struct intel_crtc *intel_crtc)
        assert_pch_refclk_enabled(dev_priv);
 
        if (pll->active++ && pll->on) {
-               assert_pch_pll_enabled(dev_priv, intel_crtc);
+               assert_pch_pll_enabled(dev_priv, pll, NULL);
                return;
        }
 
@@ -1460,12 +1617,12 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
                      intel_crtc->base.base.id);
 
        if (WARN_ON(pll->active == 0)) {
-               assert_pch_pll_disabled(dev_priv, intel_crtc);
+               assert_pch_pll_disabled(dev_priv, pll, NULL);
                return;
        }
 
        if (--pll->active) {
-               assert_pch_pll_enabled(dev_priv, intel_crtc);
+               assert_pch_pll_enabled(dev_priv, pll, NULL);
                return;
        }
 
@@ -1495,7 +1652,9 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv,
        BUG_ON(dev_priv->info->gen < 5);
 
        /* Make sure PCH DPLL is enabled */
-       assert_pch_pll_enabled(dev_priv, to_intel_crtc(crtc));
+       assert_pch_pll_enabled(dev_priv,
+                              to_intel_crtc(crtc)->pch_pll,
+                              to_intel_crtc(crtc));
 
        /* FDI must be feeding us bits for PCH ports */
        assert_fdi_tx_enabled(dev_priv, pipe);
@@ -3656,13 +3815,37 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
        return display_bpc != bpc;
 }
 
+static int vlv_get_refclk(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int refclk = 27000; /* for DP & HDMI */
+
+       return 100000; /* only one validated so far */
+
+       if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
+               refclk = 96000;
+       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+               if (intel_panel_use_ssc(dev_priv))
+                       refclk = 100000;
+               else
+                       refclk = 96000;
+       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
+               refclk = 100000;
+       }
+
+       return refclk;
+}
+
 static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int refclk;
 
-       if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+       if (IS_VALLEYVIEW(dev)) {
+               refclk = vlv_get_refclk(crtc);
+       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
            intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
                refclk = dev_priv->lvds_ssc_freq * 1000;
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
@@ -3777,6 +3960,72 @@ static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock,
        I915_WRITE(LVDS, temp);
 }
 
+static void vlv_update_pll(struct drm_crtc *crtc,
+                          struct drm_display_mode *mode,
+                          struct drm_display_mode *adjusted_mode,
+                          intel_clock_t *clock, intel_clock_t *reduced_clock,
+                          int refclk, int num_connectors)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
+       u32 dpll, mdiv, pdiv;
+       u32 bestn, bestm1, bestm2, bestp1, bestp2;
+       bool is_hdmi;
+
+       is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
+
+       bestn = clock->n;
+       bestm1 = clock->m1;
+       bestm2 = clock->m2;
+       bestp1 = clock->p1;
+       bestp2 = clock->p2;
+
+       /* Enable DPIO clock input */
+       dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
+               DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
+       I915_WRITE(DPLL(pipe), dpll);
+       POSTING_READ(DPLL(pipe));
+
+       mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
+       mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
+       mdiv |= ((bestn << DPIO_N_SHIFT));
+       mdiv |= (1 << DPIO_POST_DIV_SHIFT);
+       mdiv |= (1 << DPIO_K_SHIFT);
+       mdiv |= DPIO_ENABLE_CALIBRATION;
+       intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
+
+       intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000);
+
+       pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) |
+               (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) |
+               (8 << DPIO_DRIVER_CTL_SHIFT) | (5 << DPIO_CLK_BIAS_CTL_SHIFT);
+       intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv);
+
+       intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051);
+
+       dpll |= DPLL_VCO_ENABLE;
+       I915_WRITE(DPLL(pipe), dpll);
+       POSTING_READ(DPLL(pipe));
+       if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
+               DRM_ERROR("DPLL %d failed to lock\n", pipe);
+
+       if (is_hdmi) {
+               u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode);
+
+               if (temp > 1)
+                       temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
+               else
+                       temp = 0;
+
+               I915_WRITE(DPLL_MD(pipe), temp);
+               POSTING_READ(DPLL_MD(pipe));
+       }
+
+       intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */
+}
+
 static void i9xx_update_pll(struct drm_crtc *crtc,
                            struct drm_display_mode *mode,
                            struct drm_display_mode *adjusted_mode,
@@ -4034,6 +4283,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 
        if (IS_GEN2(dev))
                i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors);
+       else if (IS_VALLEYVIEW(dev))
+               vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL,
+                              refclk, num_connectors);
        else
                i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
                                has_reduced_clock ? &reduced_clock : NULL,
@@ -4395,25 +4647,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
                                                    &clock,
                                                    &reduced_clock);
        }
-       /* SDVO TV has fixed PLL values depend on its clock range,
-          this mirrors vbios setting. */
-       if (is_sdvo && is_tv) {
-               if (adjusted_mode->clock >= 100000
-                   && adjusted_mode->clock < 140500) {
-                       clock.p1 = 2;
-                       clock.p2 = 10;
-                       clock.n = 3;
-                       clock.m1 = 16;
-                       clock.m2 = 8;
-               } else if (adjusted_mode->clock >= 140500
-                          && adjusted_mode->clock <= 200000) {
-                       clock.p1 = 1;
-                       clock.p2 = 10;
-                       clock.n = 6;
-                       clock.m1 = 12;
-                       clock.m2 = 8;
-               }
-       }
+
+       if (is_sdvo && is_tv)
+               i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
+
 
        /* FDI link */
        pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
@@ -4421,16 +4658,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
        /* CPU eDP doesn't require FDI link, so just set DP M/N
           according to current link config */
        if (is_cpu_edp) {
-               target_clock = mode->clock;
                intel_edp_link_config(edp_encoder, &lane, &link_bw);
        } else {
-               /* [e]DP over FDI requires target mode clock
-                  instead of link clock */
-               if (is_dp)
-                       target_clock = mode->clock;
-               else
-                       target_clock = adjusted_mode->clock;
-
                /* FDI is a binary signal running at ~2.7GHz, encoding
                 * each output octet as 10 bits. The actual frequency
                 * is stored as a divider into a 100MHz clock, and the
@@ -4441,6 +4670,14 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
                link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
        }
 
+       /* [e]DP over FDI requires target mode clock instead of link clock. */
+       if (edp_encoder)
+               target_clock = intel_edp_target_clock(edp_encoder, mode);
+       else if (is_dp)
+               target_clock = mode->clock;
+       else
+               target_clock = adjusted_mode->clock;
+
        /* determine panel color depth */
        temp = I915_READ(PIPECONF(pipe));
        temp &= ~PIPE_BPC_MASK;
@@ -4652,16 +4889,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
                if (is_lvds && has_reduced_clock && i915_powersave) {
                        I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
                        intel_crtc->lowfreq_avail = true;
-                       if (HAS_PIPE_CXSR(dev)) {
-                               DRM_DEBUG_KMS("enabling CxSR downclocking\n");
-                               pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
-                       }
                } else {
                        I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
-                       if (HAS_PIPE_CXSR(dev)) {
-                               DRM_DEBUG_KMS("disabling CxSR downclocking\n");
-                               pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
-                       }
                }
        }
 
@@ -6902,9 +7131,9 @@ static void ivb_pch_pwm_override(struct drm_device *dev)
         * IVB has CPU eDP backlight regs too, set things up to let the
         * PCH regs control the backlight
         */
-       I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE);
+       I915_WRITE(BLC_PWM_CPU_CTL2, BLM_PWM_ENABLE);
        I915_WRITE(BLC_PWM_CPU_CTL, 0);
-       I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30));
+       I915_WRITE(BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE | BLM_PCH_OVERRIDE_ENABLE);
 }
 
 void intel_modeset_init_hw(struct drm_device *dev)
@@ -6961,7 +7190,7 @@ void intel_modeset_init(struct drm_device *dev)
                dev->mode_config.max_width = 8192;
                dev->mode_config.max_height = 8192;
        }
-       dev->mode_config.fb_base = dev->agp->base;
+       dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr;
 
        DRM_DEBUG_KMS("%d display pipe%s available.\n",
                      dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : "");
This page took 0.032859 seconds and 5 git commands to generate.