Commit 34fd3e5d authored by Alastair Bridgewater's avatar Alastair Bridgewater Committed by Ben Skeggs

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: default avatarAlastair Bridgewater <alastair.bridgewater@gmail.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 31fe2c20
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/hdmi.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic.h> #include <drm/drm_atomic.h>
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
#include <drm/drm_edid.h>
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/cl0002.h> #include <nvif/cl0002.h>
...@@ -2710,6 +2712,7 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) ...@@ -2710,6 +2712,7 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
struct { struct {
struct nv50_disp_mthd_v1 base; struct nv50_disp_mthd_v1 base;
struct nv50_disp_sor_hdmi_pwr_v0 pwr; struct nv50_disp_sor_hdmi_pwr_v0 pwr;
u8 infoframes[2 * 17]; /* two frames, up to 17 bytes each */
} args = { } args = {
.base.version = 1, .base.version = 1,
.base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, .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) ...@@ -2721,17 +2724,42 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
}; };
struct nouveau_connector *nv_connector; struct nouveau_connector *nv_connector;
u32 max_ac_packet; 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); nv_connector = nouveau_encoder_connector_get(nv_encoder);
if (!drm_detect_hdmi_monitor(nv_connector->edid)) if (!drm_detect_hdmi_monitor(nv_connector->edid))
return; 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 = mode->htotal - mode->hdisplay;
max_ac_packet -= args.pwr.rekey; max_ac_packet -= args.pwr.rekey;
max_ac_packet -= 18; /* constant from tegra */ max_ac_packet -= 18; /* constant from tegra */
args.pwr.max_ac_packet = max_ac_packet / 32; 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); nv50_audio_enable(encoder, mode);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment