From patchwork Mon Jan 11 16:37:07 2021 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: 12011091 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF699C433DB for ; Mon, 11 Jan 2021 16:37:40 +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 A5D242250E for ; Mon, 11 Jan 2021 16:37:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A5D242250E 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 2D68089D5C; Mon, 11 Jan 2021 16:37:40 +0000 (UTC) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTPS id C996B89CF5 for ; Mon, 11 Jan 2021 16:37:38 +0000 (UTC) IronPort-SDR: kQB6BLuk1PJRn4YCa03g9mRnAD35WFhE8AsKRe0PqRUSCpc82pzv+isNB6uiglCncO1KNAzhQy /TbB77chligA== X-IronPort-AV: E=McAfee;i="6000,8403,9861"; a="196480924" X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="196480924" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 08:37:38 -0800 IronPort-SDR: QjA5bYrB1zPKdoY5v1XW6Pvl62HjOS44NUWU/m5jVW0G6YW5ssnmUi3028zUY67fdv0VTuovDJ wFZRbRwQbSXw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="404164822" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by FMSMGA003.fm.intel.com with SMTP; 11 Jan 2021 08:37:36 -0800 Received: by stinkbox (sSMTP sendmail emulation); Mon, 11 Jan 2021 18:37:35 +0200 From: Ville Syrjala To: intel-gfx@lists.freedesktop.org Date: Mon, 11 Jan 2021 18:37:07 +0200 Message-Id: <20210111163711.12913-8-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210111163711.12913-1-ville.syrjala@linux.intel.com> References: <20210111163711.12913-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 07/11] drm/i915: Reuse the async_flip() hook for the async flip disable w/a X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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 some platforms we need to trigger an extra async flip with the async flip bit disabled, and then wait for the next vblank until the async flip bit off state will actually latch. Currently the w/a is just open coded for skl+ universal planes. Instead of doing that lets reuse the .async_flip() hook for this purpose since it needs to write the exact same set of registers. In order to do this we'll just have the caller pass in the state of the async flip bit explicitly. Cc: Karthik B S Cc: Vandita Kulkarni Signed-off-by: Ville Syrjälä Reviewed-by: Karthik B S --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 59 ++++++++----------- .../drm/i915/display/intel_display_types.h | 4 +- drivers/gpu/drm/i915/display/intel_sprite.c | 7 ++- 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b5e1ee99535c..4683f98f7e54 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -452,7 +452,7 @@ void intel_update_plane(struct intel_plane *plane, trace_intel_update_plane(&plane->base, crtc); if (crtc_state->uapi.async_flip && plane->async_flip) - plane->async_flip(plane, crtc_state, plane_state); + plane->async_flip(plane, crtc_state, plane_state, true); else plane->update_plane(plane, crtc_state, plane_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index fc932028c368..9ea7a89432d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6166,41 +6166,36 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state, } } -static void skl_disable_async_flip_wa(struct intel_atomic_state *state, - struct intel_crtc *crtc, - const struct intel_crtc_state *new_crtc_state) +static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct drm_i915_private *i915 = to_i915(state->base.dev); + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + u8 update_planes = new_crtc_state->update_planes; + const struct intel_plane_state *old_plane_state; struct intel_plane *plane; - struct intel_plane_state *new_plane_state; + bool need_vbl_wait = false; int i; - for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) { - u32 update_mask = new_crtc_state->update_planes; - u32 plane_ctl, surf_addr; - enum plane_id plane_id; - unsigned long irqflags; - enum pipe pipe; - - if (crtc->pipe != plane->pipe || - !(update_mask & BIT(plane->id))) - continue; - - plane_id = plane->id; - pipe = plane->pipe; - - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); - plane_ctl = intel_de_read_fw(dev_priv, PLANE_CTL(pipe, plane_id)); - surf_addr = intel_de_read_fw(dev_priv, PLANE_SURF(pipe, plane_id)); - - plane_ctl &= ~PLANE_CTL_ASYNC_FLIP; - - intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); - intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), surf_addr); - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (plane->need_async_flip_disable_wa && + plane->pipe == crtc->pipe && + update_planes & BIT(plane->id)) { + /* + * Apart from the async flip bit we want to + * preserve the old state for the plane. + */ + plane->async_flip(plane, old_crtc_state, + old_plane_state, false); + need_vbl_wait = true; + } } - intel_wait_for_vblank(dev_priv, crtc->pipe); + if (need_vbl_wait) + intel_wait_for_vblank(i915, crtc->pipe); } static void intel_pre_plane_update(struct intel_atomic_state *state, @@ -6293,10 +6288,8 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * WA for platforms where async address update enable bit * is double buffered and only latched at start of vblank. */ - if (old_crtc_state->uapi.async_flip && - !new_crtc_state->uapi.async_flip && - IS_GEN_RANGE(dev_priv, 9, 10)) - skl_disable_async_flip_wa(state, crtc, new_crtc_state); + if (old_crtc_state->uapi.async_flip && !new_crtc_state->uapi.async_flip) + intel_crtc_async_flip_disable_wa(state, crtc); } static void intel_crtc_disable_planes(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 255648ab0fa7..56d9a18ef114 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1221,6 +1221,7 @@ struct intel_plane { enum pipe pipe; bool has_fbc; bool has_ccs; + bool need_async_flip_disable_wa; u32 frontbuffer_bit; struct { @@ -1257,7 +1258,8 @@ struct intel_plane { const struct intel_plane_state *plane_state); void (*async_flip)(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state); + const struct intel_plane_state *plane_state, + bool async_flip); void (*enable_flip_done)(struct intel_plane *plane); void (*disable_flip_done)(struct intel_plane *plane); }; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 1188e0f92223..d7fd01e1ef77 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -771,7 +771,8 @@ icl_program_input_csc(struct intel_plane *plane, static void skl_plane_async_flip(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state) + const struct intel_plane_state *plane_state, + bool async_flip) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); unsigned long irqflags; @@ -782,7 +783,8 @@ skl_plane_async_flip(struct intel_plane *plane, plane_ctl |= skl_plane_ctl_crtc(crtc_state); - plane_ctl |= PLANE_CTL_ASYNC_FLIP; + if (async_flip) + plane_ctl |= PLANE_CTL_ASYNC_FLIP; spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); @@ -3335,6 +3337,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->min_cdclk = skl_plane_min_cdclk; if (plane_id == PLANE_PRIMARY) { + plane->need_async_flip_disable_wa = IS_GEN_RANGE(dev_priv, 9, 10); plane->async_flip = skl_plane_async_flip; plane->enable_flip_done = skl_plane_enable_flip_done; plane->disable_flip_done = skl_plane_disable_flip_done;