}
 }
 
+static enum pipe vlv_find_free_pps(struct drm_i915_private *dev_priv)
+{
+       struct intel_encoder *encoder;
+       unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B);
+
+       /*
+        * We don't have power sequencer currently.
+        * Pick one that's not used by other ports.
+        */
+       for_each_intel_encoder(&dev_priv->drm, encoder) {
+               struct intel_dp *intel_dp;
+
+               if (encoder->type != INTEL_OUTPUT_DP &&
+                   encoder->type != INTEL_OUTPUT_EDP)
+                       continue;
+
+               intel_dp = enc_to_intel_dp(&encoder->base);
+
+               if (encoder->type == INTEL_OUTPUT_EDP) {
+                       WARN_ON(intel_dp->active_pipe != INVALID_PIPE &&
+                               intel_dp->active_pipe != intel_dp->pps_pipe);
+
+                       if (intel_dp->pps_pipe != INVALID_PIPE)
+                               pipes &= ~(1 << intel_dp->pps_pipe);
+               } else {
+                       WARN_ON(intel_dp->pps_pipe != INVALID_PIPE);
+
+                       if (intel_dp->active_pipe != INVALID_PIPE)
+                               pipes &= ~(1 << intel_dp->active_pipe);
+               }
+       }
+
+       if (pipes == 0)
+               return INVALID_PIPE;
+
+       return ffs(pipes) - 1;
+}
+
 static enum pipe
 vlv_power_sequencer_pipe(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 = to_i915(dev);
-       struct intel_encoder *encoder;
-       unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B);
        enum pipe pipe;
 
        lockdep_assert_held(&dev_priv->pps_mutex);
        /* We should never land here with regular DP ports */
        WARN_ON(!is_edp(intel_dp));
 
+       WARN_ON(intel_dp->active_pipe != INVALID_PIPE &&
+               intel_dp->active_pipe != intel_dp->pps_pipe);
+
        if (intel_dp->pps_pipe != INVALID_PIPE)
                return intel_dp->pps_pipe;
 
-       /*
-        * We don't have power sequencer currently.
-        * Pick one that's not used by other ports.
-        */
-       for_each_intel_encoder(dev, encoder) {
-               struct intel_dp *tmp;
-
-               if (encoder->type != INTEL_OUTPUT_EDP)
-                       continue;
-
-               tmp = enc_to_intel_dp(&encoder->base);
-
-               if (tmp->pps_pipe != INVALID_PIPE)
-                       pipes &= ~(1 << tmp->pps_pipe);
-       }
+       pipe = vlv_find_free_pps(dev_priv);
 
        /*
         * Didn't find one. This should not happen since there
         * are two power sequencers and up to two eDP ports.
         */
-       if (WARN_ON(pipes == 0))
+       if (WARN_ON(pipe == INVALID_PIPE))
                pipe = PIPE_A;
-       else
-               pipe = ffs(pipes) - 1;
 
        vlv_steal_power_sequencer(dev, pipe);
        intel_dp->pps_pipe = pipe;
        for_each_intel_encoder(dev, encoder) {
                struct intel_dp *intel_dp;
 
-               if (encoder->type != INTEL_OUTPUT_EDP)
+               if (encoder->type != INTEL_OUTPUT_DP &&
+                   encoder->type != INTEL_OUTPUT_EDP)
                        continue;
 
                intel_dp = enc_to_intel_dp(&encoder->base);
+
+               WARN_ON(intel_dp->active_pipe != INVALID_PIPE);
+
+               if (encoder->type != INTEL_OUTPUT_EDP)
+                       continue;
+
                if (IS_GEN9_LP(dev_priv))
                        intel_dp->pps_reset = true;
                else
        enum pipe pipe = intel_dp->pps_pipe;
        i915_reg_t pp_on_reg = PP_ON_DELAYS(pipe);
 
+       WARN_ON(intel_dp->active_pipe != INVALID_PIPE);
+
        edp_panel_vdd_off_sync(intel_dp);
 
        /*
                struct intel_dp *intel_dp;
                enum port port;
 
-               if (encoder->type != INTEL_OUTPUT_EDP)
+               if (encoder->type != INTEL_OUTPUT_DP &&
+                   encoder->type != INTEL_OUTPUT_EDP)
                        continue;
 
                intel_dp = enc_to_intel_dp(&encoder->base);
                port = dp_to_dig_port(intel_dp)->port;
 
+               WARN(intel_dp->active_pipe == pipe,
+                    "stealing pipe %c power sequencer from active (e)DP port %c\n",
+                    pipe_name(pipe), port_name(port));
+
                if (intel_dp->pps_pipe != pipe)
                        continue;
 
                DRM_DEBUG_KMS("stealing pipe %c power sequencer from port %c\n",
                              pipe_name(pipe), port_name(port));
 
-               WARN(encoder->base.crtc,
-                    "stealing pipe %c power sequencer from active eDP port %c\n",
-                    pipe_name(pipe), port_name(port));
-
                /* make sure vdd is off before we steal it */
                vlv_detach_power_sequencer(intel_dp);
        }
 
        lockdep_assert_held(&dev_priv->pps_mutex);
 
