intel_hdmi_infoframe_enable(DP_SDP_VSC))
                intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
 
-       drm_dbg_kms(&dev_priv->drm, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, flipline: %d, vmin vblank: %d, vmax vblank: %d\n",
+       drm_dbg_kms(&dev_priv->drm, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, guardband: %d flipline: %d, vmin vblank: %d, vmax vblank: %d\n",
                    yesno(pipe_config->vrr.enable),
                    pipe_config->vrr.vmin, pipe_config->vrr.vmax,
-                   pipe_config->vrr.pipeline_full, pipe_config->vrr.flipline,
+                   pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband,
+                   pipe_config->vrr.flipline,
                    intel_vrr_vmin_vblank_start(pipe_config),
                    intel_vrr_vmax_vblank_start(pipe_config));
 
        PIPE_CONF_CHECK_I(vrr.vmax);
        PIPE_CONF_CHECK_I(vrr.flipline);
        PIPE_CONF_CHECK_I(vrr.pipeline_full);
+       PIPE_CONF_CHECK_I(vrr.guardband);
 
        PIPE_CONF_CHECK_BOOL(has_psr);
        PIPE_CONF_CHECK_BOOL(has_psr2);
 
        i915->framestart_delay = 1; /* 1-4 */
 
+       i915->window2_delay = 0; /* No DSB so no window2 delay */
+
        intel_mode_config_init(i915);
 
        ret = intel_cdclk_init(i915);
 
        struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 
        /* The hw imposes the extra scanline before frame start */
-       return crtc_state->vrr.pipeline_full + i915->framestart_delay + 1;
+       if (DISPLAY_VER(i915) >= 13)
+               return crtc_state->vrr.guardband + i915->framestart_delay + 1;
+       else
+               return crtc_state->vrr.pipeline_full + i915->framestart_delay + 1;
 }
 
 int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state)
 intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
                         struct drm_connector_state *conn_state)
 {
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
        struct intel_connector *connector =
                to_intel_connector(conn_state->connector);
        struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
        crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
 
        /*
-        * FIXME: s/4/framestart_delay+1/ to get consistent
-        * earliest/latest points for register latching regardless
-        * of the framestart_delay used?
-        *
-        * FIXME: this really needs the extra scanline to provide consistent
-        * behaviour for all framestart_delay values. Otherwise with
-        * framestart_delay==3 we will end up extending the min vblank by
-        * one extra line.
+        * For XE_LPD+, we use guardband and pipeline override
+        * is deprecated.
         */
-       crtc_state->vrr.pipeline_full =
-               min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vdisplay - 4 - 1);
+       if (DISPLAY_VER(i915) >= 13)
+               crtc_state->vrr.guardband =
+                       crtc_state->vrr.vmin - adjusted_mode->crtc_vdisplay -
+                       i915->window2_delay;
+       else
+               /*
+                * FIXME: s/4/framestart_delay+1/ to get consistent
+                * earliest/latest points for register latching regardless
+                * of the framestart_delay used?
+                *
+                * FIXME: this really needs the extra scanline to provide consistent
+                * behaviour for all framestart_delay values. Otherwise with
+                * framestart_delay==3 we will end up extending the min vblank by
+                * one extra line.
+                */
+               crtc_state->vrr.pipeline_full =
+                       min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vdisplay - 4 - 1);
 
        crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
 }
        if (!crtc_state->vrr.enable)
                return;
 
-       trans_vrr_ctl = VRR_CTL_VRR_ENABLE |
-               VRR_CTL_IGN_MAX_SHIFT | VRR_CTL_FLIP_LINE_EN |
-               VRR_CTL_PIPELINE_FULL(crtc_state->vrr.pipeline_full) |
-               VRR_CTL_PIPELINE_FULL_OVERRIDE;
+       if (DISPLAY_VER(dev_priv) >= 13)
+               trans_vrr_ctl = VRR_CTL_VRR_ENABLE |
+                       VRR_CTL_IGN_MAX_SHIFT | VRR_CTL_FLIP_LINE_EN |
+                       XELPD_VRR_CTL_VRR_GUARDBAND(crtc_state->vrr.guardband);
+       else
+               trans_vrr_ctl = VRR_CTL_VRR_ENABLE |
+                       VRR_CTL_IGN_MAX_SHIFT | VRR_CTL_FLIP_LINE_EN |
+                       VRR_CTL_PIPELINE_FULL(crtc_state->vrr.pipeline_full) |
+                       VRR_CTL_PIPELINE_FULL_OVERRIDE;
 
        intel_de_write(dev_priv, TRANS_VRR_VMIN(cpu_transcoder), crtc_state->vrr.vmin - 1);
        intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), crtc_state->vrr.vmax - 1);
        if (!crtc_state->vrr.enable)
                return;
 
-       if (trans_vrr_ctl & VRR_CTL_PIPELINE_FULL_OVERRIDE)
-               crtc_state->vrr.pipeline_full = REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl);
+       if (DISPLAY_VER(dev_priv) >= 13)
+               crtc_state->vrr.guardband =
+                       REG_FIELD_GET(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, trans_vrr_ctl);
+       else
+               if (trans_vrr_ctl & VRR_CTL_PIPELINE_FULL_OVERRIDE)
+                       crtc_state->vrr.pipeline_full =
+                               REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl);
        if (trans_vrr_ctl & VRR_CTL_FLIP_LINE_EN)
                crtc_state->vrr.flipline = intel_de_read(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder)) + 1;
        crtc_state->vrr.vmax = intel_de_read(dev_priv, TRANS_VRR_VMAX(cpu_transcoder)) + 1;