bxt_power_sequencer_idx(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-       struct intel_connector *connector = intel_dp->attached_connector;
-       int backlight_controller = connector->panel.vbt.backlight.controller;
+       int pps_idx = intel_dp->pps.pps_idx;
 
        lockdep_assert_held(&dev_priv->display.pps.mutex);
 
        drm_WARN_ON(&dev_priv->drm, !intel_dp_is_edp(intel_dp));
 
        if (!intel_dp->pps.pps_reset)
-               return backlight_controller;
+               return pps_idx;
 
        intel_dp->pps.pps_reset = false;
 
         */
        pps_init_registers(intel_dp, false);
 
-       return backlight_controller;
+       return pps_idx;
 }
 
 typedef bool (*pps_check)(struct drm_i915_private *dev_priv, int pps_idx);
                    pipe_name(intel_dp->pps.pps_pipe));
 }
 
+static int
+bxt_initial_pps_idx(struct drm_i915_private *i915, pps_check check)
+{
+       int pps_idx, pps_num = 2;
+
+       for (pps_idx = 0; pps_idx < pps_num; pps_idx++) {
+               if (check(i915, pps_idx))
+                       return pps_idx;
+       }
+
+       return -1;
+}
+
+static void
+pps_initial_setup(struct intel_dp *intel_dp)
+{
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       struct intel_connector *connector = intel_dp->attached_connector;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+       lockdep_assert_held(&i915->display.pps.mutex);
+
+       if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
+               vlv_initial_power_sequencer_setup(intel_dp);
+               return;
+       }
+
+       if (!IS_GEMINILAKE(i915) && !IS_BROXTON(i915))
+               return;
+
+       /* first ask the VBT */
+       intel_dp->pps.pps_idx = connector->panel.vbt.backlight.controller;
+       if (drm_WARN_ON(&i915->drm, intel_dp->pps.pps_idx >= 2))
+               intel_dp->pps.pps_idx = -1;
+
+       /* VBT wasn't parsed yet? pick one where the panel is on */
+       if (intel_dp->pps.pps_idx < 0)
+               intel_dp->pps.pps_idx = bxt_initial_pps_idx(i915, pps_has_pp_on);
+       /* didn't find one? pick one where vdd is on */
+       if (intel_dp->pps.pps_idx < 0)
+               intel_dp->pps.pps_idx = bxt_initial_pps_idx(i915, pps_has_vdd_on);
+       /* didn't find one? pick any */
+       if (intel_dp->pps.pps_idx < 0) {
+               intel_dp->pps.pps_idx = bxt_initial_pps_idx(i915, pps_any);
+
+               drm_dbg_kms(&i915->drm,
+                           "[ENCODER:%d:%s] no initial power sequencer, assuming %d\n",
+                           encoder->base.base.id, encoder->base.name,
+                           intel_dp->pps.pps_idx);
+               return;
+       }
+
+       drm_dbg_kms(&i915->drm,
+                   "[ENCODER:%d:%s] initial power sequencer: %d\n",
+                   encoder->base.base.id, encoder->base.name,
+                   intel_dp->pps.pps_idx);
+}
+
 void intel_pps_reset_all(struct drm_i915_private *dev_priv)
 {
        struct intel_encoder *encoder;
 
        memset(regs, 0, sizeof(*regs));
 
-       if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
-               pps_idx = bxt_power_sequencer_idx(intel_dp);
-       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                pps_idx = vlv_power_sequencer_pipe(intel_dp);
+       else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
+               pps_idx = bxt_power_sequencer_idx(intel_dp);
 
        regs->pp_ctrl = PP_CONTROL(pps_idx);
        regs->pp_stat = PP_STATUS(pps_idx);
 
 void intel_pps_init(struct intel_dp *intel_dp)
 {
-       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
        intel_wakeref_t wakeref;
 
        intel_dp->pps.initializing = true;
        pps_init_timestamps(intel_dp);
 
        with_intel_pps_lock(intel_dp, wakeref) {
-               if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
-                       vlv_initial_power_sequencer_setup(intel_dp);
+               pps_initial_setup(intel_dp);
 
                pps_init_delays(intel_dp);
                pps_init_registers(intel_dp, false);
        }
 }
 
+static void pps_init_late(struct intel_dp *intel_dp)
+{
+       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       struct intel_connector *connector = intel_dp->attached_connector;
+
+       if (!IS_GEMINILAKE(i915) && !IS_BROXTON(i915))
+               return;
+
+       drm_WARN(&i915->drm, connector->panel.vbt.backlight.controller >= 0 &&
+                intel_dp->pps.pps_idx != connector->panel.vbt.backlight.controller,
+                "[ENCODER:%d:%s] power sequencer mismatch: %d (initial) vs. %d (VBT)\n",
+                encoder->base.base.id, encoder->base.name,
+                intel_dp->pps.pps_idx, connector->panel.vbt.backlight.controller);
+
+       if (connector->panel.vbt.backlight.controller >= 0)
+               intel_dp->pps.pps_idx = connector->panel.vbt.backlight.controller;
+}
+
 void intel_pps_init_late(struct intel_dp *intel_dp)
 {
        intel_wakeref_t wakeref;
 
        with_intel_pps_lock(intel_dp, wakeref) {
                /* Reinit delays after per-panel info has been parsed from VBT */
+               pps_init_late(intel_dp);
+
                memset(&intel_dp->pps.pps_delays, 0, sizeof(intel_dp->pps.pps_delays));
                pps_init_delays(intel_dp);
                pps_init_registers(intel_dp, false);