@@ -302,6 +302,7 @@ struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
302302 refcount_inc (& hvs -> lbm_refcounts [vc4_state -> lbm_handle ].refcount );
303303
304304 vc4_state -> dlist_initialized = 0 ;
305+ vc4_state -> is_yuv444_unity = false;
305306
306307 __drm_atomic_helper_plane_duplicate_state (plane , & vc4_state -> base );
307308
@@ -871,6 +872,10 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
871872{
872873 struct vc4_dev * vc4 = to_vc4_dev (state -> plane -> dev );
873874 struct vc4_plane_state * vc4_state = to_vc4_plane_state (state );
875+ bool no_interpolate = state -> scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR ;
876+
877+ if (vc4_state -> is_yuv444_unity )
878+ no_interpolate = 1 ;
874879
875880 WARN_ON_ONCE (vc4 -> gen > VC4_GEN_6_D );
876881
@@ -879,15 +884,15 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
879884 vc4_write_ppf (vc4_state , vc4_state -> src_w [channel ],
880885 vc4_state -> crtc_w , vc4_state -> src_x , channel ,
881886 state -> chroma_siting_h ,
882- state -> scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR );
887+ no_interpolate );
883888 }
884889
885890 /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
886891 if (vc4_state -> y_scaling [channel ] == VC4_SCALING_PPF ) {
887892 vc4_write_ppf (vc4_state , vc4_state -> src_h [channel ],
888893 vc4_state -> crtc_h , vc4_state -> src_y , channel ,
889894 state -> chroma_siting_v ,
890- state -> scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR );
895+ no_interpolate );
891896 vc4_dlist_write (vc4_state , 0xc0c0c0c0 );
892897 }
893898
@@ -1867,12 +1872,19 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
18671872 if (vc4_state -> x_scaling [0 ] == VC4_SCALING_NONE ) {
18681873 vc4_state -> x_scaling [0 ] = VC4_SCALING_PPF ;
18691874 vc4_state -> is_unity = false;
1875+ vc4_state -> is_yuv444_unity = true;
18701876 }
18711877
18721878 if (vc4_state -> y_scaling [0 ] == VC4_SCALING_NONE ) {
18731879 vc4_state -> y_scaling [0 ] = VC4_SCALING_PPF ;
18741880 vc4_state -> is_unity = false;
1881+ } else {
1882+ /* Ensure that resizing vertically but not horizontally
1883+ * doesn't switch the scaling filter.
1884+ */
1885+ vc4_state -> is_yuv444_unity = false;
18751886 }
1887+
18761888 }
18771889
18781890 if (!vc4_state -> src_w [0 ] || !vc4_state -> src_h [0 ] ||
@@ -2199,6 +2211,9 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
21992211 filter = & vc4 -> hvs -> nearest_neighbour_filter ;
22002212 break ;
22012213 }
2214+ if (vc4_state -> is_yuv444_unity )
2215+ filter = & vc4 -> hvs -> nearest_neighbour_filter ;
2216+
22022217 u32 kernel = VC4_SET_FIELD (filter -> start ,
22032218 SCALER_PPF_KERNEL_OFFSET );
22042219
0 commit comments