@@ -111,6 +111,8 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
111111 struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
112112 const struct drm_display_mode * adjusted_mode =
113113 & crtc_state -> hw .adjusted_mode ;
114+ int pipe_src_w = drm_rect_width (& crtc_state -> pipe_src );
115+ int pipe_src_h = drm_rect_height (& crtc_state -> pipe_src );
114116 int min_src_w , min_src_h , min_dst_w , min_dst_h ;
115117 int max_src_w , max_src_h , max_dst_w , max_dst_h ;
116118
@@ -207,6 +209,21 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
207209 return - EINVAL ;
208210 }
209211
212+ /*
213+ * The pipe scaler does not use all the bits of PIPESRC, at least
214+ * on the earlier platforms. So even when we're scaling a plane
215+ * the *pipe* source size must not be too large. For simplicity
216+ * we assume the limits match the scaler source size limits. Might
217+ * not be 100% accurate on all platforms, but good enough for now.
218+ */
219+ if (pipe_src_w > max_src_w || pipe_src_h > max_src_h ) {
220+ drm_dbg_kms (& dev_priv -> drm ,
221+ "scaler_user index %u.%u: pipe src size %ux%u "
222+ "is out of scaler range\n" ,
223+ crtc -> pipe , scaler_user , pipe_src_w , pipe_src_h );
224+ return - EINVAL ;
225+ }
226+
210227 /* mark this plane as a scaler user in crtc_state */
211228 scaler_state -> scaler_users |= (1 << scaler_user );
212229 drm_dbg_kms (& dev_priv -> drm , "scaler_user index %u.%u: "
0 commit comments