From patchwork Thu Feb 18 15:58:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 8351781 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7E267C0553 for ; Thu, 18 Feb 2016 15:58:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9E9422034C for ; Thu, 18 Feb 2016 15:58:12 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id C7B772034A for ; Thu, 18 Feb 2016 15:58:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ED0556EC57; Thu, 18 Feb 2016 15:58:10 +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 ESMTP id 62C636EC57 for ; Thu, 18 Feb 2016 15:58:07 +0000 (UTC) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP; 18 Feb 2016 07:58:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,466,1449561600"; d="scan'208";a="915858682" Received: from rosetta.fi.intel.com (HELO rosetta) ([10.237.72.66]) by orsmga002.jf.intel.com with ESMTP; 18 Feb 2016 07:58:05 -0800 Received: by rosetta (Postfix, from userid 1000) id CB12E81941; Thu, 18 Feb 2016 17:58:09 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Thu, 18 Feb 2016 17:58:09 +0200 Message-Id: <1455811089-27884-1-git-send-email-mika.kuoppala@intel.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1455808874-22089-3-git-send-email-mika.kuoppala@intel.com> References: <1455808874-22089-3-git-send-email-mika.kuoppala@intel.com> Cc: Rodrigo Vivi Subject: [Intel-gfx] [PATCH 2/4] drm/i915/gen9: Verify and enforce dc6 state writes 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-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP It has been observed that sometimes disabling the dc6 fails and dc6 state pops back up, brief moment after disabling. This has to be dmc save/restore timing issue or other bug in the way dc states are handled. Try to work around this issue as we don't have firmware fix yet available. Verify that the value we wrote for the dmc sticks, and also enforce it by rewriting it, if it didn't. v2: Zero rereads on rewrite for extra paranoia (Imre) Testcase: kms_flip/basic-flip-vs-dpms References: https://bugs.freedesktop.org/show_bug.cgi?id=93768 Cc: Patrik Jakobsson Cc: Rodrigo Vivi Cc: Imre Deak Signed-off-by: Mika Kuoppala Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_runtime_pm.c | 41 +++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 8b9290fdb3b2..814cf5ac1ef0 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -470,6 +470,43 @@ static void gen9_set_dc_state_debugmask_memory_up( } } +static void gen9_write_dc_state(struct drm_i915_private *dev_priv, + u32 state) +{ + int rewrites = 0; + int rereads = 0; + u32 v; + + I915_WRITE(DC_STATE_EN, state); + + /* It has been observed that disabling the dc6 state sometimes + * doesn't stick and dmc keeps returning old value. Make sure + * the write really sticks enough times and also force rewrite until + * we are confident that state is exactly what we want. + */ + do { + v = I915_READ(DC_STATE_EN); + + if (v != state) { + I915_WRITE(DC_STATE_EN, state); + rewrites++; + rereads = 0; + } else if (rereads++ > 5) { + break; + } + + } while (rewrites < 100); + + if (v != state) + DRM_ERROR("Writing dc state to 0x%x failed, now 0x%x\n", + state, v); + + /* Most of the times we need one retry, avoid spam */ + if (rewrites > 1) + DRM_DEBUG_KMS("Rewrote dc state to 0x%x %d times\n", + state, rewrites); +} + static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) { uint32_t val; @@ -502,8 +539,8 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) val &= ~mask; val |= state; - I915_WRITE(DC_STATE_EN, val); - POSTING_READ(DC_STATE_EN); + + gen9_write_dc_state(dev_priv, val); dev_priv->csr.dc_state = val & mask; }