From: Alastair Bridgewater Date: Tue, 11 Apr 2017 17:11:18 +0000 (-0400) Subject: drm/nouveau: Pass mode-dependent AVI and Vendor HDMI InfoFrames to NVKM X-Git-Tag: v4.13-rc1~73^2~13^2~70 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=34fd3e5d8c5f6bdcc2245084036680a4bfc23370;p=linux.git drm/nouveau: Pass mode-dependent AVI and Vendor HDMI InfoFrames to NVKM 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 Signed-off-by: Ben Skeggs --- diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 83eee1f00336..0f817a6b1650 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include #include @@ -2710,6 +2712,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, @@ -2721,17 +2724,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); }