drm/nouveau/disp: keep track of high-speed state, program into clock
authorIlia Mirkin <imirkin@alum.mit.edu>
Tue, 4 Sep 2018 00:57:35 +0000 (20:57 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 10 Oct 2018 23:54:10 +0000 (09:54 +1000)
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>
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c

index ad5f658..9b16a08 100644 (file)
@@ -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);
 }
index c5d3442..0f0c86c 100644 (file)
@@ -41,6 +41,11 @@ struct nvkm_ior {
                u8 nr;
                u8 bw;
        } dp;
+
+       /* Armed TMDS state. */
+       struct {
+               bool high_speed;
+       } tmds;
 };
 
 struct nvkm_ior_func {
index e6e6dfb..456a5a1 100644 (file)
@@ -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