drm/i915/skl: Program the DDB allocation
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_dp.c
index 90d752d5d6ea7758f8a6fa1d3bcc4c4ab4531764..5f2c206aef130bfb681879c07d5d26534197f8d8 100644 (file)
@@ -330,6 +330,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe = intel_dp->pps_pipe;
+       bool pll_enabled;
        uint32_t DP;
 
        if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN,
@@ -353,6 +354,16 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        else if (pipe == PIPE_B)
                DP |= DP_PIPEB_SELECT;
 
+       pll_enabled = I915_READ(DPLL(pipe)) & DPLL_VCO_ENABLE;
+
+       /*
+        * The DPLL for the pipe must be enabled for this to work.
+        * So enable temporarily it if it's not already enabled.
+        */
+       if (!pll_enabled)
+               vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
+                                &chv_dpll[0].dpll : &vlv_dpll[0].dpll);
+
        /*
         * Similar magic as in intel_dp_enable_port().
         * We _must_ do this port enable + disable trick
@@ -367,6 +378,9 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
 
        I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(intel_dp->output_reg);
+
+       if (!pll_enabled)
+               vlv_force_pll_off(dev, pipe);
 }
 
 static enum pipe
@@ -1314,7 +1328,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
                DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
                                 pipe_name(crtc->pipe));
                intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
-               intel_write_eld(encoder);
+               intel_audio_codec_enable(encoder);
        }
 
        /* Split out the IBX/CPU vs CPT settings */
@@ -3798,7 +3812,6 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 
                /* Try 5 times, then try clock recovery if that fails */
                if (tries > 5) {
-                       intel_dp_link_down(intel_dp);
                        intel_dp_start_link_train(intel_dp);
                        intel_dp_set_link_train(intel_dp, &DP,
                                                training_pattern |
@@ -4663,9 +4676,52 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
        pps_unlock(intel_dp);
 }
 
+static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
+{
+       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct drm_device *dev = intel_dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum intel_display_power_domain power_domain;
+
+       lockdep_assert_held(&dev_priv->pps_mutex);
+
+       if (!edp_have_panel_vdd(intel_dp))
+               return;
+
+       /*
+        * The VDD bit needs a power domain reference, so if the bit is
+        * already enabled when we boot or resume, grab this reference and
+        * schedule a vdd off, so we don't hold on to the reference
+        * indefinitely.
+        */
+       DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
+       power_domain = intel_display_port_power_domain(&intel_dig_port->base);
+       intel_display_power_get(dev_priv, power_domain);
+
+       edp_panel_vdd_schedule_off(intel_dp);
+}
+
 static void intel_dp_encoder_reset(struct drm_encoder *encoder)
 {
-       intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
+       struct intel_dp *intel_dp;
+
+       if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
+               return;
+
+       intel_dp = enc_to_intel_dp(encoder);
+
+       pps_lock(intel_dp);
+
+       /*
+        * Read out the current power sequencer assignment,
+        * in case the BIOS did something with it.
+        */
+       if (IS_VALLEYVIEW(encoder->dev))
+               vlv_initial_power_sequencer_setup(intel_dp);
+
+       intel_edp_panel_vdd_sanitize(intel_dp);
+
+       pps_unlock(intel_dp);
 }
 
 static const struct drm_connector_funcs intel_dp_connector_funcs = {
@@ -5136,37 +5192,6 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
        return downclock_mode;
 }
 
-void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
-{
-       struct drm_device *dev = intel_encoder->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp *intel_dp;
-       enum intel_display_power_domain power_domain;
-
-       if (intel_encoder->type != INTEL_OUTPUT_EDP)
-               return;
-
-       intel_dp = enc_to_intel_dp(&intel_encoder->base);
-
-       pps_lock(intel_dp);
-
-       if (!edp_have_panel_vdd(intel_dp))
-               goto out;
-       /*
-        * The VDD bit needs a power domain reference, so if the bit is
-        * already enabled when we boot or resume, grab this reference and
-        * schedule a vdd off, so we don't hold on to the reference
-        * indefinitely.
-        */
-       DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
-       power_domain = intel_display_port_power_domain(intel_encoder);
-       intel_display_power_get(dev_priv, power_domain);
-
-       edp_panel_vdd_schedule_off(intel_dp);
- out:
-       pps_unlock(intel_dp);
-}
-
 static bool intel_edp_init_connector(struct intel_dp *intel_dp,
                                     struct intel_connector *intel_connector)
 {
@@ -5186,7 +5211,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
        if (!is_edp(intel_dp))
                return true;
 
-       intel_edp_panel_vdd_sanitize(intel_encoder);
+       pps_lock(intel_dp);
+       intel_edp_panel_vdd_sanitize(intel_dp);
+       pps_unlock(intel_dp);
 
        /* Cache DPCD and EDID for edp. */
        has_dpcd = intel_dp_get_dpcd(intel_dp);
@@ -5350,12 +5377,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
        if (is_edp(intel_dp)) {
                pps_lock(intel_dp);
-               if (IS_VALLEYVIEW(dev)) {
+               intel_dp_init_panel_power_timestamps(intel_dp);
+               if (IS_VALLEYVIEW(dev))
                        vlv_initial_power_sequencer_setup(intel_dp);
-               } else {
-                       intel_dp_init_panel_power_timestamps(intel_dp);
+               else
                        intel_dp_init_panel_power_sequencer(dev, intel_dp);
-               }
                pps_unlock(intel_dp);
        }
 
This page took 0.029869 seconds and 5 git commands to generate.