drm/i915: Enable Resource Streamer state save/restore on MI_SET_CONTEXT
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_dp.c
index f9e4fa84245031baf0b7ebc72fa05ee46f6f87d1..367f71224c96a20bc48f0f72f57a38969a9407e9 100644 (file)
@@ -567,7 +567,9 @@ static u32 _pp_ctrl_reg(struct intel_dp *intel_dp)
 {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
-       if (HAS_PCH_SPLIT(dev))
+       if (IS_BROXTON(dev))
+               return BXT_PP_CONTROL(0);
+       else if (HAS_PCH_SPLIT(dev))
                return PCH_PP_CONTROL;
        else
                return VLV_PIPE_PP_CONTROL(vlv_power_sequencer_pipe(intel_dp));
@@ -577,7 +579,9 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp)
 {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
-       if (HAS_PCH_SPLIT(dev))
+       if (IS_BROXTON(dev))
+               return BXT_PP_STATUS(0);
+       else if (HAS_PCH_SPLIT(dev))
                return PCH_PP_STATUS;
        else
                return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
@@ -1378,7 +1382,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 
                if (INTEL_INFO(dev)->gen >= 9) {
                        int ret;
-                       ret = skl_update_scaler_users(intel_crtc, pipe_config, NULL, NULL, 0);
+                       ret = skl_update_scaler_crtc(pipe_config, 0);
                        if (ret)
                                return ret;
                }
@@ -1703,8 +1707,10 @@ static  u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
        lockdep_assert_held(&dev_priv->pps_mutex);
 
        control = I915_READ(_pp_ctrl_reg(intel_dp));
-       control &= ~PANEL_UNLOCK_MASK;
-       control |= PANEL_UNLOCK_REGS;
+       if (!IS_BROXTON(dev)) {
+               control &= ~PANEL_UNLOCK_MASK;
+               control |= PANEL_UNLOCK_REGS;
+       }
        return control;
 }
 
@@ -3418,92 +3424,6 @@ gen7_edp_signal_levels(uint8_t train_set)
        }
 }
 
-/* Gen7.5's (HSW) DP voltage swing and pre-emphasis control */
-static uint32_t
-hsw_signal_levels(uint8_t train_set)
-{
-       int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-                                        DP_TRAIN_PRE_EMPHASIS_MASK);
-       switch (signal_levels) {
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               return DDI_BUF_TRANS_SELECT(0);
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-               return DDI_BUF_TRANS_SELECT(1);
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-               return DDI_BUF_TRANS_SELECT(2);
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
-               return DDI_BUF_TRANS_SELECT(3);
-
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               return DDI_BUF_TRANS_SELECT(4);
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-               return DDI_BUF_TRANS_SELECT(5);
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-               return DDI_BUF_TRANS_SELECT(6);
-
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               return DDI_BUF_TRANS_SELECT(7);
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-               return DDI_BUF_TRANS_SELECT(8);
-
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               return DDI_BUF_TRANS_SELECT(9);
-       default:
-               DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-                             "0x%x\n", signal_levels);
-               return DDI_BUF_TRANS_SELECT(0);
-       }
-}
-
-static void bxt_signal_levels(struct intel_dp *intel_dp)
-{
-       struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-       enum port port = dport->port;
-       struct drm_device *dev = dport->base.base.dev;
-       struct intel_encoder *encoder = &dport->base;
-       uint8_t train_set = intel_dp->train_set[0];
-       uint32_t level = 0;
-
-       int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-                                        DP_TRAIN_PRE_EMPHASIS_MASK);
-       switch (signal_levels) {
-       default:
-               DRM_DEBUG_KMS("Unsupported voltage swing/pre-emph level\n");
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               level = 0;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-               level = 1;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-               level = 2;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
-               level = 3;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               level = 4;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-               level = 5;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-               level = 6;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               level = 7;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-               level = 8;
-               break;
-       case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-               level = 9;
-               break;
-       }
-
-       bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
-}
-
 /* Properly updates "DP" with the correct signal levels. */
 static void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
@@ -3511,22 +3431,20 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        enum port port = intel_dig_port->port;
        struct drm_device *dev = intel_dig_port->base.base.dev;
-       uint32_t signal_levels, mask;
+       uint32_t signal_levels, mask = 0;
        uint8_t train_set = intel_dp->train_set[0];
 
-       if (IS_BROXTON(dev)) {
-               signal_levels = 0;
-               bxt_signal_levels(intel_dp);
-               mask = 0;
-       } else if (HAS_DDI(dev)) {
-               signal_levels = hsw_signal_levels(train_set);
-               mask = DDI_BUF_EMP_MASK;
+       if (HAS_DDI(dev)) {
+               signal_levels = ddi_signal_levels(intel_dp);
+
+               if (IS_BROXTON(dev))
+                       signal_levels = 0;
+               else
+                       mask = DDI_BUF_EMP_MASK;
        } else if (IS_CHERRYVIEW(dev)) {
                signal_levels = chv_signal_levels(intel_dp);
-               mask = 0;
        } else if (IS_VALLEYVIEW(dev)) {
                signal_levels = vlv_signal_levels(intel_dp);
-               mask = 0;
        } else if (IS_GEN7(dev) && port == PORT_A) {
                signal_levels = gen7_edp_signal_levels(train_set);
                mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
@@ -5093,8 +5011,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct edp_power_seq cur, vbt, spec,
                *final = &intel_dp->pps_delays;
-       u32 pp_on, pp_off, pp_div, pp;
-       int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+       u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0;
+       int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg = 0;
 
        lockdep_assert_held(&dev_priv->pps_mutex);
 
@@ -5102,7 +5020,16 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
        if (final->t11_t12 != 0)
                return;
 
-       if (HAS_PCH_SPLIT(dev)) {
+       if (IS_BROXTON(dev)) {
+               /*
+                * TODO: BXT has 2 sets of PPS registers.
+                * Correct Register for Broxton need to be identified
+                * using VBT. hardcoding for now
+                */
+               pp_ctrl_reg = BXT_PP_CONTROL(0);
+               pp_on_reg = BXT_PP_ON_DELAYS(0);
+               pp_off_reg = BXT_PP_OFF_DELAYS(0);
+       } else if (HAS_PCH_SPLIT(dev)) {
                pp_ctrl_reg = PCH_PP_CONTROL;
                pp_on_reg = PCH_PP_ON_DELAYS;
                pp_off_reg = PCH_PP_OFF_DELAYS;
@@ -5118,12 +5045,14 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
 
        /* Workaround: Need to write PP_CONTROL with the unlock key as
         * the very first thing. */
-       pp = ironlake_get_pp_control(intel_dp);
-       I915_WRITE(pp_ctrl_reg, pp);
+       pp_ctl = ironlake_get_pp_control(intel_dp);
 
        pp_on = I915_READ(pp_on_reg);
        pp_off = I915_READ(pp_off_reg);
-       pp_div = I915_READ(pp_div_reg);
+       if (!IS_BROXTON(dev)) {
+               I915_WRITE(pp_ctrl_reg, pp_ctl);
+               pp_div = I915_READ(pp_div_reg);
+       }
 
        /* Pull timing values out of registers */
        cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
@@ -5138,8 +5067,17 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
        cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
                PANEL_POWER_DOWN_DELAY_SHIFT;
 
-       cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
+       if (IS_BROXTON(dev)) {
+               u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
+                       BXT_POWER_CYCLE_DELAY_SHIFT;
+               if (tmp > 0)
+                       cur.t11_t12 = (tmp - 1) * 1000;
+               else
+                       cur.t11_t12 = 0;
+       } else {
+               cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
                       PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000;
+       }
 
        DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
                      cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
@@ -5196,13 +5134,23 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 pp_on, pp_off, pp_div, port_sel = 0;
        int div = HAS_PCH_SPLIT(dev) ? intel_pch_rawclk(dev) : intel_hrawclk(dev);
-       int pp_on_reg, pp_off_reg, pp_div_reg;
+       int pp_on_reg, pp_off_reg, pp_div_reg = 0, pp_ctrl_reg;
        enum port port = dp_to_dig_port(intel_dp)->port;
        const struct edp_power_seq *seq = &intel_dp->pps_delays;
 
        lockdep_assert_held(&dev_priv->pps_mutex);
 
-       if (HAS_PCH_SPLIT(dev)) {
+       if (IS_BROXTON(dev)) {
+               /*
+                * TODO: BXT has 2 sets of PPS registers.
+                * Correct Register for Broxton need to be identified
+                * using VBT. hardcoding for now
+                */
+               pp_ctrl_reg = BXT_PP_CONTROL(0);
+               pp_on_reg = BXT_PP_ON_DELAYS(0);
+               pp_off_reg = BXT_PP_OFF_DELAYS(0);
+
+       } else if (HAS_PCH_SPLIT(dev)) {
                pp_on_reg = PCH_PP_ON_DELAYS;
                pp_off_reg = PCH_PP_OFF_DELAYS;
                pp_div_reg = PCH_PP_DIVISOR;
@@ -5228,9 +5176,16 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
                 (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT);
        /* Compute the divisor for the pp clock, simply match the Bspec
         * formula. */
-       pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT;
-       pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
-                       << PANEL_POWER_CYCLE_DELAY_SHIFT);
+       if (IS_BROXTON(dev)) {
+               pp_div = I915_READ(pp_ctrl_reg);
+               pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK;
+               pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000)
+                               << BXT_POWER_CYCLE_DELAY_SHIFT);
+       } else {
+               pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT;
+               pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
+                               << PANEL_POWER_CYCLE_DELAY_SHIFT);
+       }
 
        /* Haswell doesn't have any port selection bits for the panel
         * power sequencer any more. */
@@ -5247,11 +5202,16 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 
        I915_WRITE(pp_on_reg, pp_on);
        I915_WRITE(pp_off_reg, pp_off);
-       I915_WRITE(pp_div_reg, pp_div);
+       if (IS_BROXTON(dev))
+               I915_WRITE(pp_ctrl_reg, pp_div);
+       else
+               I915_WRITE(pp_div_reg, pp_div);
 
        DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",
                      I915_READ(pp_on_reg),
                      I915_READ(pp_off_reg),
+                     IS_BROXTON(dev) ?
+                     (I915_READ(pp_ctrl_reg) & BXT_POWER_CYCLE_DELAY_MASK) :
                      I915_READ(pp_div_reg));
 }
 
@@ -5486,16 +5446,15 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
        crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
        pipe = to_intel_crtc(crtc)->pipe;
 
+       frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+       dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
+
        /* invalidate means busy screen hence upclock */
-       if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
+       if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
                intel_dp_set_drrs_state(dev_priv->dev,
                                dev_priv->drrs.dp->attached_connector->panel.
                                fixed_mode->vrefresh);
-       }
 
-       frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
-
-       dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
        mutex_unlock(&dev_priv->drrs.mutex);
 }
 
@@ -5531,10 +5490,12 @@ void intel_edp_drrs_flush(struct drm_device *dev,
 
        crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
        pipe = to_intel_crtc(crtc)->pipe;
+
+       frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
        dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
 
        /* flush means busy screen hence upclock */
-       if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+       if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
                intel_dp_set_drrs_state(dev_priv->dev,
                                dev_priv->drrs.dp->attached_connector->panel.
                                fixed_mode->vrefresh);
This page took 0.030668 seconds and 5 git commands to generate.