Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/psr: Do not use pipe_src as borders for SU area

This far using crtc_state->pipe_src as borders for Selective Update area
haven't caused visible problems as drm_rect_width(crtc_state->pipe_src) ==
crtc_state->hw.adjusted_mode.crtc_hdisplay and
drm_rect_height(crtc_state->pipe_src) ==
crtc_state->hw.adjusted_mode.crtc_vdisplay when pipe scaling is not
used. On the other hand using pipe scaling is forcing full frame updates and all the
Selective Update area calculations are skipped. Now this improper usage of
crtc_state->pipe_src is causing following warnings:

<4> [7771.978166] xe 0000:00:02.0: [drm] drm_WARN_ON_ONCE(su_lines % vdsc_cfg->slice_height)

after WARN_ON_ONCE was added by commit:

"drm/i915/dsc: Add helper for writing DSC Selective Update ET parameters"

These warnings are seen when DSC and pipe scaling are enabled
simultaneously. This is because on full frame update SU area is improperly
set as pipe_src which is not aligned with DSC slice height.

Fix these by creating local rectangle using
crtc_state->hw.adjusted_mode.crtc_hdisplay and
crtc_state->hw.adjusted_mode.crtc_vdisplay. Use this local rectangle as
borders for SU area.

Fixes: d6774b8c3c58 ("drm/i915: Ensure damage clip area is within pipe area")
Cc: <stable@vger.kernel.org> # v6.0+
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patch.msgid.link/20260327114553.195285-1-jouni.hogander@intel.com
(cherry picked from commit da0cdc1c329dd2ff09c41fbbe9fbd9c92c5d2c6e)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

authored by

Jouni Högander and committed by
Joonas Lahtinen
75519f5d 591cd656

+19 -11
+19 -11
drivers/gpu/drm/i915/display/intel_psr.c
··· 2678 2678 2679 2679 static void clip_area_update(struct drm_rect *overlap_damage_area, 2680 2680 struct drm_rect *damage_area, 2681 - struct drm_rect *pipe_src) 2681 + struct drm_rect *display_area) 2682 2682 { 2683 - if (!drm_rect_intersect(damage_area, pipe_src)) 2683 + if (!drm_rect_intersect(damage_area, display_area)) 2684 2684 return; 2685 2685 2686 2686 if (overlap_damage_area->y1 == -1) { ··· 2731 2731 static void 2732 2732 intel_psr2_sel_fetch_et_alignment(struct intel_atomic_state *state, 2733 2733 struct intel_crtc *crtc, 2734 + struct drm_rect *display_area, 2734 2735 bool *cursor_in_su_area) 2735 2736 { 2736 2737 struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); ··· 2759 2758 continue; 2760 2759 2761 2760 clip_area_update(&crtc_state->psr2_su_area, &new_plane_state->uapi.dst, 2762 - &crtc_state->pipe_src); 2761 + display_area); 2763 2762 *cursor_in_su_area = true; 2764 2763 } 2765 2764 } ··· 2856 2855 struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); 2857 2856 struct intel_plane_state *new_plane_state, *old_plane_state; 2858 2857 struct intel_plane *plane; 2858 + struct drm_rect display_area = { 2859 + .x1 = 0, 2860 + .y1 = 0, 2861 + .x2 = crtc_state->hw.adjusted_mode.crtc_hdisplay, 2862 + .y2 = crtc_state->hw.adjusted_mode.crtc_vdisplay, 2863 + }; 2859 2864 bool full_update = false, su_area_changed; 2860 2865 int i, ret; 2861 2866 ··· 2875 2868 2876 2869 crtc_state->psr2_su_area.x1 = 0; 2877 2870 crtc_state->psr2_su_area.y1 = -1; 2878 - crtc_state->psr2_su_area.x2 = drm_rect_width(&crtc_state->pipe_src); 2871 + crtc_state->psr2_su_area.x2 = drm_rect_width(&display_area); 2879 2872 crtc_state->psr2_su_area.y2 = -1; 2880 2873 2881 2874 /* ··· 2913 2906 damaged_area.y1 = old_plane_state->uapi.dst.y1; 2914 2907 damaged_area.y2 = old_plane_state->uapi.dst.y2; 2915 2908 clip_area_update(&crtc_state->psr2_su_area, &damaged_area, 2916 - &crtc_state->pipe_src); 2909 + &display_area); 2917 2910 } 2918 2911 2919 2912 if (new_plane_state->uapi.visible) { 2920 2913 damaged_area.y1 = new_plane_state->uapi.dst.y1; 2921 2914 damaged_area.y2 = new_plane_state->uapi.dst.y2; 2922 2915 clip_area_update(&crtc_state->psr2_su_area, &damaged_area, 2923 - &crtc_state->pipe_src); 2916 + &display_area); 2924 2917 } 2925 2918 continue; 2926 2919 } else if (new_plane_state->uapi.alpha != old_plane_state->uapi.alpha) { ··· 2928 2921 damaged_area.y1 = new_plane_state->uapi.dst.y1; 2929 2922 damaged_area.y2 = new_plane_state->uapi.dst.y2; 2930 2923 clip_area_update(&crtc_state->psr2_su_area, &damaged_area, 2931 - &crtc_state->pipe_src); 2924 + &display_area); 2932 2925 continue; 2933 2926 } 2934 2927 ··· 2944 2937 damaged_area.x1 += new_plane_state->uapi.dst.x1 - src.x1; 2945 2938 damaged_area.x2 += new_plane_state->uapi.dst.x1 - src.x1; 2946 2939 2947 - clip_area_update(&crtc_state->psr2_su_area, &damaged_area, &crtc_state->pipe_src); 2940 + clip_area_update(&crtc_state->psr2_su_area, &damaged_area, &display_area); 2948 2941 } 2949 2942 2950 2943 /* ··· 2979 2972 * cursor is added into affected planes even when 2980 2973 * cursor is not updated by itself. 2981 2974 */ 2982 - intel_psr2_sel_fetch_et_alignment(state, crtc, &cursor_in_su_area); 2975 + intel_psr2_sel_fetch_et_alignment(state, crtc, &display_area, 2976 + &cursor_in_su_area); 2983 2977 2984 2978 su_area_changed = intel_psr2_sel_fetch_pipe_alignment(crtc_state); 2985 2979 ··· 3056 3048 3057 3049 skip_sel_fetch_set_loop: 3058 3050 if (full_update) 3059 - clip_area_update(&crtc_state->psr2_su_area, &crtc_state->pipe_src, 3060 - &crtc_state->pipe_src); 3051 + clip_area_update(&crtc_state->psr2_su_area, &display_area, 3052 + &display_area); 3061 3053 3062 3054 psr2_man_trk_ctl_calc(crtc_state, full_update); 3063 3055 crtc_state->pipe_srcsz_early_tpt =