summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvd0_display.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-11-16 11:21:37 +1000
committerBen Skeggs <bskeggs@redhat.com>2012-11-29 09:57:55 +1000
commit97b19b5c6f32842c92800b62b367cc5a91555188 (patch)
tree752ec394bc119984d24bda72604915482de8045b /drivers/gpu/drm/nouveau/nvd0_display.c
parentde8268c503de7754ae7d535c3b114b1c83e00612 (diff)
downloadlinux-97b19b5c6f32842c92800b62b367cc5a91555188.tar.bz2
drm/nvd0/disp: implement dac support for older display classes
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvd0_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index 8abc3edb4612..037602b72d6c 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -1264,30 +1264,46 @@ static void
nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct nvd0_mast *mast = nvd0_mast(encoder->dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
- u32 syncs, magic, *push;
-
- syncs = 0x00000001;
- if (mode->flags & DRM_MODE_FLAG_NHSYNC)
- syncs |= 0x00000008;
- if (mode->flags & DRM_MODE_FLAG_NVSYNC)
- syncs |= 0x00000010;
-
- magic = 0x31ec6000 | (nv_crtc->index << 25);
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- magic |= 0x00000001;
+ u32 *push;
nvd0_dac_dpms(encoder, DRM_MODE_DPMS_ON);
- push = evo_wait(nvd0_mast(encoder->dev), 8);
+ push = evo_wait(mast, 8);
if (push) {
- evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
- evo_data(push, syncs);
- evo_data(push, magic);
- evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1);
- evo_data(push, 1 << nv_crtc->index);
- evo_kick(push, nvd0_mast(encoder->dev));
+ if (nvd0_vers(mast) < NVD0_DISP_MAST_CLASS) {
+ u32 syncs = 0x00000000;
+
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ syncs |= 0x00000001;
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ syncs |= 0x00000002;
+
+ evo_mthd(push, 0x0400 + (nv_encoder->or * 0x080), 2);
+ evo_data(push, 1 << nv_crtc->index);
+ evo_data(push, syncs);
+ } else {
+ u32 magic = 0x31ec6000 | (nv_crtc->index << 25);
+ u32 syncs = 0x00000001;
+
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ syncs |= 0x00000008;
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ syncs |= 0x00000010;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ magic |= 0x00000001;
+
+ evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
+ evo_data(push, syncs);
+ evo_data(push, magic);
+ evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1);
+ evo_data(push, 1 << nv_crtc->index);
+ }
+
+ evo_kick(push, mast);
}
nv_encoder->crtc = encoder->crtc;
@@ -1297,23 +1313,30 @@ static void
nvd0_dac_disconnect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
+ struct nvd0_mast *mast = nvd0_mast(encoder->dev);
+ const int or = nv_encoder->or;
u32 *push;
if (nv_encoder->crtc) {
nvd0_crtc_prepare(nv_encoder->crtc);
- push = evo_wait(nvd0_mast(dev), 4);
+ push = evo_wait(mast, 4);
if (push) {
- evo_mthd(push, 0x0180 + (nv_encoder->or * 0x20), 1);
- evo_data(push, 0x00000000);
+ if (nvd0_vers(mast) < NVD0_DISP_MAST_CLASS) {
+ evo_mthd(push, 0x0400 + (or * 0x080), 1);
+ evo_data(push, 0x00000000);
+ } else {
+ evo_mthd(push, 0x0180 + (or * 0x020), 1);
+ evo_data(push, 0x00000000);
+ }
+
evo_mthd(push, 0x0080, 1);
evo_data(push, 0x00000000);
- evo_kick(push, nvd0_mast(dev));
+ evo_kick(push, mast);
}
-
- nv_encoder->crtc = NULL;
}
+
+ nv_encoder->crtc = NULL;
}
static enum drm_connector_status