From patchwork Fri Apr 1 22:29:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 12798828 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 81414C433EF for ; Fri, 1 Apr 2022 22:28:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1978310E155; Fri, 1 Apr 2022 22:27:59 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id CBA8D10E0CC for ; Fri, 1 Apr 2022 22:27:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648852077; x=1680388077; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=ly950f1+Gehr/pHweBoktBRS+pe3HmYu/3jbZhyRvME=; b=B4MwdGQEi5klvc8xLBFkJAjcVDT4e4WgP9ok1nJ9OVDDyV6ZJIVHlkrh aeT787zNalVLiyq2a2jqIfjwpd7Cq/Q/9QdDtdhLlNFAltz4xXQeRTMNM kKqVOL+GP2ksMZg+eZQoGnw5t6GPpKmsqCqlhirwViQpAcbhgfQUQU+pv +D69BMAtdB8gvh1aJ2wmK5ipF9YOHifUaH7eNWzldiHBCfFF4hTK2x2Sv s6CpPq2HqVd/+JOFXxZP/DZdQgHg82Gd05WU6+WSQmzDpAQWNJQgvAmwR XdNx7CUeFi4oqD+I3vStg7MXVJPHLQ+C5cR3RzQVW86kwPkjxTHN7QWlp A==; X-IronPort-AV: E=McAfee;i="6200,9189,10304"; a="247750781" X-IronPort-AV: E=Sophos;i="5.90,228,1643702400"; d="scan'208";a="247750781" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 15:27:56 -0700 X-IronPort-AV: E=Sophos;i="5.90,228,1643702400"; d="scan'208";a="567866707" Received: from srtirum1-mobl.amr.corp.intel.com (HELO josouza-mobl2.amr.corp.intel.com) ([10.213.185.120]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 15:27:54 -0700 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org Date: Fri, 1 Apr 2022 15:29:09 -0700 Message-Id: <20220401222911.199284-1-jose.souza@intel.com> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 1/3] drm/i915/display/psr: Set partial frame enable when forcing full frame fetch 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" Following up what was done in commit 804f46885317 ("drm/i915/psr: Set "SF Partial Frame Enable" also on full update") and also setting partial frame enable when psr_force_hw_tracking_exit() is called. Also as PSR2_MAN_TRK_CTL is a double buffered registers do a RMW is not a good idea so here also setting the man_trk_ctl_enable_bit() that is required in TGL and only doing a register write. v2: - not doing a rmw Cc: Jouni Högander Cc: Mika Kahola Signed-off-by: José Roberto de Souza Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_psr.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 80002ca6a6ebe..2da2468f555ec 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1436,6 +1436,11 @@ void intel_psr_resume(struct intel_dp *intel_dp) mutex_unlock(&psr->lock); } +static inline u32 man_trk_ctl_enable_bit_get(struct drm_i915_private *dev_priv) +{ + return IS_ALDERLAKE_P(dev_priv) ? 0 : PSR2_MAN_TRK_CTL_ENABLE; +} + static inline u32 man_trk_ctl_single_full_frame_bit_get(struct drm_i915_private *dev_priv) { return IS_ALDERLAKE_P(dev_priv) ? @@ -1455,9 +1460,11 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); if (intel_dp->psr.psr2_sel_fetch_enabled) - intel_de_rmw(dev_priv, - PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0, - man_trk_ctl_single_full_frame_bit_get(dev_priv)); + intel_de_write(dev_priv, + PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), + man_trk_ctl_enable_bit_get(dev_priv) | + man_trk_ctl_partial_frame_bit_get(dev_priv) | + man_trk_ctl_single_full_frame_bit_get(dev_priv)); /* * Display WA #0884: skl+ @@ -1554,10 +1561,7 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - u32 val = 0; - - if (!IS_ALDERLAKE_P(dev_priv)) - val = PSR2_MAN_TRK_CTL_ENABLE; + u32 val = man_trk_ctl_enable_bit_get(dev_priv); /* SF partial frame enable has to be set even on full update */ val |= man_trk_ctl_partial_frame_bit_get(dev_priv); From patchwork Fri Apr 1 22:29:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 12798827 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D62AAC433F5 for ; Fri, 1 Apr 2022 22:27:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EE64710E0CC; Fri, 1 Apr 2022 22:27:58 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5785310E0CC for ; Fri, 1 Apr 2022 22:27:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648852078; x=1680388078; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wSjWBGHY1fYypYgwF5GR8WLWrk/A5L+g25Fv3hqYS08=; b=O/eDqBFN0zh3RgJdUvw2x4RbIJKYMfaYZlQtQxgisJjrYfa2Bang8ojU NbwhiDeVTs0YfCUl8eUfCz3jwKsZy/FXVmBHRE6Nms0FDfh2JOiD14Dmv 8DuGSxG/5L3NQB+/rB5qvRT6+TeD7EDt88eHjJrsStZuL9VaEnH2JE/Sk cipAJbshtLjF5QkCcGxMWum2JmIASwscgy3Rjdsq52MftPr7UnnFQc+jO 20RdqqWbDClbu9DLTSXCAIi7pCueuuRLt0idPv9Ei8/t3ivB4r2hHVjft fG9zTf8sB/SnRjPbT5NHsLFFbjlnLESXhFn5/iakeFPJzey20bnAfa2lK g==; X-IronPort-AV: E=McAfee;i="6200,9189,10304"; a="247750786" X-IronPort-AV: E=Sophos;i="5.90,228,1643702400"; d="scan'208";a="247750786" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 15:27:58 -0700 X-IronPort-AV: E=Sophos;i="5.90,228,1643702400"; d="scan'208";a="567866725" Received: from srtirum1-mobl.amr.corp.intel.com (HELO josouza-mobl2.amr.corp.intel.com) ([10.213.185.120]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 15:27:56 -0700 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org Date: Fri, 1 Apr 2022 15:29:10 -0700 Message-Id: <20220401222911.199284-2-jose.souza@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220401222911.199284-1-jose.souza@intel.com> References: <20220401222911.199284-1-jose.souza@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 2/3] drm/i915/display/psr: Lock and unlock PSR around pipe updates 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" Frontbuffer rendering and page flips can race with each other and this can potentialy cause issues with PSR2 selective fetch. And because pipe/crtc updates are time sentive we can't grab the PSR lock after intel_pipe_update_start() and before intel_pipe_update_end(). So here adding the lock and unlock functions and calls, the proper PSR2 selective fetch handling will come in a separated patch. Cc: Jouni Högander Cc: Mika Kahola Signed-off-by: José Roberto de Souza Reported-by: kernel test robot Reported-by: kernel test robot Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_crtc.c | 6 +- drivers/gpu/drm/i915/display/intel_psr.c | 69 ++++++++++++++++++++--- drivers/gpu/drm/i915/display/intel_psr.h | 5 +- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index f655c16228776..a5439182d5ae4 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -507,6 +507,8 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) VBLANK_EVASION_TIME_US); max = vblank_start - 1; + intel_psr_lock(new_crtc_state); + if (min <= 0 || max <= 0) goto irq_disable; @@ -518,7 +520,7 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) * VBL interrupts will start the PSR exit and prevent a PSR * re-entry as well. */ - intel_psr_wait_for_idle(new_crtc_state); + intel_psr_wait_for_idle_locked(new_crtc_state); local_irq_disable(); @@ -683,6 +685,8 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) local_irq_enable(); + intel_psr_unlock(new_crtc_state); + if (intel_vgpu_active(dev_priv)) return; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 2da2468f555ec..58597480054eb 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1548,10 +1548,19 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_encoder *encoder; if (!crtc_state->enable_psr2_sel_fetch) return; + for_each_intel_encoder_mask_with_psr(&dev_priv->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + lockdep_assert_held(&intel_dp->psr.lock); + break; + } + intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder), crtc_state->psr2_man_track_ctl); } @@ -1919,13 +1928,13 @@ static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp) } /** - * intel_psr_wait_for_idle - wait for PSR be ready for a pipe update + * intel_psr_wait_for_idle_locked - wait for PSR be ready for a pipe update * @new_crtc_state: new CRTC state * * This function is expected to be called from pipe_update_start() where it is * not expected to race with PSR enable or disable. */ -void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state) +void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_state) { struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev); struct intel_encoder *encoder; @@ -1938,12 +1947,10 @@ void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state) struct intel_dp *intel_dp = enc_to_intel_dp(encoder); int ret; - mutex_lock(&intel_dp->psr.lock); + lockdep_assert_held(&intel_dp->psr.lock); - if (!intel_dp->psr.enabled) { - mutex_unlock(&intel_dp->psr.lock); + if (!intel_dp->psr.enabled) continue; - } if (intel_dp->psr.psr2_enabled) ret = _psr2_ready_for_pipe_update_locked(intel_dp); @@ -1952,8 +1959,6 @@ void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state) if (ret) drm_err(&dev_priv->drm, "PSR wait timed out, atomic update may fail\n"); - - mutex_unlock(&intel_dp->psr.lock); } } @@ -2444,3 +2449,51 @@ bool intel_psr_enabled(struct intel_dp *intel_dp) return ret; } + +/** + * intel_psr_lock - grab psr.lock mutex + * @crtc_state: the crtc state + * + * This is initially meant to be used by around CRTC update, when + * vblank sensitive registers are updated and we need grab the lock + * before it to avoid vblank evasion. + */ +void intel_psr_lock(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_encoder *encoder; + + if (!crtc_state->has_psr) + return; + + for_each_intel_encoder_mask_with_psr(&i915->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + mutex_lock(&intel_dp->psr.lock); + break; + } +} + +/** + * intel_psr_lock - grab psr.lock mutex + * @crtc_state: the crtc state + * + * Release the PSR lock that was held during pipe update. + */ +void intel_psr_unlock(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_encoder *encoder; + + if (!crtc_state->has_psr) + return; + + for_each_intel_encoder_mask_with_psr(&i915->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + mutex_unlock(&intel_dp->psr.lock); + break; + } +} diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index f6526d9ccfdc6..2ac3a46cccc50 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -41,7 +41,7 @@ void intel_psr_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config); void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir); void intel_psr_short_pulse(struct intel_dp *intel_dp); -void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state); +void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_state); bool intel_psr_enabled(struct intel_dp *intel_dp); int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc); @@ -55,4 +55,7 @@ void intel_psr2_disable_plane_sel_fetch(struct intel_plane *plane, void intel_psr_pause(struct intel_dp *intel_dp); void intel_psr_resume(struct intel_dp *intel_dp); +void intel_psr_lock(const struct intel_crtc_state *crtc_state); +void intel_psr_unlock(const struct intel_crtc_state *crtc_state); + #endif /* __INTEL_PSR_H__ */ From patchwork Fri Apr 1 22:29:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 12798829 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 40F94C433FE for ; Fri, 1 Apr 2022 22:28:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1C5C910E158; Fri, 1 Apr 2022 22:28:02 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id DEF7710E158 for ; Fri, 1 Apr 2022 22:28:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648852080; x=1680388080; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iiv+Z6V9hVu7OD7T7blPQ/B4AZGSJqx355cMYJJ2DSg=; b=TnCtSDFvXtPLIvAbHMzfqMt2FmXDnKLeeapYuJKVAE4ATgCLRx59v9Lq nbf/NmuECYZUBqYD38DOvxH36kJaBgQuujBa3uy7M4aV4w4HJ8/OBkIO7 gOE2bTlopOqEvsG5yv7tk+YjL7W+Ur9+BlfbyjDPVpfB4DQyAd7xjiUF5 3VLMzhi17ghgXqM/Vw6Sx827Iytfns0H6WGZX1ZL8HYeXP2MVWy0ktpfl nKzdskwt2k0qwyS4v5Po+WcLax1lubueFCKv2BK0RXOx6unCW1Mr4T2ic R50oZCmk3XLbqxCXXtbXdYYY+SNiHEzKx6GxTotYtlz3lwf5H7j+bBgF3 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10304"; a="247750796" X-IronPort-AV: E=Sophos;i="5.90,228,1643702400"; d="scan'208";a="247750796" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 15:28:00 -0700 X-IronPort-AV: E=Sophos;i="5.90,228,1643702400"; d="scan'208";a="567866758" Received: from srtirum1-mobl.amr.corp.intel.com (HELO josouza-mobl2.amr.corp.intel.com) ([10.213.185.120]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 15:27:58 -0700 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org Date: Fri, 1 Apr 2022 15:29:11 -0700 Message-Id: <20220401222911.199284-3-jose.souza@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220401222911.199284-1-jose.souza@intel.com> References: <20220401222911.199284-1-jose.souza@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 3/3] drm/i915/display/psr: Use continuos full frame to handle frontbuffer invalidations 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" Instead of exit PSR when a frontbuffer invalidation happens, we can enable the PSR2 selective fetch continuous full frame, that will keep the panel updated like PSR was disabled but without keeping PSR active. So as soon as the frontbuffer flush happens we can disable the continuous full frame and start to do selective fetches much quicker than the path that would enable PSR, that will wait a few frames to actually activate PSR. Also this approach has proven to fix some glitches found in Alderlake-P when there are a lot of invalidations happening together with page flips. Some may ask why it is writing to CURSURFLIVE(), it is because that is the way that hardware team provided us to poke display to handle PSR updates, and it is being used since display 9. v2: - handling possible race conditions between frontbuffer rendering and page flips Cc: Khaled Almahallawy Cc: Shawn C Lee Cc: Jouni Högander Cc: Mika Kahola Signed-off-by: José Roberto de Souza Reviewed-by: Jouni Högander --- .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 88 ++++++++++++++++--- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 96024f7d839d4..cfd042117b109 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1525,6 +1525,7 @@ struct intel_psr { bool colorimetry_support; bool psr2_enabled; bool psr2_sel_fetch_enabled; + bool psr2_sel_fetch_cff_enabled; bool req_psr2_sdp_prior_scanline; u8 sink_sync_latency; ktime_t last_entry_attempt; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 58597480054eb..5b1963b7743dc 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1221,6 +1221,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_dp->psr.dc3co_exit_delay = val; intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline; intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch; + intel_dp->psr.psr2_sel_fetch_cff_enabled = false; intel_dp->psr.req_psr2_sdp_prior_scanline = crtc_state->req_psr2_sdp_prior_scanline; @@ -1455,6 +1456,13 @@ static inline u32 man_trk_ctl_partial_frame_bit_get(struct drm_i915_private *dev PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; } +static inline u32 man_trk_ctl_continuos_full_frame(struct drm_i915_private *dev_priv) +{ + return IS_ALDERLAKE_P(dev_priv) ? + ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME : + PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME; +} + static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -1558,6 +1566,8 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st struct intel_dp *intel_dp = enc_to_intel_dp(encoder); lockdep_assert_held(&intel_dp->psr.lock); + if (intel_dp->psr.psr2_sel_fetch_cff_enabled) + return; break; } @@ -2135,6 +2145,27 @@ static void intel_psr_work(struct work_struct *work) mutex_unlock(&intel_dp->psr.lock); } +static void _psr_invalidate_handle(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + if (intel_dp->psr.psr2_sel_fetch_enabled) { + u32 val; + + if (intel_dp->psr.psr2_sel_fetch_cff_enabled) + return; + + val = man_trk_ctl_enable_bit_get(dev_priv) | + man_trk_ctl_partial_frame_bit_get(dev_priv) | + man_trk_ctl_continuos_full_frame(dev_priv); + intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), val); + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); + intel_dp->psr.psr2_sel_fetch_cff_enabled = true; + } else { + intel_psr_exit(intel_dp); + } +} + /** * intel_psr_invalidate - Invalidade PSR * @dev_priv: i915 device @@ -2171,7 +2202,7 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv, intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits; if (pipe_frontbuffer_bits) - intel_psr_exit(intel_dp); + _psr_invalidate_handle(intel_dp); mutex_unlock(&intel_dp->psr.lock); } @@ -2203,6 +2234,42 @@ tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, intel_dp->psr.dc3co_exit_delay); } +static void _psr_flush_handle(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + if (intel_dp->psr.psr2_sel_fetch_enabled) { + if (intel_dp->psr.psr2_sel_fetch_cff_enabled) { + /* can we turn CFF off? */ + if (intel_dp->psr.busy_frontbuffer_bits == 0) { + u32 val = man_trk_ctl_enable_bit_get(dev_priv) | + man_trk_ctl_partial_frame_bit_get(dev_priv) | + man_trk_ctl_single_full_frame_bit_get(dev_priv); + + /* + * turn continuous full frame off and do a single + * full frame + */ + intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), + val); + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); + intel_dp->psr.psr2_sel_fetch_cff_enabled = false; + } + } else { + /* + * continuous full frame is disabled, only a single full + * frame is required + */ + psr_force_hw_tracking_exit(intel_dp); + } + } else { + psr_force_hw_tracking_exit(intel_dp); + + if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits) + schedule_work(&intel_dp->psr.work); + } +} + /** * intel_psr_flush - Flush PSR * @dev_priv: i915 device @@ -2240,25 +2307,22 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, * we have to ensure that the PSR is not activated until * intel_psr_resume() is called. */ - if (intel_dp->psr.paused) { - mutex_unlock(&intel_dp->psr.lock); - continue; - } + if (intel_dp->psr.paused) + goto unlock; if (origin == ORIGIN_FLIP || (origin == ORIGIN_CURSOR_UPDATE && !intel_dp->psr.psr2_sel_fetch_enabled)) { tgl_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin); - mutex_unlock(&intel_dp->psr.lock); - continue; + goto unlock; } - /* By definition flush = invalidate + flush */ - if (pipe_frontbuffer_bits) - psr_force_hw_tracking_exit(intel_dp); + if (pipe_frontbuffer_bits == 0) + goto unlock; - if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits) - schedule_work(&intel_dp->psr.work); + /* By definition flush = invalidate + flush */ + _psr_flush_handle(intel_dp); +unlock: mutex_unlock(&intel_dp->psr.lock); } }