From patchwork Wed Sep 8 22:52:17 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?RGF2aWQgSMODwqRyZGVtYW4=?= X-Patchwork-Id: 164631 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o88N08qO010506 for ; Wed, 8 Sep 2010 23:00:43 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D4BB39EBEF for ; Wed, 8 Sep 2010 16:00:07 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 08 Sep 2010 23:00:43 +0000 (UTC) X-Greylist: delayed 441 seconds by postgrey-1.31 at gabe; Wed, 08 Sep 2010 15:59:43 PDT Received: from palpatine.hardeman.nu (1-1-12-13a.han.sth.bostream.se [82.182.30.168]) by gabe.freedesktop.org (Postfix) with ESMTP id 8EE1A9E73D for ; Wed, 8 Sep 2010 15:59:43 -0700 (PDT) Received: from basil.haag.hardeman.nu (host-88-217-225-61.customer.m-online.net [88.217.225.61]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by palpatine.hardeman.nu (Postfix) with ESMTPSA id 30B7F165D; Thu, 9 Sep 2010 00:52:19 +0200 (CEST) Received: by basil.haag.hardeman.nu (Postfix, from userid 1000) id 30A091A0726; Thu, 9 Sep 2010 00:52:17 +0200 (CEST) To: intel-gfx@lists.freedesktop.org From: David =?utf-8?b?SMOkcmRlbWFu?= Date: Thu, 09 Sep 2010 00:52:17 +0200 Message-ID: <20100908225217.6870.54888.stgit@localhost.localdomain> User-Agent: StGit/0.15 MIME-Version: 1.0 Cc: jesse.barnes@intel.com Subject: [Intel-gfx] [PATCH] i915: enable AVI infoframe for intel_hdmi.c X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-MIME-Autoconverted: from base64 to 8bit by demeter1.kernel.org id o88N08qO010506 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)