From 6d4990c9b5b0723f17c6c4fa1af11c186fad630f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 30 Jun 2010 15:25:57 +1000 Subject: [PATCH] --- yaml --- r: 205049 b: refs/heads/master c: 7149eee87a020cb81c52e9653a44c5f9e7c2a0d9 h: refs/heads/master i: 205047: bb4812a52e16770588fb043ce4300c81012b930e v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_reg.h | 1 + trunk/drivers/gpu/drm/nouveau/nv50_display.c | 31 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 354e9ba795a4..41e8bf62d6e9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 309b8c89c8ddf9dd8e5f253c185d6af1d0358a79 +refs/heads/master: 7149eee87a020cb81c52e9653a44c5f9e7c2a0d9 diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_reg.h b/trunk/drivers/gpu/drm/nouveau/nouveau_reg.h index 6ca80a3fe70d..b6391a132f0a 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -814,6 +814,7 @@ #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff #define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) +#define NV50_SOR_DP_CTRL_ENABLED 0x00000001 #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 #define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_display.c b/trunk/drivers/gpu/drm/nouveau/nv50_display.c index e031904ef7a7..0c762049cb68 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_display.c @@ -821,6 +821,36 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb) } } +/* If programming a TMDS output on a SOR that can also be configured for + * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. + * + * It looks like the VBIOS TMDS scripts make an attempt at this, however, + * the VBIOS scripts on at least one board I have only switch it off on + * link 0, causing a blank display if the output has previously been + * programmed for DisplayPort. + */ +static void +nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) +{ + int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); + struct drm_encoder *encoder; + u32 tmp; + + if (dcb->type != OUTPUT_TMDS) + return; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + + if (nv_encoder->dcb->type == OUTPUT_DP) { + tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); + tmp &= ~NV50_SOR_DP_CTRL_ENABLED; + nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); + break; + } + } +} + static void nv50_display_unk20_handler(struct drm_device *dev) { @@ -845,6 +875,7 @@ nv50_display_unk20_handler(struct drm_device *dev) nouveau_bios_run_display_table(dev, dcbent, script, pclk); nv50_display_unk20_dp_hack(dev, dcbent); + nv50_display_unk20_dp_set_tmds(dev, dcbent); tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); tmp &= ~0x000000f;