From 4eed4a0a4ac31830b4c328739cabb69721584bfc Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:26 +0100 Subject: [PATCH] drm: Set the relevant infoframe field when scanning out a 3D mode MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When scanning out a 3D mode on HDMI, we need to send an HDMI infoframe with the corresponding layout to the sink. v2: Make s3d_structure_from_display_mode() less subtle (Ville Syrjälä) Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_edid.c | 40 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 73660075de31..0bae76d40f28 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3421,6 +3421,33 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, } EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode); +static enum hdmi_3d_structure +s3d_structure_from_display_mode(const struct drm_display_mode *mode) +{ + u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK; + + switch (layout) { + case DRM_MODE_FLAG_3D_FRAME_PACKING: + return HDMI_3D_STRUCTURE_FRAME_PACKING; + case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: + return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE; + case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: + return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE; + case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: + return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL; + case DRM_MODE_FLAG_3D_L_DEPTH: + return HDMI_3D_STRUCTURE_L_DEPTH; + case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: + return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH; + case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: + return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM; + case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: + return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF; + default: + return HDMI_3D_STRUCTURE_INVALID; + } +} + /** * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with * data from a DRM display mode @@ -3438,20 +3465,29 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, const struct drm_display_mode *mode) { int err; + u32 s3d_flags; u8 vic; if (!frame || !mode) return -EINVAL; vic = drm_match_hdmi_mode(mode); - if (!vic) + s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK; + + if (!vic && !s3d_flags) + return -EINVAL; + + if (vic && s3d_flags) return -EINVAL; err = hdmi_vendor_infoframe_init(frame); if (err < 0) return err; - frame->vic = vic; + if (vic) + frame->vic = vic; + else + frame->s3d_struct = s3d_structure_from_display_mode(mode); return 0; } -- 2.20.1