@@ -2619,6 +2619,12 @@ void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb,
26192619
26202620 intel_de_write_dsb (display , dsb , PIPE_SRCSZ_ERLY_TPT (crtc -> pipe ),
26212621 crtc_state -> pipe_srcsz_early_tpt );
2622+
2623+ if (!crtc_state -> dsc .compression_enable )
2624+ return ;
2625+
2626+ intel_dsc_su_et_parameters_configure (dsb , encoder , crtc_state ,
2627+ drm_rect_height (& crtc_state -> psr2_su_area ));
26222628}
26232629
26242630static void psr2_man_trk_ctl_calc (struct intel_crtc_state * crtc_state ,
@@ -2689,11 +2695,12 @@ static void clip_area_update(struct drm_rect *overlap_damage_area,
26892695 overlap_damage_area -> y2 = damage_area -> y2 ;
26902696}
26912697
2692- static void intel_psr2_sel_fetch_pipe_alignment (struct intel_crtc_state * crtc_state )
2698+ static bool intel_psr2_sel_fetch_pipe_alignment (struct intel_crtc_state * crtc_state )
26932699{
26942700 struct intel_display * display = to_intel_display (crtc_state );
26952701 const struct drm_dsc_config * vdsc_cfg = & crtc_state -> dsc .config ;
26962702 u16 y_alignment ;
2703+ bool su_area_changed = false;
26972704
26982705 /* ADLP aligns the SU region to vdsc slice height in case dsc is enabled */
26992706 if (crtc_state -> dsc .compression_enable &&
@@ -2702,10 +2709,18 @@ static void intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_st
27022709 else
27032710 y_alignment = crtc_state -> su_y_granularity ;
27042711
2705- crtc_state -> psr2_su_area .y1 -= crtc_state -> psr2_su_area .y1 % y_alignment ;
2706- if (crtc_state -> psr2_su_area .y2 % y_alignment )
2712+ if (crtc_state -> psr2_su_area .y1 % y_alignment ) {
2713+ crtc_state -> psr2_su_area .y1 -= crtc_state -> psr2_su_area .y1 % y_alignment ;
2714+ su_area_changed = true;
2715+ }
2716+
2717+ if (crtc_state -> psr2_su_area .y2 % y_alignment ) {
27072718 crtc_state -> psr2_su_area .y2 = ((crtc_state -> psr2_su_area .y2 /
27082719 y_alignment ) + 1 ) * y_alignment ;
2720+ su_area_changed = true;
2721+ }
2722+
2723+ return su_area_changed ;
27092724}
27102725
27112726/*
@@ -2839,7 +2854,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
28392854 struct intel_crtc_state * crtc_state = intel_atomic_get_new_crtc_state (state , crtc );
28402855 struct intel_plane_state * new_plane_state , * old_plane_state ;
28412856 struct intel_plane * plane ;
2842- bool full_update = false, cursor_in_su_area = false ;
2857+ bool full_update = false, su_area_changed ;
28432858 int i , ret ;
28442859
28452860 if (!crtc_state -> enable_psr2_sel_fetch )
@@ -2946,15 +2961,32 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
29462961 if (ret )
29472962 return ret ;
29482963
2949- /*
2950- * Adjust su area to cover cursor fully as necessary (early
2951- * transport). This needs to be done after
2952- * drm_atomic_add_affected_planes to ensure visible cursor is added into
2953- * affected planes even when cursor is not updated by itself.
2954- */
2955- intel_psr2_sel_fetch_et_alignment (state , crtc , & cursor_in_su_area );
2964+ do {
2965+ bool cursor_in_su_area ;
29562966
2957- intel_psr2_sel_fetch_pipe_alignment (crtc_state );
2967+ /*
2968+ * Adjust su area to cover cursor fully as necessary
2969+ * (early transport). This needs to be done after
2970+ * drm_atomic_add_affected_planes to ensure visible
2971+ * cursor is added into affected planes even when
2972+ * cursor is not updated by itself.
2973+ */
2974+ intel_psr2_sel_fetch_et_alignment (state , crtc , & cursor_in_su_area );
2975+
2976+ su_area_changed = intel_psr2_sel_fetch_pipe_alignment (crtc_state );
2977+
2978+ /*
2979+ * If the cursor was outside the SU area before
2980+ * alignment, the alignment step (which only expands
2981+ * SU) may pull the cursor partially inside, so we
2982+ * must run ET alignment again to fully cover it. But
2983+ * if the cursor was already fully inside before
2984+ * alignment, expanding the SU area won't change that,
2985+ * so no further work is needed.
2986+ */
2987+ if (cursor_in_su_area )
2988+ break ;
2989+ } while (su_area_changed );
29582990
29592991 /*
29602992 * Now that we have the pipe damaged area check if it intersect with
@@ -3014,6 +3046,10 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
30143046 }
30153047
30163048skip_sel_fetch_set_loop :
3049+ if (full_update )
3050+ clip_area_update (& crtc_state -> psr2_su_area , & crtc_state -> pipe_src ,
3051+ & crtc_state -> pipe_src );
3052+
30173053 psr2_man_trk_ctl_calc (crtc_state , full_update );
30183054 crtc_state -> pipe_srcsz_early_tpt =
30193055 psr2_pipe_srcsz_early_tpt_calc (crtc_state , full_update );
0 commit comments