From patchwork Wed Nov 27 20:12:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 11264895 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 05F23139A for ; Wed, 27 Nov 2019 20:13:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E1D3B207DD for ; Wed, 27 Nov 2019 20:13:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E1D3B207DD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6B1CE897F5; Wed, 27 Nov 2019 20:13:17 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2DB12897F5 for ; Wed, 27 Nov 2019 20:13:15 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Nov 2019 12:13:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,250,1571727600"; d="scan'208";a="217442028" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga001.fm.intel.com with SMTP; 27 Nov 2019 12:12:58 -0800 Received: by stinkbox (sSMTP sendmail emulation); Wed, 27 Nov 2019 22:12:58 +0200 From: Ville Syrjala To: intel-gfx@lists.freedesktop.org Date: Wed, 27 Nov 2019 22:12:20 +0200 Message-Id: <20191127201222.16669-13-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191127201222.16669-1-ville.syrjala@linux.intel.com> References: <20191127201222.16669-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 12/14] drm/i915/fbc: Wait for vblank after FBC disable on glk+ 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä On glk+ the hardware gets confused if we disable FBC while it's recompressing and we perform a plane update during the same frame. The result is that top of the screen gets corrupted. We can avoid that by giving the hardware enough time to finish the FBC disable before we touch the plane registers. Ie. we need an extra vblank wait after FBC disable. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++- drivers/gpu/drm/i915/display/intel_fbc.c | 26 +++++++++++++++++--- drivers/gpu/drm/i915/display/intel_fbc.h | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d592b7284406..3210a0f00009 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6105,7 +6105,9 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state, intel_atomic_get_new_plane_state(intel_state, to_intel_plane(primary)); - intel_fbc_pre_update(crtc, pipe_config, new_primary_state); + if (intel_fbc_pre_update(crtc, pipe_config, new_primary_state)) + intel_wait_for_vblank(dev_priv, crtc->pipe); + /* * Gen2 reports pipe underruns whenever all planes are disabled. * So disable underrun reporting before all the planes get disabled. diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 220fbe5bd919..78fe4abb5a93 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -859,16 +859,17 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) return true; } -void intel_fbc_pre_update(struct intel_crtc *crtc, +bool intel_fbc_pre_update(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; const char *reason = "update pending"; + bool need_vblank_wait = false; if (!fbc_supported(dev_priv)) - return; + return need_vblank_wait; mutex_lock(&fbc->lock); @@ -878,10 +879,29 @@ void intel_fbc_pre_update(struct intel_crtc *crtc, intel_fbc_update_state_cache(crtc, crtc_state, plane_state); fbc->flip_pending = true; - if (!intel_fbc_can_flip_nuke(crtc_state)) + if (!intel_fbc_can_flip_nuke(crtc_state)) { intel_fbc_deactivate(dev_priv, reason); + + /* + * Display WA #1198: glk+ + * Need an extra vblank wait between FBC disable and most plane + * updates. Bspec says this is only needed for plane disable, but + * that is not true. Touching most plane registers will cause the + * corruption to appear. Also SKL/derivatives do not seem to be + * affected. + * + * TODO: could optimize this a bit by sampling the frame + * counter when we disable FBC (if it was already done earlier) + * and skipping the extra vblank wait before the plane update + * if at least one frame has already passed. + */ + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) + need_vblank_wait = true; + } unlock: mutex_unlock(&fbc->lock); + + return need_vblank_wait; } /** diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index ba8eeefd4d9a..9a2f1094cbda 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -19,7 +19,7 @@ struct intel_plane_state; void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, struct intel_atomic_state *state); bool intel_fbc_is_active(struct drm_i915_private *dev_priv); -void intel_fbc_pre_update(struct intel_crtc *crtc, +bool intel_fbc_pre_update(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_fbc_post_update(struct intel_crtc *crtc);