Blob Blame History Raw
From a971558c298755d2c07bc5508c65d689471763c8 Mon Sep 17 00:00:00 2001
From: Ilia Mirkin <imirkin@alum.mit.edu>
Date: Mon, 3 Sep 2018 20:57:35 -0400
Subject: [PATCH] drm/nouveau/disp: keep track of high-speed state, program into clock
Git-commit: a971558c298755d2c07bc5508c65d689471763c8
Patch-mainline: v4.20-rc1
References: bsc#1133593

The register programmed by the clock method needs to contain a different
setting for the link speed as well as special divider settings.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c |  2 ++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h       |  5 +++++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c  | 11 +++++++----
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
index ad5f658c3f6d..9b16a08eb4d9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
@@ -31,4 +31,6 @@ gm200_hdmi_scdc(struct nvkm_ior *ior, int head, u8 scdc)
 	const u32 ctrl = scdc & 0x3;
 
 	nvkm_mask(device, 0x61c5bc + hoff, 0x00000003, ctrl);
+
+	ior->tmds.high_speed = !!(scdc & 0x2);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index c5d34424f45f..0f0c86c32ec3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -41,6 +41,11 @@ struct nvkm_ior {
 		u8 nr;
 		u8 bw;
 	} dp;
+
+	/* Armed TMDS state. */
+	struct {
+		bool high_speed;
+	} tmds;
 };
 
 struct nvkm_ior_func {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
index e6e6dfbb1283..456a5a143522 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
@@ -120,13 +120,16 @@ void
 gf119_sor_clock(struct nvkm_ior *sor)
 {
 	struct nvkm_device *device = sor->disp->engine.subdev.device;
-	const int  div = sor->asy.link == 3;
 	const u32 soff = nv50_ior_base(sor);
+	u32 div1 = sor->asy.link == 3;
+	u32 div2 = sor->asy.link == 3;
 	if (sor->asy.proto == TMDS) {
-		/* NFI why, but this sets DP_LINK_BW_2_7 when using TMDS. */
-		nvkm_mask(device, 0x612300 + soff, 0x007c0000, 0x0a << 18);
+		const u32 speed = sor->tmds.high_speed ? 0x14 : 0x0a;
+		nvkm_mask(device, 0x612300 + soff, 0x007c0000, speed << 18);
+		if (sor->tmds.high_speed)
+			div2 = 1;
 	}
-	nvkm_mask(device, 0x612300 + soff, 0x00000707, (div << 8) | div);
+	nvkm_mask(device, 0x612300 + soff, 0x00000707, (div2 << 8) | div1);
 }
 
 void
-- 
2.16.4