aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-06-30 01:25:57 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-12 20:13:12 -0400
commit7149eee87a020cb81c52e9653a44c5f9e7c2a0d9 (patch)
tree9eba071055ddea1aa36c5a1425c1379061d29145
parent309b8c89c8ddf9dd8e5f253c185d6af1d0358a79 (diff)
drm/nv50: fix DP->DVI if output has been programmed for native DP previously
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_reg.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c31
2 files changed, 32 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 6ca80a3fe70d..b6391a132f0a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -814,6 +814,7 @@
814#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 814#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000
815#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff 815#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff
816#define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) 816#define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80)
817#define NV50_SOR_DP_CTRL_ENABLED 0x00000001
817#define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 818#define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000
818#define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 819#define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000
819#define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 820#define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index e031904ef7a7..0c762049cb68 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -821,6 +821,36 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb)
821 } 821 }
822} 822}
823 823
824/* If programming a TMDS output on a SOR that can also be configured for
825 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
826 *
827 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
828 * the VBIOS scripts on at least one board I have only switch it off on
829 * link 0, causing a blank display if the output has previously been
830 * programmed for DisplayPort.
831 */
832static void
833nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
834{
835 int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
836 struct drm_encoder *encoder;
837 u32 tmp;
838
839 if (dcb->type != OUTPUT_TMDS)
840 return;
841
842 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
843 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
844
845 if (nv_encoder->dcb->type == OUTPUT_DP) {
846 tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
847 tmp &= ~NV50_SOR_DP_CTRL_ENABLED;
848 nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
849 break;
850 }
851 }
852}
853
824static void 854static void
825nv50_display_unk20_handler(struct drm_device *dev) 855nv50_display_unk20_handler(struct drm_device *dev)
826{ 856{
@@ -845,6 +875,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
845 nouveau_bios_run_display_table(dev, dcbent, script, pclk); 875 nouveau_bios_run_display_table(dev, dcbent, script, pclk);
846 876
847 nv50_display_unk20_dp_hack(dev, dcbent); 877 nv50_display_unk20_dp_hack(dev, dcbent);
878 nv50_display_unk20_dp_set_tmds(dev, dcbent);
848 879
849 tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); 880 tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
850 tmp &= ~0x000000f; 881 tmp &= ~0x000000f;