All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i915: enable AVI infoframe for intel_hdmi.c
@ 2010-09-08 22:52 David Härdeman
  2010-09-08 23:26 ` Chris Wilson
  0 siblings, 1 reply; 2+ messages in thread
From: David Härdeman @ 2010-09-08 22:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: jesse.barnes

This patch enables the sending of AVI infoframes in
drivers/gpu/drm/i915/intel_hdmi.c.

My receiver currently loses sync when the HDMI output on my computer
(DG45FC motherboard) is switched from 800x600 (the BIOS resolution) to
1920x1080 as part of the boot. Fixable by switching inputs on the receiver
a couple of times.

With this patch, my receiver has not lost sync yet (> 40 tries).

I'm not sure that the general approach is sound, which is why I'm sending
this out for some feedback and review (in particular, is the SDVOB and SDVOC
handling in intel_hdmi_set_avi_infoframe() correct?).

Regards,
David Härdeman
---
 drivers/gpu/drm/i915/i915_reg.h   |   16 +++++++
 drivers/gpu/drm/i915/intel_hdmi.c |   90 +++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 67e3ec1..6c2d9a6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1330,6 +1330,22 @@
 #define   LVDS_B0B3_POWER_DOWN		(0 << 2)
 #define   LVDS_B0B3_POWER_UP		(3 << 2)
 
+/* Video Data Island Packet control */
+#define VIDEO_DIP_DATA		0x61178
+#define VIDEO_DIP_CTL		0x61170
+#define   VIDEO_DIP_ENABLE		(1 << 31)
+#define   VIDEO_DIP_PORT_B		(1 << 29)
+#define   VIDEO_DIP_PORT_C		(2 << 29)
+#define   VIDEO_DIP_ENABLE_AVI		(1 << 21)
+#define   VIDEO_DIP_ENABLE_VENDOR	(2 << 21)
+#define   VIDEO_DIP_ENABLE_SPD		(8 << 21)
+#define   VIDEO_DIP_SELECT_AVI		(0 << 19)
+#define   VIDEO_DIP_SELECT_VENDOR	(1 << 19)
+#define   VIDEO_DIP_SELECT_SPD		(3 << 19)
+#define   VIDEO_DIP_FREQ_ONCE		(0 << 16)
+#define   VIDEO_DIP_FREQ_VSYNC		(1 << 16)
+#define   VIDEO_DIP_FREQ_2VSYNC		(2 << 16)
+
 /* Panel power sequencing */
 #define PP_STATUS	0x61200
 #define   PP_ON		(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index ccd4c97..e3a92c2 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -48,6 +48,93 @@ static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
 	return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base);
 }
 
+#define DIP_TYPE_AVI    0x82
+#define DIP_VERSION_AVI 0x2
+#define DIP_LEN_AVI     13
+
+struct dip_avi_infoframe {
+	uint8_t type;           /* HB0 */
+	uint8_t ver;            /* HB1 */
+	uint8_t len;            /* HB2 - body len, not including checksum */
+	uint8_t ecc;            /* HW specific, not part of the infoframe */
+	uint8_t checksum;       /* PB0 */
+	uint8_t Y_A_B_S;        /* PB1 - Y 6:5, A 4:4, B 3:2, S 1:0 */
+	uint8_t C_M_R;          /* PB2 - C 7:6, M 5:4, R 3:0 */
+	uint8_t ITC_EC_Q_SC;    /* PB3 - ITC 7:7, EC 6:4, Q 3:2, SC 1:0 */
+	uint8_t VIC;            /* PB4 - VIC 6:0 */
+	uint8_t PR;             /* PB5 - PR 3:0 */
+	/* PB6 - PB13 */
+	uint16_t top_bar_end;
+	uint16_t bottom_bar_start;
+	uint16_t left_bar_end;
+	uint16_t right_bar_start;
+	/* Pad to 32-bit */
+	uint16_t padding;
+} __attribute__((packed));
+
+static void intel_hdmi_calc_csum(struct dip_avi_infoframe *avi_if)
+{
+	uint8_t *data = (uint8_t *)avi_if;
+	uint8_t sum = 0;
+	unsigned i;
+
+	avi_if->checksum = 0;
+	avi_if->ecc = 0;
+	avi_if->padding = 0;
+
+	for (i = 0; i < sizeof(*avi_if); i++)
+		sum += data[i];
+
+	avi_if->checksum = 0x100 - sum;
+}
+static void intel_hdmi_write_avi_infoframe(struct drm_encoder *encoder,
+					   struct dip_avi_infoframe *avi_if)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 *data = (u32 *)avi_if;
+	unsigned i;
+
+	for (i = 0; i < sizeof(*avi_if); i += 4) {
+		I915_WRITE(VIDEO_DIP_DATA, *data);
+		data++;
+	}
+
+}
+
+static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
+{
+	struct dip_avi_infoframe avi_if = {
+		.type = DIP_TYPE_AVI,
+		.ver = DIP_VERSION_AVI,
+		.len = DIP_LEN_AVI,
+		.Y_A_B_S = 0x02,
+		.C_M_R = 0x28,
+	};
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	u32 port;
+
+	if (!intel_hdmi->has_hdmi_sink)
+		return;
+
+	if (intel_hdmi->sdvox_reg == SDVOB)
+		port = VIDEO_DIP_PORT_B;
+	else if (intel_hdmi->sdvox_reg == SDVOC)
+		port = VIDEO_DIP_PORT_C;
+	else
+		return;
+
+	intel_hdmi_calc_csum(&avi_if);
+	I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | port | VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC);
+	POSTING_READ(VIDEO_DIP_ENABLE);
+	intel_hdmi_write_avi_infoframe(encoder, &avi_if);
+	I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | port | VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC);
+	POSTING_READ(VIDEO_DIP_ENABLE);
+}
+
+
 static void intel_hdmi_mode_set(struct drm_encoder *encoder,
 				struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
@@ -67,6 +154,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
 
 	if (intel_hdmi->has_hdmi_sink) {
 		sdvox |= SDVO_AUDIO_ENABLE;
+		sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC;
 		if (HAS_PCH_CPT(dev))
 			sdvox |= HDMI_MODE_SELECT;
 	}
@@ -80,6 +168,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
 
 	I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
 	POSTING_READ(intel_hdmi->sdvox_reg);
+
+	intel_hdmi_set_avi_infoframe(encoder);
 }
 
 static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] i915: enable AVI infoframe for intel_hdmi.c
  2010-09-08 22:52 [PATCH] i915: enable AVI infoframe for intel_hdmi.c David Härdeman
@ 2010-09-08 23:26 ` Chris Wilson
  0 siblings, 0 replies; 2+ messages in thread
