All of lore.kernel.org
 help / color / mirror / Atom feed
From: Damien Lespiau <damien.lespiau@gmail.com>
To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: [PATCH 3/3] drm/i915: Add HDMI vendor info frame support
Date: Thu, 27 Sep 2012 19:41:08 +0100	[thread overview]
Message-ID: <1348771268-3436-4-git-send-email-damien.lespiau@gmail.com> (raw)
In-Reply-To: <1348771268-3436-1-git-send-email-damien.lespiau@gmail.com>

From: Damien Lespiau <damien.lespiau@intel.com>

When scanning out a 3D framebuffer, send the corresponding infoframe to
the HDMI sink.

See http://www.hdmi.org/manufacturer/specification.aspx for details.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h   | 14 +++++++++++
 drivers/gpu/drm/i915/intel_hdmi.c  | 49 +++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_modes.c | 12 ++++++++++
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cd54cf8..c326d30e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -263,6 +263,13 @@ struct cxsr_latency {
 #define DIP_SPD_BD	0xa
 #define DIP_SPD_SCD	0xb
 
+#define DIP_TYPE_VENDOR		0x81
+#define DIP_VERSION_VENDOR	0x1
+#define DIP_HDMI_3D_PRESENT	(0x2<<5)
+#define DIP_HDMI_3D_STRUCT_FP	(0x0<<4)
+#define DIP_HDMI_3D_STRUCT_TB	(0x6<<4)
+#define DIP_HDMI_3D_STRUCT_SBSH	(0x8<<4)
+
 struct dip_infoframe {
 	uint8_t type;		/* HB0 */
 	uint8_t ver;		/* HB1 */
@@ -292,6 +299,12 @@ struct dip_infoframe {
 			uint8_t pd[16];
 			uint8_t sdi;
 		} __attribute__ ((packed)) spd;
+		struct {
+			uint8_t vendor_id[3];
+			uint8_t video_format;
+			uint8_t s3d_struct;
+			uint8_t s3d_ext_data;
+		} __attribute__ ((packed)) hdmi;
 		uint8_t payload[27];
 	} __attribute__ ((packed)) body;
 } __attribute__((packed));
@@ -348,6 +361,7 @@ int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
 
 extern void intel_attach_force_audio_property(struct drm_connector *connector);
 extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
+extern void intel_attach_expose_3d_modes_property(struct drm_connector *connector);
 
 extern void intel_crt_init(struct drm_device *dev);
 extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 98f6024..2d51b7e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -83,6 +83,8 @@ static u32 g4x_infoframe_index(struct dip_infoframe *frame)
 		return VIDEO_DIP_SELECT_AVI;
 	case DIP_TYPE_SPD:
 		return VIDEO_DIP_SELECT_SPD;
+	case DIP_TYPE_VENDOR:
+		return VIDEO_DIP_SELECT_VENDOR;
 	default:
 		DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
 		return 0;
@@ -96,6 +98,8 @@ static u32 g4x_infoframe_enable(struct dip_infoframe *frame)
 		return VIDEO_DIP_ENABLE_AVI;
 	case DIP_TYPE_SPD:
 		return VIDEO_DIP_ENABLE_SPD;
+	case DIP_TYPE_VENDOR:
+		return VIDEO_DIP_ENABLE_VENDOR;
 	default:
 		DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
 		return 0;
@@ -338,6 +342,42 @@ static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
 	intel_set_infoframe(encoder, &spd_if);
 }
 
