@@ -185,11 +185,45 @@ static void kmb_crtc_atomic_flush(struct drm_crtc *crtc,
185
185
spin_unlock_irq (& crtc -> dev -> event_lock );
186
186
}
187
187
188
+ static enum drm_mode_status
189
+ kmb_crtc_mode_valid (struct drm_crtc * crtc ,
190
+ const struct drm_display_mode * mode )
191
+ {
192
+ int refresh ;
193
+ struct drm_device * dev = crtc -> dev ;
194
+ int vfp = mode -> vsync_start - mode -> vdisplay ;
195
+
196
+ if (mode -> vdisplay < KMB_CRTC_MAX_HEIGHT ) {
197
+ drm_dbg (dev , "height = %d less than %d" ,
198
+ mode -> vdisplay , KMB_CRTC_MAX_HEIGHT );
199
+ return MODE_BAD_VVALUE ;
200
+ }
201
+ if (mode -> hdisplay < KMB_CRTC_MAX_WIDTH ) {
202
+ drm_dbg (dev , "width = %d less than %d" ,
203
+ mode -> hdisplay , KMB_CRTC_MAX_WIDTH );
204
+ return MODE_BAD_HVALUE ;
205
+ }
206
+ refresh = drm_mode_vrefresh (mode );
207
+ if (refresh < KMB_MIN_VREFRESH || refresh > KMB_MAX_VREFRESH ) {
208
+ drm_dbg (dev , "refresh = %d less than %d or greater than %d" ,
209
+ refresh , KMB_MIN_VREFRESH , KMB_MAX_VREFRESH );
210
+ return MODE_BAD ;
211
+ }
212
+
213
+ if (vfp < KMB_CRTC_MIN_VFP ) {
214
+ drm_dbg (dev , "vfp = %d less than %d" , vfp , KMB_CRTC_MIN_VFP );
215
+ return MODE_BAD ;
216
+ }
217
+
218
+ return MODE_OK ;
219
+ }
220
+
188
221
static const struct drm_crtc_helper_funcs kmb_crtc_helper_funcs = {
189
222
.atomic_begin = kmb_crtc_atomic_begin ,
190
223
.atomic_enable = kmb_crtc_atomic_enable ,
191
224
.atomic_disable = kmb_crtc_atomic_disable ,
192
225
.atomic_flush = kmb_crtc_atomic_flush ,
226
+ .mode_valid = kmb_crtc_mode_valid ,
193
227
};
194
228
195
229
int kmb_setup_crtc (struct drm_device * drm )
0 commit comments