-       if (!is_edp(intel_dp))
-               return;
+       WARN_ON(intel_dp->active_pipe != INVALID_PIPE);
 
-       if (intel_dp->pps_pipe == crtc->pipe)
-               return;
-
-       /*
-        * If another power sequencer was being used on this
-        * port previously make sure to turn off vdd there while
-        * we still have control of it.
-        */
-       if (intel_dp->pps_pipe != INVALID_PIPE)
+       if (intel_dp->pps_pipe != INVALID_PIPE &&
+           intel_dp->pps_pipe != crtc->pipe) {
+               /*
+                * If another power sequencer was being used on this
+                * port previously make sure to turn off vdd there while
+                * we still have control of it.
+                */
                vlv_detach_power_sequencer(intel_dp);
+       }
 
        /*
         * We may be stealing the power
         */
        vlv_steal_power_sequencer(dev, crtc->pipe);
 
+       intel_dp->active_pipe = crtc->pipe;
+
+       if (!is_edp(intel_dp))
+               return;
+
        /* now it's all ours */
        intel_dp->pps_pipe = crtc->pipe;
 
        msleep(intel_dp->panel_power_down_delay);
 
        intel_dp->DP = DP;
+
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+               pps_lock(intel_dp);
+               intel_dp->active_pipe = INVALID_PIPE;
+               pps_unlock(intel_dp);
+       }
 }
 
 bool
        edp_panel_vdd_schedule_off(intel_dp);
 }
 
+static enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
+{
+       struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+
+       if ((intel_dp->DP & DP_PORT_EN) == 0)
+               return INVALID_PIPE;
+
+       if (IS_CHERRYVIEW(dev_priv))
+               return DP_PORT_TO_PIPE_CHV(intel_dp->DP);
+       else
+               return PORT_TO_PIPE(intel_dp->DP);
+}
+
 void intel_dp_encoder_reset(struct drm_encoder *encoder)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->dev);
        if (lspcon->active)
                lspcon_resume(lspcon);
 
-       if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
-               return;
-
        pps_lock(intel_dp);
 
-       /* Reinit the power sequencer, in case BIOS did something with it. */
-       intel_dp_pps_init(encoder->dev, intel_dp);
-       intel_edp_panel_vdd_sanitize(intel_dp);
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               intel_dp->active_pipe = vlv_active_pipe(intel_dp);
+
+       if (is_edp(intel_dp)) {
+               /* Reinit the power sequencer, in case BIOS did something with it. */
+               intel_dp_pps_init(encoder->dev, intel_dp);
+               intel_edp_panel_vdd_sanitize(intel_dp);
+       }
 
        pps_unlock(intel_dp);
 }
                 * If the current pipe isn't valid, try the PPS pipe, and if that
                 * fails just assume pipe A.
                 */
-               if (IS_CHERRYVIEW(dev_priv))
-                       pipe = DP_PORT_TO_PIPE_CHV(intel_dp->DP);
-               else
-                       pipe = PORT_TO_PIPE(intel_dp->DP);
+               pipe = vlv_active_pipe(intel_dp);
 
                if (pipe != PIPE_A && pipe != PIPE_B)
                        pipe = intel_dp->pps_pipe;
                return false;
 
        intel_dp->pps_pipe = INVALID_PIPE;
+       intel_dp->active_pipe = INVALID_PIPE;
 
        /* intel_dp vfuncs */
        if (INTEL_GEN(dev_priv) >= 9)
        else
                type = DRM_MODE_CONNECTOR_DisplayPort;
 
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               intel_dp->active_pipe = vlv_active_pipe(intel_dp);
+
        /*
         * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
         * for DP the encoder type can be set by the caller to