From patchwork Tue Jul 11 22:19:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jim.bride@linux.intel.com X-Patchwork-Id: 9835569 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C1D8860325 for ; Tue, 11 Jul 2017 22:22:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BC2212850E for ; Tue, 11 Jul 2017 22:22:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B1396285B9; Tue, 11 Jul 2017 22:22:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 652082850E for ; Tue, 11 Jul 2017 22:22:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8275E6E31F; Tue, 11 Jul 2017 22:22:30 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id BC7D06E31A for ; Tue, 11 Jul 2017 22:22:26 +0000 (UTC) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga105.jf.intel.com with ESMTP; 11 Jul 2017 15:22:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.40,347,1496127600"; d="scan'208"; a="1171319926" Received: from shiv.jf.intel.com ([10.54.75.141]) by fmsmga001.fm.intel.com with ESMTP; 11 Jul 2017 15:22:26 -0700 From: Jim Bride To: intel-gfx@lists.freedesktop.org Date: Tue, 11 Jul 2017 15:19:54 -0700 Message-Id: <1499811596-14634-3-git-send-email-jim.bride@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1499811596-14634-1-git-send-email-jim.bride@linux.intel.com> References: <1499811596-14634-1-git-send-email-jim.bride@linux.intel.com> Cc: Jani Nikula , Paulo Zanoni , Rodrigo Vivi Subject: [Intel-gfx] [PATCH v3 2/4] drm/i915/psr: Account for sink CRC raciness on some panels X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP According to the eDP spec, when the count field in TEST_SINK_MISC increments then the six bytes of sink CRC information in the DPCD should be valid. Unfortunately, this doesn't seem to be the case on some panels, and as a result we get some incorrect and inconsistent values from the sink CRC DPCD locations at times. This problem exhibits itself more on faster processors (relative failure rates HSW < SKL < KBL.) In order to try and account for this, we try a lot harder to read the sink CRC until we get consistent values twice in a row before returning what we read and delay for a time before trying to read. We still see some occasional failures, but reading the sink CRC is much more reliable, particularly on SKL and KBL, with these changes than without. v2: * Reduce number of retries when reading the sink CRC (Jani) * Refactor to minimize changes to the code (Jani) * Rebase Cc: Rodrigo Vivi Cc: Paulo Zanoni Cc: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Jim Bride --- drivers/gpu/drm/i915/intel_dp.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2d42d09..69c8130c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3906,6 +3906,14 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) u8 buf; int count, ret; int attempts = 6; + u8 old_crc[6]; + + if (crc != NULL) { + memset(crc, 0, 6); + memset(old_crc, 0xff, 6); + } else { + return -ENOMEM; + } ret = intel_dp_sink_crc_start(intel_dp); if (ret) @@ -3929,11 +3937,35 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) goto stop; } - if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) { - ret = -EIO; - goto stop; - } + attempts = 6; + + /* + * Sometimes it takes a while for the "real" CRC values to land in + * the DPCD, so try several times until we get two reads in a row + * that are the same. If we're an eDP panel, delay between reads + * for a while since the values take a bit longer to propagate. + */ + do { + intel_wait_for_vblank(dev_priv, intel_crtc->pipe); + if (is_edp(intel_dp)) + usleep_range(20000, 25000); + + if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, + crc, 6) < 0) { + ret = -EIO; + goto stop; + } + + if (memcmp(old_crc, crc, 6) == 0) { + ret = 0; + goto stop; + } else { + memcpy(old_crc, crc, 6); + } + } while (--attempts); + DRM_DEBUG_KMS("Failed to get CRC after 6 attempts.\n"); + ret = -ETIMEDOUT; stop: intel_dp_sink_crc_stop(intel_dp); return ret;