diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-03-11 21:42:20 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-03-13 03:15:06 -0400 |
commit | 3488c57b983546e6bf4c9e0bfd0f7f2a1292267a (patch) | |
tree | e71cef2d0d1766bc4065e2b5468608598ece0739 /drivers/gpu/drm/nouveau/nvd0_display.c | |
parent | 6860dc8251eacd1672fa660b85bb59a45350aa70 (diff) |
drm/nvd0/disp: move syncs/magic setup to or mode_set
NVIDIA appear to do these around the same place they do the MODE_CTRL
methods, and for DP at least we need to bash some extra bits in "syncs"
to keep EVO happy.
It's a bit of a guess as to the 6/8bpc, but i have no better idea yet.
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.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 3c2543190bb8..ae6d80fff4bd 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -634,8 +634,7 @@ nvd0_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
634 | u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks; | 634 | u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks; |
635 | u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks; | 635 | u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks; |
636 | u32 vblan2e = 0, vblan2s = 1; | 636 | u32 vblan2e = 0, vblan2s = 1; |
637 | u32 magic = 0x31ec6000; | 637 | u32 *push; |
638 | u32 syncs, *push; | ||
639 | int ret; | 638 | int ret; |
640 | 639 | ||
641 | hactive = mode->htotal; | 640 | hactive = mode->htotal; |
@@ -655,15 +654,8 @@ nvd0_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
655 | vblan2e = vactive + vsynce + vbackp; | 654 | vblan2e = vactive + vsynce + vbackp; |
656 | vblan2s = vblan2e + (mode->vdisplay * vscan / ilace); | 655 | vblan2s = vblan2e + (mode->vdisplay * vscan / ilace); |
657 | vactive = (vactive * 2) + 1; | 656 | vactive = (vactive * 2) + 1; |
658 | magic |= 0x00000001; | ||
659 | } | 657 | } |
660 | 658 | ||
661 | syncs = 0x00000001; | ||
662 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
663 | syncs |= 0x00000008; | ||
664 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
665 | syncs |= 0x00000010; | ||
666 | |||
667 | ret = nvd0_crtc_swap_fbs(crtc, old_fb); | 659 | ret = nvd0_crtc_swap_fbs(crtc, old_fb); |
668 | if (ret) | 660 | if (ret) |
669 | return ret; | 661 | return ret; |
@@ -683,9 +675,6 @@ nvd0_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
683 | evo_data(push, mode->clock * 1000); | 675 | evo_data(push, mode->clock * 1000); |
684 | evo_data(push, 0x00200000); /* ??? */ | 676 | evo_data(push, 0x00200000); /* ??? */ |
685 | evo_data(push, mode->clock * 1000); | 677 | evo_data(push, mode->clock * 1000); |
686 | evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); | ||
687 | evo_data(push, syncs); | ||
688 | evo_data(push, magic); | ||
689 | evo_mthd(push, 0x04d0 + (nv_crtc->index * 0x300), 2); | 678 | evo_mthd(push, 0x04d0 + (nv_crtc->index * 0x300), 2); |
690 | evo_data(push, 0x00000311); | 679 | evo_data(push, 0x00000311); |
691 | evo_data(push, 0x00000100); | 680 | evo_data(push, 0x00000100); |
@@ -974,13 +963,26 @@ nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
974 | { | 963 | { |
975 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 964 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
976 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 965 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
977 | u32 *push; | 966 | u32 syncs, magic, *push; |
967 | |||
968 | syncs = 0x00000001; | ||
969 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
970 | syncs |= 0x00000008; | ||
971 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
972 | syncs |= 0x00000010; | ||
973 | |||
974 | magic = 0x31ec6000 | (nv_crtc->index << 25); | ||
975 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
976 | magic |= 0x00000001; | ||
978 | 977 | ||
979 | nvd0_dac_dpms(encoder, DRM_MODE_DPMS_ON); | 978 | nvd0_dac_dpms(encoder, DRM_MODE_DPMS_ON); |
980 | 979 | ||
981 | push = evo_wait(encoder->dev, EVO_MASTER, 4); | 980 | push = evo_wait(encoder->dev, EVO_MASTER, 8); |
982 | if (push) { | 981 | if (push) { |
983 | evo_mthd(push, 0x0180 + (nv_encoder->or * 0x20), 2); | 982 | evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); |
983 | evo_data(push, syncs); | ||
984 | evo_data(push, magic); | ||
985 | evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 2); | ||
984 | evo_data(push, 1 << nv_crtc->index); | 986 | evo_data(push, 1 << nv_crtc->index); |
985 | evo_data(push, 0x00ff); | 987 | evo_data(push, 0x00ff); |
986 | evo_kick(push, encoder->dev, EVO_MASTER); | 988 | evo_kick(push, encoder->dev, EVO_MASTER); |
@@ -1404,7 +1406,18 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1404 | struct nouveau_connector *nv_connector; | 1406 | struct nouveau_connector *nv_connector; |
1405 | struct nvbios *bios = &dev_priv->vbios; | 1407 | struct nvbios *bios = &dev_priv->vbios; |
1406 | u32 mode_ctrl = (1 << nv_crtc->index); | 1408 | u32 mode_ctrl = (1 << nv_crtc->index); |
1407 | u32 *push, or_config; | 1409 | u32 syncs, magic, *push; |
1410 | u32 or_config; | ||
1411 | |||
1412 | syncs = 0x00000001; | ||
1413 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
1414 | syncs |= 0x00000008; | ||
1415 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
1416 | syncs |= 0x00000010; | ||
1417 | |||
1418 | magic = 0x31ec6000 | (nv_crtc->index << 25); | ||
1419 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1420 | magic |= 0x00000001; | ||
1408 | 1421 | ||
1409 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | 1422 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
1410 | switch (nv_encoder->dcb->type) { | 1423 | switch (nv_encoder->dcb->type) { |
@@ -1454,10 +1467,13 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1454 | } | 1467 | } |
1455 | break; | 1468 | break; |
1456 | case OUTPUT_DP: | 1469 | case OUTPUT_DP: |
1457 | if (nv_connector->base.display_info.bpc == 6) | 1470 | if (nv_connector->base.display_info.bpc == 6) { |
1458 | nv_encoder->dp.datarate = mode->clock * 18 / 8; | 1471 | nv_encoder->dp.datarate = mode->clock * 18 / 8; |
1459 | else | 1472 | syncs |= 0x00000140; |
1473 | } else { | ||
1460 | nv_encoder->dp.datarate = mode->clock * 24 / 8; | 1474 | nv_encoder->dp.datarate = mode->clock * 24 / 8; |
1475 | syncs |= 0x00000180; | ||
1476 | } | ||
1461 | 1477 | ||
1462 | if (nv_encoder->dcb->sorconf.link & 1) | 1478 | if (nv_encoder->dcb->sorconf.link & 1) |
1463 | mode_ctrl |= 0x00000800; | 1479 | mode_ctrl |= 0x00000800; |
@@ -1478,9 +1494,12 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1478 | nv_encoder->dp.datarate); | 1494 | nv_encoder->dp.datarate); |
1479 | } | 1495 | } |
1480 | 1496 | ||
1481 | push = evo_wait(dev, EVO_MASTER, 4); | 1497 | push = evo_wait(dev, EVO_MASTER, 8); |
1482 | if (push) { | 1498 | if (push) { |
1483 | evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 2); | 1499 | evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); |
1500 | evo_data(push, syncs); | ||
1501 | evo_data(push, magic); | ||
1502 | evo_mthd(push, 0x0200 + (nv_encoder->or * 0x020), 2); | ||
1484 | evo_data(push, mode_ctrl); | 1503 | evo_data(push, mode_ctrl); |
1485 | evo_data(push, or_config); | 1504 | evo_data(push, or_config); |
1486 | evo_kick(push, dev, EVO_MASTER); | 1505 | evo_kick(push, dev, EVO_MASTER); |