[v2,09/10] drm/nouveau: Handle frame-packing mode geometry and timing effects

Submitted by Alastair Bridgewater on March 27, 2017, 9:58 p.m.

Details

Message ID 20170327215807.8461-10-alastair.bridgewater@gmail.com
State New
Headers show
Series "drm/nouveau: Enable HDMI Stereoscopy" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Alastair Bridgewater March 27, 2017, 9:58 p.m.
* Frame-packing modes add an extra vtotal raster lines to each
frame above and beyond what the basic mode description calls for.
Account for this during scaler configuration (possibly a bit of a
hack), during CRTC configuration (clearly not a hack), and when
checking that a mode is vaild for a given connector (cribbed from
the i915 driver).

Signed-off-by: Alastair Bridgewater <alastair.bridgewater@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_connector.c |  3 +++
 drivers/gpu/drm/nouveau/nv50_display.c      | 21 ++++++++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 947c200..4e3563e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -1044,6 +1044,9 @@  nouveau_connector_mode_valid(struct drm_connector *connector,
 		return MODE_BAD;
 	}
 
+	if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
+		clock *= 2;
+
 	if (clock < min_clock)
 		return MODE_CLOCK_LOW;
 
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 008aea6..fa97604 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1963,6 +1963,7 @@  nv50_head_atomic_check_view(struct nv50_head_atom *armh,
 	struct drm_display_mode *umode = &asyh->state.mode;
 	int mode = asyc->scaler.mode;
 	struct edid *edid;
+	int umode_vdisplay, omode_hdisplay, omode_vdisplay;
 
 	if (connector->edid_blob_ptr)
 		edid = (struct edid *)connector->edid_blob_ptr->data;
@@ -1977,12 +1978,18 @@  nv50_head_atomic_check_view(struct nv50_head_atom *armh,
 		mode = DRM_MODE_SCALE_FULLSCREEN;
 	}
 
+	/* For the user-specified mode, we must ignore doublescan and
+	 * the like, but honor frame packing.
+	 */
+	umode_vdisplay = umode->vdisplay;
+	if ((umode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
+		umode_vdisplay += umode->vtotal;
 	asyh->view.iW = umode->hdisplay;
-	asyh->view.iH = umode->vdisplay;
-	asyh->view.oW = omode->hdisplay;
-	asyh->view.oH = omode->vdisplay;
-	if (omode->flags & DRM_MODE_FLAG_DBLSCAN)
-		asyh->view.oH *= 2;
+	asyh->view.iH = umode_vdisplay;
+	/* For the ouput mode, we can just use the stock helper. */
+	drm_crtc_get_hv_timing(omode, &omode_hdisplay, &omode_vdisplay);
+	asyh->view.oW = omode_hdisplay;
+	asyh->view.oH = omode_vdisplay;
 
 	/* Add overscan compensation if necessary, will keep the aspect
 	 * ratio the same as the backend mode unless overridden by the
@@ -2012,7 +2019,7 @@  nv50_head_atomic_check_view(struct nv50_head_atom *armh,
 	switch (mode) {
 	case DRM_MODE_SCALE_CENTER:
 		asyh->view.oW = min((u16)umode->hdisplay, asyh->view.oW);
-		asyh->view.oH = min((u16)umode->vdisplay, asyh->view.oH);
+		asyh->view.oH = min((u16)umode_vdisplay, asyh->view.oH);
 		/* fall-through */
 	case DRM_MODE_SCALE_ASPECT:
 		if (asyh->view.oH < asyh->view.oW) {
@@ -2037,7 +2044,7 @@  nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
 	struct nv50_head_mode *m = &asyh->mode;
 	u32 hbackp, vbackp, hfrontp, vfrontp;
 
-	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE);
 
 	hbackp = mode->crtc_htotal - mode->crtc_hsync_end;
 	vbackp = mode->crtc_vtotal - mode->crtc_vsync_end;

Comments

Hi Alastair,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.11-rc4 next-20170327]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Alastair-Bridgewater/Enable-HDMI-Stereoscopy/20170328-090906
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-randconfig-s0-201713 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/nouveau/nv50_display.c: In function 'nv50_head_atomic_check_view':
>> drivers/gpu/drm/nouveau/nv50_display.c:1995:2: error: implicit declaration of function 'drm_crtc_get_hv_timing' [-Werror=implicit-function-declaration]
     drm_crtc_get_hv_timing(omode, &omode_hdisplay, &omode_vdisplay);
     ^~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/drm_crtc_get_hv_timing +1995 drivers/gpu/drm/nouveau/nv50_display.c

  1989		umode_vdisplay = umode->vdisplay;
  1990		if ((umode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
  1991			umode_vdisplay += umode->vtotal;
  1992		asyh->view.iW = umode->hdisplay;
  1993		asyh->view.iH = umode_vdisplay;
  1994		/* For the ouput mode, we can just use the stock helper. */
> 1995		drm_crtc_get_hv_timing(omode, &omode_hdisplay, &omode_vdisplay);
  1996		asyh->view.oW = omode_hdisplay;
  1997		asyh->view.oH = omode_vdisplay;
  1998	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation