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@xxxxxxxxx> --- drivers/gpu/drm/nouveau/include/nvif/cl5070.h | 4 +++- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c | 9 ++++++++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl5070.h b/drivers/gpu/drm/nouveau/include/nvif/cl5070.h index ae49dfd..9d46eba 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl5070.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl5070.h @@ -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 { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c index 1c4256e..77e5f5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c index 632f02d..66ee883 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c index 4e8067d..3c8c26a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c index f1afc16..8ed00db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c @@ -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); -- 2.10.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel