Commit 1cb9469e authored by Ben Skeggs's avatar Ben Skeggs

drm/nv50/disp: fix scaling of doublescan modes

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 616a5f57
...@@ -195,7 +195,8 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) ...@@ -195,7 +195,8 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
struct drm_crtc *crtc = &nv_crtc->base; struct drm_crtc *crtc = &nv_crtc->base;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct nouveau_channel *evo = nv50_display(dev)->master; struct nouveau_channel *evo = nv50_display(dev)->master;
struct drm_display_mode *mode = &crtc->mode; struct drm_display_mode *umode = &crtc->mode;
struct drm_display_mode *omode;
int scaling_mode, ret; int scaling_mode, ret;
u32 ctrl = 0, oX, oY; u32 ctrl = 0, oX, oY;
...@@ -212,13 +213,15 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) ...@@ -212,13 +213,15 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
/* start off at the resolution we programmed the crtc for, this /* start off at the resolution we programmed the crtc for, this
* effectively handles NONE/FULL scaling * effectively handles NONE/FULL scaling
*/ */
if (scaling_mode != DRM_MODE_SCALE_NONE) { if (scaling_mode != DRM_MODE_SCALE_NONE)
oX = nv_connector->native_mode->hdisplay; omode = nv_connector->native_mode;
oY = nv_connector->native_mode->vdisplay; else
} else { omode = umode;
oX = mode->hdisplay;
oY = mode->vdisplay; oX = omode->hdisplay;
} oY = omode->vdisplay;
if (omode->flags & DRM_MODE_FLAG_DBLSCAN)
oY *= 2;
/* add overscan compensation if necessary, will keep the aspect /* add overscan compensation if necessary, will keep the aspect
* ratio the same as the backend mode unless overridden by the * ratio the same as the backend mode unless overridden by the
...@@ -248,15 +251,15 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) ...@@ -248,15 +251,15 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
*/ */
switch (scaling_mode) { switch (scaling_mode) {
case DRM_MODE_SCALE_CENTER: case DRM_MODE_SCALE_CENTER:
oX = min((u32)mode->hdisplay, oX); oX = min((u32)umode->hdisplay, oX);
oY = min((u32)mode->vdisplay, oY); oY = min((u32)umode->vdisplay, oY);
/* fall-through */ /* fall-through */
case DRM_MODE_SCALE_ASPECT: case DRM_MODE_SCALE_ASPECT:
if (oY < oX) { if (oY < oX) {
u32 aspect = (mode->hdisplay << 19) / mode->vdisplay; u32 aspect = (umode->hdisplay << 19) / umode->vdisplay;
oX = ((oY * aspect) + (aspect / 2)) >> 19; oX = ((oY * aspect) + (aspect / 2)) >> 19;
} else { } else {
u32 aspect = (mode->vdisplay << 19) / mode->hdisplay; u32 aspect = (umode->vdisplay << 19) / umode->hdisplay;
oY = ((oX * aspect) + (aspect / 2)) >> 19; oY = ((oX * aspect) + (aspect / 2)) >> 19;
} }
break; break;
...@@ -264,9 +267,9 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) ...@@ -264,9 +267,9 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
break; break;
} }
if (mode->hdisplay != oX || mode->vdisplay != oY || if (umode->hdisplay != oX || umode->vdisplay != oY ||
mode->flags & DRM_MODE_FLAG_INTERLACE || umode->flags & DRM_MODE_FLAG_INTERLACE ||
mode->flags & DRM_MODE_FLAG_DBLSCAN) umode->flags & DRM_MODE_FLAG_DBLSCAN)
ctrl |= NV50_EVO_CRTC_SCALE_CTRL_ACTIVE; ctrl |= NV50_EVO_CRTC_SCALE_CTRL_ACTIVE;
ret = RING_SPACE(evo, 5); ret = RING_SPACE(evo, 5);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment