[v3,01/10] drm/nouveau: Clean up nv50_head_atomic_check_mode() and fix blankus calculation

Submitted by Alastair Bridgewater on April 11, 2017, 5:11 p.m.

Details

Message ID 20170411171125.10496-2-alastair.bridgewater@gmail.com
State New
Headers show

Not browsing as part of any series.

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index c9910c8..c901f32 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -2035,34 +2035,37 @@  static void
 nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
 {
 	struct drm_display_mode *mode = &asyh->state.adjusted_mode;
-	u32 ilace   = (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1;
-	u32 vscan   = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1;
-	u32 hbackp  =  mode->htotal - mode->hsync_end;
-	u32 vbackp  = (mode->vtotal - mode->vsync_end) * vscan / ilace;
-	u32 hfrontp =  mode->hsync_start - mode->hdisplay;
-	u32 vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace;
-	u32 blankus;
 	struct nv50_head_mode *m = &asyh->mode;
+	u32 blankus;
 
-	m->h.active = mode->htotal;
-	m->h.synce  = mode->hsync_end - mode->hsync_start - 1;
-	m->h.blanke = m->h.synce + hbackp;
-	m->h.blanks = mode->htotal - hfrontp - 1;
+	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 
-	m->v.active = mode->vtotal * vscan / ilace;
-	m->v.synce  = ((mode->vsync_end - mode->vsync_start) * vscan / ilace) - 1;
-	m->v.blanke = m->v.synce + vbackp;
-	m->v.blanks = m->v.active - vfrontp - 1;
+	/*
+	 * DRM modes are defined in terms of a repeating interval
+	 * starting with the active display area.  The hardware modes
+	 * are defined in terms of a repeating interval starting one
+	 * unit (pixel or line) into the sync pulse.  So, add bias.
+	 */
+
+	m->h.active = mode->crtc_htotal;
+	m->h.synce  = mode->crtc_hsync_end - mode->crtc_hsync_start - 1;
+	m->h.blanke = mode->crtc_hblank_end - mode->crtc_hsync_start - 1;
+	m->h.blanks = m->h.blanke + mode->crtc_hdisplay;
+
+	m->v.active = mode->crtc_vtotal;
+	m->v.synce  = mode->crtc_vsync_end - mode->crtc_vsync_start - 1;
+	m->v.blanke = mode->crtc_vblank_end - mode->crtc_vsync_start - 1;
+	m->v.blanks = m->v.blanke + mode->crtc_vdisplay;
 
 	/*XXX: Safe underestimate, even "0" works */
-	blankus = (m->v.active - mode->vdisplay - 2) * m->h.active;
+	blankus = (m->v.active - mode->crtc_vdisplay - 2) * m->h.active;
 	blankus *= 1000;
-	blankus /= mode->clock;
+	blankus /= mode->crtc_clock;
 	m->v.blankus = blankus;
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
-		m->v.blank2e =  m->v.active + m->v.synce + vbackp;
-		m->v.blank2s =  m->v.blank2e + (mode->vdisplay * vscan / ilace);
+		m->v.blank2e =  m->v.active + m->v.blanke;
+		m->v.blank2s =  m->v.blank2e + mode->crtc_vdisplay;
 		m->v.active  = (m->v.active * 2) + 1;
 		m->interlace = true;
 	} else {
@@ -2070,9 +2073,8 @@  nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
 		m->v.blank2s = 1;
 		m->interlace = false;
 	}
-	m->clock = mode->clock;
+	m->clock = mode->crtc_clock;
 
-	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 	asyh->set.mode = true;
 }