clear_bit_unlock(I915_RESET_MODESET, &dev_priv->gt.reset.flags);
 }
 
-static void icl_set_pipe_chicken(struct intel_crtc *crtc)
+static bool underrun_recovery_supported(const struct intel_crtc_state *crtc_state)
 {
+       if (crtc_state->pch_pfit.enabled &&
+           (crtc_state->pipe_src_w > drm_rect_width(&crtc_state->pch_pfit.dst) ||
+            crtc_state->pipe_src_h > drm_rect_height(&crtc_state->pch_pfit.dst) ||
+            crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420))
+               return false;
+
+       if (crtc_state->dsc.compression_enable)
+               return false;
+
+       if (crtc_state->has_psr2)
+               return false;
+
+       return true;
+}
+
+static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum pipe pipe = crtc->pipe;
        u32 tmp;
         */
        tmp |= PIXEL_ROUNDING_TRUNC_FB_PASSTHRU;
 
-       /*
-        * "The underrun recovery mechanism should be disabled
-        *  when the following is enabled for this pipe:
-        *  WiDi
-        *  Downscaling (this includes YUV420 fullblend)
-        *  COG
-        *  DSC
-        *  PSR2"
-        *
-        * FIXME: enable whenever possible...
-        */
-       if (IS_ALDERLAKE_P(dev_priv))
-               tmp |= UNDERRUN_RECOVERY_DISABLE;
+       if (IS_DG2(dev_priv)) {
+               /*
+                * Underrun recovery must always be disabled on DG2.  However
+                * the chicken bit meaning is inverted compared to other
+                * platforms.
+                */
+               tmp &= ~UNDERRUN_RECOVERY_ENABLE_DG2;
+       } else if (DISPLAY_VER(dev_priv) >= 13) {
+               if (underrun_recovery_supported(crtc_state))
+                       tmp &= ~UNDERRUN_RECOVERY_DISABLE_ADLP;
+               else
+                       tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP;
+       }
 
        intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);
 }
        hsw_set_linetime_wm(new_crtc_state);
 
        if (DISPLAY_VER(dev_priv) >= 11)
-               icl_set_pipe_chicken(crtc);
+               icl_set_pipe_chicken(new_crtc_state);
 
        if (dev_priv->display.initial_watermarks)
                dev_priv->display.initial_watermarks(state, crtc);
                hsw_set_linetime_wm(new_crtc_state);
 
        if (DISPLAY_VER(dev_priv) >= 11)
-               icl_set_pipe_chicken(crtc);
+               icl_set_pipe_chicken(new_crtc_state);
 }
 
 static void commit_pipe_pre_planes(struct intel_atomic_state *state,