@@ -363,6 +363,35 @@ nv50_outp_atomic_check_view(struct drm_encoder *encoder,
363
363
return 0 ;
364
364
}
365
365
366
+ static void
367
+ nv50_outp_atomic_fix_depth (struct drm_encoder * encoder , struct drm_crtc_state * crtc_state )
368
+ {
369
+ struct nv50_head_atom * asyh = nv50_head_atom (crtc_state );
370
+ struct nouveau_encoder * nv_encoder = nouveau_encoder (encoder );
371
+ struct drm_display_mode * mode = & asyh -> state .adjusted_mode ;
372
+ unsigned int max_rate , mode_rate ;
373
+
374
+ switch (nv_encoder -> dcb -> type ) {
375
+ case DCB_OUTPUT_DP :
376
+ max_rate = nv_encoder -> dp .link_nr * nv_encoder -> dp .link_bw ;
377
+
378
+ /* we don't support more than 10 anyway */
379
+ asyh -> or .bpc = min_t (u8 , asyh -> or .bpc , 10 );
380
+
381
+ /* reduce the bpc until it works out */
382
+ while (asyh -> or .bpc > 6 ) {
383
+ mode_rate = DIV_ROUND_UP (mode -> clock * asyh -> or .bpc * 3 , 8 );
384
+ if (mode_rate <= max_rate )
385
+ break ;
386
+
387
+ asyh -> or .bpc -= 2 ;
388
+ }
389
+ break ;
390
+ default :
391
+ break ;
392
+ }
393
+ }
394
+
366
395
static int
367
396
nv50_outp_atomic_check (struct drm_encoder * encoder ,
368
397
struct drm_crtc_state * crtc_state ,
@@ -381,6 +410,9 @@ nv50_outp_atomic_check(struct drm_encoder *encoder,
381
410
if (crtc_state -> mode_changed || crtc_state -> connectors_changed )
382
411
asyh -> or .bpc = connector -> display_info .bpc ;
383
412
413
+ /* We might have to reduce the bpc */
414
+ nv50_outp_atomic_fix_depth (encoder , crtc_state );
415
+
384
416
return 0 ;
385
417
}
386
418
0 commit comments