From: Chris Wilson @ 2010-09-08 23:26 UTC (permalink / raw)
  To: intel-gfx; +Cc: jesse.barnes

[-- Attachment #1: Type: text/plain, Size: 1015 bytes --]

On Thu, 09 Sep 2010 00:52:17 +0200, David Härdeman <david@hardeman.nu> wrote:
> This patch enables the sending of AVI infoframes in
> drivers/gpu/drm/i915/intel_hdmi.c.
> 
> My receiver currently loses sync when the HDMI output on my computer
> (DG45FC motherboard) is switched from 800x600 (the BIOS resolution) to
> 1920x1080 as part of the boot. Fixable by switching inputs on the receiver
> a couple of times.
> 
> With this patch, my receiver has not lost sync yet (> 40 tries).
> 
> I'm not sure that the general approach is sound, which is why I'm sending
> this out for some feedback and review (in particular, is the SDVOB and SDVOC
> handling in intel_hdmi_set_avi_infoframe() correct?).

Oh, more code duplication... I thought I recognised this, we do this for
SDVO HDMI but not integrated HDMI.

Can you move the dip_infoframe helper functions into intel_hdmi.c and call
them from intel_sdvo.c? And then we can take a closer look at sdvox.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-09-08 23:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-08 22:52 [PATCH] i915: enable AVI infoframe for intel_hdmi.c David Härdeman
2010-09-08 23:26 ` Chris Wilson

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.