diff mbox series

[1/2] drm/i915/display: Add block_dc6_needed variable into intel_crtc

Message ID 20240913073347.3273589-2-jouni.hogander@intel.com (mailing list archive)
State New
Headers show
Series Block DC6 on Vblank enable for Panel Replay | expand

Commit Message

Hogander, Jouni Sept. 13, 2024, 7:33 a.m. UTC
We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
prevent DC6 in case of Panel Replay. This causes problems if user-space is
polling for vblank events. For this purpose add new block_dc6_needed
variable into intel_crtc.

Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
---
 .../gpu/drm/i915/display/intel_display_irq.c  | 28 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_display_irq.h  |  3 ++
 .../drm/i915/display/intel_display_types.h    |  7 +++++
 drivers/gpu/drm/i915/display/intel_psr.c      |  7 +++++
 4 files changed, 45 insertions(+)

Comments

Ville Syrjälä Sept. 13, 2024, 3:03 p.m. UTC | #1
On Fri, Sep 13, 2024 at 10:33:46AM +0300, Jouni Högander wrote:
> We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
> prevent DC6 in case of Panel Replay. This causes problems if user-space is
> polling for vblank events. For this purpose add new block_dc6_needed
> variable into intel_crtc.
> 
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> ---
>  .../gpu/drm/i915/display/intel_display_irq.c  | 28 +++++++++++++++++++
>  .../gpu/drm/i915/display/intel_display_irq.h  |  3 ++
>  .../drm/i915/display/intel_display_types.h    |  7 +++++
>  drivers/gpu/drm/i915/display/intel_psr.c      |  7 +++++
>  4 files changed, 45 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index 8f13f148c73e3..7ff721bcec0d3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -1361,6 +1361,34 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
>  	return true;
>  }
>  
> +/**
> + * block_dc6_on_vblank_get - get block DC6 entry reference
> + *
> + * @_crtc: drm crtc pointer
> + *
> + * This function is called from Panel Replay code when Panel Replay gets
> + * activated. Intention is to block DC6 entry when VBI is enabled and Panel
> + * Replay is active.
> + */
> +void block_dc6_on_vblank_get(struct drm_crtc *_crtc)
> +{
> +	to_intel_crtc(_crtc)->block_dc6_needed++;
> +}
> +
> +/**
> + * block_dc6_on_vblank_put - free block DC6 entry reference
> + *
> + * @crtc: drm crtc pointer
> + *
> + * This function is called from Panel Replay code when Panel Replay is
> + * deactivated. Intention is to block DC6 entry when VBI is enabled and Panel
> + * Replay is active.
> + */
> +void block_dc6_on_vblank_put(struct drm_crtc *crtc)
> +{
> +	to_intel_crtc(crtc)->block_dc6_needed--;
> +}
> +
>  int bdw_enable_vblank(struct drm_crtc *_crtc)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(_crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h
> index 2a090dd6abd7c..fe3ada8f37283 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
> @@ -77,6 +77,9 @@ void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_
>  void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]);
>  void i8xx_pipestat_irq_handler(struct drm_i915_private *i915, u16 iir, u32 pipe_stats[I915_MAX_PIPES]);
>  
> +void block_dc6_on_vblank_get(struct drm_crtc *crtc);
> +void block_dc6_on_vblank_put(struct drm_crtc *crtc);
> +
>  void intel_display_irq_init(struct drm_i915_private *i915);
>  
>  #endif /* __INTEL_DISPLAY_IRQ_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 000ab373c8879..df0c3eb750809 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1413,6 +1413,13 @@ struct intel_crtc {
>  #ifdef CONFIG_DEBUG_FS
>  	struct intel_pipe_crc pipe_crc;
>  #endif
> +
> +	/*
> +	 * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
> +	 * prevent DC6 in case of Panel Replay. This causes problems if user-space is
> +	 * polling for vblank events.
> +	 */
> +	u8 block_dc6_needed;
>  };
>  
>  struct intel_plane {
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 1a4ef231a53ca..f9e5177893c46 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -35,6 +35,7 @@
>  #include "intel_cursor_regs.h"
>  #include "intel_ddi.h"
>  #include "intel_de.h"
> +#include "intel_display_irq.h"
>  #include "intel_display_types.h"
>  #include "intel_dp.h"
>  #include "intel_dp_aux.h"
> @@ -970,6 +971,9 @@ static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
>  			       val);
>  	}
>  
> +	if (intel_dp_is_edp(intel_dp))
> +		block_dc6_on_vblank_get(&intel_crtc_for_pipe(display, intel_dp->psr.pipe)->base);

This still feels racy. Can't we make it just a simple flag that
gets set just once before/during intel_crtc_vblank_on()?

