Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7149eee8 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50: fix DP->DVI if output has been programmed for native DP previously



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 309b8c89
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+31 −0
Original line number Diff line number Diff line
@@ -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;