Now that we have mechanism by which to pass mode-dependent HDMI
InfoFrames to the low-level hardware driver, it is incumbent upon
us to do so.

Signed-off-by: Alastair Bridgewater <alastair.bridgewa...@gmail.com>
---
 drivers/gpu/drm/nouveau/nv50_display.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_display.c 
b/drivers/gpu/drm/nouveau/nv50_display.c
index c901f32..93149ca 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -23,6 +23,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/hdmi.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_atomic.h>
@@ -31,6 +32,7 @@
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_plane_helper.h>
+#include <drm/drm_edid.h>
 
 #include <nvif/class.h>
 #include <nvif/cl0002.h>
@@ -2717,6 +2719,7 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
drm_display_mode *mode)
        struct {
                struct nv50_disp_mthd_v1 base;
                struct nv50_disp_sor_hdmi_pwr_v0 pwr;
+               u8 infoframes[2 * 17]; /* two frames, up to 17 bytes each */
        } args = {
                .base.version = 1,
                .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR,
@@ -2728,17 +2731,42 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
drm_display_mode *mode)
        };
        struct nouveau_connector *nv_connector;
        u32 max_ac_packet;
+       union hdmi_infoframe avi_frame;
+       union hdmi_infoframe vendor_frame;
+       int ret;
+       int size;
 
        nv_connector = nouveau_encoder_connector_get(nv_encoder);
        if (!drm_detect_hdmi_monitor(nv_connector->edid))
                return;
 
+       ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode);
+       if (!ret) {
+               /* We have an AVI InfoFrame, populate it to the display */
+               args.pwr.avi_infoframe_length
+                       = hdmi_infoframe_pack(&avi_frame, args.infoframes, 17);
+       }
+
+       ret = 
drm_hdmi_vendor_infoframe_from_display_mode(&vendor_frame.vendor.hdmi, mode);
+       if (!ret) {
+               /* We have a Vendor InfoFrame, populate it to the display */
+               args.pwr.vendor_infoframe_length
+                       = hdmi_infoframe_pack(&vendor_frame,
+                                             args.infoframes
+                                             + args.pwr.avi_infoframe_length,
+                                             17);
+       }
+
        max_ac_packet  = mode->htotal - mode->hdisplay;
        max_ac_packet -= args.pwr.rekey;
        max_ac_packet -= 18; /* constant from tegra */
        args.pwr.max_ac_packet = max_ac_packet / 32;
 
-       nvif_mthd(disp->disp, 0, &args, sizeof(args));
+       size = sizeof(args.base)
+               + sizeof(args.pwr)
+               + args.pwr.avi_infoframe_length
+               + args.pwr.vendor_infoframe_length;
+       nvif_mthd(disp->disp, 0, &args, size);
        nv50_audio_enable(encoder, mode);
 }
 
-- 
2.10.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to