intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer
@ 2021-08-25  0:58 José Roberto de Souza
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW José Roberto de Souza
                   ` (11 more replies)
  0 siblings, 12 replies; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Gwan-gyeong Mun, Daniel Vetter

This will break some IGT tests, here(https://patchwork.freedesktop.org/series/93764/)
I fixed the ones part of fast-feedback test list but probably there
will be more tests needing fix.

v2:
- dropped a "drm/damage_helper" patch
- new patch renaming all DRRS functions to intel_drrs_*()
- enabling PSR support for display 9, it was left disabled as mistake
- returning in frontbuffer functions to not set fb_tracking.busy/flip_bits

Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>

José Roberto de Souza (8):
  drm/i915/display: Drop PSR support from HSW and BDW
  drm/i915/display: Move DRRS code its own file
  drm/i915/display: Renaming DRRS functions to intel_drrs_*()
  drm/i915/display: Some code improvements and code style fixes for DRRS
  drm/i915/display: Share code between intel_drrs_flush and
    intel_drrs_invalidate
  drm/i915/display: Prepare DRRS for frontbuffer rendering drop
  drm/i915/display/skl+: Drop frontbuffer rendering support
  drm/i915/display: Drop PSR frontbuffer rendering support

 Documentation/gpu/i915.rst                    |  25 +-
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/display/intel_cursor.c   |   6 +-
 drivers/gpu/drm/i915/display/intel_ddi.c      |   7 +-
 drivers/gpu/drm/i915/display/intel_display.c  |   2 +
 .../drm/i915/display/intel_display_debugfs.c  |   9 +-
 .../drm/i915/display/intel_display_types.h    |   2 -
 drivers/gpu/drm/i915/display/intel_dp.c       | 473 +-----------------
 drivers/gpu/drm/i915/display/intel_dp.h       |  11 -
 drivers/gpu/drm/i915/display/intel_drrs.c     | 450 +++++++++++++++++
 drivers/gpu/drm/i915/display/intel_drrs.h     |  36 ++
 drivers/gpu/drm/i915/display/intel_fb.c       |   8 +-
 .../gpu/drm/i915/display/intel_frontbuffer.c  |  25 +-
 drivers/gpu/drm/i915/display/intel_psr.c      | 283 ++---------
 drivers/gpu/drm/i915/display/intel_psr.h      |   8 +-
 drivers/gpu/drm/i915/i915_drv.h               |   4 +-
 drivers/gpu/drm/i915/i915_irq.c               |  16 -
 drivers/gpu/drm/i915/i915_pci.c               |   4 +-
 drivers/gpu/drm/i915/i915_reg.h               |  21 +-
 19 files changed, 581 insertions(+), 810 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h

-- 
2.33.0


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-08-25 15:50   ` Rodrigo Vivi
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file José Roberto de Souza
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Gwan-gyeong Mun, José Roberto de Souza

At this point is sure that HSW and BDW will never have PSR enabled by
default, so here dropping it from device info and cleaning up code.

v2:
- enable psr support for display 9

Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 97 ++++--------------------
 drivers/gpu/drm/i915/i915_drv.h          |  2 -
 drivers/gpu/drm/i915/i915_irq.c          | 16 ----
 drivers/gpu/drm/i915/i915_pci.c          |  4 +-
 drivers/gpu/drm/i915/i915_reg.h          | 21 ++---
 5 files changed, 20 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index cade37f67f33c..3f6fb7d67f84d 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -364,41 +364,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
 	}
 }
 
-static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	u32 aux_clock_divider, aux_ctl;
-	int i;
-	static const u8 aux_msg[] = {
-		[0] = DP_AUX_NATIVE_WRITE << 4,
-		[1] = DP_SET_POWER >> 8,
-		[2] = DP_SET_POWER & 0xff,
-		[3] = 1 - 1,
-		[4] = DP_SET_POWER_D0,
-	};
-	u32 psr_aux_mask = EDP_PSR_AUX_CTL_TIME_OUT_MASK |
-			   EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK |
-			   EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK |
-			   EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK;
-
-	BUILD_BUG_ON(sizeof(aux_msg) > 20);
-	for (i = 0; i < sizeof(aux_msg); i += 4)
-		intel_de_write(dev_priv,
-			       EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2),
-			       intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
-
-	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
-
-	/* Start with bits set for DDI_AUX_CTL register */
-	aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, sizeof(aux_msg),
-					     aux_clock_divider);
-
-	/* Select only valid bits for SRD_AUX_CTL */
-	aux_ctl &= psr_aux_mask;
-	intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder),
-		       aux_ctl);
-}
-
 static void intel_psr_enable_sink(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -621,9 +586,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 static bool
 transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder trans)
 {
-	if (DISPLAY_VER(dev_priv) < 9)
-		return false;
-	else if (DISPLAY_VER(dev_priv) >= 12)
+	if (DISPLAY_VER(dev_priv) >= 12)
 		return trans == TRANSCODER_A;
 	else
 		return trans == TRANSCODER_EDP;
@@ -1114,12 +1077,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp)
 	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
 	u32 mask;
 
-	/* Only HSW and BDW have PSR AUX registers that need to be setup. SKL+
-	 * use hardcoded values PSR AUX transactions
-	 */
-	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-		hsw_psr_setup_aux(intel_dp);
-
 	if (intel_dp->psr.psr2_enabled && DISPLAY_VER(dev_priv) == 9) {
 		i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
 		u32 chicken = intel_de_read(dev_priv, reg);
@@ -1460,23 +1417,16 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	if (DISPLAY_VER(dev_priv) >= 9)
-		/*
-		 * Display WA #0884: skl+
-		 * This documented WA for bxt can be safely applied
-		 * broadly so we can force HW tracking to exit PSR
-		 * instead of disabling and re-enabling.
-		 * Workaround tells us to write 0 to CUR_SURFLIVE_A,
-		 * but it makes more sense write to the current active
-		 * pipe.
-		 */
-		intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
-	else
-		/*
-		 * A write to CURSURFLIVE do not cause HW tracking to exit PSR
-		 * on older gens so doing the manual exit instead.
-		 */
-		intel_psr_exit(intel_dp);
+	/*
+	 * Display WA #0884: skl+
+	 * This documented WA for bxt can be safely applied
+	 * broadly so we can force HW tracking to exit PSR
+	 * instead of disabling and re-enabling.
+	 * Workaround tells us to write 0 to CUR_SURFLIVE_A,
+	 * but it makes more sense write to the current active
+	 * pipe.
+	 */
+	intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
 }
 
 void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
@@ -1744,7 +1694,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
 		      const struct intel_crtc_state *crtc_state,
 		      const struct drm_connector_state *conn_state)
 {
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_psr *psr = &intel_dp->psr;
 	bool enable, psr2_enable;
 
@@ -1761,15 +1710,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
 		/* Force a PSR exit when enabling CRC to avoid CRC timeouts */
 		if (crtc_state->crc_enabled && psr->enabled)
 			psr_force_hw_tracking_exit(intel_dp);
-		else if (DISPLAY_VER(dev_priv) < 9 && psr->enabled) {
-			/*
-			 * Activate PSR again after a force exit when enabling
-			 * CRC in older gens
-			 */
-			if (!intel_dp->psr.active &&
-			    !intel_dp->psr.busy_frontbuffer_bits)
-				schedule_work(&intel_dp->psr.work);
-		}
 
 		goto unlock;
 	}
@@ -2182,23 +2122,12 @@ void intel_psr_init(struct intel_dp *intel_dp)
 
 	intel_dp->psr.source_support = true;
 
-	if (IS_HASWELL(dev_priv))
-		/*
-		 * HSW don't have PSR registers on the same space as transcoder
-		 * so set this to a value that when subtract to the register
-		 * in transcoder space results in the right offset for HSW
-		 */
-		dev_priv->hsw_psr_mmio_adjust = _SRD_CTL_EDP - _HSW_EDP_PSR_BASE;
-
 	if (dev_priv->params.enable_psr == -1)
-		if (DISPLAY_VER(dev_priv) < 9 || !dev_priv->vbt.psr.enable)
+		if (!dev_priv->vbt.psr.enable)
 			dev_priv->params.enable_psr = 0;
 
 	/* Set link_standby x link_off defaults */
-	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-		/* HSW and BDW require workarounds that we don't implement. */
-		intel_dp->psr.link_standby = false;
-	else if (DISPLAY_VER(dev_priv) < 12)
+	if (DISPLAY_VER(dev_priv) < 12)
 		/* For new platforms up to TGL let's respect VBT back again */
 		intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 106f218cec2b5..91453f7dbd656 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -886,8 +886,6 @@ struct drm_i915_private {
 	 */
 	u32 gpio_mmio_base;
 
-	u32 hsw_psr_mmio_adjust;
-
 	/* MMIO base address for MIPI regs */
 	u32 mipi_mmio_base;
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 58a452c3f0867..0a1681384c84b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2123,22 +2123,6 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
 	if (de_iir & DE_ERR_INT_IVB)
 		ivb_err_int_handler(dev_priv);
 
-	if (de_iir & DE_EDP_PSR_INT_HSW) {
-		struct intel_encoder *encoder;
-
-		for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
-			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-			u32 psr_iir = intel_uncore_read(&dev_priv->uncore,
-							EDP_PSR_IIR);
-
-			intel_psr_irq_handler(intel_dp, psr_iir);
-			intel_uncore_write(&dev_priv->uncore,
-					   EDP_PSR_IIR, psr_iir);
-			break;
-		}
-	}
-
 	if (de_iir & DE_AUX_CHANNEL_A_IVB)
 		dp_aux_irq_handler(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 96cfd6427cec1..ddb4434b3e41e 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -537,8 +537,6 @@ static const struct intel_device_info vlv_info = {
 		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \
 	.display.has_ddi = 1, \
 	.display.has_fpga_dbg = 1, \
-	.display.has_psr = 1, \
-	.display.has_psr_hw_tracking = 1, \
 	.display.has_dp_mst = 1, \
 	.has_rc6p = 0 /* RC6p removed-by HSW */, \
 	HSW_PIPE_OFFSETS, \
@@ -642,6 +640,8 @@ static const struct intel_device_info chv_info = {
 	.has_gt_uc = 1, \
 	.display.has_hdcp = 1, \
 	.display.has_ipc = 1, \
+	.display.has_psr = 1, \
+	.display.has_psr_hw_tracking = 1, \
 	.dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */ \
 	.dbuf.slice_mask = BIT(DBUF_S1)
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8d4cf1e203ab7..6add651262e29 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4513,11 +4513,9 @@ enum {
  * HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one
  * instance of it
  */
-#define _HSW_EDP_PSR_BASE			0x64800
 #define _SRD_CTL_A				0x60800
 #define _SRD_CTL_EDP				0x6f800
-#define _PSR_ADJ(tran, reg)			(_TRANS2(tran, reg) - dev_priv->hsw_psr_mmio_adjust)
-#define EDP_PSR_CTL(tran)			_MMIO(_PSR_ADJ(tran, _SRD_CTL_A))
+#define EDP_PSR_CTL(tran)			_MMIO(_TRANS2(tran, _SRD_CTL_A))
 #define   EDP_PSR_ENABLE			(1 << 31)
 #define   BDW_PSR_SINGLE_FRAME			(1 << 30)
 #define   EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK	(1 << 29) /* SW can't modify */
@@ -4561,22 +4559,13 @@ enum {
 #define   EDP_PSR_POST_EXIT(trans)		(0x2 << _EDP_PSR_TRANS_SHIFT(trans))
 #define   EDP_PSR_PRE_ENTRY(trans)		(0x1 << _EDP_PSR_TRANS_SHIFT(trans))
 
-#define _SRD_AUX_CTL_A				0x60810
-#define _SRD_AUX_CTL_EDP			0x6f810
-#define EDP_PSR_AUX_CTL(tran)			_MMIO(_PSR_ADJ(tran, _SRD_AUX_CTL_A))
-#define   EDP_PSR_AUX_CTL_TIME_OUT_MASK		(3 << 26)
-#define   EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK	(0x1f << 20)
-#define   EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK	(0xf << 16)
-#define   EDP_PSR_AUX_CTL_ERROR_INTERRUPT	(1 << 11)
-#define   EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK	(0x7ff)
-
 #define _SRD_AUX_DATA_A				0x60814
 #define _SRD_AUX_DATA_EDP			0x6f814
-#define EDP_PSR_AUX_DATA(tran, i)		_MMIO(_PSR_ADJ(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */
+#define EDP_PSR_AUX_DATA(tran, i)		_MMIO(_TRANS2(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */
 
 #define _SRD_STATUS_A				0x60840
 #define _SRD_STATUS_EDP				0x6f840
-#define EDP_PSR_STATUS(tran)			_MMIO(_PSR_ADJ(tran, _SRD_STATUS_A))
+#define EDP_PSR_STATUS(tran)			_MMIO(_TRANS2(tran, _SRD_STATUS_A))
 #define   EDP_PSR_STATUS_STATE_MASK		(7 << 29)
 #define   EDP_PSR_STATUS_STATE_SHIFT		29
 #define   EDP_PSR_STATUS_STATE_IDLE		(0 << 29)
@@ -4603,13 +4592,13 @@ enum {
 
 #define _SRD_PERF_CNT_A			0x60844
 #define _SRD_PERF_CNT_EDP		0x6f844
-#define EDP_PSR_PERF_CNT(tran)		_MMIO(_PSR_ADJ(tran, _SRD_PERF_CNT_A))
+#define EDP_PSR_PERF_CNT(tran)		_MMIO(_TRANS2(tran, _SRD_PERF_CNT_A))
 #define   EDP_PSR_PERF_CNT_MASK		0xffffff
 
 /* PSR_MASK on SKL+ */
 #define _SRD_DEBUG_A				0x60860
 #define _SRD_DEBUG_EDP				0x6f860
-#define EDP_PSR_DEBUG(tran)			_MMIO(_PSR_ADJ(tran, _SRD_DEBUG_A))
+#define EDP_PSR_DEBUG(tran)			_MMIO(_TRANS2(tran, _SRD_DEBUG_A))
 #define   EDP_PSR_DEBUG_MASK_MAX_SLEEP         (1 << 28)
 #define   EDP_PSR_DEBUG_MASK_LPSP              (1 << 27)
 #define   EDP_PSR_DEBUG_MASK_MEMUP             (1 << 26)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-08-25 15:55   ` Rodrigo Vivi
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/display: Renaming DRRS functions to intel_drrs_*() José Roberto de Souza
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jani Nikula, Rodrigo Vivi, José Roberto de Souza

intel_dp.c is a 5k lines monster, so moving DRRS out of it to reduce
some lines from it.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 Documentation/gpu/i915.rst                    |  14 +-
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |   1 +
 .../drm/i915/display/intel_display_debugfs.c  |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 467 +----------------
 drivers/gpu/drm/i915/display/intel_dp.h       |  11 -
 drivers/gpu/drm/i915/display/intel_drrs.c     | 477 ++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_drrs.h     |  32 ++
 .../gpu/drm/i915/display/intel_frontbuffer.c  |   1 +
 9 files changed, 521 insertions(+), 484 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 204ebdaadb45a..03021dfa0dd81 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -183,25 +183,25 @@ Frame Buffer Compression (FBC)
 Display Refresh Rate Switching (DRRS)
 -------------------------------------
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :doc: Display Refresh Rate Switching (DRRS)
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :functions: intel_dp_set_drrs_state
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :functions: intel_edp_drrs_enable
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :functions: intel_edp_drrs_disable
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :functions: intel_edp_drrs_invalidate
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :functions: intel_edp_drrs_flush
 
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
+.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
    :functions: intel_dp_drrs_init
 
 DPIO
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index fd997dfa5e32c..ee502a2354c44 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -213,6 +213,7 @@ i915-y += \
 	display/intel_dpll.o \
 	display/intel_dpll_mgr.o \
 	display/intel_dpt.o \
+	display/intel_drrs.o \
 	display/intel_dsb.o \
 	display/intel_fb.o \
 	display/intel_fbc.o \
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 1ef7a65feb660..828df570a4809 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -40,6 +40,7 @@
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
+#include "intel_drrs.h"
 #include "intel_dsi.h"
 #include "intel_fdi.h"
 #include "intel_fifo_underrun.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 8fdacb252bb19..b136a0fc0963b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -13,6 +13,7 @@
 #include "intel_display_types.h"
 #include "intel_dmc.h"
 #include "intel_dp.h"
+#include "intel_drrs.h"
 #include "intel_fbc.h"
 #include "intel_hdcp.h"
 #include "intel_hdmi.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index fd4f7e82e4205..965b888e0e771 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -55,6 +55,7 @@
 #include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
 #include "intel_dpll.h"
+#include "intel_drrs.h"
 #include "intel_fifo_underrun.h"
 #include "intel_hdcp.h"
 #include "intel_hdmi.h"
@@ -1675,46 +1676,6 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
 		intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
 }
 
-static void
-intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
-			     struct intel_crtc_state *pipe_config,
-			     int output_bpp, bool constant_n)
-{
-	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	int pixel_clock;
-
-	if (pipe_config->vrr.enable)
-		return;
-
-	/*
-	 * DRRS and PSR can't be enable together, so giving preference to PSR
-	 * as it allows more power-savings by complete shutting down display,
-	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
-	 * after intel_psr_compute_config().
-	 */
-	if (pipe_config->has_psr)
-		return;
-
-	if (!intel_connector->panel.downclock_mode ||
-	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
-		return;
-
-	pipe_config->has_drrs = true;
-
-	pixel_clock = intel_connector->panel.downclock_mode->clock;
-	if (pipe_config->splitter.enable)
-		pixel_clock /= pipe_config->splitter.link_count;
-
-	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
-			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
-			       constant_n, pipe_config->fec_enable);
-
-	/* FIXME: abstract this better */
-	if (pipe_config->splitter.enable)
-		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
-}
-
 int
 intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_state *pipe_config,
@@ -4785,432 +4746,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
 		drm_connector_attach_vrr_capable_property(connector);
 }
 
-/**
- * intel_dp_set_drrs_state - program registers for RR switch to take effect
- * @dev_priv: i915 device
- * @crtc_state: a pointer to the active intel_crtc_state
- * @refresh_rate: RR to be programmed
- *
- * This function gets called when refresh rate (RR) has to be changed from
- * one frequency to another. Switches can be between high and low RR
- * supported by the panel or to any other RR based on media playback (in
- * this case, RR value needs to be passed from user space).
- *
- * The caller of this function needs to take a lock on dev_priv->drrs.
- */
-static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
-				    const struct intel_crtc_state *crtc_state,
-				    int refresh_rate)
-{
-	struct intel_dp *intel_dp = dev_priv->drrs.dp;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
-
-	if (refresh_rate <= 0) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Refresh rate should be positive non-zero.\n");
-		return;
-	}
-
-	if (intel_dp == NULL) {
-		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
-		return;
-	}
-
-	if (!crtc) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "DRRS: intel_crtc not initialized\n");
-		return;
-	}
-
-	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
-		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
-		return;
-	}
-
-	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
-			refresh_rate)
-		index = DRRS_LOW_RR;
-
-	if (index == dev_priv->drrs.refresh_rate_type) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "DRRS requested for previously set RR...ignoring\n");
-		return;
-	}
-
-	if (!crtc_state->hw.active) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "eDP encoder disabled. CRTC not Active\n");
-		return;
-	}
-
-	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
-		switch (index) {
-		case DRRS_HIGH_RR:
-			intel_dp_set_m_n(crtc_state, M1_N1);
-			break;
-		case DRRS_LOW_RR:
-			intel_dp_set_m_n(crtc_state, M2_N2);
-			break;
-		case DRRS_MAX_RR:
-		default:
-			drm_err(&dev_priv->drm,
-				"Unsupported refreshrate type\n");
-		}
-	} else if (DISPLAY_VER(dev_priv) > 6) {
-		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
-		u32 val;
-
-		val = intel_de_read(dev_priv, reg);
-		if (index > DRRS_HIGH_RR) {
-			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
-			else
-				val |= PIPECONF_EDP_RR_MODE_SWITCH;
-		} else {
-			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
-			else
-				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
-		}
-		intel_de_write(dev_priv, reg, val);
-	}
-
-	dev_priv->drrs.refresh_rate_type = index;
-
-	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
-		    refresh_rate);
-}
-
-static void
-intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	dev_priv->drrs.busy_frontbuffer_bits = 0;
-	dev_priv->drrs.dp = intel_dp;
-}
-
-/**
- * intel_edp_drrs_enable - init drrs struct if supported
- * @intel_dp: DP struct
- * @crtc_state: A pointer to the active crtc state.
- *
- * Initializes frontbuffer_bits and drrs.dp
- */
-void intel_edp_drrs_enable(struct intel_dp *intel_dp,
-			   const struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	if (!crtc_state->has_drrs)
-		return;
-
-	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
-
-	mutex_lock(&dev_priv->drrs.mutex);
-
-	if (dev_priv->drrs.dp) {
-		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
-		goto unlock;
-	}
-
-	intel_edp_drrs_enable_locked(intel_dp);
-
-unlock:
-	mutex_unlock(&dev_priv->drrs.mutex);
-}
-
-static void
-intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
-			      const struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
-		int refresh;
-
-		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
-		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
-	}
-
-	dev_priv->drrs.dp = NULL;
-}
-
-/**
- * intel_edp_drrs_disable - Disable DRRS
- * @intel_dp: DP struct
- * @old_crtc_state: Pointer to old crtc_state.
- *
- */
-void intel_edp_drrs_disable(struct intel_dp *intel_dp,
-			    const struct intel_crtc_state *old_crtc_state)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	if (!old_crtc_state->has_drrs)
-		return;
-
-	mutex_lock(&dev_priv->drrs.mutex);
-	if (!dev_priv->drrs.dp) {
-		mutex_unlock(&dev_priv->drrs.mutex);
-		return;
-	}
-
-	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
-	mutex_unlock(&dev_priv->drrs.mutex);
-
-	cancel_delayed_work_sync(&dev_priv->drrs.work);
-}
-
-/**
- * intel_edp_drrs_update - Update DRRS state
- * @intel_dp: Intel DP
- * @crtc_state: new CRTC state
- *
- * This function will update DRRS states, disabling or enabling DRRS when
- * executing fastsets. For full modeset, intel_edp_drrs_disable() and
- * intel_edp_drrs_enable() should be called instead.
- */
-void
-intel_edp_drrs_update(struct intel_dp *intel_dp,
-		      const struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
-		return;
-
-	mutex_lock(&dev_priv->drrs.mutex);
-
-	/* New state matches current one? */
-	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
-		goto unlock;
-
-	if (crtc_state->has_drrs)
-		intel_edp_drrs_enable_locked(intel_dp);
-	else
-		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
-
-unlock:
-	mutex_unlock(&dev_priv->drrs.mutex);
-}
-
-static void intel_edp_drrs_downclock_work(struct work_struct *work)
-{
-	struct drm_i915_private *dev_priv =
-		container_of(work, typeof(*dev_priv), drrs.work.work);
-	struct intel_dp *intel_dp;
-
-	mutex_lock(&dev_priv->drrs.mutex);
-
-	intel_dp = dev_priv->drrs.dp;
-
-	if (!intel_dp)
-		goto unlock;
-
-	/*
-	 * The delayed work can race with an invalidate hence we need to
-	 * recheck.
-	 */
-
-	if (dev_priv->drrs.busy_frontbuffer_bits)
-		goto unlock;
-
-	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
-		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
-
-		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
-			drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
-	}
-
-unlock:
-	mutex_unlock(&dev_priv->drrs.mutex);
-}
-
-/**
- * intel_edp_drrs_invalidate - Disable Idleness DRRS
- * @dev_priv: i915 device
- * @frontbuffer_bits: frontbuffer plane tracking bits
- *
- * This function gets called everytime rendering on the given planes start.
- * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
- *
- * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
- */
-void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
-			       unsigned int frontbuffer_bits)
-{
-	struct intel_dp *intel_dp;
-	struct drm_crtc *crtc;
-	enum pipe pipe;
-
-	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
-		return;
-
-	cancel_delayed_work(&dev_priv->drrs.work);
-
-	mutex_lock(&dev_priv->drrs.mutex);
-
-	intel_dp = dev_priv->drrs.dp;
-	if (!intel_dp) {
-		mutex_unlock(&dev_priv->drrs.mutex);
-		return;
-	}
-
-	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
-	pipe = to_intel_crtc(crtc)->pipe;
-
-	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
-	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
-
-	/* invalidate means busy screen hence upclock */
-	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
-		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
-					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
-
-	mutex_unlock(&dev_priv->drrs.mutex);
-}
-
-/**
- * intel_edp_drrs_flush - Restart Idleness DRRS
- * @dev_priv: i915 device
- * @frontbuffer_bits: frontbuffer plane tracking bits
- *
- * This function gets called every time rendering on the given planes has
- * completed or flip on a crtc is completed. So DRRS should be upclocked
- * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
- * if no other planes are dirty.
- *
- * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
- */
-void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
-			  unsigned int frontbuffer_bits)
-{
-	struct intel_dp *intel_dp;
-	struct drm_crtc *crtc;
-	enum pipe pipe;
-
-	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
-		return;
-
-	cancel_delayed_work(&dev_priv->drrs.work);
-
-	mutex_lock(&dev_priv->drrs.mutex);
-
-	intel_dp = dev_priv->drrs.dp;
-	if (!intel_dp) {
-		mutex_unlock(&dev_priv->drrs.mutex);
-		return;
-	}
-
-	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
-	pipe = to_intel_crtc(crtc)->pipe;
-
-	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
-	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
-
-	/* flush means busy screen hence upclock */
-	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
-		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
-					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
-
-	/*
-	 * flush also means no more activity hence schedule downclock, if all
-	 * other fbs are quiescent too
-	 */
-	if (!dev_priv->drrs.busy_frontbuffer_bits)
-		schedule_delayed_work(&dev_priv->drrs.work,
-				msecs_to_jiffies(1000));
-	mutex_unlock(&dev_priv->drrs.mutex);
-}
-
-/**
- * DOC: Display Refresh Rate Switching (DRRS)
- *
- * Display Refresh Rate Switching (DRRS) is a power conservation feature
- * which enables swtching between low and high refresh rates,
- * dynamically, based on the usage scenario. This feature is applicable
- * for internal panels.
- *
- * Indication that the panel supports DRRS is given by the panel EDID, which
- * would list multiple refresh rates for one resolution.
- *
- * DRRS is of 2 types - static and seamless.
- * Static DRRS involves changing refresh rate (RR) by doing a full modeset
- * (may appear as a blink on screen) and is used in dock-undock scenario.
- * Seamless DRRS involves changing RR without any visual effect to the user
- * and can be used during normal system usage. This is done by programming
- * certain registers.
- *
- * Support for static/seamless DRRS may be indicated in the VBT based on
- * inputs from the panel spec.
- *
- * DRRS saves power by switching to low RR based on usage scenarios.
- *
- * The implementation is based on frontbuffer tracking implementation.  When
- * there is a disturbance on the screen triggered by user activity or a periodic
- * system activity, DRRS is disabled (RR is changed to high RR).  When there is
- * no movement on screen, after a timeout of 1 second, a switch to low RR is
- * made.
- *
- * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
- * and intel_edp_drrs_flush() are called.
- *
- * DRRS can be further extended to support other internal panels and also
- * the scenario of video playback wherein RR is set based on the rate
- * requested by userspace.
- */
-
-/**
- * intel_dp_drrs_init - Init basic DRRS work and mutex.
- * @connector: eDP connector
- * @fixed_mode: preferred mode of panel
- *
- * This function is  called only once at driver load to initialize basic
- * DRRS stuff.
- *
- * Returns:
- * Downclock mode if panel supports it, else return NULL.
- * DRRS support is determined by the presence of downclock mode (apart
- * from VBT setting).
- */
-static struct drm_display_mode *
-intel_dp_drrs_init(struct intel_connector *connector,
-		   struct drm_display_mode *fixed_mode)
-{
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-	struct drm_display_mode *downclock_mode = NULL;
-
-	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
-	mutex_init(&dev_priv->drrs.mutex);
-
-	if (DISPLAY_VER(dev_priv) <= 6) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "DRRS supported for Gen7 and above\n");
-		return NULL;
-	}
-
-	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
-		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
-		return NULL;
-	}
-
-	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
-	if (!downclock_mode) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Downclock mode is not found. DRRS not supported\n");
-		return NULL;
-	}
-
-	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
-
-	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
-	drm_dbg_kms(&dev_priv->drm,
-		    "seamless DRRS supported for eDP panel.\n");
-	return downclock_mode;
-}
-
 static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 				     struct intel_connector *intel_connector)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index ae0f776bffab8..a28fff286c21a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -70,17 +70,6 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp);
 int intel_dp_max_lane_count(struct intel_dp *intel_dp);
 int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
 
-void intel_edp_drrs_enable(struct intel_dp *intel_dp,
-			   const struct intel_crtc_state *crtc_state);
-void intel_edp_drrs_disable(struct intel_dp *intel_dp,
-			    const struct intel_crtc_state *crtc_state);
-void intel_edp_drrs_update(struct intel_dp *intel_dp,
-			   const struct intel_crtc_state *crtc_state);
-void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
-			       unsigned int frontbuffer_bits);
-void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
-			  unsigned int frontbuffer_bits);
-
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   u8 *link_bw, u8 *rate_select);
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
new file mode 100644
index 0000000000000..be9b6d4482f04
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -0,0 +1,477 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "intel_atomic.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_drrs.h"
+#include "intel_panel.h"
+
+/**
+ * DOC: Display Refresh Rate Switching (DRRS)
+ *
+ * Display Refresh Rate Switching (DRRS) is a power conservation feature
+ * which enables swtching between low and high refresh rates,
+ * dynamically, based on the usage scenario. This feature is applicable
+ * for internal panels.
+ *
+ * Indication that the panel supports DRRS is given by the panel EDID, which
+ * would list multiple refresh rates for one resolution.
+ *
+ * DRRS is of 2 types - static and seamless.
+ * Static DRRS involves changing refresh rate (RR) by doing a full modeset
+ * (may appear as a blink on screen) and is used in dock-undock scenario.
+ * Seamless DRRS involves changing RR without any visual effect to the user
+ * and can be used during normal system usage. This is done by programming
+ * certain registers.
+ *
+ * Support for static/seamless DRRS may be indicated in the VBT based on
+ * inputs from the panel spec.
+ *
+ * DRRS saves power by switching to low RR based on usage scenarios.
+ *
+ * The implementation is based on frontbuffer tracking implementation.  When
+ * there is a disturbance on the screen triggered by user activity or a periodic
+ * system activity, DRRS is disabled (RR is changed to high RR).  When there is
+ * no movement on screen, after a timeout of 1 second, a switch to low RR is
+ * made.
+ *
+ * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
+ * and intel_edp_drrs_flush() are called.
+ *
+ * DRRS can be further extended to support other internal panels and also
+ * the scenario of video playback wherein RR is set based on the rate
+ * requested by userspace.
+ */
+
+void
+intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
+			     struct intel_crtc_state *pipe_config,
+			     int output_bpp, bool constant_n)
+{
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	int pixel_clock;
+
+	if (pipe_config->vrr.enable)
+		return;
+
+	/*
+	 * DRRS and PSR can't be enable together, so giving preference to PSR
+	 * as it allows more power-savings by complete shutting down display,
+	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
+	 * after intel_psr_compute_config().
+	 */
+	if (pipe_config->has_psr)
+		return;
+
+	if (!intel_connector->panel.downclock_mode ||
+	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
+		return;
+
+	pipe_config->has_drrs = true;
+
+	pixel_clock = intel_connector->panel.downclock_mode->clock;
+	if (pipe_config->splitter.enable)
+		pixel_clock /= pipe_config->splitter.link_count;
+
+	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
+			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
+			       constant_n, pipe_config->fec_enable);
+
+	/* FIXME: abstract this better */
+	if (pipe_config->splitter.enable)
+		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
+}
+
+/**
+ * intel_dp_set_drrs_state - program registers for RR switch to take effect
+ * @dev_priv: i915 device
+ * @crtc_state: a pointer to the active intel_crtc_state
+ * @refresh_rate: RR to be programmed
+ *
+ * This function gets called when refresh rate (RR) has to be changed from
+ * one frequency to another. Switches can be between high and low RR
+ * supported by the panel or to any other RR based on media playback (in
+ * this case, RR value needs to be passed from user space).
+ *
+ * The caller of this function needs to take a lock on dev_priv->drrs.
+ */
+static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
+				    const struct intel_crtc_state *crtc_state,
+				    int refresh_rate)
+{
+	struct intel_dp *intel_dp = dev_priv->drrs.dp;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
+
+	if (refresh_rate <= 0) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "Refresh rate should be positive non-zero.\n");
+		return;
+	}
+
+	if (intel_dp == NULL) {
+		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
+		return;
+	}
+
+	if (!crtc) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "DRRS: intel_crtc not initialized\n");
+		return;
+	}
+
+	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
+		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
+		return;
+	}
+
+	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
+			refresh_rate)
+		index = DRRS_LOW_RR;
+
+	if (index == dev_priv->drrs.refresh_rate_type) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "DRRS requested for previously set RR...ignoring\n");
+		return;
+	}
+
+	if (!crtc_state->hw.active) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "eDP encoder disabled. CRTC not Active\n");
+		return;
+	}
+
+	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
+		switch (index) {
+		case DRRS_HIGH_RR:
+			intel_dp_set_m_n(crtc_state, M1_N1);
+			break;
+		case DRRS_LOW_RR:
+			intel_dp_set_m_n(crtc_state, M2_N2);
+			break;
+		case DRRS_MAX_RR:
+		default:
+			drm_err(&dev_priv->drm,
+				"Unsupported refreshrate type\n");
+		}
+	} else if (DISPLAY_VER(dev_priv) > 6) {
+		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
+		u32 val;
+
+		val = intel_de_read(dev_priv, reg);
+		if (index > DRRS_HIGH_RR) {
+			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+			else
+				val |= PIPECONF_EDP_RR_MODE_SWITCH;
+		} else {
+			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+			else
+				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
+		}
+		intel_de_write(dev_priv, reg, val);
+	}
+
+	dev_priv->drrs.refresh_rate_type = index;
+
+	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
+		    refresh_rate);
+}
+
+static void
+intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	dev_priv->drrs.busy_frontbuffer_bits = 0;
+	dev_priv->drrs.dp = intel_dp;
+}
+
+/**
+ * intel_edp_drrs_enable - init drrs struct if supported
+ * @intel_dp: DP struct
+ * @crtc_state: A pointer to the active crtc state.
+ *
+ * Initializes frontbuffer_bits and drrs.dp
+ */
+void intel_edp_drrs_enable(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	if (!crtc_state->has_drrs)
+		return;
+
+	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
+
+	mutex_lock(&dev_priv->drrs.mutex);
+
+	if (dev_priv->drrs.dp) {
+		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
+		goto unlock;
+	}
+
+	intel_edp_drrs_enable_locked(intel_dp);
+
+unlock:
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+static void
+intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
+		int refresh;
+
+		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
+		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
+	}
+
+	dev_priv->drrs.dp = NULL;
+}
+
+/**
+ * intel_edp_drrs_disable - Disable DRRS
+ * @intel_dp: DP struct
+ * @old_crtc_state: Pointer to old crtc_state.
+ *
+ */
+void intel_edp_drrs_disable(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *old_crtc_state)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	if (!old_crtc_state->has_drrs)
+		return;
+
+	mutex_lock(&dev_priv->drrs.mutex);
+	if (!dev_priv->drrs.dp) {
+		mutex_unlock(&dev_priv->drrs.mutex);
+		return;
+	}
+
+	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
+	mutex_unlock(&dev_priv->drrs.mutex);
+
+	cancel_delayed_work_sync(&dev_priv->drrs.work);
+}
+
+/**
+ * intel_edp_drrs_update - Update DRRS state
+ * @intel_dp: Intel DP
+ * @crtc_state: new CRTC state
+ *
+ * This function will update DRRS states, disabling or enabling DRRS when
+ * executing fastsets. For full modeset, intel_edp_drrs_disable() and
+ * intel_edp_drrs_enable() should be called instead.
+ */
+void
+intel_edp_drrs_update(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
+		return;
+
+	mutex_lock(&dev_priv->drrs.mutex);
+
+	/* New state matches current one? */
+	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
+		goto unlock;
+
+	if (crtc_state->has_drrs)
+		intel_edp_drrs_enable_locked(intel_dp);
+	else
+		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
+
+unlock:
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+static void intel_edp_drrs_downclock_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv), drrs.work.work);
+	struct intel_dp *intel_dp;
+
+	mutex_lock(&dev_priv->drrs.mutex);
+
+	intel_dp = dev_priv->drrs.dp;
+
+	if (!intel_dp)
+		goto unlock;
+
+	/*
+	 * The delayed work can race with an invalidate hence we need to
+	 * recheck.
+	 */
+
+	if (dev_priv->drrs.busy_frontbuffer_bits)
+		goto unlock;
+
+	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
+		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+
+		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
+					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
+	}
+
+unlock:
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * intel_edp_drrs_invalidate - Disable Idleness DRRS
+ * @dev_priv: i915 device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called everytime rendering on the given planes start.
+ * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
+ *
+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
+ */
+void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
+			       unsigned int frontbuffer_bits)
+{
+	struct intel_dp *intel_dp;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+
+	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
+		return;
+
+	cancel_delayed_work(&dev_priv->drrs.work);
+
+	mutex_lock(&dev_priv->drrs.mutex);
+
+	intel_dp = dev_priv->drrs.dp;
+	if (!intel_dp) {
+		mutex_unlock(&dev_priv->drrs.mutex);
+		return;
+	}
+
+	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
+
+	/* invalidate means busy screen hence upclock */
+	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
+					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
+
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * intel_edp_drrs_flush - Restart Idleness DRRS
+ * @dev_priv: i915 device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called every time rendering on the given planes has
+ * completed or flip on a crtc is completed. So DRRS should be upclocked
+ * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
+ * if no other planes are dirty.
+ *
+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
+ */
+void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
+			  unsigned int frontbuffer_bits)
+{
+	struct intel_dp *intel_dp;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+
+	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
+		return;
+
+	cancel_delayed_work(&dev_priv->drrs.work);
+
+	mutex_lock(&dev_priv->drrs.mutex);
+
+	intel_dp = dev_priv->drrs.dp;
+	if (!intel_dp) {
+		mutex_unlock(&dev_priv->drrs.mutex);
+		return;
+	}
+
+	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
+
+	/* flush means busy screen hence upclock */
+	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
+					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
+
+	/*
+	 * flush also means no more activity hence schedule downclock, if all
+	 * other fbs are quiescent too
+	 */
+	if (!dev_priv->drrs.busy_frontbuffer_bits)
+		schedule_delayed_work(&dev_priv->drrs.work,
+				      msecs_to_jiffies(1000));
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * intel_dp_drrs_init - Init basic DRRS work and mutex.
+ * @connector: eDP connector
+ * @fixed_mode: preferred mode of panel
+ *
+ * This function is  called only once at driver load to initialize basic
+ * DRRS stuff.
+ *
+ * Returns:
+ * Downclock mode if panel supports it, else return NULL.
+ * DRRS support is determined by the presence of downclock mode (apart
+ * from VBT setting).
+ */
+struct drm_display_mode *
+intel_dp_drrs_init(struct intel_connector *connector,
+		   struct drm_display_mode *fixed_mode)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct drm_display_mode *downclock_mode = NULL;
+
+	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
+	mutex_init(&dev_priv->drrs.mutex);
+
+	if (DISPLAY_VER(dev_priv) <= 6) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "DRRS supported for Gen7 and above\n");
+		return NULL;
+	}
+
+	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
+		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
+		return NULL;
+	}
+
+	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
+	if (!downclock_mode) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "Downclock mode is not found. DRRS not supported\n");
+		return NULL;
+	}
+
+	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
+
+	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
+	drm_dbg_kms(&dev_priv->drm,
+		    "seamless DRRS supported for eDP panel.\n");
+	return downclock_mode;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
new file mode 100644
index 0000000000000..ffa175b4cf4f4
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_drrs.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#ifndef __INTEL_DRRS_H__
+#define __INTEL_DRRS_H__
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_crtc_state;
+struct intel_connector;
+struct intel_dp;
+
+void intel_edp_drrs_enable(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state);
+void intel_edp_drrs_disable(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state);
+void intel_edp_drrs_update(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state);
+void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
+			       unsigned int frontbuffer_bits);
+void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
+			  unsigned int frontbuffer_bits);
+void intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
+				  struct intel_crtc_state *pipe_config,
+				  int output_bpp, bool constant_n);
+struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector,
+					    struct drm_display_mode *fixed_mode);
+
+#endif /* __INTEL_DRRS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 8e75debcce1a9..e4834d84ce5e3 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -62,6 +62,7 @@
 #include "intel_display_types.h"
 #include "intel_fbc.h"
 #include "intel_frontbuffer.h"
+#include "intel_drrs.h"
 #include "intel_psr.h"
 
 /**
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 3/8] drm/i915/display: Renaming DRRS functions to intel_drrs_*()
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW José Roberto de Souza
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-08-25 15:56   ` Rodrigo Vivi
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS José Roberto de Souza
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jani Nikula, Rodrigo Vivi, José Roberto de Souza

We had a mix of intel_edp_drrs_*(), intel_dp_drrs_*() and
intel_dp_set_drrs_state(), so properly renaming all functions to
keep the same pattern.

While at it, also dropping intel_dp_set_drrs_state from the
documentation as it is a static function.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 Documentation/gpu/i915.rst                    | 13 +--
 drivers/gpu/drm/i915/display/intel_ddi.c      |  6 +-
 .../drm/i915/display/intel_display_debugfs.c  |  6 +-
 drivers/gpu/drm/i915/display/intel_dp.c       |  6 +-
 drivers/gpu/drm/i915/display/intel_drrs.c     | 92 +++++++++----------
 drivers/gpu/drm/i915/display/intel_drrs.h     | 30 +++---
 .../gpu/drm/i915/display/intel_frontbuffer.c  |  4 +-
 7 files changed, 76 insertions(+), 81 deletions(-)

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 03021dfa0dd81..101dde3eb1ea9 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -187,22 +187,19 @@ Display Refresh Rate Switching (DRRS)
    :doc: Display Refresh Rate Switching (DRRS)
 
 .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
-   :functions: intel_dp_set_drrs_state
+   :functions: intel_drrs_enable
 
 .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
-   :functions: intel_edp_drrs_enable
+   :functions: intel_drrs_disable
 
 .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
-   :functions: intel_edp_drrs_disable
+   :functions: intel_drrs_invalidate
 
 .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
-   :functions: intel_edp_drrs_invalidate
+   :functions: intel_drrs_flush
 
 .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
-   :functions: intel_edp_drrs_flush
-
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
-   :functions: intel_dp_drrs_init
+   :functions: intel_drrs_init
 
 DPIO
 ----
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 828df570a4809..7714566dec81b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3015,7 +3015,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
 	if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
 		intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
 
-	intel_edp_drrs_enable(intel_dp, crtc_state);
+	intel_drrs_enable(intel_dp, crtc_state);
 
 	if (crtc_state->has_audio)
 		intel_audio_codec_enable(encoder, crtc_state, conn_state);
@@ -3203,7 +3203,7 @@ static void intel_pre_disable_ddi(struct intel_atomic_state *state,
 		return;
 
 	intel_dp = enc_to_intel_dp(encoder);
-	intel_edp_drrs_disable(intel_dp, old_crtc_state);
+	intel_drrs_disable(intel_dp, old_crtc_state);
 	intel_psr_disable(intel_dp, old_crtc_state);
 }
 
@@ -3233,7 +3233,7 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
 
 	intel_psr_update(intel_dp, crtc_state, conn_state);
 	intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
-	intel_edp_drrs_update(intel_dp, crtc_state);
+	intel_drrs_update(intel_dp, crtc_state);
 
 	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index b136a0fc0963b..ca819f9e353d0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -2045,11 +2045,9 @@ static int i915_drrs_ctl_set(void *data, u64 val)
 
 			intel_dp = enc_to_intel_dp(encoder);
 			if (val)
-				intel_edp_drrs_enable(intel_dp,
-						      crtc_state);
+				intel_drrs_enable(intel_dp, crtc_state);
 			else
-				intel_edp_drrs_disable(intel_dp,
-						       crtc_state);
+				intel_drrs_disable(intel_dp, crtc_state);
 		}
 		drm_connector_list_iter_end(&conn_iter);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 965b888e0e771..192564eb60949 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1784,8 +1784,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 
 	intel_vrr_compute_config(pipe_config, conn_state);
 	intel_psr_compute_config(intel_dp, pipe_config);
-	intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp,
-				     constant_n);
+	intel_drrs_compute_config(intel_dp, pipe_config, output_bpp,
+				  constant_n);
 	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
 	intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
 
@@ -4804,7 +4804,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 
 	fixed_mode = intel_panel_edid_fixed_mode(intel_connector);
 	if (fixed_mode)
-		downclock_mode = intel_dp_drrs_init(intel_connector, fixed_mode);
+		downclock_mode = intel_drrs_init(intel_connector, fixed_mode);
 
 	/* multiply the mode clock and horizontal timings for MSO */
 	intel_edp_mso_mode_fixup(intel_connector, fixed_mode);
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index be9b6d4482f04..1aa9793521158 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -39,8 +39,8 @@
  * no movement on screen, after a timeout of 1 second, a switch to low RR is
  * made.
  *
- * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
- * and intel_edp_drrs_flush() are called.
+ * For integration with frontbuffer tracking code, intel_drrs_invalidate()
+ * and intel_drrs_flush() are called.
  *
  * DRRS can be further extended to support other internal panels and also
  * the scenario of video playback wherein RR is set based on the rate
@@ -48,9 +48,9 @@
  */
 
 void
-intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
-			     struct intel_crtc_state *pipe_config,
-			     int output_bpp, bool constant_n)
+intel_drrs_compute_config(struct intel_dp *intel_dp,
+			  struct intel_crtc_state *pipe_config,
+			  int output_bpp, bool constant_n)
 {
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -62,7 +62,7 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
 	/*
 	 * DRRS and PSR can't be enable together, so giving preference to PSR
 	 * as it allows more power-savings by complete shutting down display,
-	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
+	 * so to guarantee this, intel_drrs_compute_config() must be called
 	 * after intel_psr_compute_config().
 	 */
 	if (pipe_config->has_psr)
@@ -88,7 +88,7 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
 }
 
 /**
- * intel_dp_set_drrs_state - program registers for RR switch to take effect
+ * intel_drrs_set_state - program registers for RR switch to take effect
  * @dev_priv: i915 device
  * @crtc_state: a pointer to the active intel_crtc_state
  * @refresh_rate: RR to be programmed
@@ -100,9 +100,9 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
  *
  * The caller of this function needs to take a lock on dev_priv->drrs.
  */
-static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
-				    const struct intel_crtc_state *crtc_state,
-				    int refresh_rate)
+static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
+				 const struct intel_crtc_state *crtc_state,
+				 int refresh_rate)
 {
 	struct intel_dp *intel_dp = dev_priv->drrs.dp;
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -185,7 +185,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
 }
 
 static void
-intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
+intel_drrs_enable_locked(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -194,14 +194,14 @@ intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
 }
 
 /**
- * intel_edp_drrs_enable - init drrs struct if supported
+ * intel_drrs_enable - init drrs struct if supported
  * @intel_dp: DP struct
  * @crtc_state: A pointer to the active crtc state.
  *
  * Initializes frontbuffer_bits and drrs.dp
  */
-void intel_edp_drrs_enable(struct intel_dp *intel_dp,
-			   const struct intel_crtc_state *crtc_state)
+void intel_drrs_enable(struct intel_dp *intel_dp,
+		       const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -217,15 +217,15 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp,
 		goto unlock;
 	}
 
-	intel_edp_drrs_enable_locked(intel_dp);
+	intel_drrs_enable_locked(intel_dp);
 
 unlock:
 	mutex_unlock(&dev_priv->drrs.mutex);
 }
 
 static void
-intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
-			      const struct intel_crtc_state *crtc_state)
+intel_drrs_disable_locked(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -233,20 +233,20 @@ intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
 		int refresh;
 
 		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
-		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
+		intel_drrs_set_state(dev_priv, crtc_state, refresh);
 	}
 
 	dev_priv->drrs.dp = NULL;
 }
 
 /**
- * intel_edp_drrs_disable - Disable DRRS
+ * intel_drrs_disable - Disable DRRS
  * @intel_dp: DP struct
  * @old_crtc_state: Pointer to old crtc_state.
  *
  */
-void intel_edp_drrs_disable(struct intel_dp *intel_dp,
-			    const struct intel_crtc_state *old_crtc_state)
+void intel_drrs_disable(struct intel_dp *intel_dp,
+			const struct intel_crtc_state *old_crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -259,24 +259,24 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp,
 		return;
 	}
 
-	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
+	intel_drrs_disable_locked(intel_dp, old_crtc_state);
 	mutex_unlock(&dev_priv->drrs.mutex);
 
 	cancel_delayed_work_sync(&dev_priv->drrs.work);
 }
 
 /**
- * intel_edp_drrs_update - Update DRRS state
+ * intel_drrs_update - Update DRRS state
  * @intel_dp: Intel DP
  * @crtc_state: new CRTC state
  *
  * This function will update DRRS states, disabling or enabling DRRS when
- * executing fastsets. For full modeset, intel_edp_drrs_disable() and
- * intel_edp_drrs_enable() should be called instead.
+ * executing fastsets. For full modeset, intel_drrs_disable() and
+ * intel_drrs_enable() should be called instead.
  */
 void
-intel_edp_drrs_update(struct intel_dp *intel_dp,
-		      const struct intel_crtc_state *crtc_state)
+intel_drrs_update(struct intel_dp *intel_dp,
+		  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
@@ -290,15 +290,15 @@ intel_edp_drrs_update(struct intel_dp *intel_dp,
 		goto unlock;
 
 	if (crtc_state->has_drrs)
-		intel_edp_drrs_enable_locked(intel_dp);
+		intel_drrs_enable_locked(intel_dp);
 	else
-		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
+		intel_drrs_disable_locked(intel_dp, crtc_state);
 
 unlock:
 	mutex_unlock(&dev_priv->drrs.mutex);
 }
 
-static void intel_edp_drrs_downclock_work(struct work_struct *work)
+static void intel_drrs_downclock_work(struct work_struct *work)
 {
 	struct drm_i915_private *dev_priv =
 		container_of(work, typeof(*dev_priv), drrs.work.work);
@@ -322,8 +322,8 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
 	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
 		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
 
-		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
-					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
+		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
+				     drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
 	}
 
 unlock:
@@ -331,7 +331,7 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
 }
 
 /**
- * intel_edp_drrs_invalidate - Disable Idleness DRRS
+ * intel_drrs_invalidate - Disable Idleness DRRS
  * @dev_priv: i915 device
  * @frontbuffer_bits: frontbuffer plane tracking bits
  *
@@ -340,8 +340,8 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
  *
  * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
  */
-void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
-			       unsigned int frontbuffer_bits)
+void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
+			   unsigned int frontbuffer_bits)
 {
 	struct intel_dp *intel_dp;
 	struct drm_crtc *crtc;
@@ -368,14 +368,14 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
 
 	/* invalidate means busy screen hence upclock */
 	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
-		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
-					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
+		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
+				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
 
 	mutex_unlock(&dev_priv->drrs.mutex);
 }
 
 /**
- * intel_edp_drrs_flush - Restart Idleness DRRS
+ * intel_drrs_flush - Restart Idleness DRRS
  * @dev_priv: i915 device
  * @frontbuffer_bits: frontbuffer plane tracking bits
  *
@@ -386,8 +386,8 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
  *
  * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
  */
-void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
-			  unsigned int frontbuffer_bits)
+void intel_drrs_flush(struct drm_i915_private *dev_priv,
+		      unsigned int frontbuffer_bits)
 {
 	struct intel_dp *intel_dp;
 	struct drm_crtc *crtc;
@@ -414,8 +414,8 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
 
 	/* flush means busy screen hence upclock */
 	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
-		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
-					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
+		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
+				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
 
 	/*
 	 * flush also means no more activity hence schedule downclock, if all
@@ -428,7 +428,7 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
 }
 
 /**
- * intel_dp_drrs_init - Init basic DRRS work and mutex.
+ * intel_drrs_init - Init basic DRRS work and mutex.
  * @connector: eDP connector
  * @fixed_mode: preferred mode of panel
  *
@@ -441,13 +441,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
  * from VBT setting).
  */
 struct drm_display_mode *
-intel_dp_drrs_init(struct intel_connector *connector,
-		   struct drm_display_mode *fixed_mode)
+intel_drrs_init(struct intel_connector *connector,
+		struct drm_display_mode *fixed_mode)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct drm_display_mode *downclock_mode = NULL;
 
-	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
+	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work);
 	mutex_init(&dev_priv->drrs.mutex);
 
 	if (DISPLAY_VER(dev_priv) <= 6) {
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
index ffa175b4cf4f4..73be7e9a43691 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.h
+++ b/drivers/gpu/drm/i915/display/intel_drrs.h
@@ -13,20 +13,20 @@ struct intel_crtc_state;
 struct intel_connector;
 struct intel_dp;
 
-void intel_edp_drrs_enable(struct intel_dp *intel_dp,
-			   const struct intel_crtc_state *crtc_state);
-void intel_edp_drrs_disable(struct intel_dp *intel_dp,
-			    const struct intel_crtc_state *crtc_state);
-void intel_edp_drrs_update(struct intel_dp *intel_dp,
-			   const struct intel_crtc_state *crtc_state);
-void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
-			       unsigned int frontbuffer_bits);
-void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
-			  unsigned int frontbuffer_bits);
-void intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
-				  struct intel_crtc_state *pipe_config,
-				  int output_bpp, bool constant_n);
-struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector,
-					    struct drm_display_mode *fixed_mode);
+void intel_drrs_enable(struct intel_dp *intel_dp,
+		       const struct intel_crtc_state *crtc_state);
+void intel_drrs_disable(struct intel_dp *intel_dp,
+			const struct intel_crtc_state *crtc_state);
+void intel_drrs_update(struct intel_dp *intel_dp,
+		       const struct intel_crtc_state *crtc_state);
+void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
+			   unsigned int frontbuffer_bits);
+void intel_drrs_flush(struct drm_i915_private *dev_priv,
+		      unsigned int frontbuffer_bits);
+void intel_drrs_compute_config(struct intel_dp *intel_dp,
+			       struct intel_crtc_state *pipe_config,
+			       int output_bpp, bool constant_n);
+struct drm_display_mode *intel_drrs_init(struct intel_connector *connector,
+					 struct drm_display_mode *fixed_mode);
 
 #endif /* __INTEL_DRRS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index e4834d84ce5e3..0492446cd04ad 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -92,7 +92,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
 	trace_intel_frontbuffer_flush(frontbuffer_bits, origin);
 
 	might_sleep();
-	intel_edp_drrs_flush(i915, frontbuffer_bits);
+	intel_drrs_flush(i915, frontbuffer_bits);
 	intel_psr_flush(i915, frontbuffer_bits, origin);
 	intel_fbc_flush(i915, frontbuffer_bits, origin);
 }
@@ -181,7 +181,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
 
 	might_sleep();
 	intel_psr_invalidate(i915, frontbuffer_bits, origin);
-	intel_edp_drrs_invalidate(i915, frontbuffer_bits);
+	intel_drrs_invalidate(i915, frontbuffer_bits);
 	intel_fbc_invalidate(i915, frontbuffer_bits, origin);
 }
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (2 preceding siblings ...)
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/display: Renaming DRRS functions to intel_drrs_*() José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-09-02 15:15   ` Gwan-gyeong Mun
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate José Roberto de Souza
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: José Roberto de Souza

It started as a code style fix for the lines above 100 col but it
turned out to simplifications to intel_drrs_set_state().
Now it receives the desired refresh rate type, high or low.

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_drrs.c | 60 ++++++++---------------
 1 file changed, 21 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 1aa9793521158..5eb5033242575 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -91,7 +91,7 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
  * intel_drrs_set_state - program registers for RR switch to take effect
  * @dev_priv: i915 device
  * @crtc_state: a pointer to the active intel_crtc_state
- * @refresh_rate: RR to be programmed
+ * @refresh_type: high or low refresh rate to be programmed
  *
  * This function gets called when refresh rate (RR) has to be changed from
  * one frequency to another. Switches can be between high and low RR
@@ -102,19 +102,13 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
  */
 static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
 				 const struct intel_crtc_state *crtc_state,
-				 int refresh_rate)
+				 enum drrs_refresh_rate_type refresh_type)
 {
 	struct intel_dp *intel_dp = dev_priv->drrs.dp;
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
+	struct drm_display_mode *mode;
 
-	if (refresh_rate <= 0) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "Refresh rate should be positive non-zero.\n");
-		return;
-	}
-
-	if (intel_dp == NULL) {
+	if (!intel_dp) {
 		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
 		return;
 	}
@@ -130,15 +124,8 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
 		return;
 	}
 
-	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
-			refresh_rate)
-		index = DRRS_LOW_RR;
-
-	if (index == dev_priv->drrs.refresh_rate_type) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "DRRS requested for previously set RR...ignoring\n");
+	if (refresh_type == dev_priv->drrs.refresh_rate_type)
 		return;
-	}
 
 	if (!crtc_state->hw.active) {
 		drm_dbg_kms(&dev_priv->drm,
@@ -147,7 +134,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
 	}
 
 	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
-		switch (index) {
+		switch (refresh_type) {
 		case DRRS_HIGH_RR:
 			intel_dp_set_m_n(crtc_state, M1_N1);
 			break;
@@ -164,7 +151,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
 		u32 val;
 
 		val = intel_de_read(dev_priv, reg);
-		if (index > DRRS_HIGH_RR) {
+		if (refresh_type == DRRS_LOW_RR) {
 			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
 			else
@@ -178,10 +165,14 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
 		intel_de_write(dev_priv, reg, val);
 	}
 
-	dev_priv->drrs.refresh_rate_type = index;
+	dev_priv->drrs.refresh_rate_type = refresh_type;
 
+	if (refresh_type == DRRS_LOW_RR)
+		mode = intel_dp->attached_connector->panel.fixed_mode;
+	else
+		mode = intel_dp->attached_connector->panel.downclock_mode;
 	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
-		    refresh_rate);
+		    drm_mode_vrefresh(mode));
 }
 
 static void
@@ -229,13 +220,7 @@ intel_drrs_disable_locked(struct intel_dp *intel_dp,
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
-		int refresh;
-
-		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
-		intel_drrs_set_state(dev_priv, crtc_state, refresh);
-	}
-
+	intel_drrs_set_state(dev_priv, crtc_state, DRRS_HIGH_RR);
 	dev_priv->drrs.dp = NULL;
 }
 
@@ -303,6 +288,7 @@ static void intel_drrs_downclock_work(struct work_struct *work)
 	struct drm_i915_private *dev_priv =
 		container_of(work, typeof(*dev_priv), drrs.work.work);
 	struct intel_dp *intel_dp;
+	struct drm_crtc *crtc;
 
 	mutex_lock(&dev_priv->drrs.mutex);
 
@@ -319,12 +305,8 @@ static void intel_drrs_downclock_work(struct work_struct *work)
 	if (dev_priv->drrs.busy_frontbuffer_bits)
 		goto unlock;
 
-	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
-		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
-
-		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
-				     drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
-	}
+	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+	intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, DRRS_LOW_RR);
 
 unlock:
 	mutex_unlock(&dev_priv->drrs.mutex);
@@ -367,9 +349,9 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
 	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
 
 	/* invalidate means busy screen hence upclock */
-	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+	if (frontbuffer_bits)
 		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
-				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
+				     DRRS_HIGH_RR);
 
 	mutex_unlock(&dev_priv->drrs.mutex);
 }
@@ -413,9 +395,9 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
 	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
 
 	/* flush means busy screen hence upclock */
-	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+	if (frontbuffer_bits)
 		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
-				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
+				     DRRS_HIGH_RR);
 
 	/*
 	 * flush also means no more activity hence schedule downclock, if all
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (3 preceding siblings ...)
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-09-02 15:57   ` Gwan-gyeong Mun
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Prepare DRRS for frontbuffer rendering drop José Roberto de Souza
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: José Roberto de Souza

Both functions are pretty much equal, with minor changes that can be
handled by a single parameter.

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_drrs.c | 82 +++++++++--------------
 1 file changed, 32 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 5eb5033242575..8583da4e82434 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -312,18 +312,9 @@ static void intel_drrs_downclock_work(struct work_struct *work)
 	mutex_unlock(&dev_priv->drrs.mutex);
 }
 
-/**
- * intel_drrs_invalidate - Disable Idleness DRRS
- * @dev_priv: i915 device
- * @frontbuffer_bits: frontbuffer plane tracking bits
- *
- * This function gets called everytime rendering on the given planes start.
- * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
- *
- * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
- */
-void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
-			   unsigned int frontbuffer_bits)
+static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
+					  unsigned int frontbuffer_bits,
+					  bool invalidate)
 {
 	struct intel_dp *intel_dp;
 	struct drm_crtc *crtc;
@@ -346,16 +337,42 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
 	pipe = to_intel_crtc(crtc)->pipe;
 
 	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
-	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
+	if (invalidate)
+		dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
+	else
+		dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
 
-	/* invalidate means busy screen hence upclock */
+	/* flush/invalidate means busy screen hence upclock */
 	if (frontbuffer_bits)
 		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
 				     DRRS_HIGH_RR);
 
+	/*
+	 * flush also means no more activity hence schedule downclock, if all
+	 * other fbs are quiescent too
+	 */
+	if (!dev_priv->drrs.busy_frontbuffer_bits)
+		schedule_delayed_work(&dev_priv->drrs.work,
+				      msecs_to_jiffies(1000));
 	mutex_unlock(&dev_priv->drrs.mutex);
 }
 
+/**
+ * intel_drrs_invalidate - Disable Idleness DRRS
+ * @dev_priv: i915 device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called everytime rendering on the given planes start.
+ * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
+ *
+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
+ */
+void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
+			   unsigned int frontbuffer_bits)
+{
+	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, true);
+}
+
 /**
  * intel_drrs_flush - Restart Idleness DRRS
  * @dev_priv: i915 device
@@ -371,42 +388,7 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
 void intel_drrs_flush(struct drm_i915_private *dev_priv,
 		      unsigned int frontbuffer_bits)
 {
-	struct intel_dp *intel_dp;
-	struct drm_crtc *crtc;
-	enum pipe pipe;
-
-	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
-		return;
-
-	cancel_delayed_work(&dev_priv->drrs.work);
-
-	mutex_lock(&dev_priv->drrs.mutex);
-
-	intel_dp = dev_priv->drrs.dp;
-	if (!intel_dp) {
-		mutex_unlock(&dev_priv->drrs.mutex);
-		return;
-	}
-
-	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
-	pipe = to_intel_crtc(crtc)->pipe;
-
-	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
-	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
-
-	/* flush means busy screen hence upclock */
-	if (frontbuffer_bits)
-		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
-				     DRRS_HIGH_RR);
-
-	/*
-	 * flush also means no more activity hence schedule downclock, if all
-	 * other fbs are quiescent too
-	 */
-	if (!dev_priv->drrs.busy_frontbuffer_bits)
-		schedule_delayed_work(&dev_priv->drrs.work,
-				      msecs_to_jiffies(1000));
-	mutex_unlock(&dev_priv->drrs.mutex);
+	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
 }
 
 /**
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Prepare DRRS for frontbuffer rendering drop
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (4 preceding siblings ...)
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-09-02 16:09   ` Gwan-gyeong Mun
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support José Roberto de Souza
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: José Roberto de Souza

Frontbuffer rendering will be dropped for modern platforms but
before that we to prepare DRRS for it.

intel_drrs_flush and intel_drrs_invalidate will not be called
for platforms that will not support frontbuffer rendering so DRRS
needs another way to be notified about to page flips so it can change
between high and low refresh rates as needed.

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 2 ++
 drivers/gpu/drm/i915/display/intel_drrs.c    | 9 +++++++++
 drivers/gpu/drm/i915/display/intel_drrs.h    | 4 ++++
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 794690c0dba56..808002aa439e2 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -52,6 +52,7 @@
 #include "display/intel_dp_mst.h"
 #include "display/intel_dpll.h"
 #include "display/intel_dpll_mgr.h"
+#include "display/intel_drrs.h"
 #include "display/intel_dsi.h"
 #include "display/intel_dvo.h"
 #include "display/intel_fb.h"
@@ -2436,6 +2437,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
 		hsw_enable_ips(new_crtc_state);
 
 	intel_fbc_post_update(state, crtc);
+	intel_drrs_page_flip(state, crtc);
 
 	if (needs_nv12_wa(old_crtc_state) &&
 	    !needs_nv12_wa(new_crtc_state))
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 8583da4e82434..6ae778c306006 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -391,6 +391,15 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
 	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
 }
 
+void intel_drrs_page_flip(struct intel_atomic_state *state,
+			  struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	unsigned int frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
+
+	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
+}
+
 /**
  * intel_drrs_init - Init basic DRRS work and mutex.
  * @connector: eDP connector
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
index 73be7e9a43691..9ec9c447211af 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.h
+++ b/drivers/gpu/drm/i915/display/intel_drrs.h
@@ -9,6 +9,8 @@
 #include <linux/types.h>
 
 struct drm_i915_private;
+struct intel_atomic_state;
+struct intel_crtc;
 struct intel_crtc_state;
 struct intel_connector;
 struct intel_dp;
@@ -23,6 +25,8 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
 			   unsigned int frontbuffer_bits);
 void intel_drrs_flush(struct drm_i915_private *dev_priv,
 		      unsigned int frontbuffer_bits);
+void intel_drrs_page_flip(struct intel_atomic_state *state,
+			  struct intel_crtc *crtc);
 void intel_drrs_compute_config(struct intel_dp *intel_dp,
 			       struct intel_crtc_state *pipe_config,
 			       int output_bpp, bool constant_n);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (5 preceding siblings ...)
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Prepare DRRS for frontbuffer rendering drop José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-09-02 18:42   ` Gwan-gyeong Mun
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/display: Drop PSR " José Roberto de Souza
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx
  Cc: Daniel Vetter, Gwan-gyeong Mun, Ville Syrjälä,
	Jani Nikula, Rodrigo Vivi, José Roberto de Souza

By now all the userspace applications should have migrated to atomic
or at least be calling DRM_IOCTL_MODE_DIRTYFB.

With that we can kill frontbuffer rendering support in i915 for
modern platforms.

So here converting legacy APIs into atomic commits so it can be
properly handled by driver i915.

Several IGT tests will fail with this changes, because some tests
were stressing those frontbuffer rendering scenarios that no userspace
should be using by now, fixes to IGT should be sent soon.

v2:
- return earlier to not set fb_tracking.busy/flip_bits
- added a warn on to make sure we are not setting the busy/flip_bits

Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_cursor.c    |  6 ++----
 drivers/gpu/drm/i915/display/intel_fb.c        |  8 +++++++-
 .../gpu/drm/i915/display/intel_frontbuffer.c   | 18 ++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h                |  2 ++
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index c7618fef01439..5aa996c3b7980 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -617,6 +617,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
 			   u32 src_w, u32 src_h,
 			   struct drm_modeset_acquire_ctx *ctx)
 {
+	struct drm_i915_private *i915 = to_i915(_crtc->dev);
 	struct intel_plane *plane = to_intel_plane(_plane);
 	struct intel_crtc *crtc = to_intel_crtc(_crtc);
 	struct intel_plane_state *old_plane_state =
@@ -633,12 +634,9 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
 	 * PSR2 selective fetch also requires the slow path as
 	 * PSR2 plane and transcoder registers can only be updated during
 	 * vblank.
-	 *
-	 * FIXME bigjoiner fastpath would be good
 	 */
 	if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
-	    crtc_state->update_pipe || crtc_state->bigjoiner ||
-	    crtc_state->enable_psr2_sel_fetch)
+	    crtc_state->update_pipe || !HAS_FRONTBUFFER_RENDERING(i915))
 		goto slow;
 
 	/*
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index e4b8602ec0cd2..3eb60785c9f29 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -3,6 +3,7 @@
  * Copyright © 2021 Intel Corporation
  */
 
+#include <drm/drm_damage_helper.h>
 #include <drm/drm_framebuffer.h>
 #include <drm/drm_modeset_helper.h>
 
@@ -1235,10 +1236,15 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
 					unsigned int num_clips)
 {
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 
 	i915_gem_object_flush_if_display(obj);
-	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
 
+	if (!HAS_FRONTBUFFER_RENDERING(i915))
+		return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips,
+						 num_clips);
+
+	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 0492446cd04ad..3860f87dac31c 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -112,6 +112,9 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
 void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
 				    unsigned frontbuffer_bits)
 {
+	if (!HAS_FRONTBUFFER_RENDERING(i915))
+		return;
+
 	spin_lock(&i915->fb_tracking.lock);
 	i915->fb_tracking.flip_bits |= frontbuffer_bits;
 	/* Remove stale busy bits due to the old buffer. */
@@ -132,6 +135,12 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
 void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
 				     unsigned frontbuffer_bits)
 {
+	if (!HAS_FRONTBUFFER_RENDERING(i915)) {
+		drm_WARN_ON_ONCE(&i915->drm, i915->fb_tracking.flip_bits |
+					     i915->fb_tracking.busy_bits);
+		return;
+	}
+
 	spin_lock(&i915->fb_tracking.lock);
 	/* Mask any cancelled flips. */
 	frontbuffer_bits &= i915->fb_tracking.flip_bits;
@@ -156,6 +165,9 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
 void intel_frontbuffer_flip(struct drm_i915_private *i915,
 			    unsigned frontbuffer_bits)
 {
+	if (!HAS_FRONTBUFFER_RENDERING(i915))
+		return;
+
 	spin_lock(&i915->fb_tracking.lock);
 	/* Remove stale busy bits due to the old buffer. */
 	i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
@@ -170,6 +182,9 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
 {
 	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
 
+	if (!HAS_FRONTBUFFER_RENDERING(i915))
+		return;
+
 	if (origin == ORIGIN_CS) {
 		spin_lock(&i915->fb_tracking.lock);
 		i915->fb_tracking.busy_bits |= frontbuffer_bits;
@@ -191,6 +206,9 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
 {
 	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
 
+	if (!HAS_FRONTBUFFER_RENDERING(i915))
+		return;
+
 	if (origin == ORIGIN_CS) {
 		spin_lock(&i915->fb_tracking.lock);
 		/* Filter out new bits since rendering started. */
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 91453f7dbd656..20c135a2bba33 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1721,6 +1721,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_ASYNC_FLIPS(i915)		(DISPLAY_VER(i915) >= 5)
 
+#define HAS_FRONTBUFFER_RENDERING(i915)	(DISPLAY_VER(i915) < 9)
+
 /* Only valid when HAS_DISPLAY() is true */
 #define INTEL_DISPLAY_ENABLED(dev_priv) \
 	(drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] [PATCH v2 8/8] drm/i915/display: Drop PSR frontbuffer rendering support
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (6 preceding siblings ...)
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support José Roberto de Souza
@ 2021-08-25  0:58 ` José Roberto de Souza
  2021-09-06 16:05   ` Gwan-gyeong Mun
  2021-08-25  1:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Drop frontbuffer rendering support from Skylake and newer (rev2) Patchwork
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2021-08-25  0:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Gwan-gyeong Mun, José Roberto de Souza

After commit "drm/i915/display/skl+: Drop frontbuffer rendering
support" frontbuffer rendering is not supported for display 9 and
newer and as PSR is only supported by default in display 9 and newer
we can now drop all frontbuffer rendering support for PSR code.

Some DC3CO code was commented with a macro, because the function
caller is being dropped. As DC3CO is already disabled by default
because it requires changes in its sequences

Two DC3CO functions lost their callers while dropping frontbuffer
rendering but as DC3CO is already disabled by default because it
requires fixes, will leave this task to whoever will fix DC3CO.

Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 .../drm/i915/display/intel_display_debugfs.c  |   2 -
 .../drm/i915/display/intel_display_types.h    |   2 -
 .../gpu/drm/i915/display/intel_frontbuffer.c  |   2 -
 drivers/gpu/drm/i915/display/intel_psr.c      | 186 ++----------------
 drivers/gpu/drm/i915/display/intel_psr.h      |   8 +-
 5 files changed, 18 insertions(+), 182 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index ca819f9e353d0..6d733b276d5b0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -374,8 +374,6 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
 	seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
 		   enableddisabled(enabled), val);
 	psr_source_status(intel_dp, m);
-	seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
-		   psr->busy_frontbuffer_bits);
 
 	/*
 	 * SKL+ Perf counter is reset to 0 everytime DC state is entered
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index c2725d07b9303..18616435dcb18 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1512,7 +1512,6 @@ struct intel_psr {
 	enum transcoder transcoder;
 	bool active;
 	struct work_struct work;
-	unsigned int busy_frontbuffer_bits;
 	bool sink_psr2_support;
 	bool link_standby;
 	bool colorimetry_support;
@@ -1523,7 +1522,6 @@ struct intel_psr {
 	ktime_t last_entry_attempt;
 	ktime_t last_exit;
 	bool sink_not_reliable;
-	bool irq_aux_error;
 	u16 su_w_granularity;
 	u16 su_y_granularity;
 	u32 dc3co_exitline;
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 3860f87dac31c..1d8314d3712f4 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -93,7 +93,6 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
 
 	might_sleep();
 	intel_drrs_flush(i915, frontbuffer_bits);
-	intel_psr_flush(i915, frontbuffer_bits, origin);
 	intel_fbc_flush(i915, frontbuffer_bits, origin);
 }
 
@@ -195,7 +194,6 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
 	trace_intel_frontbuffer_invalidate(frontbuffer_bits, origin);
 
 	might_sleep();
-	intel_psr_invalidate(i915, frontbuffer_bits, origin);
 	intel_drrs_invalidate(i915, frontbuffer_bits);
 	intel_fbc_invalidate(i915, frontbuffer_bits, origin);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 3f6fb7d67f84d..8c9bd5846a8d0 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -224,15 +224,12 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
 		drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
 			 transcoder_name(cpu_transcoder));
 
-		intel_dp->psr.irq_aux_error = true;
-
 		/*
 		 * If this interruption is not masked it will keep
 		 * interrupting so fast that it prevents the scheduled
 		 * work to run.
 		 * Also after a PSR error, we don't want to arm PSR
 		 * again so we don't care about unmask the interruption
-		 * or unset irq_aux_error.
 		 */
 		val = intel_de_read(dev_priv, imr_reg);
 		val |= EDP_PSR_ERROR(trans_shift);
@@ -614,14 +611,6 @@ static void psr2_program_idle_frames(struct intel_dp *intel_dp,
 	intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
 }
 
-static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	psr2_program_idle_frames(intel_dp, 0);
-	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
-}
-
 static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1177,7 +1166,6 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
 	drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
 
 	intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
-	intel_dp->psr.busy_frontbuffer_bits = 0;
 	intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
 	intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
 	/* DC5/DC6 requires at least 6 idle frames */
@@ -1784,36 +1772,6 @@ void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state)
 	}
 }
 
-static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	i915_reg_t reg;
-	u32 mask;
-	int err;
-
-	if (!intel_dp->psr.enabled)
-		return false;
-
-	if (intel_dp->psr.psr2_enabled) {
-		reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
-		mask = EDP_PSR2_STATUS_STATE_MASK;
-	} else {
-		reg = EDP_PSR_STATUS(intel_dp->psr.transcoder);
-		mask = EDP_PSR_STATUS_STATE_MASK;
-	}
-
-	mutex_unlock(&intel_dp->psr.lock);
-
-	err = intel_de_wait_for_clear(dev_priv, reg, mask, 50);
-	if (err)
-		drm_err(&dev_priv->drm,
-			"Timed out waiting for PSR Idle for re-enable\n");
-
-	/* After the unlocked wait, verify that PSR is still wanted! */
-	mutex_lock(&intel_dp->psr.lock);
-	return err == 0 && intel_dp->psr.enabled;
-}
-
 static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
 {
 	struct drm_connector_list_iter conn_iter;
@@ -1912,16 +1870,6 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
 	return ret;
 }
 
-static void intel_psr_handle_irq(struct intel_dp *intel_dp)
-{
-	struct intel_psr *psr = &intel_dp->psr;
-
-	intel_psr_disable_locked(intel_dp);
-	psr->sink_not_reliable = true;
-	/* let's make sure that sink is awaken */
-	drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
-}
-
 static void intel_psr_work(struct work_struct *work)
 {
 	struct intel_dp *intel_dp =
@@ -1929,75 +1877,30 @@ static void intel_psr_work(struct work_struct *work)
 
 	mutex_lock(&intel_dp->psr.lock);
 
-	if (!intel_dp->psr.enabled)
-		goto unlock;
-
-	if (READ_ONCE(intel_dp->psr.irq_aux_error))
-		intel_psr_handle_irq(intel_dp);
-
-	/*
-	 * We have to make sure PSR is ready for re-enable
-	 * otherwise it keeps disabled until next full enable/disable cycle.
-	 * PSR might take some time to get fully disabled
-	 * and be ready for re-enable.
-	 */
-	if (!__psr_wait_for_idle_locked(intel_dp))
-		goto unlock;
-
-	/*
-	 * The delayed work can race with an invalidate hence we need to
-	 * recheck. Since psr_flush first clears this and then reschedules we
-	 * won't ever miss a flush when bailing out here.
-	 */
-	if (intel_dp->psr.busy_frontbuffer_bits || intel_dp->psr.active)
-		goto unlock;
+	/* Handling PSR error interruption */
+	intel_psr_disable_locked(intel_dp);
+	intel_dp->psr.sink_not_reliable = true;
+	/* let's make sure that sink is awaken */
+	drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
 
-	intel_psr_activate(intel_dp);
-unlock:
 	mutex_unlock(&intel_dp->psr.lock);
 }
 
-/**
- * intel_psr_invalidate - Invalidade PSR
- * @dev_priv: i915 device
- * @frontbuffer_bits: frontbuffer plane tracking bits
- * @origin: which operation caused the invalidate
- *
- * Since the hardware frontbuffer tracking has gaps we need to integrate
- * with the software frontbuffer tracking. This function gets called every
- * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be
- * disabled if the frontbuffer mask contains a buffer relevant to PSR.
- *
- * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
+/*
+ * TODO: Functions below lost their callers to a refactor but as DC3CO is
+ * already disabled by default because it requires fixes, will leave this task
+ * to whoever will fix DC3CO.
  */
-void intel_psr_invalidate(struct drm_i915_private *dev_priv,
-			  unsigned frontbuffer_bits, enum fb_op_origin origin)
-{
-	struct intel_encoder *encoder;
-
-	if (origin == ORIGIN_FLIP)
-		return;
-
-	for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
-		unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		mutex_lock(&intel_dp->psr.lock);
-		if (!intel_dp->psr.enabled) {
-			mutex_unlock(&intel_dp->psr.lock);
-			continue;
-		}
-
-		pipe_frontbuffer_bits &=
-			INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
-		intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits;
+#if 0
 
-		if (pipe_frontbuffer_bits)
-			intel_psr_exit(intel_dp);
+static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-		mutex_unlock(&intel_dp->psr.lock);
-	}
+	psr2_program_idle_frames(intel_dp, 0);
+	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
 }
+
 /*
  * When we will be completely rely on PSR2 S/W tracking in future,
  * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
@@ -2032,62 +1935,7 @@ tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
 	mutex_unlock(&intel_dp->psr.lock);
 }
 
-/**
- * intel_psr_flush - Flush PSR
- * @dev_priv: i915 device
- * @frontbuffer_bits: frontbuffer plane tracking bits
- * @origin: which operation caused the flush
- *
- * Since the hardware frontbuffer tracking has gaps we need to integrate
- * with the software frontbuffer tracking. This function gets called every
- * time frontbuffer rendering has completed and flushed out to memory. PSR
- * can be enabled again if no other frontbuffer relevant to PSR is dirty.
- *
- * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
- */
-void intel_psr_flush(struct drm_i915_private *dev_priv,
-		     unsigned frontbuffer_bits, enum fb_op_origin origin)
-{
-	struct intel_encoder *encoder;
-
-	for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
-		unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		if (origin == ORIGIN_FLIP) {
-			tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin);
-			continue;
-		}
-
-		mutex_lock(&intel_dp->psr.lock);
-		if (!intel_dp->psr.enabled) {
-			mutex_unlock(&intel_dp->psr.lock);
-			continue;
-		}
-
-		pipe_frontbuffer_bits &=
-			INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
-		intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits;
-
-		/*
-		 * If the PSR is paused by an explicit intel_psr_paused() call,
-		 * 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;
-		}
-
-		/* By definition flush = invalidate + flush */
-		if (pipe_frontbuffer_bits)
-			psr_force_hw_tracking_exit(intel_dp);
-
-		if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
-			schedule_work(&intel_dp->psr.work);
-		mutex_unlock(&intel_dp->psr.lock);
-	}
-}
+#endif
 
 /**
  * intel_psr_init - Init basic PSR work and mutex.
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index 641521b101c82..58e2e5c2b81ef 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -6,7 +6,7 @@
 #ifndef __INTEL_PSR_H__
 #define __INTEL_PSR_H__
 
-#include "intel_frontbuffer.h"
+#include <linux/types.h>
 
 struct drm_connector;
 struct drm_connector_state;
@@ -29,12 +29,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
 		      const struct intel_crtc_state *crtc_state,
 		      const struct drm_connector_state *conn_state);
 int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
-void intel_psr_invalidate(struct drm_i915_private *dev_priv,
-			  unsigned frontbuffer_bits,
-			  enum fb_op_origin origin);
-void intel_psr_flush(struct drm_i915_private *dev_priv,
-		     unsigned frontbuffer_bits,
-		     enum fb_op_origin origin);
 void intel_psr_init(struct intel_dp *intel_dp);
 void intel_psr_compute_config(struct intel_dp *intel_dp,
 			      struct intel_crtc_state *crtc_state);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Drop frontbuffer rendering support from Skylake and newer (rev2)
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (7 preceding siblings ...)
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/display: Drop PSR " José Roberto de Souza
@ 2021-08-25  1:01 ` Patchwork
  2021-08-25  1:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2021-08-25  1:01 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: Drop frontbuffer rendering support from Skylake and newer (rev2)
URL   : https://patchwork.freedesktop.org/series/93769/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
98e381aebd23 drm/i915/display: Drop PSR support from HSW and BDW
-:267: WARNING:LONG_LINE_COMMENT: line length of 113 exceeds 100 columns
#267: FILE: drivers/gpu/drm/i915/i915_reg.h:4564:
+#define EDP_PSR_AUX_DATA(tran, i)		_MMIO(_TRANS2(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */

total: 0 errors, 1 warnings, 0 checks, 240 lines checked
63c0e2b638ba drm/i915/display: Move DRRS code its own file
-:604: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#604: 
new file mode 100644

-:725: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!intel_dp"
#725: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:117:
+	if (intel_dp == NULL) {

-:934: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#934: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:326:
+					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));

-:980: WARNING:LONG_LINE: line length of 107 exceeds 100 columns
#980: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:372:
+					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));

-:1026: WARNING:LONG_LINE: line length of 107 exceeds 100 columns
#1026: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:418:
+					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));

total: 0 errors, 4 warnings, 1 checks, 1071 lines checked
08ba0f6456b9 drm/i915/display: Renaming DRRS functions to intel_drrs_*()
-:312: WARNING:LONG_LINE: line length of 108 exceeds 100 columns
#312: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:326:
+				     drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));

-:343: WARNING:LONG_LINE: line length of 104 exceeds 100 columns
#343: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:372:
+				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));

-:372: WARNING:LONG_LINE: line length of 104 exceeds 100 columns
#372: FILE: drivers/gpu/drm/i915/display/intel_drrs.c:418:
+				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));

total: 0 errors, 3 warnings, 0 checks, 387 lines checked
e920d82d8295 drm/i915/display: Some code improvements and code style fixes for DRRS
b274e5714903 drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate
ce03aa5335cd drm/i915/display: Prepare DRRS for frontbuffer rendering drop
8547f773f8a0 drm/i915/display/skl+: Drop frontbuffer rendering support
4f324d4c88dd drm/i915/display: Drop PSR frontbuffer rendering support
-:250: WARNING:IF_0: Consider removing the code enclosed by this #if 0 and its #endif
#250: FILE: drivers/gpu/drm/i915/display/intel_psr.c:1894:
+#if 0

total: 0 errors, 1 warnings, 0 checks, 298 lines checked



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for Drop frontbuffer rendering support from Skylake and newer (rev2)
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (8 preceding siblings ...)
  2021-08-25  1:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Drop frontbuffer rendering support from Skylake and newer (rev2) Patchwork
@ 2021-08-25  1:03 ` Patchwork
  2021-08-25  1:33 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
  2021-08-25 15:57 ` [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer Rodrigo Vivi
  11 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2021-08-25  1:03 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: Drop frontbuffer rendering support from Skylake and newer (rev2)
URL   : https://patchwork.freedesktop.org/series/93769/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BAT: failure for Drop frontbuffer rendering support from Skylake and newer (rev2)
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (9 preceding siblings ...)
  2021-08-25  1:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2021-08-25  1:33 ` Patchwork
  2021-08-25 15:57 ` [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer Rodrigo Vivi
  11 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2021-08-25  1:33 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 13978 bytes --]

== Series Details ==

Series: Drop frontbuffer rendering support from Skylake and newer (rev2)
URL   : https://patchwork.freedesktop.org/series/93769/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10517 -> Patchwork_20882
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_20882 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_20882, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_20882:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-skl-guc:         [PASS][1] -> [FAIL][2] +3 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-skl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-skl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-rkl-11600:       [PASS][3] -> [FAIL][4] +3 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-rkl-11600/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-rkl-11600/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-cfl-guc:         [PASS][5] -> [FAIL][6] +3 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-cfl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-cfl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-icl-y:           [PASS][7] -> [FAIL][8] +3 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-icl-y/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-icl-y/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-rkl-guc:         [PASS][9] -> [FAIL][10] +3 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-rkl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-rkl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-skl-6700k2:      [PASS][11] -> [FAIL][12] +3 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-skl-6700k2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-skl-6700k2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-icl-u2:          [PASS][13] -> [FAIL][14] +3 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
    - fi-cfl-8700k:       [PASS][15] -> [FAIL][16] +3 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-cfl-8700k/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-cfl-8700k/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
    - fi-cfl-8109u:       [PASS][17] -> [FAIL][18] +3 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-cfl-8109u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-cfl-8109u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
    - fi-glk-dsi:         [PASS][19] -> [FAIL][20] +3 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-glk-dsi/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-glk-dsi/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
    - fi-kbl-7500u:       [PASS][21] -> [FAIL][22] +3 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-kbl-7500u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-kbl-7500u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - fi-bxt-dsi:         [PASS][23] -> [FAIL][24] +3 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-bxt-dsi/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-bxt-dsi/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-legacy:
    - fi-cml-u2:          [PASS][25] -> [FAIL][26] +3 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-cml-u2/igt@kms_cursor_legacy@basic-flip-before-cursor-legacy.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-cml-u2/igt@kms_cursor_legacy@basic-flip-before-cursor-legacy.html

  
#### Warnings ####

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - fi-tgl-1115g4:      [DMESG-WARN][27] ([i915#4002]) -> [DMESG-FAIL][28] +3 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-1115g4/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-1115g4/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - {fi-ehl-2}:         [PASS][29] -> [FAIL][30] +3 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-ehl-2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-ehl-2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - {fi-tgl-dsi}:       [PASS][31] -> [FAIL][32] +3 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-dsi/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-dsi/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-legacy:
    - {fi-jsl-1}:         [PASS][33] -> [FAIL][34] +3 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-jsl-1/igt@kms_cursor_legacy@basic-flip-before-cursor-legacy.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-jsl-1/igt@kms_cursor_legacy@basic-flip-before-cursor-legacy.html

  
Known issues
------------

  Here are the changes found in Patchwork_20882 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-cfl-8109u:       [PASS][35] -> [DMESG-WARN][36] ([i915#203] / [i915#262] / [i915#295]) +1 similar issue
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-cfl-8109u/igt@gem_exec_suspend@basic-s0.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-cfl-8109u/igt@gem_exec_suspend@basic-s0.html

  * igt@kms_chamelium@hdmi-crc-fast:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][37] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-bsw-n3050/igt@kms_chamelium@hdmi-crc-fast.html

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-a:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][38] ([fdo#109271]) +42 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-bsw-n3050/igt@kms_pipe_crc_basic@hang-read-crc-pipe-a.html

  * igt@vgem_basic@unload:
    - fi-tgl-1115g4:      [PASS][39] -> [DMESG-WARN][40] ([i915#4002])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-1115g4/igt@vgem_basic@unload.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-1115g4/igt@vgem_basic@unload.html

  
#### Possible fixes ####

  * igt@core_hotunplug@unbind-rebind:
    - fi-tgl-1115g4:      [DMESG-WARN][41] ([i915#4002]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-1115g4/igt@core_hotunplug@unbind-rebind.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-1115g4/igt@core_hotunplug@unbind-rebind.html

  * igt@i915_module_load@reload:
    - fi-tgl-1115g4:      [DMESG-WARN][43] ([i915#1385] / [i915#4002]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-1115g4/igt@i915_module_load@reload.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-1115g4/igt@i915_module_load@reload.html

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-guc:         [FAIL][45] ([i915#2203] / [i915#579]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-kbl-guc/igt@i915_pm_rpm@module-reload.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-kbl-guc/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@gt_lrc:
    - fi-rkl-guc:         [DMESG-WARN][47] ([i915#3958]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-rkl-guc/igt@i915_selftest@live@gt_lrc.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-rkl-guc/igt@i915_selftest@live@gt_lrc.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-icl-u2:          [DMESG-WARN][49] ([i915#2203] / [i915#2868]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-icl-u2/igt@kms_chamelium@hdmi-hpd-fast.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-icl-u2/igt@kms_chamelium@hdmi-hpd-fast.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-b:
    - fi-rkl-11600:       [SKIP][51] -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-rkl-11600/igt@kms_pipe_crc_basic@read-crc-pipe-b.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-rkl-11600/igt@kms_pipe_crc_basic@read-crc-pipe-b.html

  
#### Warnings ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-tgl-1115g4:      [DMESG-FAIL][53] ([i915#1888]) -> [DMESG-WARN][54] ([i915#4002])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-1115g4/igt@gem_exec_suspend@basic-s0.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-1115g4/igt@gem_exec_suspend@basic-s0.html

  * igt@i915_pm_rpm@module-reload:
    - fi-tgl-1115g4:      [INCOMPLETE][55] ([i915#4006]) -> [INCOMPLETE][56] ([i915#1385] / [i915#4006])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10517/fi-tgl-1115g4/igt@i915_pm_rpm@module-reload.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/fi-tgl-1115g4/igt@i915_pm_rpm@module-reload.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1385]: https://gitlab.freedesktop.org/drm/intel/issues/1385
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#203]: https://gitlab.freedesktop.org/drm/intel/issues/203
  [i915#2203]: https://gitlab.freedesktop.org/drm/intel/issues/2203
  [i915#262]: https://gitlab.freedesktop.org/drm/intel/issues/262
  [i915#2868]: https://gitlab.freedesktop.org/drm/intel/issues/2868
  [i915#295]: https://gitlab.freedesktop.org/drm/intel/issues/295
  [i915#3958]: https://gitlab.freedesktop.org/drm/intel/issues/3958
  [i915#4002]: https://gitlab.freedesktop.org/drm/intel/issues/4002
  [i915#4006]: https://gitlab.freedesktop.org/drm/intel/issues/4006
  [i915#579]: https://gitlab.freedesktop.org/drm/intel/issues/579


Participating hosts (39 -> 32)
------------------------------

  Additional (1): fi-bsw-n3050 
  Missing    (8): fi-kbl-soraka fi-ilk-m540 bat-adls-5 fi-hsw-4200u fi-bsw-cyan fi-dg1-1 fi-bdw-samus bat-jsl-1 


Build changes
-------------

  * Linux: CI_DRM_10517 -> Patchwork_20882

  CI-20190529: 20190529
  CI_DRM_10517: 844e662cf49196dc189309aa1692f6342e855325 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6185: 5dca04416f50576f464ebbd9aea96edccd7e4eab @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_20882: 4f324d4c88ddb3494765f5ebdcbe0d51cd07a16c @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

4f324d4c88dd drm/i915/display: Drop PSR frontbuffer rendering support
8547f773f8a0 drm/i915/display/skl+: Drop frontbuffer rendering support
ce03aa5335cd drm/i915/display: Prepare DRRS for frontbuffer rendering drop
b274e5714903 drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate
e920d82d8295 drm/i915/display: Some code improvements and code style fixes for DRRS
08ba0f6456b9 drm/i915/display: Renaming DRRS functions to intel_drrs_*()
63c0e2b638ba drm/i915/display: Move DRRS code its own file
98e381aebd23 drm/i915/display: Drop PSR support from HSW and BDW

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20882/index.html

[-- Attachment #2: Type: text/html, Size: 15848 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW José Roberto de Souza
@ 2021-08-25 15:50   ` Rodrigo Vivi
  0 siblings, 0 replies; 28+ messages in thread
From: Rodrigo Vivi @ 2021-08-25 15:50 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Gwan-gyeong Mun

On Tue, Aug 24, 2021 at 05:58:33PM -0700, José Roberto de Souza wrote:
> At this point is sure that HSW and BDW will never have PSR enabled by
> default, so here dropping it from device info and cleaning up code.
> 
> v2:
> - enable psr support for display 9
> 
> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 97 ++++--------------------
>  drivers/gpu/drm/i915/i915_drv.h          |  2 -
>  drivers/gpu/drm/i915/i915_irq.c          | 16 ----
>  drivers/gpu/drm/i915/i915_pci.c          |  4 +-
>  drivers/gpu/drm/i915/i915_reg.h          | 21 ++---
>  5 files changed, 20 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index cade37f67f33c..3f6fb7d67f84d 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -364,41 +364,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>  	}
>  }
>  
> -static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	u32 aux_clock_divider, aux_ctl;
> -	int i;
> -	static const u8 aux_msg[] = {
> -		[0] = DP_AUX_NATIVE_WRITE << 4,
> -		[1] = DP_SET_POWER >> 8,
> -		[2] = DP_SET_POWER & 0xff,
> -		[3] = 1 - 1,
> -		[4] = DP_SET_POWER_D0,
> -	};
> -	u32 psr_aux_mask = EDP_PSR_AUX_CTL_TIME_OUT_MASK |
> -			   EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK |
> -			   EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK |
> -			   EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK;
> -
> -	BUILD_BUG_ON(sizeof(aux_msg) > 20);
> -	for (i = 0; i < sizeof(aux_msg); i += 4)
> -		intel_de_write(dev_priv,
> -			       EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2),
> -			       intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
> -
> -	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
> -
> -	/* Start with bits set for DDI_AUX_CTL register */
> -	aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, sizeof(aux_msg),
> -					     aux_clock_divider);
> -
> -	/* Select only valid bits for SRD_AUX_CTL */
> -	aux_ctl &= psr_aux_mask;
> -	intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder),
> -		       aux_ctl);
> -}
> -
>  static void intel_psr_enable_sink(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> @@ -621,9 +586,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
>  static bool
>  transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder trans)
>  {
> -	if (DISPLAY_VER(dev_priv) < 9)
> -		return false;
> -	else if (DISPLAY_VER(dev_priv) >= 12)
> +	if (DISPLAY_VER(dev_priv) >= 12)
>  		return trans == TRANSCODER_A;
>  	else
>  		return trans == TRANSCODER_EDP;
> @@ -1114,12 +1077,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp)
>  	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
>  	u32 mask;
>  
> -	/* Only HSW and BDW have PSR AUX registers that need to be setup. SKL+
> -	 * use hardcoded values PSR AUX transactions
> -	 */
> -	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> -		hsw_psr_setup_aux(intel_dp);
> -
>  	if (intel_dp->psr.psr2_enabled && DISPLAY_VER(dev_priv) == 9) {
>  		i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
>  		u32 chicken = intel_de_read(dev_priv, reg);
> @@ -1460,23 +1417,16 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> -	if (DISPLAY_VER(dev_priv) >= 9)
> -		/*
> -		 * Display WA #0884: skl+
> -		 * This documented WA for bxt can be safely applied
> -		 * broadly so we can force HW tracking to exit PSR
> -		 * instead of disabling and re-enabling.
> -		 * Workaround tells us to write 0 to CUR_SURFLIVE_A,
> -		 * but it makes more sense write to the current active
> -		 * pipe.
> -		 */
> -		intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
> -	else
> -		/*
> -		 * A write to CURSURFLIVE do not cause HW tracking to exit PSR
> -		 * on older gens so doing the manual exit instead.
> -		 */
> -		intel_psr_exit(intel_dp);
> +	/*
> +	 * Display WA #0884: skl+
> +	 * This documented WA for bxt can be safely applied
> +	 * broadly so we can force HW tracking to exit PSR
> +	 * instead of disabling and re-enabling.
> +	 * Workaround tells us to write 0 to CUR_SURFLIVE_A,
> +	 * but it makes more sense write to the current active
> +	 * pipe.
> +	 */
> +	intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
>  }
>  
>  void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> @@ -1744,7 +1694,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
>  		      const struct intel_crtc_state *crtc_state,
>  		      const struct drm_connector_state *conn_state)
>  {
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	struct intel_psr *psr = &intel_dp->psr;
>  	bool enable, psr2_enable;
>  
> @@ -1761,15 +1710,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
>  		/* Force a PSR exit when enabling CRC to avoid CRC timeouts */
>  		if (crtc_state->crc_enabled && psr->enabled)
>  			psr_force_hw_tracking_exit(intel_dp);
> -		else if (DISPLAY_VER(dev_priv) < 9 && psr->enabled) {
> -			/*
> -			 * Activate PSR again after a force exit when enabling
> -			 * CRC in older gens
> -			 */
> -			if (!intel_dp->psr.active &&
> -			    !intel_dp->psr.busy_frontbuffer_bits)
> -				schedule_work(&intel_dp->psr.work);
> -		}
>  
>  		goto unlock;
>  	}
> @@ -2182,23 +2122,12 @@ void intel_psr_init(struct intel_dp *intel_dp)
>  
>  	intel_dp->psr.source_support = true;
>  
> -	if (IS_HASWELL(dev_priv))
> -		/*
> -		 * HSW don't have PSR registers on the same space as transcoder
> -		 * so set this to a value that when subtract to the register
> -		 * in transcoder space results in the right offset for HSW
> -		 */
> -		dev_priv->hsw_psr_mmio_adjust = _SRD_CTL_EDP - _HSW_EDP_PSR_BASE;
> -
>  	if (dev_priv->params.enable_psr == -1)
> -		if (DISPLAY_VER(dev_priv) < 9 || !dev_priv->vbt.psr.enable)
> +		if (!dev_priv->vbt.psr.enable)
>  			dev_priv->params.enable_psr = 0;
>  
>  	/* Set link_standby x link_off defaults */
> -	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> -		/* HSW and BDW require workarounds that we don't implement. */
> -		intel_dp->psr.link_standby = false;
> -	else if (DISPLAY_VER(dev_priv) < 12)
> +	if (DISPLAY_VER(dev_priv) < 12)
>  		/* For new platforms up to TGL let's respect VBT back again */
>  		intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link;
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 106f218cec2b5..91453f7dbd656 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -886,8 +886,6 @@ struct drm_i915_private {
>  	 */
>  	u32 gpio_mmio_base;
>  
> -	u32 hsw_psr_mmio_adjust;
> -
>  	/* MMIO base address for MIPI regs */
>  	u32 mipi_mmio_base;
>  
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 58a452c3f0867..0a1681384c84b 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2123,22 +2123,6 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
>  	if (de_iir & DE_ERR_INT_IVB)
>  		ivb_err_int_handler(dev_priv);
>  
> -	if (de_iir & DE_EDP_PSR_INT_HSW) {
> -		struct intel_encoder *encoder;
> -
> -		for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
> -			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> -
> -			u32 psr_iir = intel_uncore_read(&dev_priv->uncore,
> -							EDP_PSR_IIR);
> -
> -			intel_psr_irq_handler(intel_dp, psr_iir);
> -			intel_uncore_write(&dev_priv->uncore,
> -					   EDP_PSR_IIR, psr_iir);
> -			break;
> -		}
> -	}
> -
>  	if (de_iir & DE_AUX_CHANNEL_A_IVB)
>  		dp_aux_irq_handler(dev_priv);
>  
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 96cfd6427cec1..ddb4434b3e41e 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -537,8 +537,6 @@ static const struct intel_device_info vlv_info = {
>  		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \
>  	.display.has_ddi = 1, \
>  	.display.has_fpga_dbg = 1, \
> -	.display.has_psr = 1, \
> -	.display.has_psr_hw_tracking = 1, \
>  	.display.has_dp_mst = 1, \
>  	.has_rc6p = 0 /* RC6p removed-by HSW */, \
>  	HSW_PIPE_OFFSETS, \
> @@ -642,6 +640,8 @@ static const struct intel_device_info chv_info = {
>  	.has_gt_uc = 1, \
>  	.display.has_hdcp = 1, \
>  	.display.has_ipc = 1, \
> +	.display.has_psr = 1, \
> +	.display.has_psr_hw_tracking = 1, \
>  	.dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */ \
>  	.dbuf.slice_mask = BIT(DBUF_S1)
>  
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 8d4cf1e203ab7..6add651262e29 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4513,11 +4513,9 @@ enum {
>   * HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one
>   * instance of it
>   */
> -#define _HSW_EDP_PSR_BASE			0x64800
>  #define _SRD_CTL_A				0x60800
>  #define _SRD_CTL_EDP				0x6f800
> -#define _PSR_ADJ(tran, reg)			(_TRANS2(tran, reg) - dev_priv->hsw_psr_mmio_adjust)
> -#define EDP_PSR_CTL(tran)			_MMIO(_PSR_ADJ(tran, _SRD_CTL_A))
> +#define EDP_PSR_CTL(tran)			_MMIO(_TRANS2(tran, _SRD_CTL_A))
>  #define   EDP_PSR_ENABLE			(1 << 31)
>  #define   BDW_PSR_SINGLE_FRAME			(1 << 30)
>  #define   EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK	(1 << 29) /* SW can't modify */
> @@ -4561,22 +4559,13 @@ enum {
>  #define   EDP_PSR_POST_EXIT(trans)		(0x2 << _EDP_PSR_TRANS_SHIFT(trans))
>  #define   EDP_PSR_PRE_ENTRY(trans)		(0x1 << _EDP_PSR_TRANS_SHIFT(trans))
>  
> -#define _SRD_AUX_CTL_A				0x60810
> -#define _SRD_AUX_CTL_EDP			0x6f810
> -#define EDP_PSR_AUX_CTL(tran)			_MMIO(_PSR_ADJ(tran, _SRD_AUX_CTL_A))
> -#define   EDP_PSR_AUX_CTL_TIME_OUT_MASK		(3 << 26)
> -#define   EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK	(0x1f << 20)
> -#define   EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK	(0xf << 16)
> -#define   EDP_PSR_AUX_CTL_ERROR_INTERRUPT	(1 << 11)
> -#define   EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK	(0x7ff)
> -
>  #define _SRD_AUX_DATA_A				0x60814
>  #define _SRD_AUX_DATA_EDP			0x6f814
> -#define EDP_PSR_AUX_DATA(tran, i)		_MMIO(_PSR_ADJ(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */
> +#define EDP_PSR_AUX_DATA(tran, i)		_MMIO(_TRANS2(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */
>  
>  #define _SRD_STATUS_A				0x60840
>  #define _SRD_STATUS_EDP				0x6f840
> -#define EDP_PSR_STATUS(tran)			_MMIO(_PSR_ADJ(tran, _SRD_STATUS_A))
> +#define EDP_PSR_STATUS(tran)			_MMIO(_TRANS2(tran, _SRD_STATUS_A))
>  #define   EDP_PSR_STATUS_STATE_MASK		(7 << 29)
>  #define   EDP_PSR_STATUS_STATE_SHIFT		29
>  #define   EDP_PSR_STATUS_STATE_IDLE		(0 << 29)
> @@ -4603,13 +4592,13 @@ enum {
>  
>  #define _SRD_PERF_CNT_A			0x60844
>  #define _SRD_PERF_CNT_EDP		0x6f844
> -#define EDP_PSR_PERF_CNT(tran)		_MMIO(_PSR_ADJ(tran, _SRD_PERF_CNT_A))
> +#define EDP_PSR_PERF_CNT(tran)		_MMIO(_TRANS2(tran, _SRD_PERF_CNT_A))
>  #define   EDP_PSR_PERF_CNT_MASK		0xffffff
>  
>  /* PSR_MASK on SKL+ */
>  #define _SRD_DEBUG_A				0x60860
>  #define _SRD_DEBUG_EDP				0x6f860
> -#define EDP_PSR_DEBUG(tran)			_MMIO(_PSR_ADJ(tran, _SRD_DEBUG_A))
> +#define EDP_PSR_DEBUG(tran)			_MMIO(_TRANS2(tran, _SRD_DEBUG_A))
>  #define   EDP_PSR_DEBUG_MASK_MAX_SLEEP         (1 << 28)
>  #define   EDP_PSR_DEBUG_MASK_LPSP              (1 << 27)
>  #define   EDP_PSR_DEBUG_MASK_MEMUP             (1 << 26)
> -- 
> 2.33.0
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file José Roberto de Souza
@ 2021-08-25 15:55   ` Rodrigo Vivi
  2021-08-25 17:23     ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Rodrigo Vivi @ 2021-08-25 15:55 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Jani Nikula

On Tue, Aug 24, 2021 at 05:58:34PM -0700, José Roberto de Souza wrote:
> intel_dp.c is a 5k lines monster, so moving DRRS out of it to reduce
> some lines from it.
> 
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  Documentation/gpu/i915.rst                    |  14 +-
>  drivers/gpu/drm/i915/Makefile                 |   1 +
>  drivers/gpu/drm/i915/display/intel_ddi.c      |   1 +
>  .../drm/i915/display/intel_display_debugfs.c  |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c       | 467 +----------------
>  drivers/gpu/drm/i915/display/intel_dp.h       |  11 -
>  drivers/gpu/drm/i915/display/intel_drrs.c     | 477 ++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_drrs.h     |  32 ++
>  .../gpu/drm/i915/display/intel_frontbuffer.c  |   1 +
>  9 files changed, 521 insertions(+), 484 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h
> 
> diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> index 204ebdaadb45a..03021dfa0dd81 100644
> --- a/Documentation/gpu/i915.rst
> +++ b/Documentation/gpu/i915.rst
> @@ -183,25 +183,25 @@ Frame Buffer Compression (FBC)
>  Display Refresh Rate Switching (DRRS)
>  -------------------------------------
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :doc: Display Refresh Rate Switching (DRRS)
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :functions: intel_dp_set_drrs_state
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :functions: intel_edp_drrs_enable
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :functions: intel_edp_drrs_disable
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :functions: intel_edp_drrs_invalidate
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :functions: intel_edp_drrs_flush
>  
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
>     :functions: intel_dp_drrs_init
>  
>  DPIO
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index fd997dfa5e32c..ee502a2354c44 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -213,6 +213,7 @@ i915-y += \
>  	display/intel_dpll.o \
>  	display/intel_dpll_mgr.o \
>  	display/intel_dpt.o \
> +	display/intel_drrs.o \
>  	display/intel_dsb.o \
>  	display/intel_fb.o \
>  	display/intel_fbc.o \
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 1ef7a65feb660..828df570a4809 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -40,6 +40,7 @@
>  #include "intel_dp_link_training.h"
>  #include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
> +#include "intel_drrs.h"
>  #include "intel_dsi.h"
>  #include "intel_fdi.h"
>  #include "intel_fifo_underrun.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index 8fdacb252bb19..b136a0fc0963b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -13,6 +13,7 @@
>  #include "intel_display_types.h"
>  #include "intel_dmc.h"
>  #include "intel_dp.h"
> +#include "intel_drrs.h"
>  #include "intel_fbc.h"
>  #include "intel_hdcp.h"
>  #include "intel_hdmi.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index fd4f7e82e4205..965b888e0e771 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -55,6 +55,7 @@
>  #include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
>  #include "intel_dpll.h"
> +#include "intel_drrs.h"
>  #include "intel_fifo_underrun.h"
>  #include "intel_hdcp.h"
>  #include "intel_hdmi.h"
> @@ -1675,46 +1676,6 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
>  		intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
>  }
>  
> -static void
> -intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> -			     struct intel_crtc_state *pipe_config,
> -			     int output_bpp, bool constant_n)
> -{
> -	struct intel_connector *intel_connector = intel_dp->attached_connector;
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	int pixel_clock;
> -
> -	if (pipe_config->vrr.enable)
> -		return;
> -
> -	/*
> -	 * DRRS and PSR can't be enable together, so giving preference to PSR
> -	 * as it allows more power-savings by complete shutting down display,
> -	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> -	 * after intel_psr_compute_config().
> -	 */
> -	if (pipe_config->has_psr)
> -		return;
> -
> -	if (!intel_connector->panel.downclock_mode ||
> -	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> -		return;
> -
> -	pipe_config->has_drrs = true;
> -
> -	pixel_clock = intel_connector->panel.downclock_mode->clock;
> -	if (pipe_config->splitter.enable)
> -		pixel_clock /= pipe_config->splitter.link_count;
> -
> -	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
> -			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
> -			       constant_n, pipe_config->fec_enable);
> -
> -	/* FIXME: abstract this better */
> -	if (pipe_config->splitter.enable)
> -		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
> -}
> -
>  int
>  intel_dp_compute_config(struct intel_encoder *encoder,
>  			struct intel_crtc_state *pipe_config,
> @@ -4785,432 +4746,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
>  		drm_connector_attach_vrr_capable_property(connector);
>  }
>  
> -/**
> - * intel_dp_set_drrs_state - program registers for RR switch to take effect
> - * @dev_priv: i915 device
> - * @crtc_state: a pointer to the active intel_crtc_state
> - * @refresh_rate: RR to be programmed

I know it was already here...

> - *
> - * This function gets called when refresh rate (RR) has to be changed from
> - * one frequency to another. Switches can be between high and low RR
> - * supported by the panel or to any other RR based on media playback (in
> - * this case, RR value needs to be passed from user space).
> - *
> - * The caller of this function needs to take a lock on dev_priv->drrs.
> - */
> -static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> -				    const struct intel_crtc_state *crtc_state,
> -				    int refresh_rate)
> -{
> -	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> -
> -	if (refresh_rate <= 0) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Refresh rate should be positive non-zero.\n");
> -		return;
> -	}
> -
> -	if (intel_dp == NULL) {
> -		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> -		return;
> -	}
> -
> -	if (!crtc) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "DRRS: intel_crtc not initialized\n");
> -		return;
> -	}
> -
> -	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
> -		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
> -		return;
> -	}
> -
> -	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> -			refresh_rate)
> -		index = DRRS_LOW_RR;
> -
> -	if (index == dev_priv->drrs.refresh_rate_type) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "DRRS requested for previously set RR...ignoring\n");
> -		return;
> -	}
> -
> -	if (!crtc_state->hw.active) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "eDP encoder disabled. CRTC not Active\n");
> -		return;
> -	}
> -
> -	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> -		switch (index) {
> -		case DRRS_HIGH_RR:
> -			intel_dp_set_m_n(crtc_state, M1_N1);
> -			break;
> -		case DRRS_LOW_RR:
> -			intel_dp_set_m_n(crtc_state, M2_N2);
> -			break;
> -		case DRRS_MAX_RR:
> -		default:
> -			drm_err(&dev_priv->drm,
> -				"Unsupported refreshrate type\n");
> -		}
> -	} else if (DISPLAY_VER(dev_priv) > 6) {
> -		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
> -		u32 val;
> -
> -		val = intel_de_read(dev_priv, reg);
> -		if (index > DRRS_HIGH_RR) {
> -			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> -				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> -			else
> -				val |= PIPECONF_EDP_RR_MODE_SWITCH;
> -		} else {
> -			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> -				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> -			else
> -				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
> -		}
> -		intel_de_write(dev_priv, reg, val);
> -	}
> -
> -	dev_priv->drrs.refresh_rate_type = index;
> -
> -	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> -		    refresh_rate);
> -}
> -
> -static void
> -intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	dev_priv->drrs.busy_frontbuffer_bits = 0;
> -	dev_priv->drrs.dp = intel_dp;
> -}
> -
> -/**
> - * intel_edp_drrs_enable - init drrs struct if supported
> - * @intel_dp: DP struct
> - * @crtc_state: A pointer to the active crtc state.
> - *
> - * Initializes frontbuffer_bits and drrs.dp
> - */
> -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> -			   const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	if (!crtc_state->has_drrs)
> -		return;
> -
> -	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -
> -	if (dev_priv->drrs.dp) {
> -		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
> -		goto unlock;
> -	}
> -
> -	intel_edp_drrs_enable_locked(intel_dp);
> -
> -unlock:
> -	mutex_unlock(&dev_priv->drrs.mutex);
> -}
> -
> -static void
> -intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> -			      const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> -		int refresh;
> -
> -		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> -		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> -	}
> -
> -	dev_priv->drrs.dp = NULL;
> -}
> -
> -/**
> - * intel_edp_drrs_disable - Disable DRRS
> - * @intel_dp: DP struct
> - * @old_crtc_state: Pointer to old crtc_state.
> - *
> - */
> -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> -			    const struct intel_crtc_state *old_crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	if (!old_crtc_state->has_drrs)
> -		return;
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -	if (!dev_priv->drrs.dp) {
> -		mutex_unlock(&dev_priv->drrs.mutex);
> -		return;
> -	}
> -
> -	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> -	mutex_unlock(&dev_priv->drrs.mutex);
> -
> -	cancel_delayed_work_sync(&dev_priv->drrs.work);
> -}
> -
> -/**
> - * intel_edp_drrs_update - Update DRRS state
> - * @intel_dp: Intel DP
> - * @crtc_state: new CRTC state
> - *
> - * This function will update DRRS states, disabling or enabling DRRS when
> - * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> - * intel_edp_drrs_enable() should be called instead.
> - */
> -void
> -intel_edp_drrs_update(struct intel_dp *intel_dp,
> -		      const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> -		return;
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -
> -	/* New state matches current one? */
> -	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
> -		goto unlock;
> -
> -	if (crtc_state->has_drrs)
> -		intel_edp_drrs_enable_locked(intel_dp);
> -	else
> -		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> -
> -unlock:
> -	mutex_unlock(&dev_priv->drrs.mutex);
> -}
> -
> -static void intel_edp_drrs_downclock_work(struct work_struct *work)
> -{
> -	struct drm_i915_private *dev_priv =
> -		container_of(work, typeof(*dev_priv), drrs.work.work);
> -	struct intel_dp *intel_dp;
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -
> -	intel_dp = dev_priv->drrs.dp;
> -
> -	if (!intel_dp)
> -		goto unlock;
> -
> -	/*
> -	 * The delayed work can race with an invalidate hence we need to
> -	 * recheck.
> -	 */
> -
> -	if (dev_priv->drrs.busy_frontbuffer_bits)
> -		goto unlock;
> -
> -	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> -		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> -
> -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> -			drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> -	}
> -
> -unlock:
> -	mutex_unlock(&dev_priv->drrs.mutex);
> -}
> -
> -/**
> - * intel_edp_drrs_invalidate - Disable Idleness DRRS
> - * @dev_priv: i915 device
> - * @frontbuffer_bits: frontbuffer plane tracking bits
> - *
> - * This function gets called everytime rendering on the given planes start.
> - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> - *
> - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> - */
> -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> -			       unsigned int frontbuffer_bits)
> -{
> -	struct intel_dp *intel_dp;
> -	struct drm_crtc *crtc;
> -	enum pipe pipe;
> -
> -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> -		return;
> -
> -	cancel_delayed_work(&dev_priv->drrs.work);
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -
> -	intel_dp = dev_priv->drrs.dp;
> -	if (!intel_dp) {
> -		mutex_unlock(&dev_priv->drrs.mutex);
> -		return;
> -	}
> -
> -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> -	pipe = to_intel_crtc(crtc)->pipe;
> -
> -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> -	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> -
> -	/* invalidate means busy screen hence upclock */
> -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> -
> -	mutex_unlock(&dev_priv->drrs.mutex);
> -}
> -
> -/**
> - * intel_edp_drrs_flush - Restart Idleness DRRS
> - * @dev_priv: i915 device
> - * @frontbuffer_bits: frontbuffer plane tracking bits
> - *
> - * This function gets called every time rendering on the given planes has
> - * completed or flip on a crtc is completed. So DRRS should be upclocked
> - * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
> - * if no other planes are dirty.
> - *
> - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> - */
> -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> -			  unsigned int frontbuffer_bits)
> -{
> -	struct intel_dp *intel_dp;
> -	struct drm_crtc *crtc;
> -	enum pipe pipe;
> -
> -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> -		return;
> -
> -	cancel_delayed_work(&dev_priv->drrs.work);
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -
> -	intel_dp = dev_priv->drrs.dp;
> -	if (!intel_dp) {
> -		mutex_unlock(&dev_priv->drrs.mutex);
> -		return;
> -	}
> -
> -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> -	pipe = to_intel_crtc(crtc)->pipe;
> -
> -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> -	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> -
> -	/* flush means busy screen hence upclock */
> -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> -
> -	/*
> -	 * flush also means no more activity hence schedule downclock, if all
> -	 * other fbs are quiescent too
> -	 */
> -	if (!dev_priv->drrs.busy_frontbuffer_bits)
> -		schedule_delayed_work(&dev_priv->drrs.work,
> -				msecs_to_jiffies(1000));
> -	mutex_unlock(&dev_priv->drrs.mutex);
> -}
> -
> -/**
> - * DOC: Display Refresh Rate Switching (DRRS)
> - *
> - * Display Refresh Rate Switching (DRRS) is a power conservation feature
> - * which enables swtching between low and high refresh rates,
> - * dynamically, based on the usage scenario. This feature is applicable
> - * for internal panels.
> - *
> - * Indication that the panel supports DRRS is given by the panel EDID, which
> - * would list multiple refresh rates for one resolution.
> - *
> - * DRRS is of 2 types - static and seamless.
> - * Static DRRS involves changing refresh rate (RR) by doing a full modeset
> - * (may appear as a blink on screen) and is used in dock-undock scenario.
> - * Seamless DRRS involves changing RR without any visual effect to the user
> - * and can be used during normal system usage. This is done by programming
> - * certain registers.
> - *
> - * Support for static/seamless DRRS may be indicated in the VBT based on
> - * inputs from the panel spec.
> - *
> - * DRRS saves power by switching to low RR based on usage scenarios.
> - *
> - * The implementation is based on frontbuffer tracking implementation.  When
> - * there is a disturbance on the screen triggered by user activity or a periodic
> - * system activity, DRRS is disabled (RR is changed to high RR).  When there is
> - * no movement on screen, after a timeout of 1 second, a switch to low RR is
> - * made.
> - *
> - * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> - * and intel_edp_drrs_flush() are called.
> - *
> - * DRRS can be further extended to support other internal panels and also
> - * the scenario of video playback wherein RR is set based on the rate
> - * requested by userspace.
> - */
> -
> -/**
> - * intel_dp_drrs_init - Init basic DRRS work and mutex.
> - * @connector: eDP connector
> - * @fixed_mode: preferred mode of panel
> - *
> - * This function is  called only once at driver load to initialize basic
> - * DRRS stuff.
> - *
> - * Returns:
> - * Downclock mode if panel supports it, else return NULL.
> - * DRRS support is determined by the presence of downclock mode (apart
> - * from VBT setting).
> - */
> -static struct drm_display_mode *
> -intel_dp_drrs_init(struct intel_connector *connector,
> -		   struct drm_display_mode *fixed_mode)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> -	struct drm_display_mode *downclock_mode = NULL;
> -
> -	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> -	mutex_init(&dev_priv->drrs.mutex);
> -
> -	if (DISPLAY_VER(dev_priv) <= 6) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "DRRS supported for Gen7 and above\n");
> -		return NULL;
> -	}
> -
> -	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
> -		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
> -		return NULL;
> -	}
> -
> -	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
> -	if (!downclock_mode) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Downclock mode is not found. DRRS not supported\n");
> -		return NULL;
> -	}
> -
> -	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
> -
> -	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
> -	drm_dbg_kms(&dev_priv->drm,
> -		    "seamless DRRS supported for eDP panel.\n");
> -	return downclock_mode;
> -}
> -
>  static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  				     struct intel_connector *intel_connector)
>  {
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index ae0f776bffab8..a28fff286c21a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -70,17 +70,6 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp);
>  int intel_dp_max_lane_count(struct intel_dp *intel_dp);
>  int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
>  
> -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> -			   const struct intel_crtc_state *crtc_state);
> -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> -			    const struct intel_crtc_state *crtc_state);
> -void intel_edp_drrs_update(struct intel_dp *intel_dp,
> -			   const struct intel_crtc_state *crtc_state);
> -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> -			       unsigned int frontbuffer_bits);
> -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> -			  unsigned int frontbuffer_bits);
> -
>  void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
>  			   u8 *link_bw, u8 *rate_select);
>  bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> new file mode 100644
> index 0000000000000..be9b6d4482f04
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> @@ -0,0 +1,477 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include "i915_drv.h"
> +#include "intel_atomic.h"
> +#include "intel_de.h"
> +#include "intel_display_types.h"
> +#include "intel_drrs.h"
> +#include "intel_panel.h"
> +
> +/**
> + * DOC: Display Refresh Rate Switching (DRRS)
> + *
> + * Display Refresh Rate Switching (DRRS) is a power conservation feature
> + * which enables swtching between low and high refresh rates,
> + * dynamically, based on the usage scenario. This feature is applicable
> + * for internal panels.
> + *
> + * Indication that the panel supports DRRS is given by the panel EDID, which
> + * would list multiple refresh rates for one resolution.
> + *
> + * DRRS is of 2 types - static and seamless.
> + * Static DRRS involves changing refresh rate (RR) by doing a full modeset
> + * (may appear as a blink on screen) and is used in dock-undock scenario.
> + * Seamless DRRS involves changing RR without any visual effect to the user
> + * and can be used during normal system usage. This is done by programming
> + * certain registers.
> + *
> + * Support for static/seamless DRRS may be indicated in the VBT based on
> + * inputs from the panel spec.
> + *
> + * DRRS saves power by switching to low RR based on usage scenarios.
> + *
> + * The implementation is based on frontbuffer tracking implementation.  When
> + * there is a disturbance on the screen triggered by user activity or a periodic
> + * system activity, DRRS is disabled (RR is changed to high RR).  When there is
> + * no movement on screen, after a timeout of 1 second, a switch to low RR is
> + * made.
> + *
> + * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> + * and intel_edp_drrs_flush() are called.
> + *
> + * DRRS can be further extended to support other internal panels and also
> + * the scenario of video playback wherein RR is set based on the rate
> + * requested by userspace.
> + */
> +
> +void
> +intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> +			     struct intel_crtc_state *pipe_config,
> +			     int output_bpp, bool constant_n)
> +{
> +	struct intel_connector *intel_connector = intel_dp->attached_connector;
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +	int pixel_clock;
> +
> +	if (pipe_config->vrr.enable)
> +		return;
> +
> +	/*
> +	 * DRRS and PSR can't be enable together, so giving preference to PSR
> +	 * as it allows more power-savings by complete shutting down display,
> +	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> +	 * after intel_psr_compute_config().
> +	 */
> +	if (pipe_config->has_psr)
> +		return;
> +
> +	if (!intel_connector->panel.downclock_mode ||
> +	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> +		return;
> +
> +	pipe_config->has_drrs = true;
> +
> +	pixel_clock = intel_connector->panel.downclock_mode->clock;
> +	if (pipe_config->splitter.enable)
> +		pixel_clock /= pipe_config->splitter.link_count;
> +
> +	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
> +			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
> +			       constant_n, pipe_config->fec_enable);
> +
> +	/* FIXME: abstract this better */
> +	if (pipe_config->splitter.enable)
> +		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
> +}
> +
> +/**
> + * intel_dp_set_drrs_state - program registers for RR switch to take effect
> + * @dev_priv: i915 device
> + * @crtc_state: a pointer to the active intel_crtc_state
> + * @refresh_rate: RR to be programmed

... but let's enjoy the opportunity and avoid doc style in static functions
that should never be called outside this block.

with this addressed feel free to use:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> + *
> + * This function gets called when refresh rate (RR) has to be changed from
> + * one frequency to another. Switches can be between high and low RR
> + * supported by the panel or to any other RR based on media playback (in
> + * this case, RR value needs to be passed from user space).
> + *
> + * The caller of this function needs to take a lock on dev_priv->drrs.
> + */
> +static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> +				    const struct intel_crtc_state *crtc_state,
> +				    int refresh_rate)
> +{
> +	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> +
> +	if (refresh_rate <= 0) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Refresh rate should be positive non-zero.\n");
> +		return;
> +	}
> +
> +	if (intel_dp == NULL) {
> +		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> +		return;
> +	}
> +
> +	if (!crtc) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "DRRS: intel_crtc not initialized\n");
> +		return;
> +	}
> +
> +	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
> +		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
> +		return;
> +	}
> +
> +	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> +			refresh_rate)
> +		index = DRRS_LOW_RR;
> +
> +	if (index == dev_priv->drrs.refresh_rate_type) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "DRRS requested for previously set RR...ignoring\n");
> +		return;
> +	}
> +
> +	if (!crtc_state->hw.active) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "eDP encoder disabled. CRTC not Active\n");
> +		return;
> +	}
> +
> +	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> +		switch (index) {
> +		case DRRS_HIGH_RR:
> +			intel_dp_set_m_n(crtc_state, M1_N1);
> +			break;
> +		case DRRS_LOW_RR:
> +			intel_dp_set_m_n(crtc_state, M2_N2);
> +			break;
> +		case DRRS_MAX_RR:
> +		default:
> +			drm_err(&dev_priv->drm,
> +				"Unsupported refreshrate type\n");
> +		}
> +	} else if (DISPLAY_VER(dev_priv) > 6) {
> +		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
> +		u32 val;
> +
> +		val = intel_de_read(dev_priv, reg);
> +		if (index > DRRS_HIGH_RR) {
> +			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> +				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> +			else
> +				val |= PIPECONF_EDP_RR_MODE_SWITCH;
> +		} else {
> +			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> +				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> +			else
> +				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
> +		}
> +		intel_de_write(dev_priv, reg, val);
> +	}
> +
> +	dev_priv->drrs.refresh_rate_type = index;
> +
> +	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> +		    refresh_rate);
> +}
> +
> +static void
> +intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> +{
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> +	dev_priv->drrs.busy_frontbuffer_bits = 0;
> +	dev_priv->drrs.dp = intel_dp;
> +}
> +
> +/**
> + * intel_edp_drrs_enable - init drrs struct if supported
> + * @intel_dp: DP struct
> + * @crtc_state: A pointer to the active crtc state.
> + *
> + * Initializes frontbuffer_bits and drrs.dp
> + */
> +void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> +			   const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> +	if (!crtc_state->has_drrs)
> +		return;
> +
> +	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
> +
> +	mutex_lock(&dev_priv->drrs.mutex);
> +
> +	if (dev_priv->drrs.dp) {
> +		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
> +		goto unlock;
> +	}
> +
> +	intel_edp_drrs_enable_locked(intel_dp);
> +
> +unlock:
> +	mutex_unlock(&dev_priv->drrs.mutex);
> +}
> +
> +static void
> +intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> +			      const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> +	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> +		int refresh;
> +
> +		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> +		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> +	}
> +
> +	dev_priv->drrs.dp = NULL;
> +}
> +
> +/**
> + * intel_edp_drrs_disable - Disable DRRS
> + * @intel_dp: DP struct
> + * @old_crtc_state: Pointer to old crtc_state.
> + *
> + */
> +void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> +			    const struct intel_crtc_state *old_crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> +	if (!old_crtc_state->has_drrs)
> +		return;
> +
> +	mutex_lock(&dev_priv->drrs.mutex);
> +	if (!dev_priv->drrs.dp) {
> +		mutex_unlock(&dev_priv->drrs.mutex);
> +		return;
> +	}
> +
> +	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> +	mutex_unlock(&dev_priv->drrs.mutex);
> +
> +	cancel_delayed_work_sync(&dev_priv->drrs.work);
> +}
> +
> +/**
> + * intel_edp_drrs_update - Update DRRS state
> + * @intel_dp: Intel DP
> + * @crtc_state: new CRTC state
> + *
> + * This function will update DRRS states, disabling or enabling DRRS when
> + * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> + * intel_edp_drrs_enable() should be called instead.
> + */
> +void
> +intel_edp_drrs_update(struct intel_dp *intel_dp,
> +		      const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> +	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> +		return;
> +
> +	mutex_lock(&dev_priv->drrs.mutex);
> +
> +	/* New state matches current one? */
> +	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
> +		goto unlock;
> +
> +	if (crtc_state->has_drrs)
> +		intel_edp_drrs_enable_locked(intel_dp);
> +	else
> +		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> +
> +unlock:
> +	mutex_unlock(&dev_priv->drrs.mutex);
> +}
> +
> +static void intel_edp_drrs_downclock_work(struct work_struct *work)
> +{
> +	struct drm_i915_private *dev_priv =
> +		container_of(work, typeof(*dev_priv), drrs.work.work);
> +	struct intel_dp *intel_dp;
> +
> +	mutex_lock(&dev_priv->drrs.mutex);
> +
> +	intel_dp = dev_priv->drrs.dp;
> +
> +	if (!intel_dp)
> +		goto unlock;
> +
> +	/*
> +	 * The delayed work can race with an invalidate hence we need to
> +	 * recheck.
> +	 */
> +
> +	if (dev_priv->drrs.busy_frontbuffer_bits)
> +		goto unlock;
> +
> +	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> +		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> +
> +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> +					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> +	}
> +
> +unlock:
> +	mutex_unlock(&dev_priv->drrs.mutex);
> +}
> +
> +/**
> + * intel_edp_drrs_invalidate - Disable Idleness DRRS
> + * @dev_priv: i915 device
> + * @frontbuffer_bits: frontbuffer plane tracking bits
> + *
> + * This function gets called everytime rendering on the given planes start.
> + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> + *
> + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> + */
> +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> +			       unsigned int frontbuffer_bits)
> +{
> +	struct intel_dp *intel_dp;
> +	struct drm_crtc *crtc;
> +	enum pipe pipe;
> +
> +	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> +		return;
> +
> +	cancel_delayed_work(&dev_priv->drrs.work);
> +
> +	mutex_lock(&dev_priv->drrs.mutex);
> +
> +	intel_dp = dev_priv->drrs.dp;
> +	if (!intel_dp) {
> +		mutex_unlock(&dev_priv->drrs.mutex);
> +		return;
> +	}
> +
> +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> +	pipe = to_intel_crtc(crtc)->pipe;
> +
> +	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> +	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> +
> +	/* invalidate means busy screen hence upclock */
> +	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> +					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> +
> +	mutex_unlock(&dev_priv->drrs.mutex);
> +}
> +
> +/**
> + * intel_edp_drrs_flush - Restart Idleness DRRS
> + * @dev_priv: i915 device
> + * @frontbuffer_bits: frontbuffer plane tracking bits
> + *
> + * This function gets called every time rendering on the given planes has
> + * completed or flip on a crtc is completed. So DRRS should be upclocked
> + * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
> + * if no other planes are dirty.
> + *
> + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> + */
> +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> +			  unsigned int frontbuffer_bits)
> +{
> +	struct intel_dp *intel_dp;
> +	struct drm_crtc *crtc;
> +	enum pipe pipe;
> +
> +	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> +		return;
> +
> +	cancel_delayed_work(&dev_priv->drrs.work);
> +
> +	mutex_lock(&dev_priv->drrs.mutex);
> +
> +	intel_dp = dev_priv->drrs.dp;
> +	if (!intel_dp) {
> +		mutex_unlock(&dev_priv->drrs.mutex);
> +		return;
> +	}
> +
> +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> +	pipe = to_intel_crtc(crtc)->pipe;
> +
> +	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> +	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> +
> +	/* flush means busy screen hence upclock */
> +	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> +					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> +
> +	/*
> +	 * flush also means no more activity hence schedule downclock, if all
> +	 * other fbs are quiescent too
> +	 */
> +	if (!dev_priv->drrs.busy_frontbuffer_bits)
> +		schedule_delayed_work(&dev_priv->drrs.work,
> +				      msecs_to_jiffies(1000));
> +	mutex_unlock(&dev_priv->drrs.mutex);
> +}
> +
> +/**
> + * intel_dp_drrs_init - Init basic DRRS work and mutex.
> + * @connector: eDP connector
> + * @fixed_mode: preferred mode of panel
> + *
> + * This function is  called only once at driver load to initialize basic
> + * DRRS stuff.
> + *
> + * Returns:
> + * Downclock mode if panel supports it, else return NULL.
> + * DRRS support is determined by the presence of downclock mode (apart
> + * from VBT setting).
> + */
> +struct drm_display_mode *
> +intel_dp_drrs_init(struct intel_connector *connector,
> +		   struct drm_display_mode *fixed_mode)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct drm_display_mode *downclock_mode = NULL;
> +
> +	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> +	mutex_init(&dev_priv->drrs.mutex);
> +
> +	if (DISPLAY_VER(dev_priv) <= 6) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "DRRS supported for Gen7 and above\n");
> +		return NULL;
> +	}
> +
> +	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
> +		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
> +		return NULL;
> +	}
> +
> +	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
> +	if (!downclock_mode) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Downclock mode is not found. DRRS not supported\n");
> +		return NULL;
> +	}
> +
> +	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
> +
> +	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
> +	drm_dbg_kms(&dev_priv->drm,
> +		    "seamless DRRS supported for eDP panel.\n");
> +	return downclock_mode;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
> new file mode 100644
> index 0000000000000..ffa175b4cf4f4
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#ifndef __INTEL_DRRS_H__
> +#define __INTEL_DRRS_H__
> +
> +#include <linux/types.h>
> +
> +struct drm_i915_private;
> +struct intel_crtc_state;
> +struct intel_connector;
> +struct intel_dp;
> +
> +void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> +			   const struct intel_crtc_state *crtc_state);
> +void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> +			    const struct intel_crtc_state *crtc_state);
> +void intel_edp_drrs_update(struct intel_dp *intel_dp,
> +			   const struct intel_crtc_state *crtc_state);
> +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> +			       unsigned int frontbuffer_bits);
> +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> +			  unsigned int frontbuffer_bits);
> +void intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> +				  struct intel_crtc_state *pipe_config,
> +				  int output_bpp, bool constant_n);
> +struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector,
> +					    struct drm_display_mode *fixed_mode);
> +
> +#endif /* __INTEL_DRRS_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> index 8e75debcce1a9..e4834d84ce5e3 100644
> --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> @@ -62,6 +62,7 @@
>  #include "intel_display_types.h"
>  #include "intel_fbc.h"
>  #include "intel_frontbuffer.h"
> +#include "intel_drrs.h"
>  #include "intel_psr.h"
>  
>  /**
> -- 
> 2.33.0
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 3/8] drm/i915/display: Renaming DRRS functions to intel_drrs_*()
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/display: Renaming DRRS functions to intel_drrs_*() José Roberto de Souza
@ 2021-08-25 15:56   ` Rodrigo Vivi
  0 siblings, 0 replies; 28+ messages in thread
From: Rodrigo Vivi @ 2021-08-25 15:56 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Jani Nikula

On Tue, Aug 24, 2021 at 05:58:35PM -0700, José Roberto de Souza wrote:
> We had a mix of intel_edp_drrs_*(), intel_dp_drrs_*() and
> intel_dp_set_drrs_state(), so properly renaming all functions to
> keep the same pattern.
> 
> While at it, also dropping intel_dp_set_drrs_state from the
> documentation as it is a static function.
> 
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> ---
>  Documentation/gpu/i915.rst                    | 13 +--
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  6 +-
>  .../drm/i915/display/intel_display_debugfs.c  |  6 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       |  6 +-
>  drivers/gpu/drm/i915/display/intel_drrs.c     | 92 +++++++++----------
>  drivers/gpu/drm/i915/display/intel_drrs.h     | 30 +++---
>  .../gpu/drm/i915/display/intel_frontbuffer.c  |  4 +-
>  7 files changed, 76 insertions(+), 81 deletions(-)
> 
> diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> index 03021dfa0dd81..101dde3eb1ea9 100644
> --- a/Documentation/gpu/i915.rst
> +++ b/Documentation/gpu/i915.rst
> @@ -187,22 +187,19 @@ Display Refresh Rate Switching (DRRS)
>     :doc: Display Refresh Rate Switching (DRRS)
>  
>  .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> -   :functions: intel_dp_set_drrs_state
> +   :functions: intel_drrs_enable
>  
>  .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> -   :functions: intel_edp_drrs_enable
> +   :functions: intel_drrs_disable
>  
>  .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> -   :functions: intel_edp_drrs_disable
> +   :functions: intel_drrs_invalidate
>  
>  .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> -   :functions: intel_edp_drrs_invalidate
> +   :functions: intel_drrs_flush
>  
>  .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> -   :functions: intel_edp_drrs_flush
> -
> -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> -   :functions: intel_dp_drrs_init
> +   :functions: intel_drrs_init
>  
>  DPIO
>  ----
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 828df570a4809..7714566dec81b 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3015,7 +3015,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
>  	if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
>  		intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
>  
> -	intel_edp_drrs_enable(intel_dp, crtc_state);
> +	intel_drrs_enable(intel_dp, crtc_state);
>  
>  	if (crtc_state->has_audio)
>  		intel_audio_codec_enable(encoder, crtc_state, conn_state);
> @@ -3203,7 +3203,7 @@ static void intel_pre_disable_ddi(struct intel_atomic_state *state,
>  		return;
>  
>  	intel_dp = enc_to_intel_dp(encoder);
> -	intel_edp_drrs_disable(intel_dp, old_crtc_state);
> +	intel_drrs_disable(intel_dp, old_crtc_state);
>  	intel_psr_disable(intel_dp, old_crtc_state);
>  }
>  
> @@ -3233,7 +3233,7 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
>  
>  	intel_psr_update(intel_dp, crtc_state, conn_state);
>  	intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
> -	intel_edp_drrs_update(intel_dp, crtc_state);
> +	intel_drrs_update(intel_dp, crtc_state);
>  
>  	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index b136a0fc0963b..ca819f9e353d0 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -2045,11 +2045,9 @@ static int i915_drrs_ctl_set(void *data, u64 val)
>  
>  			intel_dp = enc_to_intel_dp(encoder);
>  			if (val)
> -				intel_edp_drrs_enable(intel_dp,
> -						      crtc_state);
> +				intel_drrs_enable(intel_dp, crtc_state);
>  			else
> -				intel_edp_drrs_disable(intel_dp,
> -						       crtc_state);
> +				intel_drrs_disable(intel_dp, crtc_state);
>  		}
>  		drm_connector_list_iter_end(&conn_iter);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 965b888e0e771..192564eb60949 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1784,8 +1784,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  
>  	intel_vrr_compute_config(pipe_config, conn_state);
>  	intel_psr_compute_config(intel_dp, pipe_config);
> -	intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp,
> -				     constant_n);
> +	intel_drrs_compute_config(intel_dp, pipe_config, output_bpp,
> +				  constant_n);
>  	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
>  	intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
>  
> @@ -4804,7 +4804,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
>  
>  	fixed_mode = intel_panel_edid_fixed_mode(intel_connector);
>  	if (fixed_mode)
> -		downclock_mode = intel_dp_drrs_init(intel_connector, fixed_mode);
> +		downclock_mode = intel_drrs_init(intel_connector, fixed_mode);
>  
>  	/* multiply the mode clock and horizontal timings for MSO */
>  	intel_edp_mso_mode_fixup(intel_connector, fixed_mode);
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> index be9b6d4482f04..1aa9793521158 100644
> --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> @@ -39,8 +39,8 @@
>   * no movement on screen, after a timeout of 1 second, a switch to low RR is
>   * made.
>   *
> - * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> - * and intel_edp_drrs_flush() are called.
> + * For integration with frontbuffer tracking code, intel_drrs_invalidate()
> + * and intel_drrs_flush() are called.
>   *
>   * DRRS can be further extended to support other internal panels and also
>   * the scenario of video playback wherein RR is set based on the rate
> @@ -48,9 +48,9 @@
>   */
>  
>  void
> -intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> -			     struct intel_crtc_state *pipe_config,
> -			     int output_bpp, bool constant_n)
> +intel_drrs_compute_config(struct intel_dp *intel_dp,
> +			  struct intel_crtc_state *pipe_config,
> +			  int output_bpp, bool constant_n)
>  {
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> @@ -62,7 +62,7 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
>  	/*
>  	 * DRRS and PSR can't be enable together, so giving preference to PSR
>  	 * as it allows more power-savings by complete shutting down display,
> -	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> +	 * so to guarantee this, intel_drrs_compute_config() must be called
>  	 * after intel_psr_compute_config().
>  	 */
>  	if (pipe_config->has_psr)
> @@ -88,7 +88,7 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
>  }
>  
>  /**
> - * intel_dp_set_drrs_state - program registers for RR switch to take effect
> + * intel_drrs_set_state - program registers for RR switch to take effect
>   * @dev_priv: i915 device
>   * @crtc_state: a pointer to the active intel_crtc_state
>   * @refresh_rate: RR to be programmed
> @@ -100,9 +100,9 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
>   *
>   * The caller of this function needs to take a lock on dev_priv->drrs.
>   */
> -static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> -				    const struct intel_crtc_state *crtc_state,
> -				    int refresh_rate)
> +static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
> +				 const struct intel_crtc_state *crtc_state,
> +				 int refresh_rate)
>  {
>  	struct intel_dp *intel_dp = dev_priv->drrs.dp;
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> @@ -185,7 +185,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
>  }
>  
>  static void
> -intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> +intel_drrs_enable_locked(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> @@ -194,14 +194,14 @@ intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
>  }
>  
>  /**
> - * intel_edp_drrs_enable - init drrs struct if supported
> + * intel_drrs_enable - init drrs struct if supported
>   * @intel_dp: DP struct
>   * @crtc_state: A pointer to the active crtc state.
>   *
>   * Initializes frontbuffer_bits and drrs.dp
>   */
> -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> -			   const struct intel_crtc_state *crtc_state)
> +void intel_drrs_enable(struct intel_dp *intel_dp,
> +		       const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> @@ -217,15 +217,15 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp,
>  		goto unlock;
>  	}
>  
> -	intel_edp_drrs_enable_locked(intel_dp);
> +	intel_drrs_enable_locked(intel_dp);
>  
>  unlock:
>  	mutex_unlock(&dev_priv->drrs.mutex);
>  }
>  
>  static void
> -intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> -			      const struct intel_crtc_state *crtc_state)
> +intel_drrs_disable_locked(struct intel_dp *intel_dp,
> +			  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> @@ -233,20 +233,20 @@ intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
>  		int refresh;
>  
>  		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> -		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> +		intel_drrs_set_state(dev_priv, crtc_state, refresh);
>  	}
>  
>  	dev_priv->drrs.dp = NULL;
>  }
>  
>  /**
> - * intel_edp_drrs_disable - Disable DRRS
> + * intel_drrs_disable - Disable DRRS
>   * @intel_dp: DP struct
>   * @old_crtc_state: Pointer to old crtc_state.
>   *
>   */
> -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> -			    const struct intel_crtc_state *old_crtc_state)
> +void intel_drrs_disable(struct intel_dp *intel_dp,
> +			const struct intel_crtc_state *old_crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> @@ -259,24 +259,24 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp,
>  		return;
>  	}
>  
> -	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> +	intel_drrs_disable_locked(intel_dp, old_crtc_state);
>  	mutex_unlock(&dev_priv->drrs.mutex);
>  
>  	cancel_delayed_work_sync(&dev_priv->drrs.work);
>  }
>  
>  /**
> - * intel_edp_drrs_update - Update DRRS state
> + * intel_drrs_update - Update DRRS state
>   * @intel_dp: Intel DP
>   * @crtc_state: new CRTC state
>   *
>   * This function will update DRRS states, disabling or enabling DRRS when
> - * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> - * intel_edp_drrs_enable() should be called instead.
> + * executing fastsets. For full modeset, intel_drrs_disable() and
> + * intel_drrs_enable() should be called instead.
>   */
>  void
> -intel_edp_drrs_update(struct intel_dp *intel_dp,
> -		      const struct intel_crtc_state *crtc_state)
> +intel_drrs_update(struct intel_dp *intel_dp,
> +		  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  
> @@ -290,15 +290,15 @@ intel_edp_drrs_update(struct intel_dp *intel_dp,
>  		goto unlock;
>  
>  	if (crtc_state->has_drrs)
> -		intel_edp_drrs_enable_locked(intel_dp);
> +		intel_drrs_enable_locked(intel_dp);
>  	else
> -		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> +		intel_drrs_disable_locked(intel_dp, crtc_state);
>  
>  unlock:
>  	mutex_unlock(&dev_priv->drrs.mutex);
>  }
>  
> -static void intel_edp_drrs_downclock_work(struct work_struct *work)
> +static void intel_drrs_downclock_work(struct work_struct *work)
>  {
>  	struct drm_i915_private *dev_priv =
>  		container_of(work, typeof(*dev_priv), drrs.work.work);
> @@ -322,8 +322,8 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
>  	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
>  		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
>  
> -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> -					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> +		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> +				     drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
>  	}
>  
>  unlock:
> @@ -331,7 +331,7 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
>  }
>  
>  /**
> - * intel_edp_drrs_invalidate - Disable Idleness DRRS
> + * intel_drrs_invalidate - Disable Idleness DRRS
>   * @dev_priv: i915 device
>   * @frontbuffer_bits: frontbuffer plane tracking bits
>   *
> @@ -340,8 +340,8 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
>   *
>   * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
>   */
> -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> -			       unsigned int frontbuffer_bits)
> +void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> +			   unsigned int frontbuffer_bits)
>  {
>  	struct intel_dp *intel_dp;
>  	struct drm_crtc *crtc;
> @@ -368,14 +368,14 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
>  
>  	/* invalidate means busy screen hence upclock */
>  	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> +		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> +				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
>  
>  	mutex_unlock(&dev_priv->drrs.mutex);
>  }
>  
>  /**
> - * intel_edp_drrs_flush - Restart Idleness DRRS
> + * intel_drrs_flush - Restart Idleness DRRS
>   * @dev_priv: i915 device
>   * @frontbuffer_bits: frontbuffer plane tracking bits
>   *
> @@ -386,8 +386,8 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
>   *
>   * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
>   */
> -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> -			  unsigned int frontbuffer_bits)
> +void intel_drrs_flush(struct drm_i915_private *dev_priv,
> +		      unsigned int frontbuffer_bits)
>  {
>  	struct intel_dp *intel_dp;
>  	struct drm_crtc *crtc;
> @@ -414,8 +414,8 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
>  
>  	/* flush means busy screen hence upclock */
>  	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> +		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> +				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
>  
>  	/*
>  	 * flush also means no more activity hence schedule downclock, if all
> @@ -428,7 +428,7 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
>  }
>  
>  /**
> - * intel_dp_drrs_init - Init basic DRRS work and mutex.
> + * intel_drrs_init - Init basic DRRS work and mutex.
>   * @connector: eDP connector
>   * @fixed_mode: preferred mode of panel
>   *
> @@ -441,13 +441,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
>   * from VBT setting).
>   */
>  struct drm_display_mode *
> -intel_dp_drrs_init(struct intel_connector *connector,
> -		   struct drm_display_mode *fixed_mode)
> +intel_drrs_init(struct intel_connector *connector,
> +		struct drm_display_mode *fixed_mode)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>  	struct drm_display_mode *downclock_mode = NULL;
>  
> -	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> +	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work);
>  	mutex_init(&dev_priv->drrs.mutex);
>  
>  	if (DISPLAY_VER(dev_priv) <= 6) {
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
> index ffa175b4cf4f4..73be7e9a43691 100644
> --- a/drivers/gpu/drm/i915/display/intel_drrs.h
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.h
> @@ -13,20 +13,20 @@ struct intel_crtc_state;
>  struct intel_connector;
>  struct intel_dp;
>  
> -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> -			   const struct intel_crtc_state *crtc_state);
> -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> -			    const struct intel_crtc_state *crtc_state);
> -void intel_edp_drrs_update(struct intel_dp *intel_dp,
> -			   const struct intel_crtc_state *crtc_state);
> -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> -			       unsigned int frontbuffer_bits);
> -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> -			  unsigned int frontbuffer_bits);
> -void intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> -				  struct intel_crtc_state *pipe_config,
> -				  int output_bpp, bool constant_n);
> -struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector,
> -					    struct drm_display_mode *fixed_mode);
> +void intel_drrs_enable(struct intel_dp *intel_dp,
> +		       const struct intel_crtc_state *crtc_state);
> +void intel_drrs_disable(struct intel_dp *intel_dp,
> +			const struct intel_crtc_state *crtc_state);
> +void intel_drrs_update(struct intel_dp *intel_dp,
> +		       const struct intel_crtc_state *crtc_state);
> +void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> +			   unsigned int frontbuffer_bits);
> +void intel_drrs_flush(struct drm_i915_private *dev_priv,
> +		      unsigned int frontbuffer_bits);
> +void intel_drrs_compute_config(struct intel_dp *intel_dp,
> +			       struct intel_crtc_state *pipe_config,
> +			       int output_bpp, bool constant_n);
> +struct drm_display_mode *intel_drrs_init(struct intel_connector *connector,
> +					 struct drm_display_mode *fixed_mode);
>  
>  #endif /* __INTEL_DRRS_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> index e4834d84ce5e3..0492446cd04ad 100644
> --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> @@ -92,7 +92,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
>  	trace_intel_frontbuffer_flush(frontbuffer_bits, origin);
>  
>  	might_sleep();
> -	intel_edp_drrs_flush(i915, frontbuffer_bits);
> +	intel_drrs_flush(i915, frontbuffer_bits);
>  	intel_psr_flush(i915, frontbuffer_bits, origin);
>  	intel_fbc_flush(i915, frontbuffer_bits, origin);
>  }
> @@ -181,7 +181,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
>  
>  	might_sleep();
>  	intel_psr_invalidate(i915, frontbuffer_bits, origin);
> -	intel_edp_drrs_invalidate(i915, frontbuffer_bits);
> +	intel_drrs_invalidate(i915, frontbuffer_bits);
>  	intel_fbc_invalidate(i915, frontbuffer_bits, origin);
>  }
>  
> -- 
> 2.33.0
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer
  2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
                   ` (10 preceding siblings ...)
  2021-08-25  1:33 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
@ 2021-08-25 15:57 ` Rodrigo Vivi
  11 siblings, 0 replies; 28+ messages in thread
From: Rodrigo Vivi @ 2021-08-25 15:57 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx, Gwan-gyeong Mun, Daniel Vetter

On Tue, Aug 24, 2021 at 05:58:32PM -0700, José Roberto de Souza wrote:
> This will break some IGT tests, here(https://patchwork.freedesktop.org/series/93764/)

Yeap, it broke. We need to fix that before we can really merge this.

> I fixed the ones part of fast-feedback test list but probably there
> will be more tests needing fix.
> 
> v2:
> - dropped a "drm/damage_helper" patch
> - new patch renaming all DRRS functions to intel_drrs_*()
> - enabling PSR support for display 9, it was left disabled as mistake
> - returning in frontbuffer functions to not set fb_tracking.busy/flip_bits
> 
> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> 
> José Roberto de Souza (8):
>   drm/i915/display: Drop PSR support from HSW and BDW
>   drm/i915/display: Move DRRS code its own file
>   drm/i915/display: Renaming DRRS functions to intel_drrs_*()
>   drm/i915/display: Some code improvements and code style fixes for DRRS
>   drm/i915/display: Share code between intel_drrs_flush and
>     intel_drrs_invalidate
>   drm/i915/display: Prepare DRRS for frontbuffer rendering drop
>   drm/i915/display/skl+: Drop frontbuffer rendering support
>   drm/i915/display: Drop PSR frontbuffer rendering support
> 
>  Documentation/gpu/i915.rst                    |  25 +-
>  drivers/gpu/drm/i915/Makefile                 |   1 +
>  drivers/gpu/drm/i915/display/intel_cursor.c   |   6 +-
>  drivers/gpu/drm/i915/display/intel_ddi.c      |   7 +-
>  drivers/gpu/drm/i915/display/intel_display.c  |   2 +
>  .../drm/i915/display/intel_display_debugfs.c  |   9 +-
>  .../drm/i915/display/intel_display_types.h    |   2 -
>  drivers/gpu/drm/i915/display/intel_dp.c       | 473 +-----------------
>  drivers/gpu/drm/i915/display/intel_dp.h       |  11 -
>  drivers/gpu/drm/i915/display/intel_drrs.c     | 450 +++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_drrs.h     |  36 ++
>  drivers/gpu/drm/i915/display/intel_fb.c       |   8 +-
>  .../gpu/drm/i915/display/intel_frontbuffer.c  |  25 +-
>  drivers/gpu/drm/i915/display/intel_psr.c      | 283 ++---------
>  drivers/gpu/drm/i915/display/intel_psr.h      |   8 +-
>  drivers/gpu/drm/i915/i915_drv.h               |   4 +-
>  drivers/gpu/drm/i915/i915_irq.c               |  16 -
>  drivers/gpu/drm/i915/i915_pci.c               |   4 +-
>  drivers/gpu/drm/i915/i915_reg.h               |  21 +-
>  19 files changed, 581 insertions(+), 810 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h
> 
> -- 
> 2.33.0
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file
  2021-08-25 15:55   ` Rodrigo Vivi
@ 2021-08-25 17:23     ` Souza, Jose
  2021-08-25 18:52       ` Rodrigo Vivi
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2021-08-25 17:23 UTC (permalink / raw)
  To: Vivi, Rodrigo; +Cc: Nikula, Jani, intel-gfx

On Wed, 2021-08-25 at 11:55 -0400, Rodrigo Vivi wrote:
> On Tue, Aug 24, 2021 at 05:58:34PM -0700, José Roberto de Souza wrote:
> > intel_dp.c is a 5k lines monster, so moving DRRS out of it to reduce
> > some lines from it.
> > 
> > Cc: Jani Nikula <jani.nikula@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  Documentation/gpu/i915.rst                    |  14 +-
> >  drivers/gpu/drm/i915/Makefile                 |   1 +
> >  drivers/gpu/drm/i915/display/intel_ddi.c      |   1 +
> >  .../drm/i915/display/intel_display_debugfs.c  |   1 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       | 467 +----------------
> >  drivers/gpu/drm/i915/display/intel_dp.h       |  11 -
> >  drivers/gpu/drm/i915/display/intel_drrs.c     | 477 ++++++++++++++++++
> >  drivers/gpu/drm/i915/display/intel_drrs.h     |  32 ++
> >  .../gpu/drm/i915/display/intel_frontbuffer.c  |   1 +
> >  9 files changed, 521 insertions(+), 484 deletions(-)
> >  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c
> >  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h
> > 
> > diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> > index 204ebdaadb45a..03021dfa0dd81 100644
> > --- a/Documentation/gpu/i915.rst
> > +++ b/Documentation/gpu/i915.rst
> > @@ -183,25 +183,25 @@ Frame Buffer Compression (FBC)
> >  Display Refresh Rate Switching (DRRS)
> >  -------------------------------------
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :doc: Display Refresh Rate Switching (DRRS)
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :functions: intel_dp_set_drrs_state
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :functions: intel_edp_drrs_enable
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :functions: intel_edp_drrs_disable
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :functions: intel_edp_drrs_invalidate
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :functions: intel_edp_drrs_flush
> >  
> > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> >     :functions: intel_dp_drrs_init
> >  
> >  DPIO
> > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > index fd997dfa5e32c..ee502a2354c44 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -213,6 +213,7 @@ i915-y += \
> >  	display/intel_dpll.o \
> >  	display/intel_dpll_mgr.o \
> >  	display/intel_dpt.o \
> > +	display/intel_drrs.o \
> >  	display/intel_dsb.o \
> >  	display/intel_fb.o \
> >  	display/intel_fbc.o \
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 1ef7a65feb660..828df570a4809 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -40,6 +40,7 @@
> >  #include "intel_dp_link_training.h"
> >  #include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> > +#include "intel_drrs.h"
> >  #include "intel_dsi.h"
> >  #include "intel_fdi.h"
> >  #include "intel_fifo_underrun.h"
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index 8fdacb252bb19..b136a0fc0963b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -13,6 +13,7 @@
> >  #include "intel_display_types.h"
> >  #include "intel_dmc.h"
> >  #include "intel_dp.h"
> > +#include "intel_drrs.h"
> >  #include "intel_fbc.h"
> >  #include "intel_hdcp.h"
> >  #include "intel_hdmi.h"
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index fd4f7e82e4205..965b888e0e771 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -55,6 +55,7 @@
> >  #include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> >  #include "intel_dpll.h"
> > +#include "intel_drrs.h"
> >  #include "intel_fifo_underrun.h"
> >  #include "intel_hdcp.h"
> >  #include "intel_hdmi.h"
> > @@ -1675,46 +1676,6 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
> >  		intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
> >  }
> >  
> > -static void
> > -intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> > -			     struct intel_crtc_state *pipe_config,
> > -			     int output_bpp, bool constant_n)
> > -{
> > -	struct intel_connector *intel_connector = intel_dp->attached_connector;
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -	int pixel_clock;
> > -
> > -	if (pipe_config->vrr.enable)
> > -		return;
> > -
> > -	/*
> > -	 * DRRS and PSR can't be enable together, so giving preference to PSR
> > -	 * as it allows more power-savings by complete shutting down display,
> > -	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> > -	 * after intel_psr_compute_config().
> > -	 */
> > -	if (pipe_config->has_psr)
> > -		return;
> > -
> > -	if (!intel_connector->panel.downclock_mode ||
> > -	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > -		return;
> > -
> > -	pipe_config->has_drrs = true;
> > -
> > -	pixel_clock = intel_connector->panel.downclock_mode->clock;
> > -	if (pipe_config->splitter.enable)
> > -		pixel_clock /= pipe_config->splitter.link_count;
> > -
> > -	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
> > -			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
> > -			       constant_n, pipe_config->fec_enable);
> > -
> > -	/* FIXME: abstract this better */
> > -	if (pipe_config->splitter.enable)
> > -		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
> > -}
> > -
> >  int
> >  intel_dp_compute_config(struct intel_encoder *encoder,
> >  			struct intel_crtc_state *pipe_config,
> > @@ -4785,432 +4746,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
> >  		drm_connector_attach_vrr_capable_property(connector);
> >  }
> >  
> > -/**
> > - * intel_dp_set_drrs_state - program registers for RR switch to take effect
> > - * @dev_priv: i915 device
> > - * @crtc_state: a pointer to the active intel_crtc_state
> > - * @refresh_rate: RR to be programmed
> 
> I know it was already here...
> 
> > - *
> > - * This function gets called when refresh rate (RR) has to be changed from
> > - * one frequency to another. Switches can be between high and low RR
> > - * supported by the panel or to any other RR based on media playback (in
> > - * this case, RR value needs to be passed from user space).
> > - *
> > - * The caller of this function needs to take a lock on dev_priv->drrs.
> > - */
> > -static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> > -				    const struct intel_crtc_state *crtc_state,
> > -				    int refresh_rate)
> > -{
> > -	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> > -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > -	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> > -
> > -	if (refresh_rate <= 0) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "Refresh rate should be positive non-zero.\n");
> > -		return;
> > -	}
> > -
> > -	if (intel_dp == NULL) {
> > -		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> > -		return;
> > -	}
> > -
> > -	if (!crtc) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "DRRS: intel_crtc not initialized\n");
> > -		return;
> > -	}
> > -
> > -	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
> > -		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
> > -		return;
> > -	}
> > -
> > -	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> > -			refresh_rate)
> > -		index = DRRS_LOW_RR;
> > -
> > -	if (index == dev_priv->drrs.refresh_rate_type) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "DRRS requested for previously set RR...ignoring\n");
> > -		return;
> > -	}
> > -
> > -	if (!crtc_state->hw.active) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "eDP encoder disabled. CRTC not Active\n");
> > -		return;
> > -	}
> > -
> > -	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> > -		switch (index) {
> > -		case DRRS_HIGH_RR:
> > -			intel_dp_set_m_n(crtc_state, M1_N1);
> > -			break;
> > -		case DRRS_LOW_RR:
> > -			intel_dp_set_m_n(crtc_state, M2_N2);
> > -			break;
> > -		case DRRS_MAX_RR:
> > -		default:
> > -			drm_err(&dev_priv->drm,
> > -				"Unsupported refreshrate type\n");
> > -		}
> > -	} else if (DISPLAY_VER(dev_priv) > 6) {
> > -		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
> > -		u32 val;
> > -
> > -		val = intel_de_read(dev_priv, reg);
> > -		if (index > DRRS_HIGH_RR) {
> > -			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > -				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > -			else
> > -				val |= PIPECONF_EDP_RR_MODE_SWITCH;
> > -		} else {
> > -			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > -				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > -			else
> > -				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
> > -		}
> > -		intel_de_write(dev_priv, reg, val);
> > -	}
> > -
> > -	dev_priv->drrs.refresh_rate_type = index;
> > -
> > -	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> > -		    refresh_rate);
> > -}
> > -
> > -static void
> > -intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> > -{
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> > -	dev_priv->drrs.busy_frontbuffer_bits = 0;
> > -	dev_priv->drrs.dp = intel_dp;
> > -}
> > -
> > -/**
> > - * intel_edp_drrs_enable - init drrs struct if supported
> > - * @intel_dp: DP struct
> > - * @crtc_state: A pointer to the active crtc state.
> > - *
> > - * Initializes frontbuffer_bits and drrs.dp
> > - */
> > -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > -			   const struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> > -	if (!crtc_state->has_drrs)
> > -		return;
> > -
> > -	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -
> > -	if (dev_priv->drrs.dp) {
> > -		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
> > -		goto unlock;
> > -	}
> > -
> > -	intel_edp_drrs_enable_locked(intel_dp);
> > -
> > -unlock:
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > -}
> > -
> > -static void
> > -intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> > -			      const struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> > -	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> > -		int refresh;
> > -
> > -		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> > -		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> > -	}
> > -
> > -	dev_priv->drrs.dp = NULL;
> > -}
> > -
> > -/**
> > - * intel_edp_drrs_disable - Disable DRRS
> > - * @intel_dp: DP struct
> > - * @old_crtc_state: Pointer to old crtc_state.
> > - *
> > - */
> > -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > -			    const struct intel_crtc_state *old_crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> > -	if (!old_crtc_state->has_drrs)
> > -		return;
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -	if (!dev_priv->drrs.dp) {
> > -		mutex_unlock(&dev_priv->drrs.mutex);
> > -		return;
> > -	}
> > -
> > -	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > -
> > -	cancel_delayed_work_sync(&dev_priv->drrs.work);
> > -}
> > -
> > -/**
> > - * intel_edp_drrs_update - Update DRRS state
> > - * @intel_dp: Intel DP
> > - * @crtc_state: new CRTC state
> > - *
> > - * This function will update DRRS states, disabling or enabling DRRS when
> > - * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> > - * intel_edp_drrs_enable() should be called instead.
> > - */
> > -void
> > -intel_edp_drrs_update(struct intel_dp *intel_dp,
> > -		      const struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> > -	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > -		return;
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -
> > -	/* New state matches current one? */
> > -	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
> > -		goto unlock;
> > -
> > -	if (crtc_state->has_drrs)
> > -		intel_edp_drrs_enable_locked(intel_dp);
> > -	else
> > -		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> > -
> > -unlock:
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > -}
> > -
> > -static void intel_edp_drrs_downclock_work(struct work_struct *work)
> > -{
> > -	struct drm_i915_private *dev_priv =
> > -		container_of(work, typeof(*dev_priv), drrs.work.work);
> > -	struct intel_dp *intel_dp;
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -
> > -	intel_dp = dev_priv->drrs.dp;
> > -
> > -	if (!intel_dp)
> > -		goto unlock;
> > -
> > -	/*
> > -	 * The delayed work can race with an invalidate hence we need to
> > -	 * recheck.
> > -	 */
> > -
> > -	if (dev_priv->drrs.busy_frontbuffer_bits)
> > -		goto unlock;
> > -
> > -	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> > -		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > -
> > -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > -			drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> > -	}
> > -
> > -unlock:
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > -}
> > -
> > -/**
> > - * intel_edp_drrs_invalidate - Disable Idleness DRRS
> > - * @dev_priv: i915 device
> > - * @frontbuffer_bits: frontbuffer plane tracking bits
> > - *
> > - * This function gets called everytime rendering on the given planes start.
> > - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> > - *
> > - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > - */
> > -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > -			       unsigned int frontbuffer_bits)
> > -{
> > -	struct intel_dp *intel_dp;
> > -	struct drm_crtc *crtc;
> > -	enum pipe pipe;
> > -
> > -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > -		return;
> > -
> > -	cancel_delayed_work(&dev_priv->drrs.work);
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -
> > -	intel_dp = dev_priv->drrs.dp;
> > -	if (!intel_dp) {
> > -		mutex_unlock(&dev_priv->drrs.mutex);
> > -		return;
> > -	}
> > -
> > -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > -	pipe = to_intel_crtc(crtc)->pipe;
> > -
> > -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > -	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> > -
> > -	/* invalidate means busy screen hence upclock */
> > -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > -
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > -}
> > -
> > -/**
> > - * intel_edp_drrs_flush - Restart Idleness DRRS
> > - * @dev_priv: i915 device
> > - * @frontbuffer_bits: frontbuffer plane tracking bits
> > - *
> > - * This function gets called every time rendering on the given planes has
> > - * completed or flip on a crtc is completed. So DRRS should be upclocked
> > - * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
> > - * if no other planes are dirty.
> > - *
> > - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > - */
> > -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > -			  unsigned int frontbuffer_bits)
> > -{
> > -	struct intel_dp *intel_dp;
> > -	struct drm_crtc *crtc;
> > -	enum pipe pipe;
> > -
> > -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > -		return;
> > -
> > -	cancel_delayed_work(&dev_priv->drrs.work);
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -
> > -	intel_dp = dev_priv->drrs.dp;
> > -	if (!intel_dp) {
> > -		mutex_unlock(&dev_priv->drrs.mutex);
> > -		return;
> > -	}
> > -
> > -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > -	pipe = to_intel_crtc(crtc)->pipe;
> > -
> > -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > -	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> > -
> > -	/* flush means busy screen hence upclock */
> > -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > -
> > -	/*
> > -	 * flush also means no more activity hence schedule downclock, if all
> > -	 * other fbs are quiescent too
> > -	 */
> > -	if (!dev_priv->drrs.busy_frontbuffer_bits)
> > -		schedule_delayed_work(&dev_priv->drrs.work,
> > -				msecs_to_jiffies(1000));
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > -}
> > -
> > -/**
> > - * DOC: Display Refresh Rate Switching (DRRS)
> > - *
> > - * Display Refresh Rate Switching (DRRS) is a power conservation feature
> > - * which enables swtching between low and high refresh rates,
> > - * dynamically, based on the usage scenario. This feature is applicable
> > - * for internal panels.
> > - *
> > - * Indication that the panel supports DRRS is given by the panel EDID, which
> > - * would list multiple refresh rates for one resolution.
> > - *
> > - * DRRS is of 2 types - static and seamless.
> > - * Static DRRS involves changing refresh rate (RR) by doing a full modeset
> > - * (may appear as a blink on screen) and is used in dock-undock scenario.
> > - * Seamless DRRS involves changing RR without any visual effect to the user
> > - * and can be used during normal system usage. This is done by programming
> > - * certain registers.
> > - *
> > - * Support for static/seamless DRRS may be indicated in the VBT based on
> > - * inputs from the panel spec.
> > - *
> > - * DRRS saves power by switching to low RR based on usage scenarios.
> > - *
> > - * The implementation is based on frontbuffer tracking implementation.  When
> > - * there is a disturbance on the screen triggered by user activity or a periodic
> > - * system activity, DRRS is disabled (RR is changed to high RR).  When there is
> > - * no movement on screen, after a timeout of 1 second, a switch to low RR is
> > - * made.
> > - *
> > - * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> > - * and intel_edp_drrs_flush() are called.
> > - *
> > - * DRRS can be further extended to support other internal panels and also
> > - * the scenario of video playback wherein RR is set based on the rate
> > - * requested by userspace.
> > - */
> > -
> > -/**
> > - * intel_dp_drrs_init - Init basic DRRS work and mutex.
> > - * @connector: eDP connector
> > - * @fixed_mode: preferred mode of panel
> > - *
> > - * This function is  called only once at driver load to initialize basic
> > - * DRRS stuff.
> > - *
> > - * Returns:
> > - * Downclock mode if panel supports it, else return NULL.
> > - * DRRS support is determined by the presence of downclock mode (apart
> > - * from VBT setting).
> > - */
> > -static struct drm_display_mode *
> > -intel_dp_drrs_init(struct intel_connector *connector,
> > -		   struct drm_display_mode *fixed_mode)
> > -{
> > -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > -	struct drm_display_mode *downclock_mode = NULL;
> > -
> > -	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> > -	mutex_init(&dev_priv->drrs.mutex);
> > -
> > -	if (DISPLAY_VER(dev_priv) <= 6) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "DRRS supported for Gen7 and above\n");
> > -		return NULL;
> > -	}
> > -
> > -	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
> > -		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
> > -		return NULL;
> > -	}
> > -
> > -	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
> > -	if (!downclock_mode) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "Downclock mode is not found. DRRS not supported\n");
> > -		return NULL;
> > -	}
> > -
> > -	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
> > -
> > -	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
> > -	drm_dbg_kms(&dev_priv->drm,
> > -		    "seamless DRRS supported for eDP panel.\n");
> > -	return downclock_mode;
> > -}
> > -
> >  static bool intel_edp_init_connector(struct intel_dp *intel_dp,
> >  				     struct intel_connector *intel_connector)
> >  {
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> > index ae0f776bffab8..a28fff286c21a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> > @@ -70,17 +70,6 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp);
> >  int intel_dp_max_lane_count(struct intel_dp *intel_dp);
> >  int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
> >  
> > -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > -			   const struct intel_crtc_state *crtc_state);
> > -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > -			    const struct intel_crtc_state *crtc_state);
> > -void intel_edp_drrs_update(struct intel_dp *intel_dp,
> > -			   const struct intel_crtc_state *crtc_state);
> > -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > -			       unsigned int frontbuffer_bits);
> > -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > -			  unsigned int frontbuffer_bits);
> > -
> >  void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
> >  			   u8 *link_bw, u8 *rate_select);
> >  bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> > new file mode 100644
> > index 0000000000000..be9b6d4482f04
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> > @@ -0,0 +1,477 @@
> > +// SPDX-License-Identifier: MIT
> > +/*
> > + * Copyright © 2021 Intel Corporation
> > + */
> > +
> > +#include "i915_drv.h"
> > +#include "intel_atomic.h"
> > +#include "intel_de.h"
> > +#include "intel_display_types.h"
> > +#include "intel_drrs.h"
> > +#include "intel_panel.h"
> > +
> > +/**
> > + * DOC: Display Refresh Rate Switching (DRRS)
> > + *
> > + * Display Refresh Rate Switching (DRRS) is a power conservation feature
> > + * which enables swtching between low and high refresh rates,
> > + * dynamically, based on the usage scenario. This feature is applicable
> > + * for internal panels.
> > + *
> > + * Indication that the panel supports DRRS is given by the panel EDID, which
> > + * would list multiple refresh rates for one resolution.
> > + *
> > + * DRRS is of 2 types - static and seamless.
> > + * Static DRRS involves changing refresh rate (RR) by doing a full modeset
> > + * (may appear as a blink on screen) and is used in dock-undock scenario.
> > + * Seamless DRRS involves changing RR without any visual effect to the user
> > + * and can be used during normal system usage. This is done by programming
> > + * certain registers.
> > + *
> > + * Support for static/seamless DRRS may be indicated in the VBT based on
> > + * inputs from the panel spec.
> > + *
> > + * DRRS saves power by switching to low RR based on usage scenarios.
> > + *
> > + * The implementation is based on frontbuffer tracking implementation.  When
> > + * there is a disturbance on the screen triggered by user activity or a periodic
> > + * system activity, DRRS is disabled (RR is changed to high RR).  When there is
> > + * no movement on screen, after a timeout of 1 second, a switch to low RR is
> > + * made.
> > + *
> > + * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> > + * and intel_edp_drrs_flush() are called.
> > + *
> > + * DRRS can be further extended to support other internal panels and also
> > + * the scenario of video playback wherein RR is set based on the rate
> > + * requested by userspace.
> > + */
> > +
> > +void
> > +intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> > +			     struct intel_crtc_state *pipe_config,
> > +			     int output_bpp, bool constant_n)
> > +{
> > +	struct intel_connector *intel_connector = intel_dp->attached_connector;
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +	int pixel_clock;
> > +
> > +	if (pipe_config->vrr.enable)
> > +		return;
> > +
> > +	/*
> > +	 * DRRS and PSR can't be enable together, so giving preference to PSR
> > +	 * as it allows more power-savings by complete shutting down display,
> > +	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> > +	 * after intel_psr_compute_config().
> > +	 */
> > +	if (pipe_config->has_psr)
> > +		return;
> > +
> > +	if (!intel_connector->panel.downclock_mode ||
> > +	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > +		return;
> > +
> > +	pipe_config->has_drrs = true;
> > +
> > +	pixel_clock = intel_connector->panel.downclock_mode->clock;
> > +	if (pipe_config->splitter.enable)
> > +		pixel_clock /= pipe_config->splitter.link_count;
> > +
> > +	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
> > +			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
> > +			       constant_n, pipe_config->fec_enable);
> > +
> > +	/* FIXME: abstract this better */
> > +	if (pipe_config->splitter.enable)
> > +		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
> > +}
> > +
> > +/**
> > + * intel_dp_set_drrs_state - program registers for RR switch to take effect
> > + * @dev_priv: i915 device
> > + * @crtc_state: a pointer to the active intel_crtc_state
> > + * @refresh_rate: RR to be programmed
> 
> ... but let's enjoy the opportunity and avoid doc style in static functions
> that should never be called outside this block.

Did that in the next patch, while renaming functions.
Is that fine? Or it should be removed in this one?

thanks for the reviews

> 
> with this addressed feel free to use:
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> > + *
> > + * This function gets called when refresh rate (RR) has to be changed from
> > + * one frequency to another. Switches can be between high and low RR
> > + * supported by the panel or to any other RR based on media playback (in
> > + * this case, RR value needs to be passed from user space).
> > + *
> > + * The caller of this function needs to take a lock on dev_priv->drrs.
> > + */
> > +static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> > +				    const struct intel_crtc_state *crtc_state,
> > +				    int refresh_rate)
> > +{
> > +	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > +	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> > +
> > +	if (refresh_rate <= 0) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "Refresh rate should be positive non-zero.\n");
> > +		return;
> > +	}
> > +
> > +	if (intel_dp == NULL) {
> > +		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> > +		return;
> > +	}
> > +
> > +	if (!crtc) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "DRRS: intel_crtc not initialized\n");
> > +		return;
> > +	}
> > +
> > +	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
> > +		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
> > +		return;
> > +	}
> > +
> > +	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> > +			refresh_rate)
> > +		index = DRRS_LOW_RR;
> > +
> > +	if (index == dev_priv->drrs.refresh_rate_type) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "DRRS requested for previously set RR...ignoring\n");
> > +		return;
> > +	}
> > +
> > +	if (!crtc_state->hw.active) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "eDP encoder disabled. CRTC not Active\n");
> > +		return;
> > +	}
> > +
> > +	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> > +		switch (index) {
> > +		case DRRS_HIGH_RR:
> > +			intel_dp_set_m_n(crtc_state, M1_N1);
> > +			break;
> > +		case DRRS_LOW_RR:
> > +			intel_dp_set_m_n(crtc_state, M2_N2);
> > +			break;
> > +		case DRRS_MAX_RR:
> > +		default:
> > +			drm_err(&dev_priv->drm,
> > +				"Unsupported refreshrate type\n");
> > +		}
> > +	} else if (DISPLAY_VER(dev_priv) > 6) {
> > +		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
> > +		u32 val;
> > +
> > +		val = intel_de_read(dev_priv, reg);
> > +		if (index > DRRS_HIGH_RR) {
> > +			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > +				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > +			else
> > +				val |= PIPECONF_EDP_RR_MODE_SWITCH;
> > +		} else {
> > +			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > +				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > +			else
> > +				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
> > +		}
> > +		intel_de_write(dev_priv, reg, val);
> > +	}
> > +
> > +	dev_priv->drrs.refresh_rate_type = index;
> > +
> > +	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> > +		    refresh_rate);
> > +}
> > +
> > +static void
> > +intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> > +{
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> > +	dev_priv->drrs.busy_frontbuffer_bits = 0;
> > +	dev_priv->drrs.dp = intel_dp;
> > +}
> > +
> > +/**
> > + * intel_edp_drrs_enable - init drrs struct if supported
> > + * @intel_dp: DP struct
> > + * @crtc_state: A pointer to the active crtc state.
> > + *
> > + * Initializes frontbuffer_bits and drrs.dp
> > + */
> > +void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > +			   const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> > +	if (!crtc_state->has_drrs)
> > +		return;
> > +
> > +	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
> > +
> > +	mutex_lock(&dev_priv->drrs.mutex);
> > +
> > +	if (dev_priv->drrs.dp) {
> > +		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
> > +		goto unlock;
> > +	}
> > +
> > +	intel_edp_drrs_enable_locked(intel_dp);
> > +
> > +unlock:
> > +	mutex_unlock(&dev_priv->drrs.mutex);
> > +}
> > +
> > +static void
> > +intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> > +			      const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> > +	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> > +		int refresh;
> > +
> > +		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> > +		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> > +	}
> > +
> > +	dev_priv->drrs.dp = NULL;
> > +}
> > +
> > +/**
> > + * intel_edp_drrs_disable - Disable DRRS
> > + * @intel_dp: DP struct
> > + * @old_crtc_state: Pointer to old crtc_state.
> > + *
> > + */
> > +void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > +			    const struct intel_crtc_state *old_crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> > +	if (!old_crtc_state->has_drrs)
> > +		return;
> > +
> > +	mutex_lock(&dev_priv->drrs.mutex);
> > +	if (!dev_priv->drrs.dp) {
> > +		mutex_unlock(&dev_priv->drrs.mutex);
> > +		return;
> > +	}
> > +
> > +	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> > +	mutex_unlock(&dev_priv->drrs.mutex);
> > +
> > +	cancel_delayed_work_sync(&dev_priv->drrs.work);
> > +}
> > +
> > +/**
> > + * intel_edp_drrs_update - Update DRRS state
> > + * @intel_dp: Intel DP
> > + * @crtc_state: new CRTC state
> > + *
> > + * This function will update DRRS states, disabling or enabling DRRS when
> > + * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> > + * intel_edp_drrs_enable() should be called instead.
> > + */
> > +void
> > +intel_edp_drrs_update(struct intel_dp *intel_dp,
> > +		      const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +
> > +	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > +		return;
> > +
> > +	mutex_lock(&dev_priv->drrs.mutex);
> > +
> > +	/* New state matches current one? */
> > +	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
> > +		goto unlock;
> > +
> > +	if (crtc_state->has_drrs)
> > +		intel_edp_drrs_enable_locked(intel_dp);
> > +	else
> > +		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> > +
> > +unlock:
> > +	mutex_unlock(&dev_priv->drrs.mutex);
> > +}
> > +
> > +static void intel_edp_drrs_downclock_work(struct work_struct *work)
> > +{
> > +	struct drm_i915_private *dev_priv =
> > +		container_of(work, typeof(*dev_priv), drrs.work.work);
> > +	struct intel_dp *intel_dp;
> > +
> > +	mutex_lock(&dev_priv->drrs.mutex);
> > +
> > +	intel_dp = dev_priv->drrs.dp;
> > +
> > +	if (!intel_dp)
> > +		goto unlock;
> > +
> > +	/*
> > +	 * The delayed work can race with an invalidate hence we need to
> > +	 * recheck.
> > +	 */
> > +
> > +	if (dev_priv->drrs.busy_frontbuffer_bits)
> > +		goto unlock;
> > +
> > +	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> > +		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > +
> > +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > +					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> > +	}
> > +
> > +unlock:
> > +	mutex_unlock(&dev_priv->drrs.mutex);
> > +}
> > +
> > +/**
> > + * intel_edp_drrs_invalidate - Disable Idleness DRRS
> > + * @dev_priv: i915 device
> > + * @frontbuffer_bits: frontbuffer plane tracking bits
> > + *
> > + * This function gets called everytime rendering on the given planes start.
> > + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> > + *
> > + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > + */
> > +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > +			       unsigned int frontbuffer_bits)
> > +{
> > +	struct intel_dp *intel_dp;
> > +	struct drm_crtc *crtc;
> > +	enum pipe pipe;
> > +
> > +	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > +		return;
> > +
> > +	cancel_delayed_work(&dev_priv->drrs.work);
> > +
> > +	mutex_lock(&dev_priv->drrs.mutex);
> > +
> > +	intel_dp = dev_priv->drrs.dp;
> > +	if (!intel_dp) {
> > +		mutex_unlock(&dev_priv->drrs.mutex);
> > +		return;
> > +	}
> > +
> > +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > +	pipe = to_intel_crtc(crtc)->pipe;
> > +
> > +	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > +	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> > +
> > +	/* invalidate means busy screen hence upclock */
> > +	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > +					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > +
> > +	mutex_unlock(&dev_priv->drrs.mutex);
> > +}
> > +
> > +/**
> > + * intel_edp_drrs_flush - Restart Idleness DRRS
> > + * @dev_priv: i915 device
> > + * @frontbuffer_bits: frontbuffer plane tracking bits
> > + *
> > + * This function gets called every time rendering on the given planes has
> > + * completed or flip on a crtc is completed. So DRRS should be upclocked
> > + * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
> > + * if no other planes are dirty.
> > + *
> > + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > + */
> > +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > +			  unsigned int frontbuffer_bits)
> > +{
> > +	struct intel_dp *intel_dp;
> > +	struct drm_crtc *crtc;
> > +	enum pipe pipe;
> > +
> > +	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > +		return;
> > +
> > +	cancel_delayed_work(&dev_priv->drrs.work);
> > +
> > +	mutex_lock(&dev_priv->drrs.mutex);
> > +
> > +	intel_dp = dev_priv->drrs.dp;
> > +	if (!intel_dp) {
> > +		mutex_unlock(&dev_priv->drrs.mutex);
> > +		return;
> > +	}
> > +
> > +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > +	pipe = to_intel_crtc(crtc)->pipe;
> > +
> > +	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > +	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> > +
> > +	/* flush means busy screen hence upclock */
> > +	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > +					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > +
> > +	/*
> > +	 * flush also means no more activity hence schedule downclock, if all
> > +	 * other fbs are quiescent too
> > +	 */
> > +	if (!dev_priv->drrs.busy_frontbuffer_bits)
> > +		schedule_delayed_work(&dev_priv->drrs.work,
> > +				      msecs_to_jiffies(1000));
> > +	mutex_unlock(&dev_priv->drrs.mutex);
> > +}
> > +
> > +/**
> > + * intel_dp_drrs_init - Init basic DRRS work and mutex.
> > + * @connector: eDP connector
> > + * @fixed_mode: preferred mode of panel
> > + *
> > + * This function is  called only once at driver load to initialize basic
> > + * DRRS stuff.
> > + *
> > + * Returns:
> > + * Downclock mode if panel supports it, else return NULL.
> > + * DRRS support is determined by the presence of downclock mode (apart
> > + * from VBT setting).
> > + */
> > +struct drm_display_mode *
> > +intel_dp_drrs_init(struct intel_connector *connector,
> > +		   struct drm_display_mode *fixed_mode)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > +	struct drm_display_mode *downclock_mode = NULL;
> > +
> > +	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> > +	mutex_init(&dev_priv->drrs.mutex);
> > +
> > +	if (DISPLAY_VER(dev_priv) <= 6) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "DRRS supported for Gen7 and above\n");
> > +		return NULL;
> > +	}
> > +
> > +	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
> > +		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
> > +		return NULL;
> > +	}
> > +
> > +	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
> > +	if (!downclock_mode) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "Downclock mode is not found. DRRS not supported\n");
> > +		return NULL;
> > +	}
> > +
> > +	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
> > +
> > +	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
> > +	drm_dbg_kms(&dev_priv->drm,
> > +		    "seamless DRRS supported for eDP panel.\n");
> > +	return downclock_mode;
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
> > new file mode 100644
> > index 0000000000000..ffa175b4cf4f4
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/display/intel_drrs.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright © 2021 Intel Corporation
> > + */
> > +
> > +#ifndef __INTEL_DRRS_H__
> > +#define __INTEL_DRRS_H__
> > +
> > +#include <linux/types.h>
> > +
> > +struct drm_i915_private;
> > +struct intel_crtc_state;
> > +struct intel_connector;
> > +struct intel_dp;
> > +
> > +void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > +			   const struct intel_crtc_state *crtc_state);
> > +void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > +			    const struct intel_crtc_state *crtc_state);
> > +void intel_edp_drrs_update(struct intel_dp *intel_dp,
> > +			   const struct intel_crtc_state *crtc_state);
> > +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > +			       unsigned int frontbuffer_bits);
> > +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > +			  unsigned int frontbuffer_bits);
> > +void intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> > +				  struct intel_crtc_state *pipe_config,
> > +				  int output_bpp, bool constant_n);
> > +struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector,
> > +					    struct drm_display_mode *fixed_mode);
> > +
> > +#endif /* __INTEL_DRRS_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > index 8e75debcce1a9..e4834d84ce5e3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > @@ -62,6 +62,7 @@
> >  #include "intel_display_types.h"
> >  #include "intel_fbc.h"
> >  #include "intel_frontbuffer.h"
> > +#include "intel_drrs.h"
> >  #include "intel_psr.h"
> >  
> >  /**
> > -- 
> > 2.33.0
> > 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file
  2021-08-25 17:23     ` Souza, Jose
@ 2021-08-25 18:52       ` Rodrigo Vivi
  0 siblings, 0 replies; 28+ messages in thread
From: Rodrigo Vivi @ 2021-08-25 18:52 UTC (permalink / raw)
  To: Souza, Jose; +Cc: Nikula, Jani, intel-gfx

On Wed, Aug 25, 2021 at 05:23:35PM +0000, Souza, Jose wrote:
> On Wed, 2021-08-25 at 11:55 -0400, Rodrigo Vivi wrote:
> > On Tue, Aug 24, 2021 at 05:58:34PM -0700, José Roberto de Souza wrote:
> > > intel_dp.c is a 5k lines monster, so moving DRRS out of it to reduce
> > > some lines from it.
> > > 
> > > Cc: Jani Nikula <jani.nikula@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  Documentation/gpu/i915.rst                    |  14 +-
> > >  drivers/gpu/drm/i915/Makefile                 |   1 +
> > >  drivers/gpu/drm/i915/display/intel_ddi.c      |   1 +
> > >  .../drm/i915/display/intel_display_debugfs.c  |   1 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c       | 467 +----------------
> > >  drivers/gpu/drm/i915/display/intel_dp.h       |  11 -
> > >  drivers/gpu/drm/i915/display/intel_drrs.c     | 477 ++++++++++++++++++
> > >  drivers/gpu/drm/i915/display/intel_drrs.h     |  32 ++
> > >  .../gpu/drm/i915/display/intel_frontbuffer.c  |   1 +
> > >  9 files changed, 521 insertions(+), 484 deletions(-)
> > >  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c
> > >  create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h
> > > 
> > > diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> > > index 204ebdaadb45a..03021dfa0dd81 100644
> > > --- a/Documentation/gpu/i915.rst
> > > +++ b/Documentation/gpu/i915.rst
> > > @@ -183,25 +183,25 @@ Frame Buffer Compression (FBC)
> > >  Display Refresh Rate Switching (DRRS)
> > >  -------------------------------------
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :doc: Display Refresh Rate Switching (DRRS)
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :functions: intel_dp_set_drrs_state
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :functions: intel_edp_drrs_enable
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :functions: intel_edp_drrs_disable
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :functions: intel_edp_drrs_invalidate
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :functions: intel_edp_drrs_flush
> > >  
> > > -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
> > > +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
> > >     :functions: intel_dp_drrs_init
> > >  
> > >  DPIO
> > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > > index fd997dfa5e32c..ee502a2354c44 100644
> > > --- a/drivers/gpu/drm/i915/Makefile
> > > +++ b/drivers/gpu/drm/i915/Makefile
> > > @@ -213,6 +213,7 @@ i915-y += \
> > >  	display/intel_dpll.o \
> > >  	display/intel_dpll_mgr.o \
> > >  	display/intel_dpt.o \
> > > +	display/intel_drrs.o \
> > >  	display/intel_dsb.o \
> > >  	display/intel_fb.o \
> > >  	display/intel_fbc.o \
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index 1ef7a65feb660..828df570a4809 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -40,6 +40,7 @@
> > >  #include "intel_dp_link_training.h"
> > >  #include "intel_dp_mst.h"
> > >  #include "intel_dpio_phy.h"
> > > +#include "intel_drrs.h"
> > >  #include "intel_dsi.h"
> > >  #include "intel_fdi.h"
> > >  #include "intel_fifo_underrun.h"
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > index 8fdacb252bb19..b136a0fc0963b 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > @@ -13,6 +13,7 @@
> > >  #include "intel_display_types.h"
> > >  #include "intel_dmc.h"
> > >  #include "intel_dp.h"
> > > +#include "intel_drrs.h"
> > >  #include "intel_fbc.h"
> > >  #include "intel_hdcp.h"
> > >  #include "intel_hdmi.h"
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index fd4f7e82e4205..965b888e0e771 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -55,6 +55,7 @@
> > >  #include "intel_dp_mst.h"
> > >  #include "intel_dpio_phy.h"
> > >  #include "intel_dpll.h"
> > > +#include "intel_drrs.h"
> > >  #include "intel_fifo_underrun.h"
> > >  #include "intel_hdcp.h"
> > >  #include "intel_hdmi.h"
> > > @@ -1675,46 +1676,6 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
> > >  		intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
> > >  }
> > >  
> > > -static void
> > > -intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> > > -			     struct intel_crtc_state *pipe_config,
> > > -			     int output_bpp, bool constant_n)
> > > -{
> > > -	struct intel_connector *intel_connector = intel_dp->attached_connector;
> > > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > -	int pixel_clock;
> > > -
> > > -	if (pipe_config->vrr.enable)
> > > -		return;
> > > -
> > > -	/*
> > > -	 * DRRS and PSR can't be enable together, so giving preference to PSR
> > > -	 * as it allows more power-savings by complete shutting down display,
> > > -	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> > > -	 * after intel_psr_compute_config().
> > > -	 */
> > > -	if (pipe_config->has_psr)
> > > -		return;
> > > -
> > > -	if (!intel_connector->panel.downclock_mode ||
> > > -	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > > -		return;
> > > -
> > > -	pipe_config->has_drrs = true;
> > > -
> > > -	pixel_clock = intel_connector->panel.downclock_mode->clock;
> > > -	if (pipe_config->splitter.enable)
> > > -		pixel_clock /= pipe_config->splitter.link_count;
> > > -
> > > -	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
> > > -			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
> > > -			       constant_n, pipe_config->fec_enable);
> > > -
> > > -	/* FIXME: abstract this better */
> > > -	if (pipe_config->splitter.enable)
> > > -		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
> > > -}
> > > -
> > >  int
> > >  intel_dp_compute_config(struct intel_encoder *encoder,
> > >  			struct intel_crtc_state *pipe_config,
> > > @@ -4785,432 +4746,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
> > >  		drm_connector_attach_vrr_capable_property(connector);
> > >  }
> > >  
> > > -/**
> > > - * intel_dp_set_drrs_state - program registers for RR switch to take effect
> > > - * @dev_priv: i915 device
> > > - * @crtc_state: a pointer to the active intel_crtc_state
> > > - * @refresh_rate: RR to be programmed
> > 
> > I know it was already here...
> > 
> > > - *
> > > - * This function gets called when refresh rate (RR) has to be changed from
> > > - * one frequency to another. Switches can be between high and low RR
> > > - * supported by the panel or to any other RR based on media playback (in
> > > - * this case, RR value needs to be passed from user space).
> > > - *
> > > - * The caller of this function needs to take a lock on dev_priv->drrs.
> > > - */
> > > -static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> > > -				    const struct intel_crtc_state *crtc_state,
> > > -				    int refresh_rate)
> > > -{
> > > -	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> > > -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > -	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> > > -
> > > -	if (refresh_rate <= 0) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "Refresh rate should be positive non-zero.\n");
> > > -		return;
> > > -	}
> > > -
> > > -	if (intel_dp == NULL) {
> > > -		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> > > -		return;
> > > -	}
> > > -
> > > -	if (!crtc) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "DRRS: intel_crtc not initialized\n");
> > > -		return;
> > > -	}
> > > -
> > > -	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
> > > -		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
> > > -		return;
> > > -	}
> > > -
> > > -	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> > > -			refresh_rate)
> > > -		index = DRRS_LOW_RR;
> > > -
> > > -	if (index == dev_priv->drrs.refresh_rate_type) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "DRRS requested for previously set RR...ignoring\n");
> > > -		return;
> > > -	}
> > > -
> > > -	if (!crtc_state->hw.active) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "eDP encoder disabled. CRTC not Active\n");
> > > -		return;
> > > -	}
> > > -
> > > -	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> > > -		switch (index) {
> > > -		case DRRS_HIGH_RR:
> > > -			intel_dp_set_m_n(crtc_state, M1_N1);
> > > -			break;
> > > -		case DRRS_LOW_RR:
> > > -			intel_dp_set_m_n(crtc_state, M2_N2);
> > > -			break;
> > > -		case DRRS_MAX_RR:
> > > -		default:
> > > -			drm_err(&dev_priv->drm,
> > > -				"Unsupported refreshrate type\n");
> > > -		}
> > > -	} else if (DISPLAY_VER(dev_priv) > 6) {
> > > -		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
> > > -		u32 val;
> > > -
> > > -		val = intel_de_read(dev_priv, reg);
> > > -		if (index > DRRS_HIGH_RR) {
> > > -			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > > -				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > > -			else
> > > -				val |= PIPECONF_EDP_RR_MODE_SWITCH;
> > > -		} else {
> > > -			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > > -				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > > -			else
> > > -				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
> > > -		}
> > > -		intel_de_write(dev_priv, reg, val);
> > > -	}
> > > -
> > > -	dev_priv->drrs.refresh_rate_type = index;
> > > -
> > > -	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> > > -		    refresh_rate);
> > > -}
> > > -
> > > -static void
> > > -intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> > > -{
> > > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > -
> > > -	dev_priv->drrs.busy_frontbuffer_bits = 0;
> > > -	dev_priv->drrs.dp = intel_dp;
> > > -}
> > > -
> > > -/**
> > > - * intel_edp_drrs_enable - init drrs struct if supported
> > > - * @intel_dp: DP struct
> > > - * @crtc_state: A pointer to the active crtc state.
> > > - *
> > > - * Initializes frontbuffer_bits and drrs.dp
> > > - */
> > > -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > > -			   const struct intel_crtc_state *crtc_state)
> > > -{
> > > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > -
> > > -	if (!crtc_state->has_drrs)
> > > -		return;
> > > -
> > > -	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
> > > -
> > > -	mutex_lock(&dev_priv->drrs.mutex);
> > > -
> > > -	if (dev_priv->drrs.dp) {
> > > -		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
> > > -		goto unlock;
> > > -	}
> > > -
> > > -	intel_edp_drrs_enable_locked(intel_dp);
> > > -
> > > -unlock:
> > > -	mutex_unlock(&dev_priv->drrs.mutex);
> > > -}
> > > -
> > > -static void
> > > -intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> > > -			      const struct intel_crtc_state *crtc_state)
> > > -{
> > > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > -
> > > -	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> > > -		int refresh;
> > > -
> > > -		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> > > -		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> > > -	}
> > > -
> > > -	dev_priv->drrs.dp = NULL;
> > > -}
> > > -
> > > -/**
> > > - * intel_edp_drrs_disable - Disable DRRS
> > > - * @intel_dp: DP struct
> > > - * @old_crtc_state: Pointer to old crtc_state.
> > > - *
> > > - */
> > > -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > > -			    const struct intel_crtc_state *old_crtc_state)
> > > -{
> > > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > -
> > > -	if (!old_crtc_state->has_drrs)
> > > -		return;
> > > -
> > > -	mutex_lock(&dev_priv->drrs.mutex);
> > > -	if (!dev_priv->drrs.dp) {
> > > -		mutex_unlock(&dev_priv->drrs.mutex);
> > > -		return;
> > > -	}
> > > -
> > > -	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> > > -	mutex_unlock(&dev_priv->drrs.mutex);
> > > -
> > > -	cancel_delayed_work_sync(&dev_priv->drrs.work);
> > > -}
> > > -
> > > -/**
> > > - * intel_edp_drrs_update - Update DRRS state
> > > - * @intel_dp: Intel DP
> > > - * @crtc_state: new CRTC state
> > > - *
> > > - * This function will update DRRS states, disabling or enabling DRRS when
> > > - * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> > > - * intel_edp_drrs_enable() should be called instead.
> > > - */
> > > -void
> > > -intel_edp_drrs_update(struct intel_dp *intel_dp,
> > > -		      const struct intel_crtc_state *crtc_state)
> > > -{
> > > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > -
> > > -	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > > -		return;
> > > -
> > > -	mutex_lock(&dev_priv->drrs.mutex);
> > > -
> > > -	/* New state matches current one? */
> > > -	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
> > > -		goto unlock;
> > > -
> > > -	if (crtc_state->has_drrs)
> > > -		intel_edp_drrs_enable_locked(intel_dp);
> > > -	else
> > > -		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> > > -
> > > -unlock:
> > > -	mutex_unlock(&dev_priv->drrs.mutex);
> > > -}
> > > -
> > > -static void intel_edp_drrs_downclock_work(struct work_struct *work)
> > > -{
> > > -	struct drm_i915_private *dev_priv =
> > > -		container_of(work, typeof(*dev_priv), drrs.work.work);
> > > -	struct intel_dp *intel_dp;
> > > -
> > > -	mutex_lock(&dev_priv->drrs.mutex);
> > > -
> > > -	intel_dp = dev_priv->drrs.dp;
> > > -
> > > -	if (!intel_dp)
> > > -		goto unlock;
> > > -
> > > -	/*
> > > -	 * The delayed work can race with an invalidate hence we need to
> > > -	 * recheck.
> > > -	 */
> > > -
> > > -	if (dev_priv->drrs.busy_frontbuffer_bits)
> > > -		goto unlock;
> > > -
> > > -	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> > > -		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > > -
> > > -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > > -			drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> > > -	}
> > > -
> > > -unlock:
> > > -	mutex_unlock(&dev_priv->drrs.mutex);
> > > -}
> > > -
> > > -/**
> > > - * intel_edp_drrs_invalidate - Disable Idleness DRRS
> > > - * @dev_priv: i915 device
> > > - * @frontbuffer_bits: frontbuffer plane tracking bits
> > > - *
> > > - * This function gets called everytime rendering on the given planes start.
> > > - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> > > - *
> > > - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > > - */
> > > -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > > -			       unsigned int frontbuffer_bits)
> > > -{
> > > -	struct intel_dp *intel_dp;
> > > -	struct drm_crtc *crtc;
> > > -	enum pipe pipe;
> > > -
> > > -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > > -		return;
> > > -
> > > -	cancel_delayed_work(&dev_priv->drrs.work);
> > > -
> > > -	mutex_lock(&dev_priv->drrs.mutex);
> > > -
> > > -	intel_dp = dev_priv->drrs.dp;
> > > -	if (!intel_dp) {
> > > -		mutex_unlock(&dev_priv->drrs.mutex);
> > > -		return;
> > > -	}
> > > -
> > > -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > > -	pipe = to_intel_crtc(crtc)->pipe;
> > > -
> > > -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > > -	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> > > -
> > > -	/* invalidate means busy screen hence upclock */
> > > -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > > -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > > -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > > -
> > > -	mutex_unlock(&dev_priv->drrs.mutex);
> > > -}
> > > -
> > > -/**
> > > - * intel_edp_drrs_flush - Restart Idleness DRRS
> > > - * @dev_priv: i915 device
> > > - * @frontbuffer_bits: frontbuffer plane tracking bits
> > > - *
> > > - * This function gets called every time rendering on the given planes has
> > > - * completed or flip on a crtc is completed. So DRRS should be upclocked
> > > - * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
> > > - * if no other planes are dirty.
> > > - *
> > > - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > > - */
> > > -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > > -			  unsigned int frontbuffer_bits)
> > > -{
> > > -	struct intel_dp *intel_dp;
> > > -	struct drm_crtc *crtc;
> > > -	enum pipe pipe;
> > > -
> > > -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > > -		return;
> > > -
> > > -	cancel_delayed_work(&dev_priv->drrs.work);
> > > -
> > > -	mutex_lock(&dev_priv->drrs.mutex);
> > > -
> > > -	intel_dp = dev_priv->drrs.dp;
> > > -	if (!intel_dp) {
> > > -		mutex_unlock(&dev_priv->drrs.mutex);
> > > -		return;
> > > -	}
> > > -
> > > -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > > -	pipe = to_intel_crtc(crtc)->pipe;
> > > -
> > > -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > > -	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> > > -
> > > -	/* flush means busy screen hence upclock */
> > > -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > > -		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > > -					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > > -
> > > -	/*
> > > -	 * flush also means no more activity hence schedule downclock, if all
> > > -	 * other fbs are quiescent too
> > > -	 */
> > > -	if (!dev_priv->drrs.busy_frontbuffer_bits)
> > > -		schedule_delayed_work(&dev_priv->drrs.work,
> > > -				msecs_to_jiffies(1000));
> > > -	mutex_unlock(&dev_priv->drrs.mutex);
> > > -}
> > > -
> > > -/**
> > > - * DOC: Display Refresh Rate Switching (DRRS)
> > > - *
> > > - * Display Refresh Rate Switching (DRRS) is a power conservation feature
> > > - * which enables swtching between low and high refresh rates,
> > > - * dynamically, based on the usage scenario. This feature is applicable
> > > - * for internal panels.
> > > - *
> > > - * Indication that the panel supports DRRS is given by the panel EDID, which
> > > - * would list multiple refresh rates for one resolution.
> > > - *
> > > - * DRRS is of 2 types - static and seamless.
> > > - * Static DRRS involves changing refresh rate (RR) by doing a full modeset
> > > - * (may appear as a blink on screen) and is used in dock-undock scenario.
> > > - * Seamless DRRS involves changing RR without any visual effect to the user
> > > - * and can be used during normal system usage. This is done by programming
> > > - * certain registers.
> > > - *
> > > - * Support for static/seamless DRRS may be indicated in the VBT based on
> > > - * inputs from the panel spec.
> > > - *
> > > - * DRRS saves power by switching to low RR based on usage scenarios.
> > > - *
> > > - * The implementation is based on frontbuffer tracking implementation.  When
> > > - * there is a disturbance on the screen triggered by user activity or a periodic
> > > - * system activity, DRRS is disabled (RR is changed to high RR).  When there is
> > > - * no movement on screen, after a timeout of 1 second, a switch to low RR is
> > > - * made.
> > > - *
> > > - * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> > > - * and intel_edp_drrs_flush() are called.
> > > - *
> > > - * DRRS can be further extended to support other internal panels and also
> > > - * the scenario of video playback wherein RR is set based on the rate
> > > - * requested by userspace.
> > > - */
> > > -
> > > -/**
> > > - * intel_dp_drrs_init - Init basic DRRS work and mutex.
> > > - * @connector: eDP connector
> > > - * @fixed_mode: preferred mode of panel
> > > - *
> > > - * This function is  called only once at driver load to initialize basic
> > > - * DRRS stuff.
> > > - *
> > > - * Returns:
> > > - * Downclock mode if panel supports it, else return NULL.
> > > - * DRRS support is determined by the presence of downclock mode (apart
> > > - * from VBT setting).
> > > - */
> > > -static struct drm_display_mode *
> > > -intel_dp_drrs_init(struct intel_connector *connector,
> > > -		   struct drm_display_mode *fixed_mode)
> > > -{
> > > -	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > > -	struct drm_display_mode *downclock_mode = NULL;
> > > -
> > > -	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> > > -	mutex_init(&dev_priv->drrs.mutex);
> > > -
> > > -	if (DISPLAY_VER(dev_priv) <= 6) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "DRRS supported for Gen7 and above\n");
> > > -		return NULL;
> > > -	}
> > > -
> > > -	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
> > > -		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
> > > -		return NULL;
> > > -	}
> > > -
> > > -	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
> > > -	if (!downclock_mode) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "Downclock mode is not found. DRRS not supported\n");
> > > -		return NULL;
> > > -	}
> > > -
> > > -	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
> > > -
> > > -	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
> > > -	drm_dbg_kms(&dev_priv->drm,
> > > -		    "seamless DRRS supported for eDP panel.\n");
> > > -	return downclock_mode;
> > > -}
> > > -
> > >  static bool intel_edp_init_connector(struct intel_dp *intel_dp,
> > >  				     struct intel_connector *intel_connector)
> > >  {
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> > > index ae0f776bffab8..a28fff286c21a 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> > > @@ -70,17 +70,6 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp);
> > >  int intel_dp_max_lane_count(struct intel_dp *intel_dp);
> > >  int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
> > >  
> > > -void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > > -			   const struct intel_crtc_state *crtc_state);
> > > -void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > > -			    const struct intel_crtc_state *crtc_state);
> > > -void intel_edp_drrs_update(struct intel_dp *intel_dp,
> > > -			   const struct intel_crtc_state *crtc_state);
> > > -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > > -			       unsigned int frontbuffer_bits);
> > > -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > > -			  unsigned int frontbuffer_bits);
> > > -
> > >  void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
> > >  			   u8 *link_bw, u8 *rate_select);
> > >  bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> > > new file mode 100644
> > > index 0000000000000..be9b6d4482f04
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> > > @@ -0,0 +1,477 @@
> > > +// SPDX-License-Identifier: MIT
> > > +/*
> > > + * Copyright © 2021 Intel Corporation
> > > + */
> > > +
> > > +#include "i915_drv.h"
> > > +#include "intel_atomic.h"
> > > +#include "intel_de.h"
> > > +#include "intel_display_types.h"
> > > +#include "intel_drrs.h"
> > > +#include "intel_panel.h"
> > > +
> > > +/**
> > > + * DOC: Display Refresh Rate Switching (DRRS)
> > > + *
> > > + * Display Refresh Rate Switching (DRRS) is a power conservation feature
> > > + * which enables swtching between low and high refresh rates,
> > > + * dynamically, based on the usage scenario. This feature is applicable
> > > + * for internal panels.
> > > + *
> > > + * Indication that the panel supports DRRS is given by the panel EDID, which
> > > + * would list multiple refresh rates for one resolution.
> > > + *
> > > + * DRRS is of 2 types - static and seamless.
> > > + * Static DRRS involves changing refresh rate (RR) by doing a full modeset
> > > + * (may appear as a blink on screen) and is used in dock-undock scenario.
> > > + * Seamless DRRS involves changing RR without any visual effect to the user
> > > + * and can be used during normal system usage. This is done by programming
> > > + * certain registers.
> > > + *
> > > + * Support for static/seamless DRRS may be indicated in the VBT based on
> > > + * inputs from the panel spec.
> > > + *
> > > + * DRRS saves power by switching to low RR based on usage scenarios.
> > > + *
> > > + * The implementation is based on frontbuffer tracking implementation.  When
> > > + * there is a disturbance on the screen triggered by user activity or a periodic
> > > + * system activity, DRRS is disabled (RR is changed to high RR).  When there is
> > > + * no movement on screen, after a timeout of 1 second, a switch to low RR is
> > > + * made.
> > > + *
> > > + * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
> > > + * and intel_edp_drrs_flush() are called.
> > > + *
> > > + * DRRS can be further extended to support other internal panels and also
> > > + * the scenario of video playback wherein RR is set based on the rate
> > > + * requested by userspace.
> > > + */
> > > +
> > > +void
> > > +intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> > > +			     struct intel_crtc_state *pipe_config,
> > > +			     int output_bpp, bool constant_n)
> > > +{
> > > +	struct intel_connector *intel_connector = intel_dp->attached_connector;
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +	int pixel_clock;
> > > +
> > > +	if (pipe_config->vrr.enable)
> > > +		return;
> > > +
> > > +	/*
> > > +	 * DRRS and PSR can't be enable together, so giving preference to PSR
> > > +	 * as it allows more power-savings by complete shutting down display,
> > > +	 * so to guarantee this, intel_dp_drrs_compute_config() must be called
> > > +	 * after intel_psr_compute_config().
> > > +	 */
> > > +	if (pipe_config->has_psr)
> > > +		return;
> > > +
> > > +	if (!intel_connector->panel.downclock_mode ||
> > > +	    dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > > +		return;
> > > +
> > > +	pipe_config->has_drrs = true;
> > > +
> > > +	pixel_clock = intel_connector->panel.downclock_mode->clock;
> > > +	if (pipe_config->splitter.enable)
> > > +		pixel_clock /= pipe_config->splitter.link_count;
> > > +
> > > +	intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
> > > +			       pipe_config->port_clock, &pipe_config->dp_m2_n2,
> > > +			       constant_n, pipe_config->fec_enable);
> > > +
> > > +	/* FIXME: abstract this better */
> > > +	if (pipe_config->splitter.enable)
> > > +		pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
> > > +}
> > > +
> > > +/**
> > > + * intel_dp_set_drrs_state - program registers for RR switch to take effect
> > > + * @dev_priv: i915 device
> > > + * @crtc_state: a pointer to the active intel_crtc_state
> > > + * @refresh_rate: RR to be programmed
> > 
> > ... but let's enjoy the opportunity and avoid doc style in static functions
> > that should never be called outside this block.
> 
> Did that in the next patch, while renaming functions.
> Is that fine? Or it should be removed in this one?

I see even on patch 5 changes on this doc section:

- * @refresh_rate: RR to be programmed
+ * @refresh_type: high or low refresh rate to be programmed

So I believe the sooner the better.

> 
> thanks for the reviews

Thank you for this great clean-up

> 
> > 
> > with this addressed feel free to use:
> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > 
> > > + *
> > > + * This function gets called when refresh rate (RR) has to be changed from
> > > + * one frequency to another. Switches can be between high and low RR
> > > + * supported by the panel or to any other RR based on media playback (in
> > > + * this case, RR value needs to be passed from user space).
> > > + *
> > > + * The caller of this function needs to take a lock on dev_priv->drrs.
> > > + */
> > > +static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
> > > +				    const struct intel_crtc_state *crtc_state,
> > > +				    int refresh_rate)
> > > +{
> > > +	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > +	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> > > +
> > > +	if (refresh_rate <= 0) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "Refresh rate should be positive non-zero.\n");
> > > +		return;
> > > +	}
> > > +
> > > +	if (intel_dp == NULL) {
> > > +		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> > > +		return;
> > > +	}
> > > +
> > > +	if (!crtc) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "DRRS: intel_crtc not initialized\n");
> > > +		return;
> > > +	}
> > > +
> > > +	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
> > > +		drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n");
> > > +		return;
> > > +	}
> > > +
> > > +	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> > > +			refresh_rate)
> > > +		index = DRRS_LOW_RR;
> > > +
> > > +	if (index == dev_priv->drrs.refresh_rate_type) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "DRRS requested for previously set RR...ignoring\n");
> > > +		return;
> > > +	}
> > > +
> > > +	if (!crtc_state->hw.active) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "eDP encoder disabled. CRTC not Active\n");
> > > +		return;
> > > +	}
> > > +
> > > +	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> > > +		switch (index) {
> > > +		case DRRS_HIGH_RR:
> > > +			intel_dp_set_m_n(crtc_state, M1_N1);
> > > +			break;
> > > +		case DRRS_LOW_RR:
> > > +			intel_dp_set_m_n(crtc_state, M2_N2);
> > > +			break;
> > > +		case DRRS_MAX_RR:
> > > +		default:
> > > +			drm_err(&dev_priv->drm,
> > > +				"Unsupported refreshrate type\n");
> > > +		}
> > > +	} else if (DISPLAY_VER(dev_priv) > 6) {
> > > +		i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
> > > +		u32 val;
> > > +
> > > +		val = intel_de_read(dev_priv, reg);
> > > +		if (index > DRRS_HIGH_RR) {
> > > +			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > > +				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > > +			else
> > > +				val |= PIPECONF_EDP_RR_MODE_SWITCH;
> > > +		} else {
> > > +			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> > > +				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> > > +			else
> > > +				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
> > > +		}
> > > +		intel_de_write(dev_priv, reg, val);
> > > +	}
> > > +
> > > +	dev_priv->drrs.refresh_rate_type = index;
> > > +
> > > +	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> > > +		    refresh_rate);
> > > +}
> > > +
> > > +static void
> > > +intel_edp_drrs_enable_locked(struct intel_dp *intel_dp)
> > > +{
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +
> > > +	dev_priv->drrs.busy_frontbuffer_bits = 0;
> > > +	dev_priv->drrs.dp = intel_dp;
> > > +}
> > > +
> > > +/**
> > > + * intel_edp_drrs_enable - init drrs struct if supported
> > > + * @intel_dp: DP struct
> > > + * @crtc_state: A pointer to the active crtc state.
> > > + *
> > > + * Initializes frontbuffer_bits and drrs.dp
> > > + */
> > > +void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > > +			   const struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +
> > > +	if (!crtc_state->has_drrs)
> > > +		return;
> > > +
> > > +	drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n");
> > > +
> > > +	mutex_lock(&dev_priv->drrs.mutex);
> > > +
> > > +	if (dev_priv->drrs.dp) {
> > > +		drm_warn(&dev_priv->drm, "DRRS already enabled\n");
> > > +		goto unlock;
> > > +	}
> > > +
> > > +	intel_edp_drrs_enable_locked(intel_dp);
> > > +
> > > +unlock:
> > > +	mutex_unlock(&dev_priv->drrs.mutex);
> > > +}
> > > +
> > > +static void
> > > +intel_edp_drrs_disable_locked(struct intel_dp *intel_dp,
> > > +			      const struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +
> > > +	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> > > +		int refresh;
> > > +
> > > +		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> > > +		intel_dp_set_drrs_state(dev_priv, crtc_state, refresh);
> > > +	}
> > > +
> > > +	dev_priv->drrs.dp = NULL;
> > > +}
> > > +
> > > +/**
> > > + * intel_edp_drrs_disable - Disable DRRS
> > > + * @intel_dp: DP struct
> > > + * @old_crtc_state: Pointer to old crtc_state.
> > > + *
> > > + */
> > > +void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > > +			    const struct intel_crtc_state *old_crtc_state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +
> > > +	if (!old_crtc_state->has_drrs)
> > > +		return;
> > > +
> > > +	mutex_lock(&dev_priv->drrs.mutex);
> > > +	if (!dev_priv->drrs.dp) {
> > > +		mutex_unlock(&dev_priv->drrs.mutex);
> > > +		return;
> > > +	}
> > > +
> > > +	intel_edp_drrs_disable_locked(intel_dp, old_crtc_state);
> > > +	mutex_unlock(&dev_priv->drrs.mutex);
> > > +
> > > +	cancel_delayed_work_sync(&dev_priv->drrs.work);
> > > +}
> > > +
> > > +/**
> > > + * intel_edp_drrs_update - Update DRRS state
> > > + * @intel_dp: Intel DP
> > > + * @crtc_state: new CRTC state
> > > + *
> > > + * This function will update DRRS states, disabling or enabling DRRS when
> > > + * executing fastsets. For full modeset, intel_edp_drrs_disable() and
> > > + * intel_edp_drrs_enable() should be called instead.
> > > + */
> > > +void
> > > +intel_edp_drrs_update(struct intel_dp *intel_dp,
> > > +		      const struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +
> > > +	if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
> > > +		return;
> > > +
> > > +	mutex_lock(&dev_priv->drrs.mutex);
> > > +
> > > +	/* New state matches current one? */
> > > +	if (crtc_state->has_drrs == !!dev_priv->drrs.dp)
> > > +		goto unlock;
> > > +
> > > +	if (crtc_state->has_drrs)
> > > +		intel_edp_drrs_enable_locked(intel_dp);
> > > +	else
> > > +		intel_edp_drrs_disable_locked(intel_dp, crtc_state);
> > > +
> > > +unlock:
> > > +	mutex_unlock(&dev_priv->drrs.mutex);
> > > +}
> > > +
> > > +static void intel_edp_drrs_downclock_work(struct work_struct *work)
> > > +{
> > > +	struct drm_i915_private *dev_priv =
> > > +		container_of(work, typeof(*dev_priv), drrs.work.work);
> > > +	struct intel_dp *intel_dp;
> > > +
> > > +	mutex_lock(&dev_priv->drrs.mutex);
> > > +
> > > +	intel_dp = dev_priv->drrs.dp;
> > > +
> > > +	if (!intel_dp)
> > > +		goto unlock;
> > > +
> > > +	/*
> > > +	 * The delayed work can race with an invalidate hence we need to
> > > +	 * recheck.
> > > +	 */
> > > +
> > > +	if (dev_priv->drrs.busy_frontbuffer_bits)
> > > +		goto unlock;
> > > +
> > > +	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> > > +		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > > +
> > > +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > > +					drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> > > +	}
> > > +
> > > +unlock:
> > > +	mutex_unlock(&dev_priv->drrs.mutex);
> > > +}
> > > +
> > > +/**
> > > + * intel_edp_drrs_invalidate - Disable Idleness DRRS
> > > + * @dev_priv: i915 device
> > > + * @frontbuffer_bits: frontbuffer plane tracking bits
> > > + *
> > > + * This function gets called everytime rendering on the given planes start.
> > > + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> > > + *
> > > + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > > + */
> > > +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > > +			       unsigned int frontbuffer_bits)
> > > +{
> > > +	struct intel_dp *intel_dp;
> > > +	struct drm_crtc *crtc;
> > > +	enum pipe pipe;
> > > +
> > > +	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > > +		return;
> > > +
> > > +	cancel_delayed_work(&dev_priv->drrs.work);
> > > +
> > > +	mutex_lock(&dev_priv->drrs.mutex);
> > > +
> > > +	intel_dp = dev_priv->drrs.dp;
> > > +	if (!intel_dp) {
> > > +		mutex_unlock(&dev_priv->drrs.mutex);
> > > +		return;
> > > +	}
> > > +
> > > +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > > +	pipe = to_intel_crtc(crtc)->pipe;
> > > +
> > > +	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > > +	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> > > +
> > > +	/* invalidate means busy screen hence upclock */
> > > +	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > > +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > > +					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > > +
> > > +	mutex_unlock(&dev_priv->drrs.mutex);
> > > +}
> > > +
> > > +/**
> > > + * intel_edp_drrs_flush - Restart Idleness DRRS
> > > + * @dev_priv: i915 device
> > > + * @frontbuffer_bits: frontbuffer plane tracking bits
> > > + *
> > > + * This function gets called every time rendering on the given planes has
> > > + * completed or flip on a crtc is completed. So DRRS should be upclocked
> > > + * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
> > > + * if no other planes are dirty.
> > > + *
> > > + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > > + */
> > > +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > > +			  unsigned int frontbuffer_bits)
> > > +{
> > > +	struct intel_dp *intel_dp;
> > > +	struct drm_crtc *crtc;
> > > +	enum pipe pipe;
> > > +
> > > +	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > > +		return;
> > > +
> > > +	cancel_delayed_work(&dev_priv->drrs.work);
> > > +
> > > +	mutex_lock(&dev_priv->drrs.mutex);
> > > +
> > > +	intel_dp = dev_priv->drrs.dp;
> > > +	if (!intel_dp) {
> > > +		mutex_unlock(&dev_priv->drrs.mutex);
> > > +		return;
> > > +	}
> > > +
> > > +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > > +	pipe = to_intel_crtc(crtc)->pipe;
> > > +
> > > +	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > > +	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> > > +
> > > +	/* flush means busy screen hence upclock */
> > > +	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > > +		intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config,
> > > +					drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > > +
> > > +	/*
> > > +	 * flush also means no more activity hence schedule downclock, if all
> > > +	 * other fbs are quiescent too
> > > +	 */
> > > +	if (!dev_priv->drrs.busy_frontbuffer_bits)
> > > +		schedule_delayed_work(&dev_priv->drrs.work,
> > > +				      msecs_to_jiffies(1000));
> > > +	mutex_unlock(&dev_priv->drrs.mutex);
> > > +}
> > > +
> > > +/**
> > > + * intel_dp_drrs_init - Init basic DRRS work and mutex.
> > > + * @connector: eDP connector
> > > + * @fixed_mode: preferred mode of panel
> > > + *
> > > + * This function is  called only once at driver load to initialize basic
> > > + * DRRS stuff.
> > > + *
> > > + * Returns:
> > > + * Downclock mode if panel supports it, else return NULL.
> > > + * DRRS support is determined by the presence of downclock mode (apart
> > > + * from VBT setting).
> > > + */
> > > +struct drm_display_mode *
> > > +intel_dp_drrs_init(struct intel_connector *connector,
> > > +		   struct drm_display_mode *fixed_mode)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > > +	struct drm_display_mode *downclock_mode = NULL;
> > > +
> > > +	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
> > > +	mutex_init(&dev_priv->drrs.mutex);
> > > +
> > > +	if (DISPLAY_VER(dev_priv) <= 6) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "DRRS supported for Gen7 and above\n");
> > > +		return NULL;
> > > +	}
> > > +
> > > +	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
> > > +		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
> > > +		return NULL;
> > > +	}
> > > +
> > > +	downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode);
> > > +	if (!downclock_mode) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "Downclock mode is not found. DRRS not supported\n");
> > > +		return NULL;
> > > +	}
> > > +
> > > +	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
> > > +
> > > +	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
> > > +	drm_dbg_kms(&dev_priv->drm,
> > > +		    "seamless DRRS supported for eDP panel.\n");
> > > +	return downclock_mode;
> > > +}
> > > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
> > > new file mode 100644
> > > index 0000000000000..ffa175b4cf4f4
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/i915/display/intel_drrs.h
> > > @@ -0,0 +1,32 @@
> > > +/* SPDX-License-Identifier: MIT */
> > > +/*
> > > + * Copyright © 2021 Intel Corporation
> > > + */
> > > +
> > > +#ifndef __INTEL_DRRS_H__
> > > +#define __INTEL_DRRS_H__
> > > +
> > > +#include <linux/types.h>
> > > +
> > > +struct drm_i915_private;
> > > +struct intel_crtc_state;
> > > +struct intel_connector;
> > > +struct intel_dp;
> > > +
> > > +void intel_edp_drrs_enable(struct intel_dp *intel_dp,
> > > +			   const struct intel_crtc_state *crtc_state);
> > > +void intel_edp_drrs_disable(struct intel_dp *intel_dp,
> > > +			    const struct intel_crtc_state *crtc_state);
> > > +void intel_edp_drrs_update(struct intel_dp *intel_dp,
> > > +			   const struct intel_crtc_state *crtc_state);
> > > +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
> > > +			       unsigned int frontbuffer_bits);
> > > +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
> > > +			  unsigned int frontbuffer_bits);
> > > +void intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
> > > +				  struct intel_crtc_state *pipe_config,
> > > +				  int output_bpp, bool constant_n);
> > > +struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector,
> > > +					    struct drm_display_mode *fixed_mode);
> > > +
> > > +#endif /* __INTEL_DRRS_H__ */
> > > diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > > index 8e75debcce1a9..e4834d84ce5e3 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > > @@ -62,6 +62,7 @@
> > >  #include "intel_display_types.h"
> > >  #include "intel_fbc.h"
> > >  #include "intel_frontbuffer.h"
> > > +#include "intel_drrs.h"
> > >  #include "intel_psr.h"
> > >  
> > >  /**
> > > -- 
> > > 2.33.0
> > > 
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS José Roberto de Souza
@ 2021-09-02 15:15   ` Gwan-gyeong Mun
  2021-09-03 20:36     ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Gwan-gyeong Mun @ 2021-09-02 15:15 UTC (permalink / raw)
  To: José Roberto de Souza, intel-gfx



On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> It started as a code style fix for the lines above 100 col but it
> turned out to simplifications to intel_drrs_set_state().
> Now it receives the desired refresh rate type, high or low.
> 
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_drrs.c | 60 ++++++++---------------
>   1 file changed, 21 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> index 1aa9793521158..5eb5033242575 100644
> --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> @@ -91,7 +91,7 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
>    * intel_drrs_set_state - program registers for RR switch to take effect
>    * @dev_priv: i915 device
>    * @crtc_state: a pointer to the active intel_crtc_state
> - * @refresh_rate: RR to be programmed
> + * @refresh_type: high or low refresh rate to be programmed
>    *
>    * This function gets called when refresh rate (RR) has to be changed from
>    * one frequency to another. Switches can be between high and low RR
> @@ -102,19 +102,13 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
>    */
>   static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
>   				 const struct intel_crtc_state *crtc_state,
> -				 int refresh_rate)
> +				 enum drrs_refresh_rate_type refresh_type)
>   {
>   	struct intel_dp *intel_dp = dev_priv->drrs.dp;
>   	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> +	struct drm_display_mode *mode;
>   
> -	if (refresh_rate <= 0) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Refresh rate should be positive non-zero.\n");
> -		return;
> -	}
> -
> -	if (intel_dp == NULL) {
> +	if (!intel_dp) {
>   		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
>   		return;
>   	}
> @@ -130,15 +124,8 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
>   		return;
>   	}
>   
> -	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> -			refresh_rate)
> -		index = DRRS_LOW_RR;
> -
> -	if (index == dev_priv->drrs.refresh_rate_type) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "DRRS requested for previously set RR...ignoring\n");
> +	if (refresh_type == dev_priv->drrs.refresh_rate_type)
>   		return;
> -	}
>   
>   	if (!crtc_state->hw.active) {
>   		drm_dbg_kms(&dev_priv->drm,
> @@ -147,7 +134,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
>   	}
>   
>   	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> -		switch (index) {
> +		switch (refresh_type) {
>   		case DRRS_HIGH_RR:
>   			intel_dp_set_m_n(crtc_state, M1_N1);
>   			break;
> @@ -164,7 +151,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
>   		u32 val;
>   
>   		val = intel_de_read(dev_priv, reg);
> -		if (index > DRRS_HIGH_RR) {
> +		if (refresh_type == DRRS_LOW_RR) {
>   			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
>   				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
>   			else
> @@ -178,10 +165,14 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
>   		intel_de_write(dev_priv, reg, val);
>   	}
> 
> -	dev_priv->drrs.refresh_rate_type = index;
> +	dev_priv->drrs.refresh_rate_type = refresh_type;
>   
> +	if (refresh_type == DRRS_LOW_RR)
> +		mode = intel_dp->attached_connector->panel.fixed_mode;
> +	else
> +		mode = intel_dp->attached_connector->panel.downclock_mode;
For DRRS_LOW_RR refresh_type, panel.downclock_mode has to be used, and 
for DRR_HIGH_RR, panel.fixed_mode has to be used.
It should be modified as follows.
	if (refresh_type == DRRS_LOW_RR)
		mode = intel_dp->attached_connector->panel.downclock_mode;
	else
		mode = intel_dp->attached_connector->panel.fixed_mode;

Except for this, the rest of the code looks good to me.


>   	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> -		    refresh_rate);
> +		    drm_mode_vrefresh(mode));
>   }
>   
>   static void
> @@ -229,13 +220,7 @@ intel_drrs_disable_locked(struct intel_dp *intel_dp,
>   {
>   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>   
> -	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> -		int refresh;
> -
> -		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> -		intel_drrs_set_state(dev_priv, crtc_state, refresh);
> -	}
> -
> +	intel_drrs_set_state(dev_priv, crtc_state, DRRS_HIGH_RR);
>   	dev_priv->drrs.dp = NULL;
>   }
>   
> @@ -303,6 +288,7 @@ static void intel_drrs_downclock_work(struct work_struct *work)
>   	struct drm_i915_private *dev_priv =
>   		container_of(work, typeof(*dev_priv), drrs.work.work);
>   	struct intel_dp *intel_dp;
> +	struct drm_crtc *crtc;
>   
>   	mutex_lock(&dev_priv->drrs.mutex);
>   
> @@ -319,12 +305,8 @@ static void intel_drrs_downclock_work(struct work_struct *work)
>   	if (dev_priv->drrs.busy_frontbuffer_bits)
>   		goto unlock;
>   
> -	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> -		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> -
> -		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> -				     drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> -	}
> +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> +	intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, DRRS_LOW_RR);
>   
>   unlock:
>   	mutex_unlock(&dev_priv->drrs.mutex);
> @@ -367,9 +349,9 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
>   	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
>   
>   	/* invalidate means busy screen hence upclock */
> -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> +	if (frontbuffer_bits)
>   		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> -				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> +				     DRRS_HIGH_RR);
>   
>   	mutex_unlock(&dev_priv->drrs.mutex);
>   }
> @@ -413,9 +395,9 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
>   	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
>   
>   	/* flush means busy screen hence upclock */
> -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> +	if (frontbuffer_bits)
>   		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> -				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> +				     DRRS_HIGH_RR);
>   
>   	/*
>   	 * flush also means no more activity hence schedule downclock, if all
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate José Roberto de Souza
@ 2021-09-02 15:57   ` Gwan-gyeong Mun
  2021-09-03 21:52     ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Gwan-gyeong Mun @ 2021-09-02 15:57 UTC (permalink / raw)
  To: José Roberto de Souza, intel-gfx



On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> Both functions are pretty much equal, with minor changes that can be
> handled by a single parameter.
> 
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_drrs.c | 82 +++++++++--------------
>   1 file changed, 32 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> index 5eb5033242575..8583da4e82434 100644
> --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> @@ -312,18 +312,9 @@ static void intel_drrs_downclock_work(struct work_struct *work)
>   	mutex_unlock(&dev_priv->drrs.mutex);
>   }
>   
> -/**
> - * intel_drrs_invalidate - Disable Idleness DRRS
> - * @dev_priv: i915 device
> - * @frontbuffer_bits: frontbuffer plane tracking bits
> - *
> - * This function gets called everytime rendering on the given planes start.
> - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> - *
> - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> - */
> -void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> -			   unsigned int frontbuffer_bits)
> +static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
> +					  unsigned int frontbuffer_bits,
> +					  bool invalidate)
>   {
>   	struct intel_dp *intel_dp;
>   	struct drm_crtc *crtc;
> @@ -346,16 +337,42 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
>   	pipe = to_intel_crtc(crtc)->pipe;
>   
>   	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> -	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> +	if (invalidate)
> +		dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> +	else
> +		dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
>   
> -	/* invalidate means busy screen hence upclock */
> +	/* flush/invalidate means busy screen hence upclock */
>   	if (frontbuffer_bits)
>   		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
>   				     DRRS_HIGH_RR);
>   
> +	/*
> +	 * flush also means no more activity hence schedule downclock, if all
> +	 * other fbs are quiescent too
> +	 */
> +	if (!dev_priv->drrs.busy_frontbuffer_bits)
> +		schedule_delayed_work(&dev_priv->drrs.work,
> +				      msecs_to_jiffies(1000));
This line of code was previously only used in the intel_drrs_flush() 
function,
In the case of the intel_drrs_invalidate() call scenario, it is not 
confirmed whether dev_priv->drrs.busy_frontbuffer_bits is always true to 
me. If it's not always true, it looks like you also need to check for 
"not invalidate".
Please ignore this comment if I'm wrong.

>   	mutex_unlock(&dev_priv->drrs.mutex);
>   }
>   
> +/**
> + * intel_drrs_invalidate - Disable Idleness DRRS
> + * @dev_priv: i915 device
> + * @frontbuffer_bits: frontbuffer plane tracking bits
> + *
> + * This function gets called everytime rendering on the given planes start.
> + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> + *
> + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> + */
> +void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> +			   unsigned int frontbuffer_bits)
> +{
> +	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, true);
> +}
> +
>   /**
>    * intel_drrs_flush - Restart Idleness DRRS
>    * @dev_priv: i915 device
> @@ -371,42 +388,7 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
>   void intel_drrs_flush(struct drm_i915_private *dev_priv,
>   		      unsigned int frontbuffer_bits)
>   {
> -	struct intel_dp *intel_dp;
> -	struct drm_crtc *crtc;
> -	enum pipe pipe;
> -
> -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> -		return;
> -
> -	cancel_delayed_work(&dev_priv->drrs.work);
> -
> -	mutex_lock(&dev_priv->drrs.mutex);
> -
> -	intel_dp = dev_priv->drrs.dp;
> -	if (!intel_dp) {
> -		mutex_unlock(&dev_priv->drrs.mutex);
> -		return;
> -	}
> -
> -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> -	pipe = to_intel_crtc(crtc)->pipe;
> -
> -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> -	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> -
> -	/* flush means busy screen hence upclock */
> -	if (frontbuffer_bits)
> -		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> -				     DRRS_HIGH_RR);
> -
> -	/*
> -	 * flush also means no more activity hence schedule downclock, if all
> -	 * other fbs are quiescent too
> -	 */
> -	if (!dev_priv->drrs.busy_frontbuffer_bits)
> -		schedule_delayed_work(&dev_priv->drrs.work,
> -				      msecs_to_jiffies(1000));
> -	mutex_unlock(&dev_priv->drrs.mutex);
> +	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
>   }
>   
>   /**
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Prepare DRRS for frontbuffer rendering drop
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Prepare DRRS for frontbuffer rendering drop José Roberto de Souza
@ 2021-09-02 16:09   ` Gwan-gyeong Mun
  0 siblings, 0 replies; 28+ messages in thread
From: Gwan-gyeong Mun @ 2021-09-02 16:09 UTC (permalink / raw)
  To: José Roberto de Souza, intel-gfx

Looks good to me.
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>

On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> Frontbuffer rendering will be dropped for modern platforms but
> before that we to prepare DRRS for it.
> 
> intel_drrs_flush and intel_drrs_invalidate will not be called
> for platforms that will not support frontbuffer rendering so DRRS
> needs another way to be notified about to page flips so it can change
> between high and low refresh rates as needed.
> 
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_display.c | 2 ++
>   drivers/gpu/drm/i915/display/intel_drrs.c    | 9 +++++++++
>   drivers/gpu/drm/i915/display/intel_drrs.h    | 4 ++++
>   3 files changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 794690c0dba56..808002aa439e2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -52,6 +52,7 @@
>   #include "display/intel_dp_mst.h"
>   #include "display/intel_dpll.h"
>   #include "display/intel_dpll_mgr.h"
> +#include "display/intel_drrs.h"
>   #include "display/intel_dsi.h"
>   #include "display/intel_dvo.h"
>   #include "display/intel_fb.h"
> @@ -2436,6 +2437,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
>   		hsw_enable_ips(new_crtc_state);
>   
>   	intel_fbc_post_update(state, crtc);
> +	intel_drrs_page_flip(state, crtc);
>   
>   	if (needs_nv12_wa(old_crtc_state) &&
>   	    !needs_nv12_wa(new_crtc_state))
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> index 8583da4e82434..6ae778c306006 100644
> --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> @@ -391,6 +391,15 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
>   	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
>   }
>   
> +void intel_drrs_page_flip(struct intel_atomic_state *state,
> +			  struct intel_crtc *crtc)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	unsigned int frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
> +
> +	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
> +}
> +
>   /**
>    * intel_drrs_init - Init basic DRRS work and mutex.
>    * @connector: eDP connector
> diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h
> index 73be7e9a43691..9ec9c447211af 100644
> --- a/drivers/gpu/drm/i915/display/intel_drrs.h
> +++ b/drivers/gpu/drm/i915/display/intel_drrs.h
> @@ -9,6 +9,8 @@
>   #include <linux/types.h>
>   
>   struct drm_i915_private;
> +struct intel_atomic_state;
> +struct intel_crtc;
>   struct intel_crtc_state;
>   struct intel_connector;
>   struct intel_dp;
> @@ -23,6 +25,8 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
>   			   unsigned int frontbuffer_bits);
>   void intel_drrs_flush(struct drm_i915_private *dev_priv,
>   		      unsigned int frontbuffer_bits);
> +void intel_drrs_page_flip(struct intel_atomic_state *state,
> +			  struct intel_crtc *crtc);
>   void intel_drrs_compute_config(struct intel_dp *intel_dp,
>   			       struct intel_crtc_state *pipe_config,
>   			       int output_bpp, bool constant_n);
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support José Roberto de Souza
@ 2021-09-02 18:42   ` Gwan-gyeong Mun
  2021-09-03 22:09     ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Gwan-gyeong Mun @ 2021-09-02 18:42 UTC (permalink / raw)
  To: José Roberto de Souza, intel-gfx
  Cc: Daniel Vetter, Ville Syrjälä, Jani Nikula, Rodrigo Vivi



On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> By now all the userspace applications should have migrated to atomic
> or at least be calling DRM_IOCTL_MODE_DIRTYFB.
> 
> With that we can kill frontbuffer rendering support in i915 for
> modern platforms.
> 
> So here converting legacy APIs into atomic commits so it can be
> properly handled by driver i915.
> 
> Several IGT tests will fail with this changes, because some tests
> were stressing those frontbuffer rendering scenarios that no userspace
> should be using by now, fixes to IGT should be sent soon.
> 
> v2:
> - return earlier to not set fb_tracking.busy/flip_bits
> - added a warn on to make sure we are not setting the busy/flip_bits
> 
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_cursor.c    |  6 ++----
>   drivers/gpu/drm/i915/display/intel_fb.c        |  8 +++++++-
>   .../gpu/drm/i915/display/intel_frontbuffer.c   | 18 ++++++++++++++++++
>   drivers/gpu/drm/i915/i915_drv.h                |  2 ++
>   4 files changed, 29 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
> index c7618fef01439..5aa996c3b7980 100644
> --- a/drivers/gpu/drm/i915/display/intel_cursor.c
> +++ b/drivers/gpu/drm/i915/display/intel_cursor.c
> @@ -617,6 +617,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
>   			   u32 src_w, u32 src_h,
>   			   struct drm_modeset_acquire_ctx *ctx)
>   {
> +	struct drm_i915_private *i915 = to_i915(_crtc->dev);
>   	struct intel_plane *plane = to_intel_plane(_plane);
>   	struct intel_crtc *crtc = to_intel_crtc(_crtc);
>   	struct intel_plane_state *old_plane_state =
> @@ -633,12 +634,9 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
>   	 * PSR2 selective fetch also requires the slow path as
>   	 * PSR2 plane and transcoder registers can only be updated during
>   	 * vblank.
> -	 *
> -	 * FIXME bigjoiner fastpath would be good
>   	 */
>   	if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
> -	    crtc_state->update_pipe || crtc_state->bigjoiner ||
> -	    crtc_state->enable_psr2_sel_fetch)
> +	    crtc_state->update_pipe || !HAS_FRONTBUFFER_RENDERING(i915))
>   		goto slow;
>   
>   	/*
> diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
> index e4b8602ec0cd2..3eb60785c9f29 100644
> --- a/drivers/gpu/drm/i915/display/intel_fb.c
> +++ b/drivers/gpu/drm/i915/display/intel_fb.c
> @@ -3,6 +3,7 @@
>    * Copyright © 2021 Intel Corporation
>    */
>   
> +#include <drm/drm_damage_helper.h>
>   #include <drm/drm_framebuffer.h>
>   #include <drm/drm_modeset_helper.h>
>   
> @@ -1235,10 +1236,15 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
>   					unsigned int num_clips)
>   {
>   	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> +	struct drm_i915_private *i915 = to_i915(obj->base.dev);
>   
>   	i915_gem_object_flush_if_display(obj);
> -	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
>   
> +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> +		return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips,
> +						 num_clips);
Hi,
Even if the userspace informs us of the dirty (damage) region of the 
front buffer being used, GEN9 to GEN12 still uses the HW Tracking 
function for PSR and FBC.
And if you look at the description of the intel_psr_flush() function, 
you can see that there are the following restrictions.

"Since the hardware frontbuffer tracking has gaps we need to integrate 
with the software frontbuffer tracking."

If this restriction is still valid from GEN9 to GEN12, even if the 
existing frontbuffer tracking function is not used, when 
intel_user_framebuffer_dirty() is called, in the case of PSR, 
psr_force_hw_tracking_exit() is called or intel_psr_exit() and 
schedule_work(psr.work) seems to be required.

In the case of FBC, it seems that calls to FBC deactive / FBC activate 
should be added.

If GEN9 to GEN12 do not have the above restrictions, please ignore this 
comment.

G.G.
> +
> +	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
>   	return 0;
>   }
>   
> diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> index 0492446cd04ad..3860f87dac31c 100644
> --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> @@ -112,6 +112,9 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
>   void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
>   				    unsigned frontbuffer_bits)
>   {
> +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> +		return;
> +
>   	spin_lock(&i915->fb_tracking.lock);
>   	i915->fb_tracking.flip_bits |= frontbuffer_bits;
>   	/* Remove stale busy bits due to the old buffer. */
> @@ -132,6 +135,12 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
>   void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
>   				     unsigned frontbuffer_bits)
>   {
> +	if (!HAS_FRONTBUFFER_RENDERING(i915)) {
> +		drm_WARN_ON_ONCE(&i915->drm, i915->fb_tracking.flip_bits |
> +					     i915->fb_tracking.busy_bits);
> +		return;
> +	}
> +
>   	spin_lock(&i915->fb_tracking.lock);
>   	/* Mask any cancelled flips. */
>   	frontbuffer_bits &= i915->fb_tracking.flip_bits;
> @@ -156,6 +165,9 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
>   void intel_frontbuffer_flip(struct drm_i915_private *i915,
>   			    unsigned frontbuffer_bits)
>   {
> +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> +		return;
> +
>   	spin_lock(&i915->fb_tracking.lock);
>   	/* Remove stale busy bits due to the old buffer. */
>   	i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
> @@ -170,6 +182,9 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
>   {
>   	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
>   
> +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> +		return;
> +
>   	if (origin == ORIGIN_CS) {
>   		spin_lock(&i915->fb_tracking.lock);
>   		i915->fb_tracking.busy_bits |= frontbuffer_bits;
> @@ -191,6 +206,9 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
>   {
>   	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
>   
> +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> +		return;
> +
>   	if (origin == ORIGIN_CS) {
>   		spin_lock(&i915->fb_tracking.lock);
>   		/* Filter out new bits since rendering started. */
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 91453f7dbd656..20c135a2bba33 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1721,6 +1721,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>   
>   #define HAS_ASYNC_FLIPS(i915)		(DISPLAY_VER(i915) >= 5)
>   
> +#define HAS_FRONTBUFFER_RENDERING(i915)	(DISPLAY_VER(i915) < 9)
> +
>   /* Only valid when HAS_DISPLAY() is true */
>   #define INTEL_DISPLAY_ENABLED(dev_priv) \
>   	(drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS
  2021-09-02 15:15   ` Gwan-gyeong Mun
@ 2021-09-03 20:36     ` Souza, Jose
  0 siblings, 0 replies; 28+ messages in thread
From: Souza, Jose @ 2021-09-03 20:36 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx

On Thu, 2021-09-02 at 18:15 +0300, Gwan-gyeong Mun wrote:
> 
> On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> > It started as a code style fix for the lines above 100 col but it
> > turned out to simplifications to intel_drrs_set_state().
> > Now it receives the desired refresh rate type, high or low.
> > 
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >   drivers/gpu/drm/i915/display/intel_drrs.c | 60 ++++++++---------------
> >   1 file changed, 21 insertions(+), 39 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> > index 1aa9793521158..5eb5033242575 100644
> > --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> > @@ -91,7 +91,7 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
> >    * intel_drrs_set_state - program registers for RR switch to take effect
> >    * @dev_priv: i915 device
> >    * @crtc_state: a pointer to the active intel_crtc_state
> > - * @refresh_rate: RR to be programmed
> > + * @refresh_type: high or low refresh rate to be programmed
> >    *
> >    * This function gets called when refresh rate (RR) has to be changed from
> >    * one frequency to another. Switches can be between high and low RR
> > @@ -102,19 +102,13 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
> >    */
> >   static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
> >   				 const struct intel_crtc_state *crtc_state,
> > -				 int refresh_rate)
> > +				 enum drrs_refresh_rate_type refresh_type)
> >   {
> >   	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> >   	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > -	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> > +	struct drm_display_mode *mode;
> >   
> > -	if (refresh_rate <= 0) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "Refresh rate should be positive non-zero.\n");
> > -		return;
> > -	}
> > -
> > -	if (intel_dp == NULL) {
> > +	if (!intel_dp) {
> >   		drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n");
> >   		return;
> >   	}
> > @@ -130,15 +124,8 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
> >   		return;
> >   	}
> >   
> > -	if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) ==
> > -			refresh_rate)
> > -		index = DRRS_LOW_RR;
> > -
> > -	if (index == dev_priv->drrs.refresh_rate_type) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "DRRS requested for previously set RR...ignoring\n");
> > +	if (refresh_type == dev_priv->drrs.refresh_rate_type)
> >   		return;
> > -	}
> >   
> >   	if (!crtc_state->hw.active) {
> >   		drm_dbg_kms(&dev_priv->drm,
> > @@ -147,7 +134,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
> >   	}
> >   
> >   	if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
> > -		switch (index) {
> > +		switch (refresh_type) {
> >   		case DRRS_HIGH_RR:
> >   			intel_dp_set_m_n(crtc_state, M1_N1);
> >   			break;
> > @@ -164,7 +151,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
> >   		u32 val;
> >   
> >   		val = intel_de_read(dev_priv, reg);
> > -		if (index > DRRS_HIGH_RR) {
> > +		if (refresh_type == DRRS_LOW_RR) {
> >   			if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> >   				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
> >   			else
> > @@ -178,10 +165,14 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
> >   		intel_de_write(dev_priv, reg, val);
> >   	}
> > 
> > -	dev_priv->drrs.refresh_rate_type = index;
> > +	dev_priv->drrs.refresh_rate_type = refresh_type;
> >   
> > +	if (refresh_type == DRRS_LOW_RR)
> > +		mode = intel_dp->attached_connector->panel.fixed_mode;
> > +	else
> > +		mode = intel_dp->attached_connector->panel.downclock_mode;
> For DRRS_LOW_RR refresh_type, panel.downclock_mode has to be used, and 
> for DRR_HIGH_RR, panel.fixed_mode has to be used.
> It should be modified as follows.
> 	if (refresh_type == DRRS_LOW_RR)
> 		mode = intel_dp->attached_connector->panel.downclock_mode;
> 	else
> 		mode = intel_dp->attached_connector->panel.fixed_mode;
> 
> Except for this, the rest of the code looks good to me.


Thanks for catching this, will fix it.

> 
> 
> >   	drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n",
> > -		    refresh_rate);
> > +		    drm_mode_vrefresh(mode));
> >   }
> >   
> >   static void
> > @@ -229,13 +220,7 @@ intel_drrs_disable_locked(struct intel_dp *intel_dp,
> >   {
> >   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> >   
> > -	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
> > -		int refresh;
> > -
> > -		refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode);
> > -		intel_drrs_set_state(dev_priv, crtc_state, refresh);
> > -	}
> > -
> > +	intel_drrs_set_state(dev_priv, crtc_state, DRRS_HIGH_RR);
> >   	dev_priv->drrs.dp = NULL;
> >   }
> >   
> > @@ -303,6 +288,7 @@ static void intel_drrs_downclock_work(struct work_struct *work)
> >   	struct drm_i915_private *dev_priv =
> >   		container_of(work, typeof(*dev_priv), drrs.work.work);
> >   	struct intel_dp *intel_dp;
> > +	struct drm_crtc *crtc;
> >   
> >   	mutex_lock(&dev_priv->drrs.mutex);
> >   
> > @@ -319,12 +305,8 @@ static void intel_drrs_downclock_work(struct work_struct *work)
> >   	if (dev_priv->drrs.busy_frontbuffer_bits)
> >   		goto unlock;
> >   
> > -	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) {
> > -		struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > -
> > -		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> > -				     drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode));
> > -	}
> > +	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > +	intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, DRRS_LOW_RR);
> >   
> >   unlock:
> >   	mutex_unlock(&dev_priv->drrs.mutex);
> > @@ -367,9 +349,9 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> >   	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> >   
> >   	/* invalidate means busy screen hence upclock */
> > -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > +	if (frontbuffer_bits)
> >   		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> > -				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > +				     DRRS_HIGH_RR);
> >   
> >   	mutex_unlock(&dev_priv->drrs.mutex);
> >   }
> > @@ -413,9 +395,9 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
> >   	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> >   
> >   	/* flush means busy screen hence upclock */
> > -	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
> > +	if (frontbuffer_bits)
> >   		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> > -				     drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode));
> > +				     DRRS_HIGH_RR);
> >   
> >   	/*
> >   	 * flush also means no more activity hence schedule downclock, if all
> > 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate
  2021-09-02 15:57   ` Gwan-gyeong Mun
@ 2021-09-03 21:52     ` Souza, Jose
  0 siblings, 0 replies; 28+ messages in thread
From: Souza, Jose @ 2021-09-03 21:52 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx

On Thu, 2021-09-02 at 18:57 +0300, Gwan-gyeong Mun wrote:
> 
> On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> > Both functions are pretty much equal, with minor changes that can be
> > handled by a single parameter.
> > 
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >   drivers/gpu/drm/i915/display/intel_drrs.c | 82 +++++++++--------------
> >   1 file changed, 32 insertions(+), 50 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
> > index 5eb5033242575..8583da4e82434 100644
> > --- a/drivers/gpu/drm/i915/display/intel_drrs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_drrs.c
> > @@ -312,18 +312,9 @@ static void intel_drrs_downclock_work(struct work_struct *work)
> >   	mutex_unlock(&dev_priv->drrs.mutex);
> >   }
> >   
> > -/**
> > - * intel_drrs_invalidate - Disable Idleness DRRS
> > - * @dev_priv: i915 device
> > - * @frontbuffer_bits: frontbuffer plane tracking bits
> > - *
> > - * This function gets called everytime rendering on the given planes start.
> > - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> > - *
> > - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > - */
> > -void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> > -			   unsigned int frontbuffer_bits)
> > +static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
> > +					  unsigned int frontbuffer_bits,
> > +					  bool invalidate)
> >   {
> >   	struct intel_dp *intel_dp;
> >   	struct drm_crtc *crtc;
> > @@ -346,16 +337,42 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> >   	pipe = to_intel_crtc(crtc)->pipe;
> >   
> >   	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > -	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> > +	if (invalidate)
> > +		dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
> > +	else
> > +		dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> >   
> > -	/* invalidate means busy screen hence upclock */
> > +	/* flush/invalidate means busy screen hence upclock */
> >   	if (frontbuffer_bits)
> >   		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> >   				     DRRS_HIGH_RR);
> >   
> > +	/*
> > +	 * flush also means no more activity hence schedule downclock, if all
> > +	 * other fbs are quiescent too
> > +	 */
> > +	if (!dev_priv->drrs.busy_frontbuffer_bits)
> > +		schedule_delayed_work(&dev_priv->drrs.work,
> > +				      msecs_to_jiffies(1000));
> This line of code was previously only used in the intel_drrs_flush() 
> function,
> In the case of the intel_drrs_invalidate() call scenario, it is not 
> confirmed whether dev_priv->drrs.busy_frontbuffer_bits is always true to 
> me. If it's not always true, it looks like you also need to check for 
> "not invalidate".
> Please ignore this comment if I'm wrong.

Huum yeah if there is a invalidate in another pipe that could delay the work to be executed or execute it without needing it.

Will change it to: if (!invalidate && !dev_priv->drrs.busy_frontbuffer_bit) It should handle this cases above.

Thanks for the catch again.

