From patchwork Wed Nov 21 22:54:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 10693267 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C353F13BF for ; Wed, 21 Nov 2018 22:54:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B30AD2C3F7 for ; Wed, 21 Nov 2018 22:54:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4BA02C4EC; Wed, 21 Nov 2018 22:54:54 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 3F91E2C3F7 for ; Wed, 21 Nov 2018 22:54:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 337906E278; Wed, 21 Nov 2018 22:54:53 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 857D26E157 for ; Wed, 21 Nov 2018 22:54:44 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Nov 2018 14:54:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,262,1539673200"; d="scan'208";a="283121278" Received: from josouza-mobl.jf.intel.com ([10.24.11.10]) by fmsmga006.fm.intel.com with ESMTP; 21 Nov 2018 14:54:43 -0800 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org Date: Wed, 21 Nov 2018 14:54:39 -0800 Message-Id: <20181121225441.18785-4-jose.souza@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181121225441.18785-1-jose.souza@intel.com> References: <20181121225441.18785-1-jose.souza@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v5 4/6] drm/i915: Disable PSR when a PSR aux error happen X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dhinakaran Pandiyan Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP While PSR is active hardware will do aux transactions by it self to wakeup sink to receive a new frame when necessary. If that transaction is not acked by sink, hardware will trigger this interruption. So let's disable PSR as it is a hint that there is problem with this sink. The removed FIXME was asking to manually train the link but we don't need to do that as by spec sink should do a short pulse when it is out of sync with source, we just need to make sure it is awaken and the SDP header with PSR inactive set it will trigger the short pulse with a error set in the link status. v3: added workarround to fix scheduled work starvation cause by to frequent PSR error interruption v4: only setting irq_aux_error as we don't care in clear it and not using dev_priv->irq_lock as consequence. v5: rebased: using edp_psr_shift() Cc: Dhinakaran Pandiyan Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_psr.c | 41 ++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c189c8055b75..3526cedf55cf 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -505,6 +505,7 @@ struct i915_psr { ktime_t last_entry_attempt; ktime_t last_exit; bool sink_not_reliable; + bool irq_aux_error; }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index ab527f9a5436..f0bfe0a5ff7c 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -169,6 +169,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) u32 transcoders = BIT(TRANSCODER_EDP); enum transcoder cpu_transcoder; ktime_t time_ns = ktime_get(); + u32 mask = 0; if (INTEL_GEN(dev_priv) >= 8) transcoders |= BIT(TRANSCODER_A) | @@ -178,10 +179,22 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { int shift = edp_psr_shift(cpu_transcoder); - /* FIXME: Exit PSR and link train manually when this happens. */ - if (psr_iir & EDP_PSR_ERROR(shift)) - DRM_DEBUG_KMS("[transcoder %s] PSR aux error\n", - transcoder_name(cpu_transcoder)); + if (psr_iir & EDP_PSR_ERROR(shift)) { + DRM_WARN("[transcoder %s] PSR aux error\n", + transcoder_name(cpu_transcoder)); + + dev_priv->psr.irq_aux_error = true; + + /* + * If this interruption is not masked it will keep + * interrupting so fast that it prevents the scheduled + * work to run. + * Also after a PSR error, we don't want to arm PSR + * again so we don't care about unmask the interruption + * or unset irq_aux_error. + */ + mask |= EDP_PSR_ERROR(shift); + } if (psr_iir & EDP_PSR_PRE_ENTRY(shift)) { dev_priv->psr.last_entry_attempt = time_ns; @@ -203,6 +216,13 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) } } } + + if (mask) { + mask |= I915_READ(EDP_PSR_IMR); + I915_WRITE(EDP_PSR_IMR, mask); + + schedule_work(&dev_priv->psr.work); + } } static bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp) @@ -938,6 +958,16 @@ int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv, return ret; } +static void intel_psr_handle_irq(struct drm_i915_private *dev_priv) +{ + struct i915_psr *psr = &dev_priv->psr; + + intel_psr_disable_locked(psr->dp); + psr->sink_not_reliable = true; + /* let's make sure that sink is awaken */ + drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER, DP_SET_POWER_D0); +} + static void intel_psr_work(struct work_struct *work) { struct drm_i915_private *dev_priv = @@ -948,6 +978,9 @@ static void intel_psr_work(struct work_struct *work) if (!dev_priv->psr.enabled) goto unlock; + if (READ_ONCE(dev_priv->psr.irq_aux_error)) + intel_psr_handle_irq(dev_priv); + /* * We have to make sure PSR is ready for re-enable * otherwise it keeps disabled until next full enable/disable cycle.