From patchwork Tue Sep 25 16:23:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Zanoni X-Patchwork-Id: 1505691 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id A41443FC71 for ; Tue, 25 Sep 2012 16:24:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8F8F9A0AC1 for ; Tue, 25 Sep 2012 09:24:14 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-gg0-f177.google.com (mail-gg0-f177.google.com [209.85.161.177]) by gabe.freedesktop.org (Postfix) with ESMTP id 3595CA086E for ; Tue, 25 Sep 2012 09:23:48 -0700 (PDT) Received: by ggnm2 with SMTP id m2so2001435ggn.36 for ; Tue, 25 Sep 2012 09:23:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=e71rdPhTJR6FqpxuUcxQJzSo34W+lCQZuVgzqiuhoaU=; b=WhkESpmGlozNr8sF1uumT6N3i9X1ojLlyLYQlczX0yzUtFBLLcopPOHi2xeJfEb3hO SYxGpauw3vo/m9BlXmDtnz02OTTLqY9tDx4Ov14I+qmlvH+hVB6T6+K2FvbgllT7HL8P AHwRo9Gc9uFNVD/9AEYcjAL1SxgYqWDRMn1+EtrfUYN/4QOCK7goO6TCMP2XWgp4EU3i 81ogo+Lle/ebvOQshlvfDLm93xw9rRhhl3YhQHHdwKqsighGtjXRHjTxkPStExZ5gz4X 0Qm+Uuj4vJh71+qXtMnp63UO2WdF7wInBKKNT0aPu34FopIx4cwwc/cMpn8noHfWQAQ7 p3fg== Received: by 10.236.76.132 with SMTP id b4mr16343100yhe.106.1348590227607; Tue, 25 Sep 2012 09:23:47 -0700 (PDT) Received: from vicky.domain.invalid ([177.40.35.112]) by mx.google.com with ESMTPS id t57sm1107682yhg.0.2012.09.25.09.23.45 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 25 Sep 2012 09:23:46 -0700 (PDT) From: Paulo Zanoni To: intel-gfx@lists.freedesktop.org Date: Tue, 25 Sep 2012 13:23:34 -0300 Message-Id: <1348590215-4053-1-git-send-email-przanoni@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1348493576-3386-2-git-send-email-przanoni@gmail.com> References: <1348493576-3386-2-git-send-email-przanoni@gmail.com> Cc: Paulo Zanoni , stable@vger.kernel.org Subject: [Intel-gfx] [PATCH] drm/i915: make sure we write all the DIP data bytes X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 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 From: Paulo Zanoni ... 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 Cc: stable@vger.kernel.org Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=46761 Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_hdmi.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a828e90..7637824 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1794,6 +1794,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 /* Pre HSW: */ #define VIDEO_DIP_ENABLE (1 << 31) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f9fb47c..08f2b63 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -151,6 +151,9 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, 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(); val |= g4x_infoframe_enable(frame); @@ -186,6 +189,9 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, 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(); val |= g4x_infoframe_enable(frame); @@ -224,6 +230,9 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, 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(); val |= g4x_infoframe_enable(frame); @@ -259,6 +268,9 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, I915_WRITE(VLV_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(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0); mmiowb(); val |= g4x_infoframe_enable(frame); @@ -292,6 +304,9 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, I915_WRITE(data_reg + i, *data); data++; } + /* Write every possible data byte to force correct ECC calculation. */ + for (; i < VIDEO_DIP_DATA_SIZE; i += 4) + I915_WRITE(data_reg + i, 0); mmiowb(); val |= hsw_infoframe_enable(frame);