> 
> >   	mutex_unlock(&dev_priv->drrs.mutex);
> >   }
> >   
> > +/**
> > + * intel_drrs_invalidate - Disable Idleness DRRS
> > + * @dev_priv: i915 device
> > + * @frontbuffer_bits: frontbuffer plane tracking bits
> > + *
> > + * This function gets called everytime rendering on the given planes start.
> > + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
> > + *
> > + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
> > + */
> > +void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> > +			   unsigned int frontbuffer_bits)
> > +{
> > +	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, true);
> > +}
> > +
> >   /**
> >    * intel_drrs_flush - Restart Idleness DRRS
> >    * @dev_priv: i915 device
> > @@ -371,42 +388,7 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
> >   void intel_drrs_flush(struct drm_i915_private *dev_priv,
> >   		      unsigned int frontbuffer_bits)
> >   {
> > -	struct intel_dp *intel_dp;
> > -	struct drm_crtc *crtc;
> > -	enum pipe pipe;
> > -
> > -	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
> > -		return;
> > -
> > -	cancel_delayed_work(&dev_priv->drrs.work);
> > -
> > -	mutex_lock(&dev_priv->drrs.mutex);
> > -
> > -	intel_dp = dev_priv->drrs.dp;
> > -	if (!intel_dp) {
> > -		mutex_unlock(&dev_priv->drrs.mutex);
> > -		return;
> > -	}
> > -
> > -	crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
> > -	pipe = to_intel_crtc(crtc)->pipe;
> > -
> > -	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
> > -	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
> > -
> > -	/* flush means busy screen hence upclock */
> > -	if (frontbuffer_bits)
> > -		intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config,
> > -				     DRRS_HIGH_RR);
> > -
> > -	/*
> > -	 * flush also means no more activity hence schedule downclock, if all
> > -	 * other fbs are quiescent too
> > -	 */
> > -	if (!dev_priv->drrs.busy_frontbuffer_bits)
> > -		schedule_delayed_work(&dev_priv->drrs.work,
> > -				      msecs_to_jiffies(1000));
> > -	mutex_unlock(&dev_priv->drrs.mutex);
> > +	intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
> >   }
> >   
> >   /**
> > 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support
  2021-09-02 18:42   ` Gwan-gyeong Mun
@ 2021-09-03 22:09     ` Souza, Jose
  2021-09-04  0:26       ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2021-09-03 22:09 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx
  Cc: daniel, ville.syrjala, Nikula, Jani, Vivi, Rodrigo

On Thu, 2021-09-02 at 21:42 +0300, Gwan-gyeong Mun wrote:
> 
> On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> > By now all the userspace applications should have migrated to atomic
> > or at least be calling DRM_IOCTL_MODE_DIRTYFB.
> > 
> > With that we can kill frontbuffer rendering support in i915 for
> > modern platforms.
> > 
> > So here converting legacy APIs into atomic commits so it can be
> > properly handled by driver i915.
> > 
> > Several IGT tests will fail with this changes, because some tests
> > were stressing those frontbuffer rendering scenarios that no userspace
> > should be using by now, fixes to IGT should be sent soon.
> > 
> > v2:
> > - return earlier to not set fb_tracking.busy/flip_bits
> > - added a warn on to make sure we are not setting the busy/flip_bits
> > 
> > Cc: Daniel Vetter <daniel@ffwll.ch>
> > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Jani Nikula <jani.nikula@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >   drivers/gpu/drm/i915/display/intel_cursor.c    |  6 ++----
> >   drivers/gpu/drm/i915/display/intel_fb.c        |  8 +++++++-
> >   .../gpu/drm/i915/display/intel_frontbuffer.c   | 18 ++++++++++++++++++
> >   drivers/gpu/drm/i915/i915_drv.h                |  2 ++
> >   4 files changed, 29 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
> > index c7618fef01439..5aa996c3b7980 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cursor.c
> > +++ b/drivers/gpu/drm/i915/display/intel_cursor.c
> > @@ -617,6 +617,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> >   			   u32 src_w, u32 src_h,
> >   			   struct drm_modeset_acquire_ctx *ctx)
> >   {
> > +	struct drm_i915_private *i915 = to_i915(_crtc->dev);
> >   	struct intel_plane *plane = to_intel_plane(_plane);
> >   	struct intel_crtc *crtc = to_intel_crtc(_crtc);
> >   	struct intel_plane_state *old_plane_state =
> > @@ -633,12 +634,9 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> >   	 * PSR2 selective fetch also requires the slow path as
> >   	 * PSR2 plane and transcoder registers can only be updated during
> >   	 * vblank.
> > -	 *
> > -	 * FIXME bigjoiner fastpath would be good
> >   	 */
> >   	if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
> > -	    crtc_state->update_pipe || crtc_state->bigjoiner ||
> > -	    crtc_state->enable_psr2_sel_fetch)
> > +	    crtc_state->update_pipe || !HAS_FRONTBUFFER_RENDERING(i915))
> >   		goto slow;
> >   
> >   	/*
> > diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
> > index e4b8602ec0cd2..3eb60785c9f29 100644
> > --- a/drivers/gpu/drm/i915/display/intel_fb.c
> > +++ b/drivers/gpu/drm/i915/display/intel_fb.c
> > @@ -3,6 +3,7 @@
> >    * Copyright © 2021 Intel Corporation
> >    */
> >   
> > +#include <drm/drm_damage_helper.h>
> >   #include <drm/drm_framebuffer.h>
> >   #include <drm/drm_modeset_helper.h>
> >   
> > @@ -1235,10 +1236,15 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
> >   					unsigned int num_clips)
> >   {
> >   	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > +	struct drm_i915_private *i915 = to_i915(obj->base.dev);
> >   
> >   	i915_gem_object_flush_if_display(obj);
> > -	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> >   
> > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > +		return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips,
> > +						 num_clips);
> Hi,
> Even if the userspace informs us of the dirty (damage) region of the 
> front buffer being used, GEN9 to GEN12 still uses the HW Tracking 
> function for PSR and FBC.
> And if you look at the description of the intel_psr_flush() function, 
> you can see that there are the following restrictions.
> 
> "Since the hardware frontbuffer tracking has gaps we need to integrate 
> with the software frontbuffer tracking."
> 
> If this restriction is still valid from GEN9 to GEN12, even if the 
> existing frontbuffer tracking function is not used, when 
> intel_user_framebuffer_dirty() is called, in the case of PSR, 
> psr_force_hw_tracking_exit() is called or intel_psr_exit() and 
> schedule_work(psr.work) seems to be required.

As this will trigger calls to the functions that write the plane registers PSR HW tracking and FBC tracking will understand a page flip happened even
if going from and to the same surface.

But will double check it.

> 
> In the case of FBC, it seems that calls to FBC deactive / FBC activate 
> should be added.
> 
> If GEN9 to GEN12 do not have the above restrictions, please ignore this 
> comment.
> 
> G.G.
> > +
> > +	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> >   	return 0;
> >   }
> >   
> > diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > index 0492446cd04ad..3860f87dac31c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > @@ -112,6 +112,9 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
> >   void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
> >   				    unsigned frontbuffer_bits)
> >   {
> > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > +		return;
> > +
> >   	spin_lock(&i915->fb_tracking.lock);
> >   	i915->fb_tracking.flip_bits |= frontbuffer_bits;
> >   	/* Remove stale busy bits due to the old buffer. */
> > @@ -132,6 +135,12 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
> >   void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
> >   				     unsigned frontbuffer_bits)
> >   {
> > +	if (!HAS_FRONTBUFFER_RENDERING(i915)) {
> > +		drm_WARN_ON_ONCE(&i915->drm, i915->fb_tracking.flip_bits |
> > +					     i915->fb_tracking.busy_bits);
> > +		return;
> > +	}
> > +
> >   	spin_lock(&i915->fb_tracking.lock);
> >   	/* Mask any cancelled flips. */
> >   	frontbuffer_bits &= i915->fb_tracking.flip_bits;
> > @@ -156,6 +165,9 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
> >   void intel_frontbuffer_flip(struct drm_i915_private *i915,
> >   			    unsigned frontbuffer_bits)
> >   {
> > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > +		return;
> > +
> >   	spin_lock(&i915->fb_tracking.lock);
> >   	/* Remove stale busy bits due to the old buffer. */
> >   	i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
> > @@ -170,6 +182,9 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
> >   {
> >   	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
> >   
> > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > +		return;
> > +
> >   	if (origin == ORIGIN_CS) {
> >   		spin_lock(&i915->fb_tracking.lock);
> >   		i915->fb_tracking.busy_bits |= frontbuffer_bits;
> > @@ -191,6 +206,9 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
> >   {
> >   	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
> >   
> > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > +		return;
> > +
> >   	if (origin == ORIGIN_CS) {
> >   		spin_lock(&i915->fb_tracking.lock);
> >   		/* Filter out new bits since rendering started. */
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 91453f7dbd656..20c135a2bba33 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1721,6 +1721,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
> >   
> >   #define HAS_ASYNC_FLIPS(i915)		(DISPLAY_VER(i915) >= 5)
> >   
> > +#define HAS_FRONTBUFFER_RENDERING(i915)	(DISPLAY_VER(i915) < 9)
> > +
> >   /* Only valid when HAS_DISPLAY() is true */
> >   #define INTEL_DISPLAY_ENABLED(dev_priv) \
> >   	(drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
> > 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support
  2021-09-03 22:09     ` Souza, Jose
@ 2021-09-04  0:26       ` Souza, Jose
  2021-09-06  9:44         ` Gwan-gyeong Mun
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2021-09-04  0:26 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx
  Cc: daniel, ville.syrjala, Nikula, Jani, Vivi, Rodrigo

On Fri, 2021-09-03 at 22:09 +0000, Souza, Jose wrote:
> On Thu, 2021-09-02 at 21:42 +0300, Gwan-gyeong Mun wrote:
> > 
> > On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> > > By now all the userspace applications should have migrated to atomic
> > > or at least be calling DRM_IOCTL_MODE_DIRTYFB.
> > > 
> > > With that we can kill frontbuffer rendering support in i915 for
> > > modern platforms.
> > > 
> > > So here converting legacy APIs into atomic commits so it can be
> > > properly handled by driver i915.
> > > 
> > > Several IGT tests will fail with this changes, because some tests
> > > were stressing those frontbuffer rendering scenarios that no userspace
> > > should be using by now, fixes to IGT should be sent soon.
> > > 
> > > v2:
> > > - return earlier to not set fb_tracking.busy/flip_bits
> > > - added a warn on to make sure we are not setting the busy/flip_bits
> > > 
> > > Cc: Daniel Vetter <daniel@ffwll.ch>
> > > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Cc: Jani Nikula <jani.nikula@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >   drivers/gpu/drm/i915/display/intel_cursor.c    |  6 ++----
> > >   drivers/gpu/drm/i915/display/intel_fb.c        |  8 +++++++-
> > >   .../gpu/drm/i915/display/intel_frontbuffer.c   | 18 ++++++++++++++++++
> > >   drivers/gpu/drm/i915/i915_drv.h                |  2 ++
> > >   4 files changed, 29 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
> > > index c7618fef01439..5aa996c3b7980 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_cursor.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_cursor.c
> > > @@ -617,6 +617,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > >   			   u32 src_w, u32 src_h,
> > >   			   struct drm_modeset_acquire_ctx *ctx)
> > >   {
> > > +	struct drm_i915_private *i915 = to_i915(_crtc->dev);
> > >   	struct intel_plane *plane = to_intel_plane(_plane);
> > >   	struct intel_crtc *crtc = to_intel_crtc(_crtc);
> > >   	struct intel_plane_state *old_plane_state =
> > > @@ -633,12 +634,9 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > >   	 * PSR2 selective fetch also requires the slow path as
> > >   	 * PSR2 plane and transcoder registers can only be updated during
> > >   	 * vblank.
> > > -	 *
> > > -	 * FIXME bigjoiner fastpath would be good
> > >   	 */
> > >   	if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
> > > -	    crtc_state->update_pipe || crtc_state->bigjoiner ||
> > > -	    crtc_state->enable_psr2_sel_fetch)
> > > +	    crtc_state->update_pipe || !HAS_FRONTBUFFER_RENDERING(i915))
> > >   		goto slow;
> > >   
> > >   	/*
> > > diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
> > > index e4b8602ec0cd2..3eb60785c9f29 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_fb.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_fb.c
> > > @@ -3,6 +3,7 @@
> > >    * Copyright © 2021 Intel Corporation
> > >    */
> > >   
> > > +#include <drm/drm_damage_helper.h>
> > >   #include <drm/drm_framebuffer.h>
> > >   #include <drm/drm_modeset_helper.h>
> > >   
> > > @@ -1235,10 +1236,15 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
> > >   					unsigned int num_clips)
> > >   {
> > >   	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > > +	struct drm_i915_private *i915 = to_i915(obj->base.dev);
> > >   
> > >   	i915_gem_object_flush_if_display(obj);
> > > -	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > >   
> > > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > > +		return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips,
> > > +						 num_clips);
> > Hi,
> > Even if the userspace informs us of the dirty (damage) region of the 
> > front buffer being used, GEN9 to GEN12 still uses the HW Tracking 
> > function for PSR and FBC.
> > And if you look at the description of the intel_psr_flush() function, 
> > you can see that there are the following restrictions.
> > 
> > "Since the hardware frontbuffer tracking has gaps we need to integrate 
> > with the software frontbuffer tracking."
> > 
> > If this restriction is still valid from GEN9 to GEN12, even if the 
> > existing frontbuffer tracking function is not used, when 
> > intel_user_framebuffer_dirty() is called, in the case of PSR, 
> > psr_force_hw_tracking_exit() is called or intel_psr_exit() and 
> > schedule_work(psr.work) seems to be required.
> 
> As this will trigger calls to the functions that write the plane registers PSR HW tracking and FBC tracking will understand a page flip happened even
> if going from and to the same surface.
> 
> But will double check it.

Yep, no issues with PSR or FBC. HW understand as a flip and it is properly handled.

> 
> > 
> > In the case of FBC, it seems that calls to FBC deactive / FBC activate 
> > should be added.
> > 
> > If GEN9 to GEN12 do not have the above restrictions, please ignore this 
> > comment.
> > 
> > G.G.
> > > +
> > > +	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > >   	return 0;
> > >   }
> > >   
> > > diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > > index 0492446cd04ad..3860f87dac31c 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> > > @@ -112,6 +112,9 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
> > >   void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
> > >   				    unsigned frontbuffer_bits)
> > >   {
> > > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > > +		return;
> > > +
> > >   	spin_lock(&i915->fb_tracking.lock);
> > >   	i915->fb_tracking.flip_bits |= frontbuffer_bits;
> > >   	/* Remove stale busy bits due to the old buffer. */
> > > @@ -132,6 +135,12 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
> > >   void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
> > >   				     unsigned frontbuffer_bits)
> > >   {
> > > +	if (!HAS_FRONTBUFFER_RENDERING(i915)) {
> > > +		drm_WARN_ON_ONCE(&i915->drm, i915->fb_tracking.flip_bits |
> > > +					     i915->fb_tracking.busy_bits);
> > > +		return;
> > > +	}
> > > +
> > >   	spin_lock(&i915->fb_tracking.lock);
> > >   	/* Mask any cancelled flips. */
> > >   	frontbuffer_bits &= i915->fb_tracking.flip_bits;
> > > @@ -156,6 +165,9 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
> > >   void intel_frontbuffer_flip(struct drm_i915_private *i915,
> > >   			    unsigned frontbuffer_bits)
> > >   {
> > > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > > +		return;
> > > +
> > >   	spin_lock(&i915->fb_tracking.lock);
> > >   	/* Remove stale busy bits due to the old buffer. */
> > >   	i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
> > > @@ -170,6 +182,9 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
> > >   {
> > >   	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
> > >   
> > > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > > +		return;
> > > +
> > >   	if (origin == ORIGIN_CS) {
> > >   		spin_lock(&i915->fb_tracking.lock);
> > >   		i915->fb_tracking.busy_bits |= frontbuffer_bits;
> > > @@ -191,6 +206,9 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
> > >   {
> > >   	struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
> > >   
> > > +	if (!HAS_FRONTBUFFER_RENDERING(i915))
> > > +		return;
> > > +
> > >   	if (origin == ORIGIN_CS) {
> > >   		spin_lock(&i915->fb_tracking.lock);
> > >   		/* Filter out new bits since rendering started. */
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index 91453f7dbd656..20c135a2bba33 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -1721,6 +1721,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
> > >   
> > >   #define HAS_ASYNC_FLIPS(i915)		(DISPLAY_VER(i915) >= 5)
> > >   
> > > +#define HAS_FRONTBUFFER_RENDERING(i915)	(DISPLAY_VER(i915) < 9)
> > > +
> > >   /* Only valid when HAS_DISPLAY() is true */
> > >   #define INTEL_DISPLAY_ENABLED(dev_priv) \
> > >   	(drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
> > > 
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support
  2021-09-04  0:26       ` Souza, Jose
@ 2021-09-06  9:44         ` Gwan-gyeong Mun
  0 siblings, 0 replies; 28+ messages in thread
From: Gwan-gyeong Mun @ 2021-09-06  9:44 UTC (permalink / raw)
  To: Souza, Jose, intel-gfx; +Cc: daniel, ville.syrjala, Nikula, Jani, Vivi, Rodrigo

Looks good to me.
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>

On 9/4/21 3:26 AM, Souza, Jose wrote:
> On Fri, 2021-09-03 at 22:09 +0000, Souza, Jose wrote:
>> On Thu, 2021-09-02 at 21:42 +0300, Gwan-gyeong Mun wrote:
>>>
>>> On 8/25/21 3:58 AM, José Roberto de Souza wrote:
>>>> By now all the userspace applications should have migrated to atomic
>>>> or at least be calling DRM_IOCTL_MODE_DIRTYFB.
>>>>
>>>> With that we can kill frontbuffer rendering support in i915 for
>>>> modern platforms.
>>>>
>>>> So here converting legacy APIs into atomic commits so it can be
>>>> properly handled by driver i915.
>>>>
>>>> Several IGT tests will fail with this changes, because some tests
>>>> were stressing those frontbuffer rendering scenarios that no userspace
>>>> should be using by now, fixes to IGT should be sent soon.
>>>>
>>>> v2:
>>>> - return earlier to not set fb_tracking.busy/flip_bits
>>>> - added a warn on to make sure we are not setting the busy/flip_bits
>>>>
>>>> Cc: Daniel Vetter <daniel@ffwll.ch>
>>>> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
>>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>>> Cc: Jani Nikula <jani.nikula@intel.com>
>>>> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>>>> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
>>>> ---
>>>>    drivers/gpu/drm/i915/display/intel_cursor.c    |  6 ++----
>>>>    drivers/gpu/drm/i915/display/intel_fb.c        |  8 +++++++-
>>>>    .../gpu/drm/i915/display/intel_frontbuffer.c   | 18 ++++++++++++++++++
>>>>    drivers/gpu/drm/i915/i915_drv.h                |  2 ++
>>>>    4 files changed, 29 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
>>>> index c7618fef01439..5aa996c3b7980 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_cursor.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_cursor.c
>>>> @@ -617,6 +617,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
>>>>       u32 src_w, u32 src_h,
>>>>       struct drm_modeset_acquire_ctx *ctx)
>>>>    {
>>>> +struct drm_i915_private *i915 = to_i915(_crtc->dev);
>>>>    struct intel_plane *plane = to_intel_plane(_plane);
>>>>    struct intel_crtc *crtc = to_intel_crtc(_crtc);
>>>>    struct intel_plane_state *old_plane_state =
>>>> @@ -633,12 +634,9 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
>>>>     * PSR2 selective fetch also requires the slow path as
>>>>     * PSR2 plane and transcoder registers can only be updated during
>>>>     * vblank.
>>>> - *
>>>> - * FIXME bigjoiner fastpath would be good
>>>>     */
>>>>    if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
>>>> -    crtc_state->update_pipe || crtc_state->bigjoiner ||
>>>> -    crtc_state->enable_psr2_sel_fetch)
>>>> +    crtc_state->update_pipe || !HAS_FRONTBUFFER_RENDERING(i915))
>>>>    goto slow;
>>>>
>>>>    /*
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
>>>> index e4b8602ec0cd2..3eb60785c9f29 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_fb.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_fb.c
>>>> @@ -3,6 +3,7 @@
>>>>     * Copyright © 2021 Intel Corporation
>>>>     */
>>>>
>>>> +#include <drm/drm_damage_helper.h>
>>>>    #include <drm/drm_framebuffer.h>
>>>>    #include <drm/drm_modeset_helper.h>
>>>>
>>>> @@ -1235,10 +1236,15 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
>>>>    unsigned int num_clips)
>>>>    {
>>>>    struct drm_i915_gem_object *obj = intel_fb_obj(fb);
>>>> +struct drm_i915_private *i915 = to_i915(obj->base.dev);
>>>>
>>>>    i915_gem_object_flush_if_display(obj);
>>>> -intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
>>>>
>>>> +if (!HAS_FRONTBUFFER_RENDERING(i915))
>>>> +return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips,
>>>> + num_clips);
>>> Hi,
>>> Even if the userspace informs us of the dirty (damage) region of the
>>> front buffer being used, GEN9 to GEN12 still uses the HW Tracking
>>> function for PSR and FBC.
>>> And if you look at the description of the intel_psr_flush() function,
>>> you can see that there are the following restrictions.
>>>
>>> "Since the hardware frontbuffer tracking has gaps we need to integrate
>>> with the software frontbuffer tracking."
>>>
>>> If this restriction is still valid from GEN9 to GEN12, even if the
>>> existing frontbuffer tracking function is not used, when
>>> intel_user_framebuffer_dirty() is called, in the case of PSR,
>>> psr_force_hw_tracking_exit() is called or intel_psr_exit() and
>>> schedule_work(psr.work) seems to be required.
>>
>> As this will trigger calls to the functions that write the plane registers PSR HW tracking and FBC tracking will understand a page flip happened even
>> if going from and to the same surface.
>>
>> But will double check it.
> 
> Yep, no issues with PSR or FBC. HW understand as a flip and it is properly handled.
> 
>>
>>>
>>> In the case of FBC, it seems that calls to FBC deactive / FBC activate
>>> should be added.
>>>
>>> If GEN9 to GEN12 do not have the above restrictions, please ignore this
>>> comment.
>>>
>>> G.G.
>>>> +
>>>> +intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
>>>>    return 0;
>>>>    }
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
>>>> index 0492446cd04ad..3860f87dac31c 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
>>>> @@ -112,6 +112,9 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
>>>>    void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
>>>>        unsigned frontbuffer_bits)
>>>>    {
>>>> +if (!HAS_FRONTBUFFER_RENDERING(i915))
>>>> +return;
>>>> +
>>>>    spin_lock(&i915->fb_tracking.lock);
>>>>    i915->fb_tracking.flip_bits |= frontbuffer_bits;
>>>>    /* Remove stale busy bits due to the old buffer. */
>>>> @@ -132,6 +135,12 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
>>>>    void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
>>>>         unsigned frontbuffer_bits)
>>>>    {
>>>> +if (!HAS_FRONTBUFFER_RENDERING(i915)) {
>>>> +drm_WARN_ON_ONCE(&i915->drm, i915->fb_tracking.flip_bits |
>>>> +     i915->fb_tracking.busy_bits);
>>>> +return;
>>>> +}
>>>> +
>>>>    spin_lock(&i915->fb_tracking.lock);
>>>>    /* Mask any cancelled flips. */
>>>>    frontbuffer_bits &= i915->fb_tracking.flip_bits;
>>>> @@ -156,6 +165,9 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
>>>>    void intel_frontbuffer_flip(struct drm_i915_private *i915,
>>>>        unsigned frontbuffer_bits)
>>>>    {
>>>> +if (!HAS_FRONTBUFFER_RENDERING(i915))
>>>> +return;
>>>> +
>>>>    spin_lock(&i915->fb_tracking.lock);
>>>>    /* Remove stale busy bits due to the old buffer. */
>>>>    i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
>>>> @@ -170,6 +182,9 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
>>>>    {
>>>>    struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
>>>>
>>>> +if (!HAS_FRONTBUFFER_RENDERING(i915))
>>>> +return;
>>>> +
>>>>    if (origin == ORIGIN_CS) {
>>>>    spin_lock(&i915->fb_tracking.lock);
>>>>    i915->fb_tracking.busy_bits |= frontbuffer_bits;
>>>> @@ -191,6 +206,9 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
>>>>    {
>>>>    struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
>>>>
>>>> +if (!HAS_FRONTBUFFER_RENDERING(i915))
>>>> +return;
>>>> +
>>>>    if (origin == ORIGIN_CS) {
>>>>    spin_lock(&i915->fb_tracking.lock);
>>>>    /* Filter out new bits since rendering started. */
>>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>>>> index 91453f7dbd656..20c135a2bba33 100644
>>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>>> @@ -1721,6 +1721,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>>>>
>>>>    #define HAS_ASYNC_FLIPS(i915)(DISPLAY_VER(i915) >= 5)
>>>>
>>>> +#define HAS_FRONTBUFFER_RENDERING(i915)(DISPLAY_VER(i915) < 9)
>>>> +
>>>>    /* Only valid when HAS_DISPLAY() is true */
>>>>    #define INTEL_DISPLAY_ENABLED(dev_priv) \
>>>>    (drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
>>>>
>>
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Intel-gfx] [PATCH v2 8/8] drm/i915/display: Drop PSR frontbuffer rendering support
  2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/display: Drop PSR " José Roberto de Souza
@ 2021-09-06 16:05   ` Gwan-gyeong Mun
  0 siblings, 0 replies; 28+ messages in thread
From: Gwan-gyeong Mun @ 2021-09-06 16:05 UTC (permalink / raw)
  To: José Roberto de Souza, intel-gfx

Looks good to me.
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>

On 8/25/21 3:58 AM, José Roberto de Souza wrote:
> After commit "drm/i915/display/skl+: Drop frontbuffer rendering
> support" frontbuffer rendering is not supported for display 9 and
> newer and as PSR is only supported by default in display 9 and newer
> we can now drop all frontbuffer rendering support for PSR code.
> 
> Some DC3CO code was commented with a macro, because the function
> caller is being dropped. As DC3CO is already disabled by default
> because it requires changes in its sequences
> 
> Two DC3CO functions lost their callers while dropping frontbuffer
> rendering but as DC3CO is already disabled by default because it
> requires fixes, will leave this task to whoever will fix DC3CO.
> 
> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>   .../drm/i915/display/intel_display_debugfs.c  |   2 -
>   .../drm/i915/display/intel_display_types.h    |   2 -
>   .../gpu/drm/i915/display/intel_frontbuffer.c  |   2 -
>   drivers/gpu/drm/i915/display/intel_psr.c      | 186 ++----------------
>   drivers/gpu/drm/i915/display/intel_psr.h      |   8 +-
>   5 files changed, 18 insertions(+), 182 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index ca819f9e353d0..6d733b276d5b0 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -374,8 +374,6 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
>   	seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
>   		   enableddisabled(enabled), val);
>   	psr_source_status(intel_dp, m);
> -	seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
> -		   psr->busy_frontbuffer_bits);
>   
>   	/*
>   	 * SKL+ Perf counter is reset to 0 everytime DC state is entered
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index c2725d07b9303..18616435dcb18 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1512,7 +1512,6 @@ struct intel_psr {
>   	enum transcoder transcoder;
>   	bool active;
>   	struct work_struct work;
> -	unsigned int busy_frontbuffer_bits;
>   	bool sink_psr2_support;
>   	bool link_standby;
>   	bool colorimetry_support;
> @@ -1523,7 +1522,6 @@ struct intel_psr {
>   	ktime_t last_entry_attempt;
>   	ktime_t last_exit;
>   	bool sink_not_reliable;
> -	bool irq_aux_error;
>   	u16 su_w_granularity;
>   	u16 su_y_granularity;
>   	u32 dc3co_exitline;
> diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> index 3860f87dac31c..1d8314d3712f4 100644
> --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
> @@ -93,7 +93,6 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
>   
>   	might_sleep();
>   	intel_drrs_flush(i915, frontbuffer_bits);
> -	intel_psr_flush(i915, frontbuffer_bits, origin);
>   	intel_fbc_flush(i915, frontbuffer_bits, origin);
>   }
>   
> @@ -195,7 +194,6 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
>   	trace_intel_frontbuffer_invalidate(frontbuffer_bits, origin);
>   
>   	might_sleep();
> -	intel_psr_invalidate(i915, frontbuffer_bits, origin);
>   	intel_drrs_invalidate(i915, frontbuffer_bits);
>   	intel_fbc_invalidate(i915, frontbuffer_bits, origin);
>   }
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 3f6fb7d67f84d..8c9bd5846a8d0 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -224,15 +224,12 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
>   		drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
>   			 transcoder_name(cpu_transcoder));
>   
> -		intel_dp->psr.irq_aux_error = true;
> -
>   		/*
>   		 * If this interruption is not masked it will keep
>   		 * interrupting so fast that it prevents the scheduled
>   		 * work to run.
>   		 * Also after a PSR error, we don't want to arm PSR
>   		 * again so we don't care about unmask the interruption
> -		 * or unset irq_aux_error.
>   		 */
>   		val = intel_de_read(dev_priv, imr_reg);
>   		val |= EDP_PSR_ERROR(trans_shift);
> @@ -614,14 +611,6 @@ static void psr2_program_idle_frames(struct intel_dp *intel_dp,
>   	intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val);
>   }
>   
> -static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	psr2_program_idle_frames(intel_dp, 0);
> -	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
> -}
> -
>   static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
>   {
>   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> @@ -1177,7 +1166,6 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
>   	drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
>   
>   	intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
> -	intel_dp->psr.busy_frontbuffer_bits = 0;
>   	intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>   	intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
>   	/* DC5/DC6 requires at least 6 idle frames */
> @@ -1784,36 +1772,6 @@ void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state)
>   	}
>   }
>   
> -static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	i915_reg_t reg;
> -	u32 mask;
> -	int err;
> -
> -	if (!intel_dp->psr.enabled)
> -		return false;
> -
> -	if (intel_dp->psr.psr2_enabled) {
> -		reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
> -		mask = EDP_PSR2_STATUS_STATE_MASK;
> -	} else {
> -		reg = EDP_PSR_STATUS(intel_dp->psr.transcoder);
> -		mask = EDP_PSR_STATUS_STATE_MASK;
> -	}
> -
> -	mutex_unlock(&intel_dp->psr.lock);
> -
> -	err = intel_de_wait_for_clear(dev_priv, reg, mask, 50);
> -	if (err)
> -		drm_err(&dev_priv->drm,
> -			"Timed out waiting for PSR Idle for re-enable\n");
> -
> -	/* After the unlocked wait, verify that PSR is still wanted! */
> -	mutex_lock(&intel_dp->psr.lock);
> -	return err == 0 && intel_dp->psr.enabled;
> -}
> -
>   static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
>   {
>   	struct drm_connector_list_iter conn_iter;
> @@ -1912,16 +1870,6 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
>   	return ret;
>   }
>   
> -static void intel_psr_handle_irq(struct intel_dp *intel_dp)
> -{
> -	struct intel_psr *psr = &intel_dp->psr;
> -
> -	intel_psr_disable_locked(intel_dp);
> -	psr->sink_not_reliable = true;
> -	/* let's make sure that sink is awaken */
> -	drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
> -}
> -
>   static void intel_psr_work(struct work_struct *work)
>   {
>   	struct intel_dp *intel_dp =
> @@ -1929,75 +1877,30 @@ static void intel_psr_work(struct work_struct *work)
>   
>   	mutex_lock(&intel_dp->psr.lock);
>   
> -	if (!intel_dp->psr.enabled)
> -		goto unlock;
> -
> -	if (READ_ONCE(intel_dp->psr.irq_aux_error))
> -		intel_psr_handle_irq(intel_dp);
> -
> -	/*
> -	 * We have to make sure PSR is ready for re-enable
> -	 * otherwise it keeps disabled until next full enable/disable cycle.
> -	 * PSR might take some time to get fully disabled
> -	 * and be ready for re-enable.
> -	 */
> -	if (!__psr_wait_for_idle_locked(intel_dp))
> -		goto unlock;
> -
> -	/*
> -	 * The delayed work can race with an invalidate hence we need to
> -	 * recheck. Since psr_flush first clears this and then reschedules we
> -	 * won't ever miss a flush when bailing out here.
> -	 */
> -	if (intel_dp->psr.busy_frontbuffer_bits || intel_dp->psr.active)
> -		goto unlock;
> +	/* Handling PSR error interruption */
> +	intel_psr_disable_locked(intel_dp);
> +	intel_dp->psr.sink_not_reliable = true;
> +	/* let's make sure that sink is awaken */
> +	drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
>   
> -	intel_psr_activate(intel_dp);
> -unlock:
>   	mutex_unlock(&intel_dp->psr.lock);
>   }
>   
> -/**
> - * intel_psr_invalidate - Invalidade PSR
> - * @dev_priv: i915 device
> - * @frontbuffer_bits: frontbuffer plane tracking bits
> - * @origin: which operation caused the invalidate
> - *
> - * Since the hardware frontbuffer tracking has gaps we need to integrate
> - * with the software frontbuffer tracking. This function gets called every
> - * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be
> - * disabled if the frontbuffer mask contains a buffer relevant to PSR.
> - *
> - * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
> +/*
> + * TODO: Functions below lost their callers to a refactor but as DC3CO is
> + * already disabled by default because it requires fixes, will leave this task
> + * to whoever will fix DC3CO.
>    */
> -void intel_psr_invalidate(struct drm_i915_private *dev_priv,
> -			  unsigned frontbuffer_bits, enum fb_op_origin origin)
> -{
> -	struct intel_encoder *encoder;
> -
> -	if (origin == ORIGIN_FLIP)
> -		return;
> -
> -	for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
> -		unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
> -		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> -
> -		mutex_lock(&intel_dp->psr.lock);
> -		if (!intel_dp->psr.enabled) {
> -			mutex_unlock(&intel_dp->psr.lock);
> -			continue;
> -		}
> -
> -		pipe_frontbuffer_bits &=
> -			INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
> -		intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits;
> +#if 0
>   
> -		if (pipe_frontbuffer_bits)
> -			intel_psr_exit(intel_dp);
> +static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
> +{
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>   
> -		mutex_unlock(&intel_dp->psr.lock);
> -	}
> +	psr2_program_idle_frames(intel_dp, 0);
> +	intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
>   }
> +
>   /*
>    * When we will be completely rely on PSR2 S/W tracking in future,
>    * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP
> @@ -2032,62 +1935,7 @@ tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
>   	mutex_unlock(&intel_dp->psr.lock);
>   }
>   
> -/**
> - * intel_psr_flush - Flush PSR
> - * @dev_priv: i915 device
> - * @frontbuffer_bits: frontbuffer plane tracking bits
> - * @origin: which operation caused the flush
> - *
> - * Since the hardware frontbuffer tracking has gaps we need to integrate
> - * with the software frontbuffer tracking. This function gets called every
> - * time frontbuffer rendering has completed and flushed out to memory. PSR
> - * can be enabled again if no other frontbuffer relevant to PSR is dirty.
> - *
> - * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
> - */
> -void intel_psr_flush(struct drm_i915_private *dev_priv,
> -		     unsigned frontbuffer_bits, enum fb_op_origin origin)
> -{
> -	struct intel_encoder *encoder;
> -
> -	for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
> -		unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
> -		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> -
> -		if (origin == ORIGIN_FLIP) {
> -			tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin);
> -			continue;
> -		}
> -
> -		mutex_lock(&intel_dp->psr.lock);
> -		if (!intel_dp->psr.enabled) {
> -			mutex_unlock(&intel_dp->psr.lock);
> -			continue;
> -		}
> -
> -		pipe_frontbuffer_bits &=
> -			INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
> -		intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits;
> -
> -		/*
> -		 * If the PSR is paused by an explicit intel_psr_paused() call,
> -		 * 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;
> -		}
> -
> -		/* By definition flush = invalidate + flush */
> -		if (pipe_frontbuffer_bits)
> -			psr_force_hw_tracking_exit(intel_dp);
> -
> -		if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
> -			schedule_work(&intel_dp->psr.work);
> -		mutex_unlock(&intel_dp->psr.lock);
> -	}
> -}
> +#endif
>   
>   /**
>    * intel_psr_init - Init basic PSR work and mutex.
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
> index 641521b101c82..58e2e5c2b81ef 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -6,7 +6,7 @@
>   #ifndef __INTEL_PSR_H__
>   #define __INTEL_PSR_H__
>   
> -#include "intel_frontbuffer.h"
> +#include <linux/types.h>
>   
>   struct drm_connector;
>   struct drm_connector_state;
> @@ -29,12 +29,6 @@ void intel_psr_update(struct intel_dp *intel_dp,
>   		      const struct intel_crtc_state *crtc_state,
>   		      const struct drm_connector_state *conn_state);
>   int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
> -void intel_psr_invalidate(struct drm_i915_private *dev_priv,
> -			  unsigned frontbuffer_bits,
> -			  enum fb_op_origin origin);
> -void intel_psr_flush(struct drm_i915_private *dev_priv,
> -		     unsigned frontbuffer_bits,
> -		     enum fb_op_origin origin);
>   void intel_psr_init(struct intel_dp *intel_dp);
>   void intel_psr_compute_config(struct intel_dp *intel_dp,
>   			      struct intel_crtc_state *crtc_state);
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2021-09-06 16:05 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-25  0:58 [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer José Roberto de Souza
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 1/8] drm/i915/display: Drop PSR support from HSW and BDW José Roberto de Souza
2021-08-25 15:50   ` Rodrigo Vivi
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 2/8] drm/i915/display: Move DRRS code its own file José Roberto de Souza
2021-08-25 15:55   ` Rodrigo Vivi
2021-08-25 17:23     ` Souza, Jose
2021-08-25 18:52       ` Rodrigo Vivi
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 3/8] drm/i915/display: Renaming DRRS functions to intel_drrs_*() José Roberto de Souza
2021-08-25 15:56   ` Rodrigo Vivi
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 4/8] drm/i915/display: Some code improvements and code style fixes for DRRS José Roberto de Souza
2021-09-02 15:15   ` Gwan-gyeong Mun
2021-09-03 20:36     ` Souza, Jose
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 5/8] drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate José Roberto de Souza
2021-09-02 15:57   ` Gwan-gyeong Mun
2021-09-03 21:52     ` Souza, Jose
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Prepare DRRS for frontbuffer rendering drop José Roberto de Souza
2021-09-02 16:09   ` Gwan-gyeong Mun
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 7/8] drm/i915/display/skl+: Drop frontbuffer rendering support José Roberto de Souza
2021-09-02 18:42   ` Gwan-gyeong Mun
2021-09-03 22:09     ` Souza, Jose
2021-09-04  0:26       ` Souza, Jose
2021-09-06  9:44         ` Gwan-gyeong Mun
2021-08-25  0:58 ` [Intel-gfx] [PATCH v2 8/8] drm/i915/display: Drop PSR " José Roberto de Souza
2021-09-06 16:05   ` Gwan-gyeong Mun
2021-08-25  1:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Drop frontbuffer rendering support from Skylake and newer (rev2) Patchwork
2021-08-25  1:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-08-25  1:33 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2021-08-25 15:57 ` [Intel-gfx] [PATCH v2 0/8] Drop frontbuffer rendering support from Skylake and newer Rodrigo Vivi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).