From patchwork Fri May 5 21:02:06 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: 9714381 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 BD5F76034B for ; Fri, 5 May 2017 21:04:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B1EF228614 for ; Fri, 5 May 2017 21:04:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A6C5028688; Fri, 5 May 2017 21:04:21 +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 4B83D28614 for ; Fri, 5 May 2017 21:04:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C7E286E738; Fri, 5 May 2017 21:04:18 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7B5276E004 for ; Fri, 5 May 2017 21:04:12 +0000 (UTC) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 May 2017 14:04:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,294,1491289200"; d="scan'208";a="853418472" Received: from shiv.jf.intel.com ([10.54.75.141]) by FMSMGA003.fm.intel.com with ESMTP; 05 May 2017 14:04:11 -0700 From: Jim Bride To: intel-gfx@lists.freedesktop.org Date: Fri, 5 May 2017 14:02:06 -0700 Message-Id: <1494018126-30190-5-git-send-email-jim.bride@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494018126-30190-1-git-send-email-jim.bride@linux.intel.com> References: <1494018126-30190-1-git-send-email-jim.bride@linux.intel.com> Cc: Paulo Zanoni , Rodrigo Vivi Subject: [Intel-gfx] [PATCH 4/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. Cc: Rodrigo Vivi Cc: Paulo Zanoni Signed-off-by: Jim Bride --- drivers/gpu/drm/i915/i915_debugfs.c | 14 +++++++-- drivers/gpu/drm/i915/intel_dp.c | 57 ++++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 870c470..4902473 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2718,7 +2718,7 @@ static int i915_sink_crc(struct seq_file *m, void *data) struct intel_connector *connector; struct drm_connector_list_iter conn_iter; struct intel_dp *intel_dp = NULL; - int ret; + int ret, tries = 6; u8 crc[6]; drm_modeset_lock_all(dev); @@ -2738,9 +2738,17 @@ static int i915_sink_crc(struct seq_file *m, void *data) intel_dp = enc_to_intel_dp(connector->base.state->best_encoder); - ret = intel_dp_sink_crc(intel_dp, crc); - if (ret) + memset(crc, 0, 6); + do { + ret = intel_dp_sink_crc(intel_dp, crc); + if (ret == -ETIMEDOUT) + usleep_range(500, 700); + } while ((ret == -ETIMEDOUT) && --tries); + + if (ret != 0) { + seq_printf(m, "000000000000\n"); goto out; + } seq_printf(m, "%02x%02x%02x%02x%02x%02x\n", crc[0], crc[1], crc[2], diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 06b8bd4..217bc06 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3877,13 +3877,15 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) do { intel_wait_for_vblank(dev_priv, intel_crtc->pipe); - + usleep_range(16700, 17000); if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { + DRM_DEBUG_KMS("Could not read TEST_SINK_MISC\n"); ret = -EIO; goto out; } count = buf & DP_TEST_COUNT_MASK; + DRM_DEBUG_KMS("PSR count is %d\n", count); } while (--attempts && count); if (attempts == 0) { @@ -3928,6 +3930,8 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) } intel_wait_for_vblank(dev_priv, intel_crtc->pipe); + usleep_range(16700, 17000); + DRM_DEBUG_KMS("PSR Successfully started sink CRC\n"); return 0; } @@ -3939,21 +3943,30 @@ 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); + else + return -ENOMEM; ret = intel_dp_sink_crc_start(intel_dp); - if (ret) + if (ret) { + DRM_DEBUG_KMS("Could not start sink crc; ret %d\n", ret); return ret; + } do { intel_wait_for_vblank(dev_priv, intel_crtc->pipe); + usleep_range(16700, 17000); if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { + DRM_DEBUG_KMS("Cound not read TEST_SINK_MISC\n"); ret = -EIO; goto stop; } count = buf & DP_TEST_COUNT_MASK; - } while (--attempts && count == 0); if (attempts == 0) { @@ -3962,11 +3975,41 @@ 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; + memset(old_crc, 0xFF, 6); + do { + intel_wait_for_vblank(dev_priv, intel_crtc->pipe); + usleep_range(16500, 17000); + if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, + crc, 6) < 0) { + DRM_DEBUG_KMS("Could not read sink crc\n"); + ret = -EIO; + goto stop; + } + + if (memcmp(old_crc, crc, 6) == 0) { + DRM_DEBUG_KMS("PSR Active: %3s Matching crc values found:" + "%02x%02x%02x%02x%02x%02x\n", + yesno(dev_priv->psr.active), + crc[0], crc[1], crc[2], + crc[3], crc[4], crc[5]); + ret = 0; + goto stop; + } else { + DRM_DEBUG_KMS("PSR Active: %3s crc %02x%02x%02x%02x%02x%02x " + "doesn't match " + "previous %02x%02x%02x%02x%02x%02x\n", + yesno(dev_priv->psr.active), + crc[0], crc[1], crc[2], + crc[3], crc[4], crc[5], + old_crc[0], old_crc[1], old_crc[2], + old_crc[3], old_crc[4], old_crc[5]); + 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;