> +
>  	intel_de_rmw(display,
>  		     PSR2_MAN_TRK_CTL(display, intel_dp->psr.transcoder),
>  		     0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
> @@ -2005,6 +2009,9 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
>  	}
>  
>  	if (intel_dp->psr.panel_replay_enabled) {
> +		if (intel_dp_is_edp(intel_dp))
> +			block_dc6_on_vblank_put(drm_crtc_from_index(display->drm,
> +								    intel_dp->psr.pipe));
>  		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder),
>  			     TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
>  	} else if (intel_dp->psr.sel_update_enabled) {
> -- 
> 2.34.1
kernel test robot Sept. 14, 2024, 1:33 a.m. UTC | #2
Hi Jouni,

kernel test robot noticed the following build errors:

[auto build test ERROR on next-20240912]
[cannot apply to drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip linus/master v6.11-rc7 v6.11-rc6 v6.11-rc5 v6.11-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jouni-H-gander/drm-i915-display-Add-block_dc6_needed-variable-into-intel_crtc/20240913-153658
base:   next-20240912
patch link:    https://lore.kernel.org/r/20240913073347.3273589-2-jouni.hogander%40intel.com
patch subject: [PATCH 1/2] drm/i915/display: Add block_dc6_needed variable into intel_crtc
config: x86_64-defconfig (https://download.01.org/0day-ci/archive/20240914/202409140953.0izbdQ9U-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240914/202409140953.0izbdQ9U-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409140953.0izbdQ9U-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/display/intel_psr.c: In function 'dg2_activate_panel_replay':
>> drivers/gpu/drm/i915/display/intel_psr.c:973:62: error: passing argument 1 of 'intel_crtc_for_pipe' from incompatible pointer type [-Werror=incompatible-pointer-types]
     973 |                 block_dc6_on_vblank_get(&intel_crtc_for_pipe(display, intel_dp->psr.pipe)->base);
         |                                                              ^~~~~~~
         |                                                              |
         |                                                              struct intel_display *
   In file included from drivers/gpu/drm/i915/display/intel_psr.c:32:
   drivers/gpu/drm/i915/display/intel_crtc.h:46:65: note: expected 'struct drm_i915_private *' but argument is of type 'struct intel_display *'
      46 | struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
         |                                        ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
   cc1: some warnings being treated as errors


vim +/intel_crtc_for_pipe +973 drivers/gpu/drm/i915/display/intel_psr.c

   954	
   955	static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
   956	{
   957		struct intel_display *display = to_intel_display(intel_dp);
   958		struct intel_psr *psr = &intel_dp->psr;
   959		enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
   960	
   961		if (intel_dp_is_edp(intel_dp) && psr->sel_update_enabled) {
   962			u32 val = psr->su_region_et_enabled ?
   963				LNL_EDP_PSR2_SU_REGION_ET_ENABLE : 0;
   964	
   965			if (intel_dp->psr.req_psr2_sdp_prior_scanline)
   966				val |= EDP_PSR2_SU_SDP_SCANLINE;
   967	
   968			intel_de_write(display, EDP_PSR2_CTL(display, cpu_transcoder),
   969				       val);
   970		}
   971	
   972		if (intel_dp_is_edp(intel_dp))
 > 973			block_dc6_on_vblank_get(&intel_crtc_for_pipe(display, intel_dp->psr.pipe)->base);
   974	
   975		intel_de_rmw(display,
   976			     PSR2_MAN_TRK_CTL(display, intel_dp->psr.transcoder),
   977			     0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
   978	
   979		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder), 0,
   980			     TRANS_DP2_PANEL_REPLAY_ENABLE);
   981	}
   982
kernel test robot Sept. 14, 2024, 2:55 a.m. UTC | #3
Hi Jouni,

kernel test robot noticed the following build errors:

[auto build test ERROR on next-20240912]
[cannot apply to drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip linus/master v6.11-rc7 v6.11-rc6 v6.11-rc5 v6.11-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jouni-H-gander/drm-i915-display-Add-block_dc6_needed-variable-into-intel_crtc/20240913-153658
base:   next-20240912
patch link:    https://lore.kernel.org/r/20240913073347.3273589-2-jouni.hogander%40intel.com
patch subject: [PATCH 1/2] drm/i915/display: Add block_dc6_needed variable into intel_crtc
config: x86_64-rhel-8.3-rust (https://download.01.org/0day-ci/archive/20240914/202409141049.BsdxC6NQ-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240914/202409141049.BsdxC6NQ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409141049.BsdxC6NQ-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/i915/display/intel_psr.c:973:48: error: incompatible pointer types passing 'struct intel_display *' to parameter of type 'struct drm_i915_private *' [-Werror,-Wincompatible-pointer-types]
     973 |                 block_dc6_on_vblank_get(&intel_crtc_for_pipe(display, intel_dp->psr.pipe)->base);
         |                                                              ^~~~~~~
   drivers/gpu/drm/i915/display/intel_crtc.h:46:65: note: passing argument to parameter 'i915' here
      46 | struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
         |                                                                 ^
   1 error generated.


vim +973 drivers/gpu/drm/i915/display/intel_psr.c

   954	
   955	static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
   956	{
   957		struct intel_display *display = to_intel_display(intel_dp);
   958		struct intel_psr *psr = &intel_dp->psr;
   959		enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
   960	
   961		if (intel_dp_is_edp(intel_dp) && psr->sel_update_enabled) {
   962			u32 val = psr->su_region_et_enabled ?
   963				LNL_EDP_PSR2_SU_REGION_ET_ENABLE : 0;
   964	
   965			if (intel_dp->psr.req_psr2_sdp_prior_scanline)
   966				val |= EDP_PSR2_SU_SDP_SCANLINE;
   967	
   968			intel_de_write(display, EDP_PSR2_CTL(display, cpu_transcoder),
   969				       val);
   970		}
   971	
   972		if (intel_dp_is_edp(intel_dp))
 > 973			block_dc6_on_vblank_get(&intel_crtc_for_pipe(display, intel_dp->psr.pipe)->base);
   974	
   975		intel_de_rmw(display,
   976			     PSR2_MAN_TRK_CTL(display, intel_dp->psr.transcoder),
   977			     0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
   978	
   979		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder), 0,
   980			     TRANS_DP2_PANEL_REPLAY_ENABLE);
   981	}
   982
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index 8f13f148c73e3..7ff721bcec0d3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -1361,6 +1361,34 @@  static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
 	return true;
 }
 
+/**
+ * block_dc6_on_vblank_get - get block DC6 entry reference
+ *
+ * @_crtc: drm crtc pointer
+ *
+ * This function is called from Panel Replay code when Panel Replay gets
+ * activated. Intention is to block DC6 entry when VBI is enabled and Panel
+ * Replay is active.
+ */
+void block_dc6_on_vblank_get(struct drm_crtc *_crtc)
+{
+	to_intel_crtc(_crtc)->block_dc6_needed++;
+}
+
+/**
+ * block_dc6_on_vblank_put - free block DC6 entry reference
+ *
+ * @crtc: drm crtc pointer
+ *
+ * This function is called from Panel Replay code when Panel Replay is
+ * deactivated. Intention is to block DC6 entry when VBI is enabled and Panel
+ * Replay is active.
+ */
+void block_dc6_on_vblank_put(struct drm_crtc *crtc)
+{
+	to_intel_crtc(crtc)->block_dc6_needed--;
+}
+
 int bdw_enable_vblank(struct drm_crtc *_crtc)
 {
 	struct intel_crtc *crtc = to_intel_crtc(_crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h
index 2a090dd6abd7c..fe3ada8f37283 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.h
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
@@ -77,6 +77,9 @@  void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_
 void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]);
 void i8xx_pipestat_irq_handler(struct drm_i915_private *i915, u16 iir, u32 pipe_stats[I915_MAX_PIPES]);
 
+void block_dc6_on_vblank_get(struct drm_crtc *crtc);
+void block_dc6_on_vblank_put(struct drm_crtc *crtc);
+
 void intel_display_irq_init(struct drm_i915_private *i915);
 
 #endif /* __INTEL_DISPLAY_IRQ_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 000ab373c8879..df0c3eb750809 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1413,6 +1413,13 @@  struct intel_crtc {
 #ifdef CONFIG_DEBUG_FS
 	struct intel_pipe_crc pipe_crc;
 #endif
+
+	/*
+	 * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
+	 * prevent DC6 in case of Panel Replay. This causes problems if user-space is
+	 * polling for vblank events.
+	 */
+	u8 block_dc6_needed;
 };
 
 struct intel_plane {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 1a4ef231a53ca..f9e5177893c46 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -35,6 +35,7 @@ 
 #include "intel_cursor_regs.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
+#include "intel_display_irq.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dp_aux.h"
@@ -970,6 +971,9 @@  static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
 			       val);
 	}
 
+	if (intel_dp_is_edp(intel_dp))
+		block_dc6_on_vblank_get(&intel_crtc_for_pipe(display, intel_dp->psr.pipe)->base);
+
 	intel_de_rmw(display,
 		     PSR2_MAN_TRK_CTL(display, intel_dp->psr.transcoder),
 		     0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
@@ -2005,6 +2009,9 @@  static void intel_psr_exit(struct intel_dp *intel_dp)
 	}
 
 	if (intel_dp->psr.panel_replay_enabled) {
+		if (intel_dp_is_edp(intel_dp))
+			block_dc6_on_vblank_put(drm_crtc_from_index(display->drm,
+								    intel_dp->psr.pipe));
 		intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder),
 			     TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
 	} else if (intel_dp->psr.sel_update_enabled) {