+static void intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder,
+					  struct drm_display_mode *adjusted_mode)
+{
+	struct dip_infoframe hdmi_if;
+
+	/* We really only need to send a HDMI vendor info frame when having
+	 * a 3D format to describe */
+	if (!(adjusted_mode->flags & DRM_MODE_FLAG_3D_MASK))
+		return;
+
+	memset(&hdmi_if, 0, sizeof(hdmi_if));
+	hdmi_if.type = DIP_TYPE_VENDOR;
+	hdmi_if.ver = DIP_VERSION_VENDOR;
+	/* HDMI IEEE registration id, least significant bit first */
+	hdmi_if.body.hdmi.vendor_id[0] = 0x03;
+	hdmi_if.body.hdmi.vendor_id[1] = 0x0c;
+	hdmi_if.body.hdmi.vendor_id[2] = 0x00;
+	hdmi_if.body.hdmi.video_format = DIP_HDMI_3D_PRESENT;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_3D_FRAME_PACKING)
+		hdmi_if.body.hdmi.s3d_struct = DIP_HDMI_3D_STRUCT_FP;
+	else if (adjusted_mode->flags & DRM_MODE_FLAG_3D_TOP_BOTTOM)
+		hdmi_if.body.hdmi.s3d_struct = DIP_HDMI_3D_STRUCT_TB;
+	else if (adjusted_mode->flags & DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF)
+		hdmi_if.body.hdmi.s3d_struct = DIP_HDMI_3D_STRUCT_SBSH;
+	/* len is the payload len, not including checksum. Side by side (half)
+	 * has an extra byte for 3D_Ext_Data */
+	if (adjusted_mode->flags & DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF) {
+		hdmi_if.len = 6;
+		/* SBSH is subsampled by a factor of 2 */
+		hdmi_if.body.hdmi.s3d_ext_data = 2 << 4;
+	} else
+		hdmi_if.len = 5;
+
+	intel_set_infoframe(encoder, &hdmi_if);
+}
+
 static void g4x_set_infoframes(struct drm_encoder *encoder,
 			       struct drm_display_mode *adjusted_mode)
 {
@@ -398,6 +438,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder,
 
 	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
 	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
 }
 
 static void ibx_set_infoframes(struct drm_encoder *encoder,
@@ -457,6 +498,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder,
 
 	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
 	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
 }
 
 static void cpt_set_infoframes(struct drm_encoder *encoder,
@@ -492,6 +534,7 @@ static void cpt_set_infoframes(struct drm_encoder *encoder,
 
 	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
 	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
 }
 
 static void vlv_set_infoframes(struct drm_encoder *encoder,
@@ -526,6 +569,7 @@ static void vlv_set_infoframes(struct drm_encoder *encoder,
 
 	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
 	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
 }
 
 static void hsw_set_infoframes(struct drm_encoder *encoder,
@@ -792,7 +836,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
 			uint64_t val)
 {
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret;
 
 	ret = drm_connector_property_set_value(connector, property, val);
@@ -828,6 +873,7 @@ intel_hdmi_set_property(struct drm_connector *connector,
 		goto done;
 	}
 
+
 	return -EINVAL;
 
 done:
@@ -887,6 +933,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
 {
 	intel_attach_force_audio_property(connector);
 	intel_attach_broadcast_rgb_property(connector);
+	intel_attach_expose_3d_modes_property(connector);
 }
 
 void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index 29b7259..50216af 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -124,3 +124,15 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector)
 
 	drm_connector_attach_property(connector, prop, 0);
 }
+
+void
+intel_attach_expose_3d_modes_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	drm_mode_create_s3d_properties(dev);
+	prop = dev->mode_config.s3d_expose_modes_property;
+	drm_connector_attach_property(connector, prop,
+				      DRM_MODE_EXPOSE_3D_MODES_OFF);
+}
-- 
1.7.11.4

  parent reply	other threads:[~2012-09-27 18:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-27 18:41 Stereo 3D modes support v2 Damien Lespiau
2012-09-27 18:41 ` [PATCH 1/3] drm: Add an "expose 3d modes" property Damien Lespiau
2012-09-29  0:45   ` [Intel-gfx] " Rodrigo Vivi
2012-09-29  9:01   ` Chris Wilson
2012-10-04 13:35   ` Daniel Vetter
2012-10-04 13:56     ` Imre Deak
2012-09-27 18:41 ` [PATCH 2/3] drm: Parse the HDMI cea vendor block for 3D present Damien Lespiau
2012-09-29  0:46   ` Rodrigo Vivi
2012-09-27 18:41 ` Damien Lespiau [this message]
2012-09-29  0:50   ` [Intel-gfx] [PATCH 3/3] drm/i915: Add HDMI vendor info frame support Rodrigo Vivi
  -- strict thread matches above, loose matches on Subject: below --
2012-09-12 17:47 [RFC] Stereo 3D modes support Damien Lespiau
2012-09-12 17:47 ` [PATCH 3/3] drm/i915: Add HDMI vendor info frame support Damien Lespiau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1348771268-3436-4-git-send-email-damien.lespiau@gmail.com \
    --to=damien.lespiau@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.