* with the 5 or 6 idle patterns.
         */
        uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
-       uint32_t val = 0x0;
+       uint32_t val = EDP_PSR_ENABLE;
+
+       val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT;
+       val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
 
        if (IS_HASWELL(dev))
                val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
        if (dev_priv->psr.link_standby)
                val |= EDP_PSR_LINK_STANDBY;
 
-       I915_WRITE(EDP_PSR_CTL, val |
-                  max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
-                  idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
-                  EDP_PSR_ENABLE);
+       if (dev_priv->vbt.psr.tp1_wakeup_time > 5)
+               val |= EDP_PSR_TP1_TIME_2500us;
+       else if (dev_priv->vbt.psr.tp1_wakeup_time > 1)
+               val |= EDP_PSR_TP1_TIME_500us;
+       else if (dev_priv->vbt.psr.tp1_wakeup_time > 0)
+               val |= EDP_PSR_TP1_TIME_100us;
+       else
+               val |= EDP_PSR_TP1_TIME_0us;
+
+       if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
+               val |= EDP_PSR_TP2_TP3_TIME_2500us;
+       else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
+               val |= EDP_PSR_TP2_TP3_TIME_500us;
+       else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
+               val |= EDP_PSR_TP2_TP3_TIME_100us;
+       else
+               val |= EDP_PSR_TP2_TP3_TIME_0us;
+
+       if (intel_dp_source_supports_hbr2(intel_dp) &&
+           drm_dp_tps3_supported(intel_dp->dpcd))
+               val |= EDP_PSR_TP1_TP3_SEL;
+       else
+               val |= EDP_PSR_TP1_TP2_SEL;
+
+       I915_WRITE(EDP_PSR_CTL, val);
+
+       if (!dev_priv->psr.psr2_support)
+               return;
+
+       /* FIXME: selective update is probably totally broken because it doesn't
+        * mesh at all with our frontbuffer tracking. And the hw alone isn't
+        * good enough. */
+       val = EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
+
+       if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
+               val |= EDP_PSR2_TP2_TIME_2500;
+       else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
+               val |= EDP_PSR2_TP2_TIME_500;
+       else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
+               val |= EDP_PSR2_TP2_TIME_100;
+       else
+               val |= EDP_PSR2_TP2_TIME_50;
 
-       if (dev_priv->psr.psr2_support)
-               I915_WRITE(EDP_PSR2_CTL, EDP_PSR2_ENABLE |
-                               EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100);
+       I915_WRITE(EDP_PSR2_CTL, val);
 }
 
 static bool intel_psr_match_conditions(struct intel_dp *intel_dp)