[Nouveau] [PATCH v2 09/10] drm/nouveau: Handle frame-packing mode geometry and timing effects
Alastair Bridgewater
alastair.bridgewater at gmail.com
Mon Mar 27 21:58:06 UTC 2017
* 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 at 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(-)
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;
--
2.10.2
More information about the Nouveau
mailing list