drm/nouveau/disp: add a way to configure scrambling/tmds for hdmi 2.0
authorIlia Mirkin <imirkin@alum.mit.edu>
Tue, 4 Sep 2018 00:57:33 +0000 (20:57 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 10 Oct 2018 23:54:10 +0000 (09:54 +1000)
High pixel clocks are required to use a 40 TMDS divider instead of 10,
and even low ones may optionally use scrambling depending on device
support.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvif/cl5070.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c

index 7cdf53615d7bb817494e81359dbb5007952d7683..bced8198726912ae4c8b7cf17a776adeddbc27c2 100644 (file)
@@ -69,7 +69,10 @@ struct nv50_disp_sor_hdmi_pwr_v0 {
        __u8  rekey;
        __u8  avi_infoframe_length;
        __u8  vendor_infoframe_length;
-       __u8  pad06[2];
+#define NV50_DISP_SOR_HDMI_PWR_V0_SCDC_SCRAMBLE (1 << 0)
+#define NV50_DISP_SOR_HDMI_PWR_V0_SCDC_DIV_BY_4 (1 << 1)
+       __u8  scdc;
+       __u8  pad07[1];
 };
 
 struct nv50_disp_sor_lvds_script_v0 {
index 19911211a12aa55a200ac75bc2f88958598d96bd..aa7aa2f21cf645bc4f978b7d9cca4c3fb82cbd96 100644 (file)
@@ -61,6 +61,7 @@ struct nvkm_ior_func {
                void (*ctrl)(struct nvkm_ior *, int head, bool enable,
                             u8 max_ac_packet, u8 rekey, u8 *avi, u8 avi_size,
                             u8 *vendor, u8 vendor_size);
+               void (*scdc)(struct nvkm_ior *, int head, u8 scdc);
        } hdmi;
 
        struct {
index 3aa5a287923931a9b9c8d86666d14022665e957e..5f758948d6e1e8954ed762b012f25e70dca2b210 100644 (file)
@@ -176,9 +176,10 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
                nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
                if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
                        nvif_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
-                                          "max_ac_packet %d rekey %d\n",
+                                          "max_ac_packet %d rekey %d scdc %d\n",
                                   args->v0.version, args->v0.state,
-                                  args->v0.max_ac_packet, args->v0.rekey);
+                                  args->v0.max_ac_packet, args->v0.rekey,
+                                  args->v0.scdc);
                        if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f)
                                return -EINVAL;
                        if ((args->v0.avi_infoframe_length
@@ -202,6 +203,11 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
                                           args->v0.max_ac_packet,
                                           args->v0.rekey, avi, avi_size,
                                           vendor, vendor_size);
+
+               if (outp->ior->func->hdmi.scdc)
+                       outp->ior->func->hdmi.scdc(
+                                       outp->ior, hidx, args->v0.scdc);
+
                return 0;
        }
                break;