Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932356Ab2JNOyL (ORCPT ); Sun, 14 Oct 2012 10:54:11 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:46622 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932239Ab2JNOnm (ORCPT ); Sun, 14 Oct 2012 10:43:42 -0400 Message-Id: <20121014143542.113662367@decadent.org.uk> User-Agent: quilt/0.60-1 Date: Sun, 14 Oct 2012 15:36:34 +0100 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Paulo Zanoni , Rodrigo Vivi , Daniel Vetter Subject: [ 061/147] drm/i915: make sure we write all the DIP data bytes In-Reply-To: <20121014143533.742627615@decadent.org.uk> X-SA-Exim-Connect-IP: 77.75.106.1 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3538 Lines: 92 3.2-stable review patch. If anyone has any objections, please let me know. ------------------ From: Paulo Zanoni commit adf00b26d18e1b3570451296e03bcb20e4798cdd upstream. ... even if the actual infoframe is smaller than the maximum possible size. If we don't write all the 32 DIP data bytes the InfoFrame ECC may not be correctly calculated in some cases (e.g., when changing the port), and this will lead to black screens on HDMI monitors. The ECC value is generated by the hardware. I don't see how this should break anything since we're writing 0 and that should be the correct value, so this patch should be safe. Notice that on IVB and older we actually have 64 bytes available for VIDEO_DIP_DATA, but only bytes 0-31 actually store infoframe data: the others are either read-only ECC values or marked as "reserved". On HSW we only have 32 bytes, and the ECC value is stored on its own separate read-only register. See BSpec. This patch fixes bug #46761, which is marked as a regression introduced by commit 4e89ee174bb2da341bf90a84321c7008a3c9210d: drm/i915: set the DIP port on ibx_write_infoframe Before commit 4e89 we were just failing to send AVI infoframes when we needed to change the port, which can lead to black screens in some cases. After commit 4e89 we started sending infoframes, but with a possibly wrong ECC value. After this patch I hope we start sending correct infoframes. Version 2: - Improve commit message - Try to make the code more clear Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=46761 Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter [bwh: Backported to 3.2: only two write_infoframe functions to be modified] Signed-off-by: Ben Hutchings --- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_hdmi.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1557,6 +1557,10 @@ /* Video Data Island Packet control */ #define VIDEO_DIP_DATA 0x61178 +/* Read the description of VIDEO_DIP_DATA (before Haswel) or VIDEO_DIP_ECC + * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte + * of the infoframe structure specified by CEA-861. */ +#define VIDEO_DIP_DATA_SIZE 32 #define VIDEO_DIP_CTL 0x61170 #define VIDEO_DIP_ENABLE (1 << 31) #define VIDEO_DIP_PORT_B (1 << 29) --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -143,6 +143,9 @@ static void i9xx_write_infoframe(struct I915_WRITE(VIDEO_DIP_DATA, *data); data++; } + /* Write every possible data byte to force correct ECC calculation. */ + for (; i < VIDEO_DIP_DATA_SIZE; i += 4) + I915_WRITE(VIDEO_DIP_DATA, 0); mmiowb(); flags |= intel_infoframe_flags(frame); @@ -176,6 +179,9 @@ static void ironlake_write_infoframe(str I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); data++; } + /* Write every possible data byte to force correct ECC calculation. */ + for (; i < VIDEO_DIP_DATA_SIZE; i += 4) + I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); mmiowb(); flags |= intel_infoframe_flags(frame); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/