drm/nouveau/disp/g84-: Extend NVKM HDMI power control method to set InfoFrames
authorAlastair Bridgewater <alastair.bridgewater@gmail.com>
Tue, 11 Apr 2017 17:11:17 +0000 (13:11 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 16 Jun 2017 04:04:18 +0000 (14:04 +1000)
The nouveau driver, in the Linux 3.7 days, used to try and set the
AVI InfoFrame based on the selected display mode.  These days, it
uses a fixed set of InfoFrames.  Start to correct that, by
providing a mechanism whereby InfoFrame data may be passed to the
NVKM functions that do the actual configuration.

At this point, only establish the new parameters and their parsing,
don't actually use the data anywhere yet (since it's not supplied
anywhere).

Signed-off-by: Alastair Bridgewater <alastair.bridgewater@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvif/cl5070.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c

index ae49dfd1f97bffc3ec3adf5d9be9b92984b545e0..9d46ebac58a2d65f09e6d2ca6389046eddddf22c 100644 (file)
@@ -76,7 +76,9 @@ struct nv50_disp_sor_hdmi_pwr_v0 {
        __u8  state;
        __u8  max_ac_packet;
        __u8  rekey;
-       __u8  pad04[4];
+       __u8  avi_infoframe_length;
+       __u8  vendor_infoframe_length;
+       __u8  pad06[2];
 };
 
 struct nv50_disp_sor_lvds_script_v0 {
index 1c4256e8cbd64b0329c2709a6ab9f20dbe97bb75..77e5f5a2f3fa4626f7a6d6f5176fa9c5b43563e4 100644 (file)
@@ -40,7 +40,7 @@ g84_hdmi_ctrl(NV50_DISP_MTHD_V1)
        int ret = -ENOSYS;
 
        nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
-       if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+       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",
                           args->v0.version, args->v0.state,
@@ -54,6 +54,13 @@ g84_hdmi_ctrl(NV50_DISP_MTHD_V1)
        } else
                return ret;
 
+       if ((args->v0.avi_infoframe_length
+            + args->v0.vendor_infoframe_length) > size)
+               return -ENOSYS;
+       else if ((args->v0.avi_infoframe_length
+                   + args->v0.vendor_infoframe_length) < size)
+               return -E2BIG;
+
        if (!(ctrl & 0x40000000)) {
                nvkm_mask(device, 0x6165a4 + hoff, 0x40000000, 0x00000000);
                nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
index 632f02da13825e3c42da50d866b4da4060bda83e..66ee88356e4e335484b1377db76dc8f4c66ec522 100644 (file)
@@ -40,7 +40,7 @@ gf119_hdmi_ctrl(NV50_DISP_MTHD_V1)
        int ret = -ENOSYS;
 
        nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
-       if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+       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",
                           args->v0.version, args->v0.state,
@@ -53,6 +53,13 @@ gf119_hdmi_ctrl(NV50_DISP_MTHD_V1)
        } else
                return ret;
 
+       if ((args->v0.avi_infoframe_length
+            + args->v0.vendor_infoframe_length) > size)
+               return -ENOSYS;
+       else if ((args->v0.avi_infoframe_length
+                   + args->v0.vendor_infoframe_length) < size)
+               return -E2BIG;
+
        if (!(ctrl & 0x40000000)) {
                nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
                nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000000);
index 4e8067d511d77675f7362bdf36d44f3b718efcda..3c8c26a44f5673f16000ab1ce79d1810e7ac7e01 100644 (file)
@@ -41,7 +41,7 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
        int ret = -ENOSYS;
 
        nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
-       if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+       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",
                           args->v0.version, args->v0.state,
@@ -54,6 +54,13 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
        } else
                return ret;
 
+       if ((args->v0.avi_infoframe_length
+            + args->v0.vendor_infoframe_length) > size)
+               return -ENOSYS;
+       else if ((args->v0.avi_infoframe_length
+                   + args->v0.vendor_infoframe_length) < size)
+               return -E2BIG;
+
        if (!(ctrl & 0x40000000)) {
                nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
                nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
index f1afc16494b692e0575477f122d5fc0aad5aee85..8ed00dbf9dc1c7219ca83a9f18c2ade01e003a3c 100644 (file)
@@ -41,7 +41,7 @@ gt215_hdmi_ctrl(NV50_DISP_MTHD_V1)
        int ret = -ENOSYS;
 
        nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
-       if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+       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",
                           args->v0.version, args->v0.state,
@@ -55,6 +55,13 @@ gt215_hdmi_ctrl(NV50_DISP_MTHD_V1)
        } else
                return ret;
 
+       if ((args->v0.avi_infoframe_length
+            + args->v0.vendor_infoframe_length) > size)
+               return -ENOSYS;
+       else if ((args->v0.avi_infoframe_length
+                   + args->v0.vendor_infoframe_length) < size)
+               return -E2BIG;
+
        if (!(ctrl & 0x40000000)) {
                nvkm_mask(device, 0x61c5a4 + soff, 0x40000000, 0x00000000);
                nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000000);