intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2
@ 2020-05-26 22:14 José Roberto de Souza
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property José Roberto de Souza
                   ` (7 more replies)
  0 siblings, 8 replies; 28+ messages in thread
From: José Roberto de Souza @ 2020-05-26 22:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: Dhinakaran Pandiyan

RKL doesn't have PSR2 HW tracking, it was replaced by software/manual
tracking.  The driver is required to track the areas that needs update
and program hardware to send selective updates.

So until the software tracking is implemented, PSR2 needs to be disabled
for platforms without PSR2 HW tracking.

This is part of RKL enabling patches, just cherry-picking here as it
is needed.

BSpec: 50422
BSpec: 50424

Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 15 +++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h          |  2 ++
 drivers/gpu/drm/i915/i915_pci.c          |  2 ++
 drivers/gpu/drm/i915/intel_device_info.h |  1 +
 4 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index b7a2c102648a..714c590b39f5 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -646,6 +646,21 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
+	/*
+	 * Some platforms lack PSR2 HW tracking and instead require manual
+	 * tracking by software.  In this case, the driver is required to track
+	 * the areas that need updates and program hardware to send selective
+	 * updates.
+	 *
+	 * So until the software tracking is implemented, PSR2 needs to be
+	 * disabled for platforms without PSR2 HW tracking.
+	 */
+	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "No PSR2 HW tracking in the platform\n");
+		return false;
+	}
+
 	/*
 	 * DSC and PSR2 cannot be enabled simultaneously. If a requested
 	 * resolution requires DSC to be enabled, priority is given to DSC
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 98f2c448cd92..146bfd276ce7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1632,6 +1632,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_DDI(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_ddi)
 #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->has_fpga_dbg)
 #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_psr)
+#define HAS_PSR_HW_TRACKING(dev_priv) \
+	(INTEL_INFO(dev_priv)->display.has_psr_hw_tracking)
 #define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0)
 
 #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6)
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 7e3252fbad8e..709e857a3983 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -536,6 +536,7 @@ static const struct intel_device_info vlv_info = {
 	.display.has_ddi = 1, \
 	.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, \
@@ -690,6 +691,7 @@ static const struct intel_device_info skl_gt4_info = {
 	.display.has_fbc = 1, \
 	.display.has_hdcp = 1, \
 	.display.has_psr = 1, \
+	.display.has_psr_hw_tracking = 1, \
 	.has_runtime_pm = 1, \
 	.display.has_csr = 1, \
 	.has_rc6 = 1, \
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index c912acd06109..1ada48ef517c 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -147,6 +147,7 @@ enum intel_ppgtt_type {
 	func(has_modular_fia); \
 	func(has_overlay); \
 	func(has_psr); \
+	func(has_psr_hw_tracking); \
 	func(overlay_needs_physical); \
 	func(supports_tv);
 
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
@ 2020-05-26 22:14 ` José Roberto de Souza
  2020-06-12 15:15   ` Mun, Gwan-gyeong
  2020-06-12 15:25   ` Ville Syrjälä
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 3/6] drm/i915: Reorder intel_psr2_config_valid() José Roberto de Souza
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 28+ messages in thread
From: José Roberto de Souza @ 2020-05-26 22:14 UTC (permalink / raw)
  To: intel-gfx

This property will be used by PSR2 software tracking, adding it to
GEN12+.

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

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index f40b909952cc..b69878334040 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -35,6 +35,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic_uapi.h>
+#include <drm/drm_damage_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_fourcc.h>
@@ -16476,6 +16477,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
 	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
 
+	if (INTEL_GEN(dev_priv) >= 12)
+		drm_plane_enable_fb_damage_clips(&cursor->base);
+
 	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
 
 	return cursor;
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 571c36f929bd..8be06cb25999 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -34,6 +34,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_color_mgmt.h>
 #include <drm/drm_crtc.h>
+#include <drm/drm_damage_helper.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_rect.h>
@@ -3151,6 +3152,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
 
 	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
 
+	if (INTEL_GEN(dev_priv) >= 12)
+		drm_plane_enable_fb_damage_clips(&plane->base);
+
 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
 
 	return plane;
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] [PATCH 3/6] drm/i915: Reorder intel_psr2_config_valid()
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property José Roberto de Souza
@ 2020-05-26 22:14 ` José Roberto de Souza
  2020-06-12 15:42   ` Mun, Gwan-gyeong
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers José Roberto de Souza
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2020-05-26 22:14 UTC (permalink / raw)
  To: intel-gfx

Future patches will bring PSR2 selective fetch configuration
validation but most of the configuration checks will be used for HW
tracking and selective fetch so the reoder was necessary.

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

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 714c590b39f5..0c86e9e341a2 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -646,21 +646,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
-	/*
-	 * Some platforms lack PSR2 HW tracking and instead require manual
-	 * tracking by software.  In this case, the driver is required to track
-	 * the areas that need updates and program hardware to send selective
-	 * updates.
-	 *
-	 * So until the software tracking is implemented, PSR2 needs to be
-	 * disabled for platforms without PSR2 HW tracking.
-	 */
-	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "No PSR2 HW tracking in the platform\n");
-		return false;
-	}
-
 	/*
 	 * DSC and PSR2 cannot be enabled simultaneously. If a requested
 	 * resolution requires DSC to be enabled, priority is given to DSC
@@ -672,6 +657,12 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
+	if (crtc_state->crc_enabled) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "PSR2 not enabled because it would inhibit pipe CRC calculation\n");
+		return false;
+	}
+
 	if (INTEL_GEN(dev_priv) >= 12) {
 		psr_max_h = 5120;
 		psr_max_v = 3200;
@@ -686,14 +677,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		max_bpp = 24;
 	}
 
-	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
-			    crtc_hdisplay, crtc_vdisplay,
-			    psr_max_h, psr_max_v);
-		return false;
-	}
-
 	if (crtc_state->pipe_bpp > max_bpp) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR2 not enabled, pipe bpp %d > max supported %d\n",
@@ -714,9 +697,26 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
-	if (crtc_state->crc_enabled) {
+	/*
+	 * Some platforms lack PSR2 HW tracking and instead require manual
+	 * tracking by software.  In this case, the driver is required to track
+	 * the areas that need updates and program hardware to send selective
+	 * updates.
+	 *
+	 * So until the software tracking is implemented, PSR2 needs to be
+	 * disabled for platforms without PSR2 HW tracking.
+	 */
+	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
 		drm_dbg_kms(&dev_priv->drm,
-			    "PSR2 not enabled because it would inhibit pipe CRC calculation\n");
+			    "No PSR2 HW tracking in the platform\n");
+		return false;
+	}
+
+	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
+			    crtc_hdisplay, crtc_vdisplay,
+			    psr_max_h, psr_max_v);
 		return false;
 	}
 
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property José Roberto de Souza
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 3/6] drm/i915: Reorder intel_psr2_config_valid() José Roberto de Souza
@ 2020-05-26 22:14 ` José Roberto de Souza
  2020-06-12 20:57   ` Mun, Gwan-gyeong
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch José Roberto de Souza
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2020-05-26 22:14 UTC (permalink / raw)
  To: intel-gfx

This registers will be used to implement PSR2 software tracking.

BSpec: 55229
BSpec: 50424
BSpec: 50420
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 68 ++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e9d50fe0f375..6f547e459d30 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4566,6 +4566,18 @@ enum {
 #define PSR2_SU_STATUS_MASK(frame)	(0x3ff << PSR2_SU_STATUS_SHIFT(frame))
 #define PSR2_SU_STATUS_FRAMES		8
 
+#define _PSR2_MAN_TRK_CTL_A				0x60910
+#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
+#define PSR2_MAN_TRK_CTL(tran)				_MMIO_TRANS2(tran, _PSR2_MAN_TRK_CTL_A)
+#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT(31)
+#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GENMASK(30, 21)
+#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIELD_PREP(PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
+#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GENMASK(20, 11)
+#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIELD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
+#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT(3)
+#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT(2)
+#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT(1)
+
 /* VGA port control */
 #define ADPA			_MMIO(0x61100)
 #define PCH_ADPA                _MMIO(0xe1100)
@@ -7129,7 +7141,52 @@ enum {
 #define PLANE_COLOR_CTL(pipe, plane)	\
 	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe), _PLANE_COLOR_CTL_2(pipe))
 
-#/* SKL new cursor registers */
+#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
+#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
+#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
+#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
+#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
+#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
+#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
+#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
+#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
+
+#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
+					     _PLANE_SEL_FETCH_BASE_1_A, \
+					     _PLANE_SEL_FETCH_BASE_2_A, \
+					     _PLANE_SEL_FETCH_BASE_3_A, \
+					     _PLANE_SEL_FETCH_BASE_4_A, \
+					     _PLANE_SEL_FETCH_BASE_5_A, \
+					     _PLANE_SEL_FETCH_BASE_6_A, \
+					     _PLANE_SEL_FETCH_BASE_7_A, \
+					     _PLANE_SEL_FETCH_BASE_CUR_A)
+#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe, _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)
+#define PLANE_SEL_FETCH_BASE(pipe, plane) (_PLANE_SEL_FETCH_BASE_1(pipe) - \
+					   _PLANE_SEL_FETCH_BASE_1_A + \
+					   _PLANE_SEL_FETCH_BASE_A(plane))
+
+#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
+#define PLANE_SEL_FETCH_CTL(pipe, plane) _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
+					       _PLANE_SEL_FETCH_CTL_1_A - \
+					       _PLANE_SEL_FETCH_BASE_1_A)
+#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
+
+#define _PLANE_SEL_FETCH_POS_1_A		0x70894
+#define PLANE_SEL_FETCH_POS(pipe, plane) _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
+					       _PLANE_SEL_FETCH_POS_1_A - \
+					       _PLANE_SEL_FETCH_BASE_1_A)
+
+#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
+#define PLANE_SEL_FETCH_SIZE(pipe, plane) _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
+						_PLANE_SEL_FETCH_SIZE_1_A - \
+						_PLANE_SEL_FETCH_BASE_1_A)
+
+#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
+#define PLANE_SEL_FETCH_OFFSET(pipe, plane) _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
+						  _PLANE_SEL_FETCH_OFFSET_1_A - \
+						  _PLANE_SEL_FETCH_BASE_1_A)
+
+/* SKL new cursor registers */
 #define _CUR_BUF_CFG_A				0x7017c
 #define _CUR_BUF_CFG_B				0x7117c
 #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
@@ -7775,11 +7832,12 @@ enum {
 # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
 # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
 
-#define CHICKEN_PAR1_1		_MMIO(0x42080)
+#define CHICKEN_PAR1_1			_MMIO(0x42080)
 #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
-#define  DPA_MASK_VBLANK_SRD	(1 << 15)
-#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
-#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
+#define  DPA_MASK_VBLANK_SRD		(1 << 15)
+#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
+#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
+#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
 
 #define CHICKEN_PAR2_1		_MMIO(0x42090)
 #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
                   ` (2 preceding siblings ...)
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers José Roberto de Souza
@ 2020-05-26 22:14 ` José Roberto de Souza
  2020-06-12 16:30   ` Ville Syrjälä
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 6/6] drm/i915: Implement PSR2 selective fetch WAs José Roberto de Souza
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 28+ messages in thread
From: José Roberto de Souza @ 2020-05-26 22:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: Dhinakaran Pandiyan

All GEN12 platforms supports PSR2 selective fetch but not all GEN12
platforms supports PSR2 hardware tracking(aka RKL).

This feature consists in software program registers with the damaged
area of each plane this way hardware will only fetch from memory those
areas and sent the PSR2 selective update blocks to panel, saving even
more power but to it actually happen userspace needs to send the
damaged areas otherwise it will still fetch the whole plane as
fallback.
As today Gnome3 do not send damaged areas and the only compositor that
I'm aware that sets the damaged areas is Weston.
https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17

So here implementing page flip part, it is still completely missing
frontbuffer modifications, that is why the enable_psr2_sel_fetch
parameter was added.

The plan is to switch all GEN12 platforms to selective fetch when
ready, it will also depend in add some tests sending damaged areas.
I have a hacked version of kms_psr2_su with 3 planes that I can
cleanup and send in a few days(99% of PSR2 selective fetch changes was
done during my free time while bored during quarantine rainy days).

BSpec: 55229
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  |   5 +
 .../drm/i915/display/intel_display_debugfs.c  |   3 +
 .../drm/i915/display/intel_display_types.h    |  10 +
 drivers/gpu/drm/i915/display/intel_psr.c      | 329 +++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
 drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
 drivers/gpu/drm/i915/i915_drv.h               |   2 +
 drivers/gpu/drm/i915/i915_params.c            |   5 +
 drivers/gpu/drm/i915/i915_params.h            |   1 +
 9 files changed, 352 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b69878334040..984809208c29 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -11729,6 +11729,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	if (INTEL_GEN(dev_priv) >= 9)
 		skl_write_cursor_wm(plane, crtc_state);
 
+	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
+
 	if (plane->cursor.base != base ||
 	    plane->cursor.size != fbc_ctl ||
 	    plane->cursor.cntl != cntl) {
@@ -15115,6 +15117,8 @@ static void commit_pipe_config(struct intel_atomic_state *state,
 
 		if (new_crtc_state->update_pipe)
 			intel_pipe_fastset(old_crtc_state, new_crtc_state);
+
+		intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
 	}
 
 	if (dev_priv->display.atomic_update_watermarks)
@@ -15156,6 +15160,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 			intel_color_load_luts(new_crtc_state);
 
 		intel_pre_plane_update(state, crtc);
+		intel_psr2_sel_fetch_update(state, crtc);
 
 		if (new_crtc_state->update_pipe)
 			intel_encoders_update_pipe(state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 70525623bcdf..0f600974462b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
 			su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
 			seq_printf(m, "%d\t%d\n", frame, su_blocks);
 		}
+
+		seq_printf(m, "PSR2 selective fetch: %s\n",
+			   enableddisabled(psr->psr2_sel_fetch_enabled));
 	}
 
 unlock:
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 30b2767578dc..b77a512e5362 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -586,6 +586,13 @@ struct intel_plane_state {
 	u32 planar_slave;
 
 	struct drm_intel_sprite_colorkey ckey;
+
+	struct {
+		u32 ctl;
+		u32 pos;
+		u32 offset;
+		u32 size;
+	} psr2_sel_fetch;
 };
 
 struct intel_initial_plane_config {
@@ -931,6 +938,7 @@ struct intel_crtc_state {
 
 	bool has_psr;
 	bool has_psr2;
+	bool enable_psr2_sel_fetch;
 	u32 dc3co_exitline;
 
 	/*
@@ -1070,6 +1078,8 @@ struct intel_crtc_state {
 
 	/* For DSB related info */
 	struct intel_dsb *dsb;
+
+	u32 psr2_sw_man_track_ctl;
 };
 
 enum intel_pipe_crc_source {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 0c86e9e341a2..bc2a2e64fe2a 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 	else
 		val |= EDP_PSR2_TP2_TIME_2500us;
 
+	if (dev_priv->psr.psr2_sel_fetch_enabled)
+		intel_de_write(dev_priv,
+			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
+			       PSR2_MAN_TRK_CTL_ENABLE);
+	else if (HAS_PSR2_SEL_FETCH(dev_priv))
+		intel_de_write(dev_priv,
+			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
+
 	/*
 	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
 	 * recommending keep this bit unset while PSR2 is enabled.
@@ -628,6 +636,38 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
 	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
 }
 
+static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
+					      struct intel_crtc_state *crtc_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_plane_state *plane_state;
+	struct intel_plane *plane;
+	int i;
+
+	if (!i915_modparams.enable_psr2_sel_fetch) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "PSR2 sel fetch not enabled, disabled by parameter\n");
+		return false;
+	}
+
+	if (crtc_state->uapi.async_flip) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "PSR2 sel fetch not enabled, async flip enabled\n");
+		return false;
+	}
+
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) {
+			drm_dbg_kms(&dev_priv->drm,
+				    "PSR2 sel fetch not enabled, plane rotated\n");
+			return false;
+		}
+	}
+
+	return crtc_state->enable_psr2_sel_fetch = true;
+}
+
 static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 				    struct intel_crtc_state *crtc_state)
 {
@@ -697,22 +737,17 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
-	/*
-	 * Some platforms lack PSR2 HW tracking and instead require manual
-	 * tracking by software.  In this case, the driver is required to track
-	 * the areas that need updates and program hardware to send selective
-	 * updates.
-	 *
-	 * So until the software tracking is implemented, PSR2 needs to be
-	 * disabled for platforms without PSR2 HW tracking.
-	 */
-	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
-		drm_dbg_kms(&dev_priv->drm,
-			    "No PSR2 HW tracking in the platform\n");
-		return false;
+	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
+		if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
+		    !HAS_PSR_HW_TRACKING(dev_priv)) {
+			drm_dbg_kms(&dev_priv->drm,
+				    "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
+			return false;
+		}
 	}
 
-	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
+	if (!crtc_state->enable_psr2_sel_fetch &&
+	    (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
 			    crtc_hdisplay, crtc_vdisplay,
@@ -863,6 +898,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
 		val |= EXITLINE_ENABLE;
 		intel_de_write(dev_priv, EXITLINE(cpu_transcoder), val);
 	}
+
+	if (HAS_PSR_HW_TRACKING(dev_priv))
+		intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
+			     dev_priv->psr.psr2_sel_fetch_enabled ?
+			     IGNORE_PSR2_HW_TRACKING : 0);
 }
 
 static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
@@ -884,7 +924,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
 	/* DC5/DC6 requires at least 6 idle frames */
 	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
 	dev_priv->psr.dc3co_exit_delay = val;
-
+	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
 	/*
 	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
 	 * will still keep the error set even after the reset done in the
@@ -1080,6 +1120,265 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
 		intel_psr_exit(dev_priv);
 }
 
+void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
+					const struct intel_crtc_state *crtc_state,
+					const struct intel_plane_state *plane_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	enum pipe pipe = plane->pipe;
+
+	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
+	    !plane_state ||
+	    !crtc_state->enable_psr2_sel_fetch)
+		return;
+
+	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
+			  plane_state->psr2_sel_fetch.ctl);
+	if (!plane_state->psr2_sel_fetch.ctl || plane->id == PLANE_CURSOR)
+		return;
+
+	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe, plane->id),
+			  plane_state->psr2_sel_fetch.pos);
+	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
+			  plane_state->psr2_sel_fetch.offset);
+	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe, plane->id),
+			  plane_state->psr2_sel_fetch.size);
+}
+
+void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct i915_psr *psr = &dev_priv->psr;
+
+	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
+	    !crtc_state->enable_psr2_sel_fetch)
+		return;
+
+	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
+		       crtc_state->psr2_sw_man_track_ctl);
+}
+
+static void intel_psr2_plane_sel_fetch_calc(struct intel_plane_state *plane_state,
+					    struct drm_rect *clip)
+{
+	int color_plane = plane_state->planar_linked_plane && !plane_state->planar_slave;
+	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+	u32 val;
+
+	if (plane->id == PLANE_CURSOR)
+		return;
+
+	val = (plane_state->color_plane[color_plane].y + clip->y1) << 16;
+	val |= plane_state->color_plane[color_plane].x;
+	plane_state->psr2_sel_fetch.offset = val;
+
+	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
+	val |= plane_state->uapi.crtc_x;
+	plane_state->psr2_sel_fetch.pos = val;
+
+	/* Sizes are 0 based */
+	val = (clip->y2 - clip->y1 - 1) << 16;
+	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
+	plane_state->psr2_sel_fetch.size = val;
+}
+
+static void intel_psr2_trans_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
+					      struct drm_rect *clip,
+					      bool full_update)
+{
+	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
+
+	if (full_update) {
+		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
+		goto exit;
+	}
+
+	if (clip->y1 == -1)
+		goto exit;
+
+	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
+	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4 + 1);
+	val |= PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4) + 1);
+exit:
+	crtc_state->psr2_sw_man_track_ctl = val;
+}
+
+static void intel_psr2_plane_sel_fetch_ctl_calc(struct intel_plane *plane,
+						struct intel_plane_state *plane_state,
+						bool enable)
+{
+	if (!enable)
+		plane_state->psr2_sel_fetch.ctl = 0;
+	else if (plane->id == PLANE_CURSOR)
+		plane_state->psr2_sel_fetch.ctl = plane->cursor.cntl;
+	else
+		plane_state->psr2_sel_fetch.ctl = plane_state->ctl;
+}
+
+static void clip_update(struct drm_rect *overlap_damage_area,
+			struct drm_rect *damage_area)
+{
+	if (overlap_damage_area->y1 == -1) {
+		overlap_damage_area->y1 = damage_area->y1;
+		overlap_damage_area->y2 = damage_area->y2;
+		return;
+	}
+
+	if (damage_area->y1 < overlap_damage_area->y1)
+		overlap_damage_area->y1 = damage_area->y1;
+
+	if (damage_area->y2 > overlap_damage_area->y2)
+		overlap_damage_area->y2 = damage_area->y2;
+}
+
+/* Update plane damage area if planes above moved or have alpha */
+static void intel_psr2_pipe_dirty_areas_set(struct intel_plane_state *plane_state,
+					    struct intel_plane *plane,
+					    const struct drm_rect *pipe_dirty_areas,
+					    struct drm_rect *plane_clip)
+{
+	enum plane_id i;
+
+	for (i = PLANE_CURSOR; i > plane->id; i--) {
+		int j;
+
+		for (j = 0; j < 2; j++) {
+			struct drm_rect r = pipe_dirty_areas[i * 2 + j];
+
+			if (!drm_rect_width(&r))
+				continue;
+			if (!drm_rect_intersect(&r, &plane_state->uapi.dst))
+				continue;
+
+			r.y1 -= plane_state->uapi.crtc_y;
+			r.y2 -= plane_state->uapi.crtc_y;
+			clip_update(plane_clip, &r);
+		}
+	}
+}
+
+void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
+				 struct intel_crtc *crtc)
+{
+	struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+	struct intel_plane_state *new_plane_state, *old_plane_state;
+	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] = {};
+	struct drm_rect pipe_clip = { .y1 = -1 };
+	struct intel_plane *plane;
+	bool full_update = false;
+	int i;
+
+	if (!crtc_state->enable_psr2_sel_fetch)
+		return;
+
+	/*
+	 * Load all the pipes areas where there is a plane with alpha or a plane
+	 * that moved or plane that the visibility changed in those
+	 * cases planes bellow it will need to be fetched in those intersection
+	 * areas even if they are not damaged in those areas.
+	 */
+	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
+					     new_plane_state, i) {
+		bool alpha, flip, dirty;
+
+		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
+			continue;
+
+		alpha = new_plane_state->uapi.alpha != U16_MAX;
+		alpha |= old_plane_state->uapi.alpha != U16_MAX;
+		flip = new_plane_state->uapi.fb != old_plane_state->uapi.fb;
+		dirty = alpha && flip;
+		dirty |= !drm_rect_equals(&new_plane_state->uapi.dst,
+					  &old_plane_state->uapi.dst);
+		dirty |= new_plane_state->uapi.visible !=
+			 old_plane_state->uapi.visible;
+		if (!dirty)
+			continue;
+
+		if (old_plane_state->uapi.visible)
+			pipe_dirty_areas[plane->id * 2] = old_plane_state->uapi.dst;
+		if (new_plane_state->uapi.visible)
+			pipe_dirty_areas[plane->id * 2 + 1] = new_plane_state->uapi.dst;
+	}
+
+	/*
+	 * Iterate over all planes, compute the damaged clip area also including
+	 * the pipe_dirty_areas, compute plane registers and update pipe damaged
+	 * area
+	 */
+	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
+					     new_plane_state, i) {
+		struct drm_rect plane_clip = { .y1 = -1 };
+		struct drm_mode_rect *clips;
+		u32 num_clips;
+		int j;
+
+		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
+			continue;
+
+		/*
+		 * TODO: Not clear how to handle planes with negative position,
+		 * also planes are not updated if they have a negative X
+		 * position so for now doing a full update in this cases
+		 */
+		if (new_plane_state->uapi.crtc_y < 0 ||
+		    new_plane_state->uapi.crtc_x < 0) {
+			full_update = true;
+			break;
+		}
+
+		intel_psr2_plane_sel_fetch_ctl_calc(plane, new_plane_state,
+						    new_plane_state->uapi.visible);
+		if (!new_plane_state->uapi.visible)
+			continue;
+
+		clips = drm_plane_get_damage_clips(&new_plane_state->uapi);
+		num_clips = drm_plane_get_damage_clips_count(&new_plane_state->uapi);
+
+		/*
+		 * If plane moved mark the whole plane area as damaged so it
+		 * can be complete draw in the new position
+		 */
+		if (!drm_rect_equals(&new_plane_state->uapi.dst,
+				     &old_plane_state->uapi.dst)) {
+			num_clips = 0;
+			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
+			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
+		} else if (!num_clips) {
+			/*
+			 * If plane don't have damage areas but the framebuffer
+			 * changed mark the whole plane as damaged
+			 */
+			if (new_plane_state->uapi.fb == old_plane_state->uapi.fb)
+				continue;
+
+			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
+			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
+		}
+
+		for (j = 0; j < num_clips; j++) {
+			struct drm_rect damage_area;
+
+			damage_area.x1 = clips[j].x1;
+			damage_area.x2 = clips[j].x2;
+			damage_area.y1 = clips[j].y1;
+			damage_area.y2 = clips[j].y2;
+			clip_update(&plane_clip, &damage_area);
+		}
+
+		intel_psr2_pipe_dirty_areas_set(new_plane_state, plane,
+						pipe_dirty_areas, &plane_clip);
+		intel_psr2_plane_sel_fetch_calc(new_plane_state, &plane_clip);
+
+		plane_clip.y1 += new_plane_state->uapi.crtc_y;
+		plane_clip.y2 += new_plane_state->uapi.crtc_y;
+		clip_update(&pipe_clip, &plane_clip);
+	}
+
+	intel_psr2_trans_man_trk_ctl_calc(crtc_state, &pipe_clip, full_update);
+}
+
 /**
  * intel_psr_update - Update PSR state
  * @intel_dp: Intel DP
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index b4515186d5f4..d80bd0e46b21 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -13,6 +13,10 @@ struct drm_connector_state;
 struct drm_i915_private;
 struct intel_crtc_state;
 struct intel_dp;
+struct intel_crtc;
+struct intel_atomic_state;
+struct intel_plane_state;
+struct intel_plane;
 
 #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
 void intel_psr_init_dpcd(struct intel_dp *intel_dp);
@@ -43,5 +47,11 @@ void intel_psr_atomic_check(struct drm_connector *connector,
 			    struct drm_connector_state *old_state,
 			    struct drm_connector_state *new_state);
 void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp);
+void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
+				 struct intel_crtc *crtc);
+void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
+					const struct intel_crtc_state *crtc_state,
+					const struct intel_plane_state *plane_state);
+void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
 
 #endif /* __INTEL_PSR_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 8be06cb25999..afede372ac05 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -690,6 +690,8 @@ skl_program_plane(struct intel_plane *plane,
 		intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
 				  (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
 
+	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
+
 	/*
 	 * The control register self-arms if the plane was previously
 	 * disabled. Try to make the plane enable atomic by writing
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 146bfd276ce7..ae7efc922393 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -503,6 +503,7 @@ struct i915_psr {
 	bool link_standby;
 	bool colorimetry_support;
 	bool psr2_enabled;
+	bool psr2_sel_fetch_enabled;
 	u8 sink_sync_latency;
 	ktime_t last_entry_attempt;
 	ktime_t last_exit;
@@ -1634,6 +1635,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_psr)
 #define HAS_PSR_HW_TRACKING(dev_priv) \
 	(INTEL_INFO(dev_priv)->display.has_psr_hw_tracking)
+#define HAS_PSR2_SEL_FETCH(dev_priv)	 (INTEL_GEN(dev_priv) >= 12)
 #define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0)
 
 #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6)
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index add00ec1f787..3005451c1194 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -88,6 +88,11 @@ i915_param_named_unsafe(enable_psr, int, 0600,
 	"(0=disabled, 1=enabled) "
 	"Default: -1 (use per-chip default)");
 
+i915_param_named_unsafe(enable_psr2_sel_fetch, int, 0400,
+	"Enable PSR2 selective fetch "
+	"(0=disabled, 1=enabled) "
+	"Default: 0");
+
 i915_param_named_unsafe(force_probe, charp, 0400,
 	"Force probe the driver for specified devices. "
 	"See CONFIG_DRM_I915_FORCE_PROBE for details.");
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 45323732f099..5a0b16923016 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -53,6 +53,7 @@ struct drm_printer;
 	param(int, enable_dc, -1, 0400) \
 	param(int, enable_fbc, -1, 0600) \
 	param(int, enable_psr, -1, 0600) \
+	param(int, enable_psr2_sel_fetch, 0, 0400) \
 	param(int, disable_power_well, -1, 0400) \
 	param(int, enable_ips, 1, 0600) \
 	param(int, invert_brightness, 0, 0600) \
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] [PATCH 6/6] drm/i915: Implement PSR2 selective fetch WAs
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
                   ` (3 preceding siblings ...)
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch José Roberto de Souza
@ 2020-05-26 22:14 ` José Roberto de Souza
  2020-05-26 22:31 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] drm/i915/rkl: Disable PSR2 Patchwork
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 28+ messages in thread
From: José Roberto de Souza @ 2020-05-26 22:14 UTC (permalink / raw)
  To: intel-gfx

This feature have 3 WAs and as commented WA 14010103792 and
WA 14010254185 conflicts, so leaving the feature disabled in the
affected steppings.

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 30 ++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_reg.h          |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index bc2a2e64fe2a..c138ab69fa93 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -518,13 +518,21 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 	else
 		val |= EDP_PSR2_TP2_TIME_2500us;
 
-	if (dev_priv->psr.psr2_sel_fetch_enabled)
+	if (dev_priv->psr.psr2_sel_fetch_enabled) {
+		/* WA 1408330847 */
+		if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0) ||
+		    IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))
+			intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
+				     DIS_RAM_BYPASS_PSR2_MAN_TRACK,
+				     DIS_RAM_BYPASS_PSR2_MAN_TRACK);
+
 		intel_de_write(dev_priv,
 			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
 			       PSR2_MAN_TRK_CTL_ENABLE);
-	else if (HAS_PSR2_SEL_FETCH(dev_priv))
+	} else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
 		intel_de_write(dev_priv,
 			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
+	}
 
 	/*
 	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
@@ -651,6 +659,17 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
 		return false;
 	}
 
+	/*
+	 * As WA 14010103792 conflicts with WA 14010254185 so disabling PSR2 SW
+	 * tracking in TGL and RKL A0
+	 */
+	if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0) ||
+	    IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "PSR2 sel fetch not enabled, feature not working in current stepping\n");
+		return false;
+	}
+
 	if (crtc_state->uapi.async_flip) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR2 sel fetch not enabled, async flip enabled\n");
@@ -1063,6 +1082,13 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
 				    psr_status_mask, 2000))
 		drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
 
+	/* WA 1408330847 */
+	if (dev_priv->psr.psr2_sel_fetch_enabled &&
+	    (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0) ||
+	     IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)))
+		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
+			     DIS_RAM_BYPASS_PSR2_MAN_TRACK, 0);
+
 	/* Disable PSR on Sink */
 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6f547e459d30..2e374e166b2e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7833,6 +7833,7 @@ enum {
 # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
 
 #define CHICKEN_PAR1_1			_MMIO(0x42080)
+#define  DIS_RAM_BYPASS_PSR2_MAN_TRACK	(1 << 16)
 #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
 #define  DPA_MASK_VBLANK_SRD		(1 << 15)
 #define  FORCE_ARB_IDLE_PLANES		(1 << 14)
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] drm/i915/rkl: Disable PSR2
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
                   ` (4 preceding siblings ...)
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 6/6] drm/i915: Implement PSR2 selective fetch WAs José Roberto de Souza
@ 2020-05-26 22:31 ` Patchwork
  2020-05-26 22:54 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
  2020-05-27  1:33 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
  7 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2020-05-26 22:31 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] drm/i915/rkl: Disable PSR2
URL   : https://patchwork.freedesktop.org/series/77676/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
3b5607178b4a drm/i915/rkl: Disable PSR2
54e02163a7f7 drm/i915: Add plane damage clips property
af8c4264fa17 drm/i915: Reorder intel_psr2_config_valid()
837cb19aab8f drm/i915: Add PSR2 software tracking registers
-:29: WARNING:LONG_LINE: line over 100 characters
#29: FILE: drivers/gpu/drm/i915/i915_reg.h:4574:
+#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIELD_PREP(PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)

-:31: WARNING:LONG_LINE: line over 100 characters
#31: FILE: drivers/gpu/drm/i915/i915_reg.h:4576:
+#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIELD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)

-:63: WARNING:LONG_LINE: line over 100 characters
#63: FILE: drivers/gpu/drm/i915/i915_reg.h:7163:
+#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe, _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)

total: 0 errors, 3 warnings, 0 checks, 87 lines checked
8dcb0cb37119 drm/i915: Implement PSR2 selective fetch
-:565: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#565: FILE: drivers/gpu/drm/i915/i915_params.c:92:
+i915_param_named_unsafe(enable_psr2_sel_fetch, int, 0400,
+	"Enable PSR2 selective fetch "

total: 0 errors, 0 warnings, 1 checks, 488 lines checked
d80c35b30749 drm/i915: Implement PSR2 selective fetch WAs

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [1/6] drm/i915/rkl: Disable PSR2
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
                   ` (5 preceding siblings ...)
  2020-05-26 22:31 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] drm/i915/rkl: Disable PSR2 Patchwork
@ 2020-05-26 22:54 ` Patchwork
  2020-05-27  1:33 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
  7 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2020-05-26 22:54 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] drm/i915/rkl: Disable PSR2
URL   : https://patchwork.freedesktop.org/series/77676/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8540 -> Patchwork_17781
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

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

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

### IGT changes ###

#### Possible fixes ####

  * igt@kms_chamelium@dp-crc-fast:
    - fi-icl-u2:          [FAIL][1] ([i915#262]) -> [PASS][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/fi-icl-u2/igt@kms_chamelium@dp-crc-fast.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/fi-icl-u2/igt@kms_chamelium@dp-crc-fast.html

  
  [i915#262]: https://gitlab.freedesktop.org/drm/intel/issues/262


Participating hosts (51 -> 45)
------------------------------

  Missing    (6): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


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

  * Linux: CI_DRM_8540 -> Patchwork_17781

  CI-20190529: 20190529
  CI_DRM_8540: b02ab97d6794973472bfdf91b62448d9354fd698 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5679: 93639b4e52140826c24da21865e912a280f9aefb @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17781: d80c35b307494430f7e33f71733ea99e5dc42673 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

d80c35b30749 drm/i915: Implement PSR2 selective fetch WAs
8dcb0cb37119 drm/i915: Implement PSR2 selective fetch
837cb19aab8f drm/i915: Add PSR2 software tracking registers
af8c4264fa17 drm/i915: Reorder intel_psr2_config_valid()
54e02163a7f7 drm/i915: Add plane damage clips property
3b5607178b4a drm/i915/rkl: Disable PSR2

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [1/6] drm/i915/rkl: Disable PSR2
  2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
                   ` (6 preceding siblings ...)
  2020-05-26 22:54 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-05-27  1:33 ` Patchwork
  7 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2020-05-27  1:33 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] drm/i915/rkl: Disable PSR2
URL   : https://patchwork.freedesktop.org/series/77676/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_8540_full -> Patchwork_17781_full
====================================================

Summary
-------

  **FAILURE**

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

  

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

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

### IGT changes ###

#### Possible regressions ####

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-apl:          [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl4/igt@gem_workarounds@suspend-resume-fd.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl1/igt@gem_workarounds@suspend-resume-fd.html

  * igt@runner@aborted:
    - shard-hsw:          NOTRUN -> [FAIL][3]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-hsw1/igt@runner@aborted.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_persistence@legacy-engines-mixed-process@render:
    - shard-skl:          [PASS][4] -> [FAIL][5] ([i915#1528])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-skl9/igt@gem_ctx_persistence@legacy-engines-mixed-process@render.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-skl8/igt@gem_ctx_persistence@legacy-engines-mixed-process@render.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-kbl:          [PASS][6] -> [DMESG-WARN][7] ([i915#180]) +3 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-kbl2/igt@gem_workarounds@suspend-resume-fd.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-kbl2/igt@gem_workarounds@suspend-resume-fd.html

  * igt@i915_suspend@sysfs-reader:
    - shard-apl:          [PASS][8] -> [DMESG-WARN][9] ([i915#180]) +3 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl1/igt@i915_suspend@sysfs-reader.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl1/igt@i915_suspend@sysfs-reader.html

  * igt@kms_big_fb@linear-64bpp-rotate-180:
    - shard-glk:          [PASS][10] -> [FAIL][11] ([i915#1119] / [i915#118] / [i915#95])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-glk5/igt@kms_big_fb@linear-64bpp-rotate-180.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-glk8/igt@kms_big_fb@linear-64bpp-rotate-180.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x21-offscreen:
    - shard-kbl:          [PASS][12] -> [FAIL][13] ([i915#54] / [i915#93] / [i915#95])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-kbl2/igt@kms_cursor_crc@pipe-a-cursor-64x21-offscreen.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-kbl7/igt@kms_cursor_crc@pipe-a-cursor-64x21-offscreen.html

  * igt@kms_cursor_legacy@2x-long-flip-vs-cursor-legacy:
    - shard-glk:          [PASS][14] -> [FAIL][15] ([i915#72]) +1 similar issue
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-glk5/igt@kms_cursor_legacy@2x-long-flip-vs-cursor-legacy.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-glk8/igt@kms_cursor_legacy@2x-long-flip-vs-cursor-legacy.html

  * igt@kms_cursor_legacy@cursorb-vs-flipa-toggle:
    - shard-glk:          [PASS][16] -> [DMESG-WARN][17] ([i915#1926] / [i915#1927])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-glk7/igt@kms_cursor_legacy@cursorb-vs-flipa-toggle.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-glk9/igt@kms_cursor_legacy@cursorb-vs-flipa-toggle.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [PASS][18] -> [FAIL][19] ([fdo#108145] / [i915#265]) +1 similar issue
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-skl3/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-skl4/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_prop_blob@blob-prop-lifetime:
    - shard-hsw:          [PASS][20] -> [DMESG-WARN][21] ([i915#1927])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-hsw7/igt@kms_prop_blob@blob-prop-lifetime.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-hsw1/igt@kms_prop_blob@blob-prop-lifetime.html

  * igt@kms_psr@no_drrs:
    - shard-iclb:         [PASS][22] -> [FAIL][23] ([i915#173])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-iclb6/igt@kms_psr@no_drrs.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-iclb1/igt@kms_psr@no_drrs.html

  * igt@kms_psr@psr2_cursor_render:
    - shard-iclb:         [PASS][24] -> [SKIP][25] ([fdo#109441]) +1 similar issue
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-iclb2/igt@kms_psr@psr2_cursor_render.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-iclb5/igt@kms_psr@psr2_cursor_render.html

  
#### Possible fixes ####

  * {igt@gem_exec_reloc@basic-concurrent0}:
    - shard-glk:          [FAIL][26] ([i915#1930]) -> [PASS][27]
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-glk9/igt@gem_exec_reloc@basic-concurrent0.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-glk1/igt@gem_exec_reloc@basic-concurrent0.html
    - shard-apl:          [FAIL][28] ([i915#1930]) -> [PASS][29]
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl8/igt@gem_exec_reloc@basic-concurrent0.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl2/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@gem_mmap_offset@clear:
    - shard-hsw:          [INCOMPLETE][30] ([i915#61]) -> [PASS][31]
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-hsw2/igt@gem_mmap_offset@clear.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-hsw2/igt@gem_mmap_offset@clear.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [DMESG-WARN][32] ([i915#1436] / [i915#716]) -> [PASS][33]
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-glk5/igt@gen9_exec_parse@allowed-all.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-glk4/igt@gen9_exec_parse@allowed-all.html

  * {igt@i915_pm_rc6_residency@rc6-fence}:
    - shard-hsw:          [WARN][34] -> [PASS][35]
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-hsw1/igt@i915_pm_rc6_residency@rc6-fence.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-hsw7/igt@i915_pm_rc6_residency@rc6-fence.html

  * {igt@kms_flip@flip-vs-suspend-interruptible@a-dp1}:
    - shard-kbl:          [DMESG-WARN][36] ([i915#180]) -> [PASS][37] +1 similar issue
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-kbl4/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-kbl6/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html

  * {igt@kms_flip@flip-vs-suspend-interruptible@c-dp1}:
    - shard-apl:          [DMESG-WARN][38] ([i915#180]) -> [PASS][39] +2 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl8/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl2/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html

  * {igt@kms_flip@flip-vs-suspend@a-dp1}:
    - shard-kbl:          [DMESG-WARN][40] ([i915#180] / [i915#93] / [i915#95]) -> [PASS][41]
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-kbl6/igt@kms_flip@flip-vs-suspend@a-dp1.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-kbl7/igt@kms_flip@flip-vs-suspend@a-dp1.html

  * igt@kms_flip_tiling@flip-changes-tiling:
    - shard-kbl:          [FAIL][42] ([i915#699] / [i915#93] / [i915#95]) -> [PASS][43]
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-kbl7/igt@kms_flip_tiling@flip-changes-tiling.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-kbl7/igt@kms_flip_tiling@flip-changes-tiling.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [SKIP][44] ([fdo#109441]) -> [PASS][45] +1 similar issue
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-iclb4/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html

  
#### Warnings ####

  * igt@gem_softpin@noreloc-s3:
    - shard-kbl:          [DMESG-FAIL][46] ([fdo#103375] / [i915#180]) -> [FAIL][47] ([fdo#103375])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-kbl1/igt@gem_softpin@noreloc-s3.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-kbl1/igt@gem_softpin@noreloc-s3.html

  * igt@kms_content_protection@atomic:
    - shard-apl:          [TIMEOUT][48] ([i915#1319] / [i915#1635]) -> [DMESG-FAIL][49] ([fdo#110321] / [i915#95])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl2/igt@kms_content_protection@atomic.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl2/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@atomic-dpms:
    - shard-apl:          [TIMEOUT][50] ([i915#1319] / [i915#1635]) -> [FAIL][51] ([fdo#110321] / [fdo#110336])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl4/igt@kms_content_protection@atomic-dpms.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl6/igt@kms_content_protection@atomic-dpms.html

  * igt@kms_content_protection@lic:
    - shard-apl:          [TIMEOUT][52] ([i915#1319] / [i915#1635]) -> [TIMEOUT][53] ([i915#1319])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8540/shard-apl8/igt@kms_content_protection@lic.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/shard-apl1/igt@kms_content_protection@lic.html

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

  [fdo#103375]: https://bugs.freedesktop.org/show_bug.cgi?id=103375
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#110321]: https://bugs.freedesktop.org/show_bug.cgi?id=110321
  [fdo#110336]: https://bugs.freedesktop.org/show_bug.cgi?id=110336
  [i915#1119]: https://gitlab.freedesktop.org/drm/intel/issues/1119
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1528]: https://gitlab.freedesktop.org/drm/intel/issues/1528
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#173]: https://gitlab.freedesktop.org/drm/intel/issues/173
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1926]: https://gitlab.freedesktop.org/drm/intel/issues/1926
  [i915#1927]: https://gitlab.freedesktop.org/drm/intel/issues/1927
  [i915#1928]: https://gitlab.freedesktop.org/drm/intel/issues/1928
  [i915#1929]: https://gitlab.freedesktop.org/drm/intel/issues/1929
  [i915#1930]: https://gitlab.freedesktop.org/drm/intel/issues/1930
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#58]: https://gitlab.freedesktop.org/drm/intel/issues/58
  [i915#61]: https://gitlab.freedesktop.org/drm/intel/issues/61
  [i915#699]: https://gitlab.freedesktop.org/drm/intel/issues/699
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#72]: https://gitlab.freedesktop.org/drm/intel/issues/72
  [i915#93]: https://gitlab.freedesktop.org/drm/intel/issues/93
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
  [k.org#198133]: https://bugzilla.kernel.org/show_bug.cgi?id=198133


Participating hosts (11 -> 11)
------------------------------

  No changes in participating hosts


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

  * Linux: CI_DRM_8540 -> Patchwork_17781

  CI-20190529: 20190529
  CI_DRM_8540: b02ab97d6794973472bfdf91b62448d9354fd698 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5679: 93639b4e52140826c24da21865e912a280f9aefb @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17781: d80c35b307494430f7e33f71733ea99e5dc42673 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17781/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property José Roberto de Souza
@ 2020-06-12 15:15   ` Mun, Gwan-gyeong
  2020-06-12 15:25   ` Ville Syrjälä
  1 sibling, 0 replies; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-12 15:15 UTC (permalink / raw)
  To: intel-gfx, Souza, Jose

This feature is supported from GEN9+, but this time it focuses on
supporting of PSR2 software tracking for GEN12+.
Looks good to me.

Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>

On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> This property will be used by PSR2 software tracking, adding it to
> GEN12+.
> 
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 4 ++++
>  drivers/gpu/drm/i915/display/intel_sprite.c  | 4 ++++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index f40b909952cc..b69878334040 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -35,6 +35,7 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_atomic_uapi.h>
> +#include <drm/drm_damage_helper.h>
>  #include <drm/drm_dp_helper.h>
>  #include <drm/drm_edid.h>
>  #include <drm/drm_fourcc.h>
> @@ -16476,6 +16477,9 @@ intel_cursor_plane_create(struct
> drm_i915_private *dev_priv,
>  	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
>  	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
>  
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		drm_plane_enable_fb_damage_clips(&cursor->base);
> +
>  	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
>  
>  	return cursor;
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c
> b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 571c36f929bd..8be06cb25999 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -34,6 +34,7 @@
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_color_mgmt.h>
>  #include <drm/drm_crtc.h>
> +#include <drm/drm_damage_helper.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_plane_helper.h>
>  #include <drm/drm_rect.h>
> @@ -3151,6 +3152,9 @@ skl_universal_plane_create(struct
> drm_i915_private *dev_priv,
>  
>  	drm_plane_create_zpos_immutable_property(&plane->base,
> plane_id);
>  
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		drm_plane_enable_fb_damage_clips(&plane->base);
> +
>  	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
>  
>  	return plane;
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property José Roberto de Souza
  2020-06-12 15:15   ` Mun, Gwan-gyeong
@ 2020-06-12 15:25   ` Ville Syrjälä
  2020-06-12 15:30     ` Souza, Jose
  1 sibling, 1 reply; 28+ messages in thread
From: Ville Syrjälä @ 2020-06-12 15:25 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: intel-gfx

On Tue, May 26, 2020 at 03:14:43PM -0700, José Roberto de Souza wrote:
> This property will be used by PSR2 software tracking, adding it to
> GEN12+.

Is there actual userspace that uses this?

> 
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 4 ++++
>  drivers/gpu/drm/i915/display/intel_sprite.c  | 4 ++++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index f40b909952cc..b69878334040 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -35,6 +35,7 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_atomic_uapi.h>
> +#include <drm/drm_damage_helper.h>
>  #include <drm/drm_dp_helper.h>
>  #include <drm/drm_edid.h>
>  #include <drm/drm_fourcc.h>
> @@ -16476,6 +16477,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
>  	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
>  	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
>  
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		drm_plane_enable_fb_damage_clips(&cursor->base);
> +
>  	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
>  
>  	return cursor;
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 571c36f929bd..8be06cb25999 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -34,6 +34,7 @@
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_color_mgmt.h>
>  #include <drm/drm_crtc.h>
> +#include <drm/drm_damage_helper.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_plane_helper.h>
>  #include <drm/drm_rect.h>
> @@ -3151,6 +3152,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
>  
>  	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
>  
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		drm_plane_enable_fb_damage_clips(&plane->base);
> +
>  	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
>  
>  	return plane;
> -- 
> 2.26.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property
  2020-06-12 15:25   ` Ville Syrjälä
@ 2020-06-12 15:30     ` Souza, Jose
  2020-06-12 15:37       ` Ville Syrjälä
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2020-06-12 15:30 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Fri, 2020-06-12 at 18:25 +0300, Ville Syrjälä wrote:
> On Tue, May 26, 2020 at 03:14:43PM -0700, José Roberto de Souza wrote:
> > This property will be used by PSR2 software tracking, adding it to
> > GEN12+.
> 
> Is there actual userspace that uses this?

Only Weston for now:

https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17

> 
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 4 ++++
> >  drivers/gpu/drm/i915/display/intel_sprite.c  | 4 ++++
> >  2 files changed, 8 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index f40b909952cc..b69878334040 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -35,6 +35,7 @@
> >  #include <drm/drm_atomic.h>
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_atomic_uapi.h>
> > +#include <drm/drm_damage_helper.h>
> >  #include <drm/drm_dp_helper.h>
> >  #include <drm/drm_edid.h>
> >  #include <drm/drm_fourcc.h>
> > @@ -16476,6 +16477,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
> >  	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
> >  	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
> >  
> > +	if (INTEL_GEN(dev_priv) >= 12)
> > +		drm_plane_enable_fb_damage_clips(&cursor->base);
> > +
> >  	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
> >  
> >  	return cursor;
> > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> > index 571c36f929bd..8be06cb25999 100644
> > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > @@ -34,6 +34,7 @@
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_color_mgmt.h>
> >  #include <drm/drm_crtc.h>
> > +#include <drm/drm_damage_helper.h>
> >  #include <drm/drm_fourcc.h>
> >  #include <drm/drm_plane_helper.h>
> >  #include <drm/drm_rect.h>
> > @@ -3151,6 +3152,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
> >  
> >  	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
> >  
> > +	if (INTEL_GEN(dev_priv) >= 12)
> > +		drm_plane_enable_fb_damage_clips(&plane->base);
> > +
> >  	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> >  
> >  	return plane;
> > -- 
> > 2.26.2
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property
  2020-06-12 15:30     ` Souza, Jose
@ 2020-06-12 15:37       ` Ville Syrjälä
  2020-06-12 15:42         ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Ville Syrjälä @ 2020-06-12 15:37 UTC (permalink / raw)
  To: Souza, Jose; +Cc: intel-gfx

On Fri, Jun 12, 2020 at 03:30:59PM +0000, Souza, Jose wrote:
> On Fri, 2020-06-12 at 18:25 +0300, Ville Syrjälä wrote:
> > On Tue, May 26, 2020 at 03:14:43PM -0700, José Roberto de Souza wrote:
> > > This property will be used by PSR2 software tracking, adding it to
> > > GEN12+.
> > 
> > Is there actual userspace that uses this?
> 
> Only Weston for now:
> 
> https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17

And what happens when userspace doesn't do this stuff?

> 
> > 
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 4 ++++
> > >  drivers/gpu/drm/i915/display/intel_sprite.c  | 4 ++++
> > >  2 files changed, 8 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index f40b909952cc..b69878334040 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -35,6 +35,7 @@
> > >  #include <drm/drm_atomic.h>
> > >  #include <drm/drm_atomic_helper.h>
> > >  #include <drm/drm_atomic_uapi.h>
> > > +#include <drm/drm_damage_helper.h>
> > >  #include <drm/drm_dp_helper.h>
> > >  #include <drm/drm_edid.h>
> > >  #include <drm/drm_fourcc.h>
> > > @@ -16476,6 +16477,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
> > >  	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
> > >  	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
> > >  
> > > +	if (INTEL_GEN(dev_priv) >= 12)
> > > +		drm_plane_enable_fb_damage_clips(&cursor->base);
> > > +
> > >  	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
> > >  
> > >  	return cursor;
> > > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> > > index 571c36f929bd..8be06cb25999 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > > @@ -34,6 +34,7 @@
> > >  #include <drm/drm_atomic_helper.h>
> > >  #include <drm/drm_color_mgmt.h>
> > >  #include <drm/drm_crtc.h>
> > > +#include <drm/drm_damage_helper.h>
> > >  #include <drm/drm_fourcc.h>
> > >  #include <drm/drm_plane_helper.h>
> > >  #include <drm/drm_rect.h>
> > > @@ -3151,6 +3152,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
> > >  
> > >  	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
> > >  
> > > +	if (INTEL_GEN(dev_priv) >= 12)
> > > +		drm_plane_enable_fb_damage_clips(&plane->base);
> > > +
> > >  	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> > >  
> > >  	return plane;
> > > -- 
> > > 2.26.2
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property
  2020-06-12 15:37       ` Ville Syrjälä
@ 2020-06-12 15:42         ` Souza, Jose
  0 siblings, 0 replies; 28+ messages in thread
From: Souza, Jose @ 2020-06-12 15:42 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Fri, 2020-06-12 at 18:37 +0300, Ville Syrjälä wrote:
> On Fri, Jun 12, 2020 at 03:30:59PM +0000, Souza, Jose wrote:
> > On Fri, 2020-06-12 at 18:25 +0300, Ville Syrjälä wrote:
> > > On Tue, May 26, 2020 at 03:14:43PM -0700, José Roberto de Souza wrote:
> > > > This property will be used by PSR2 software tracking, adding it to
> > > > GEN12+.
> > > 
> > > Is there actual userspace that uses this?
> > 
> > Only Weston for now:
> > 
> > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> 
> And what happens when userspace doesn't do this stuff?

It updates the whole area of the plane that flipped.

> 
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c | 4 ++++
> > > >  drivers/gpu/drm/i915/display/intel_sprite.c  | 4 ++++
> > > >  2 files changed, 8 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index f40b909952cc..b69878334040 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -35,6 +35,7 @@
> > > >  #include <drm/drm_atomic.h>
> > > >  #include <drm/drm_atomic_helper.h>
> > > >  #include <drm/drm_atomic_uapi.h>
> > > > +#include <drm/drm_damage_helper.h>
> > > >  #include <drm/drm_dp_helper.h>
> > > >  #include <drm/drm_edid.h>
> > > >  #include <drm/drm_fourcc.h>
> > > > @@ -16476,6 +16477,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
> > > >  	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
> > > >  	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
> > > >  
> > > > +	if (INTEL_GEN(dev_priv) >= 12)
> > > > +		drm_plane_enable_fb_damage_clips(&cursor->base);
> > > > +
> > > >  	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
> > > >  
> > > >  	return cursor;
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> > > > index 571c36f929bd..8be06cb25999 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > > > @@ -34,6 +34,7 @@
> > > >  #include <drm/drm_atomic_helper.h>
> > > >  #include <drm/drm_color_mgmt.h>
> > > >  #include <drm/drm_crtc.h>
> > > > +#include <drm/drm_damage_helper.h>
> > > >  #include <drm/drm_fourcc.h>
> > > >  #include <drm/drm_plane_helper.h>
> > > >  #include <drm/drm_rect.h>
> > > > @@ -3151,6 +3152,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
> > > >  
> > > >  	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
> > > >  
> > > > +	if (INTEL_GEN(dev_priv) >= 12)
> > > > +		drm_plane_enable_fb_damage_clips(&plane->base);
> > > > +
> > > >  	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> > > >  
> > > >  	return plane;
> > > > -- 
> > > > 2.26.2
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: Reorder intel_psr2_config_valid()
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 3/6] drm/i915: Reorder intel_psr2_config_valid() José Roberto de Souza
@ 2020-06-12 15:42   ` Mun, Gwan-gyeong
  0 siblings, 0 replies; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-12 15:42 UTC (permalink / raw)
  To: intel-gfx, Souza, Jose

Looks good to me.

Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>

On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> Future patches will bring PSR2 selective fetch configuration
> validation but most of the configuration checks will be used for HW
> tracking and selective fetch so the reoder was necessary.
> 
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 50 ++++++++++++--------
> ----
>  1 file changed, 25 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 714c590b39f5..0c86e9e341a2 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -646,21 +646,6 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>  		return false;
>  	}
>  
> -	/*
> -	 * Some platforms lack PSR2 HW tracking and instead require
> manual
> -	 * tracking by software.  In this case, the driver is required
> to track
> -	 * the areas that need updates and program hardware to send
> selective
> -	 * updates.
> -	 *
> -	 * So until the software tracking is implemented, PSR2 needs to
> be
> -	 * disabled for platforms without PSR2 HW tracking.
> -	 */
> -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "No PSR2 HW tracking in the platform\n");
> -		return false;
> -	}
> -
>  	/*
>  	 * DSC and PSR2 cannot be enabled simultaneously. If a
> requested
>  	 * resolution requires DSC to be enabled, priority is given to
> DSC
> @@ -672,6 +657,12 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>  		return false;
>  	}
>  
> +	if (crtc_state->crc_enabled) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "PSR2 not enabled because it would inhibit
> pipe CRC calculation\n");
> +		return false;
> +	}
> +
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		psr_max_h = 5120;
>  		psr_max_v = 3200;
> @@ -686,14 +677,6 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>  		max_bpp = 24;
>  	}
>  
> -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "PSR2 not enabled, resolution %dx%d > max
> supported %dx%d\n",
> -			    crtc_hdisplay, crtc_vdisplay,
> -			    psr_max_h, psr_max_v);
> -		return false;
> -	}
> -
>  	if (crtc_state->pipe_bpp > max_bpp) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "PSR2 not enabled, pipe bpp %d > max
> supported %d\n",
> @@ -714,9 +697,26 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>  		return false;
>  	}
>  
> -	if (crtc_state->crc_enabled) {
> +	/*
> +	 * Some platforms lack PSR2 HW tracking and instead require
> manual
> +	 * tracking by software.  In this case, the driver is required
> to track
> +	 * the areas that need updates and program hardware to send
> selective
> +	 * updates.
> +	 *
> +	 * So until the software tracking is implemented, PSR2 needs to
> be
> +	 * disabled for platforms without PSR2 HW tracking.
> +	 */
> +	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
>  		drm_dbg_kms(&dev_priv->drm,
> -			    "PSR2 not enabled because it would inhibit
> pipe CRC calculation\n");
> +			    "No PSR2 HW tracking in the platform\n");
> +		return false;
> +	}
> +
> +	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "PSR2 not enabled, resolution %dx%d > max
> supported %dx%d\n",
> +			    crtc_hdisplay, crtc_vdisplay,
> +			    psr_max_h, psr_max_v);
>  		return false;
>  	}
>  
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch José Roberto de Souza
@ 2020-06-12 16:30   ` Ville Syrjälä
  2020-06-12 20:33     ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Ville Syrjälä @ 2020-06-12 16:30 UTC (permalink / raw)
  To: José Roberto de Souza; +Cc: Dhinakaran Pandiyan, intel-gfx

On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de Souza wrote:
> All GEN12 platforms supports PSR2 selective fetch but not all GEN12
> platforms supports PSR2 hardware tracking(aka RKL).
> 
> This feature consists in software program registers with the damaged
> area of each plane this way hardware will only fetch from memory those
> areas and sent the PSR2 selective update blocks to panel, saving even
> more power but to it actually happen userspace needs to send the
> damaged areas otherwise it will still fetch the whole plane as
> fallback.
> As today Gnome3 do not send damaged areas and the only compositor that
> I'm aware that sets the damaged areas is Weston.
> https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> 
> So here implementing page flip part, it is still completely missing
> frontbuffer modifications, that is why the enable_psr2_sel_fetch
> parameter was added.
> 
> The plan is to switch all GEN12 platforms to selective fetch when
> ready, it will also depend in add some tests sending damaged areas.
> I have a hacked version of kms_psr2_su with 3 planes that I can
> cleanup and send in a few days(99% of PSR2 selective fetch changes was
> done during my free time while bored during quarantine rainy days).
> 
> BSpec: 55229
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
>  .../drm/i915/display/intel_display_debugfs.c  |   3 +
>  .../drm/i915/display/intel_display_types.h    |  10 +
>  drivers/gpu/drm/i915/display/intel_psr.c      | 329 +++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
>  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
>  drivers/gpu/drm/i915/i915_drv.h               |   2 +
>  drivers/gpu/drm/i915/i915_params.c            |   5 +
>  drivers/gpu/drm/i915/i915_params.h            |   1 +
>  9 files changed, 352 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index b69878334040..984809208c29 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -11729,6 +11729,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
>  	if (INTEL_GEN(dev_priv) >= 9)
>  		skl_write_cursor_wm(plane, crtc_state);
>  
> +	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
> +
>  	if (plane->cursor.base != base ||
>  	    plane->cursor.size != fbc_ctl ||
>  	    plane->cursor.cntl != cntl) {
> @@ -15115,6 +15117,8 @@ static void commit_pipe_config(struct intel_atomic_state *state,
>  
>  		if (new_crtc_state->update_pipe)
>  			intel_pipe_fastset(old_crtc_state, new_crtc_state);
> +
> +		intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
>  	}
>  
>  	if (dev_priv->display.atomic_update_watermarks)
> @@ -15156,6 +15160,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
>  			intel_color_load_luts(new_crtc_state);
>  
>  		intel_pre_plane_update(state, crtc);
> +		intel_psr2_sel_fetch_update(state, crtc);
>  
>  		if (new_crtc_state->update_pipe)
>  			intel_encoders_update_pipe(state, crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index 70525623bcdf..0f600974462b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
>  			su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
>  			seq_printf(m, "%d\t%d\n", frame, su_blocks);
>  		}
> +
> +		seq_printf(m, "PSR2 selective fetch: %s\n",
> +			   enableddisabled(psr->psr2_sel_fetch_enabled));
>  	}
>  
>  unlock:
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 30b2767578dc..b77a512e5362 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -586,6 +586,13 @@ struct intel_plane_state {
>  	u32 planar_slave;
>  
>  	struct drm_intel_sprite_colorkey ckey;
> +
> +	struct {
> +		u32 ctl;
> +		u32 pos;
> +		u32 offset;
> +		u32 size;
> +	} psr2_sel_fetch;

Do we really need all that here? We don't store them for the normal
plane updates either.

>  };
>  
>  struct intel_initial_plane_config {
> @@ -931,6 +938,7 @@ struct intel_crtc_state {
>  
>  	bool has_psr;
>  	bool has_psr2;
> +	bool enable_psr2_sel_fetch;
>  	u32 dc3co_exitline;
>  
>  	/*
> @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
>  
>  	/* For DSB related info */
>  	struct intel_dsb *dsb;
> +
> +	u32 psr2_sw_man_track_ctl;
>  };
>  
>  enum intel_pipe_crc_source {
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 0c86e9e341a2..bc2a2e64fe2a 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
>  	else
>  		val |= EDP_PSR2_TP2_TIME_2500us;
>  
> +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> +		intel_de_write(dev_priv,
> +			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
> +			       PSR2_MAN_TRK_CTL_ENABLE);
> +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> +		intel_de_write(dev_priv,
> +			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
> +
>  	/*
>  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
>  	 * recommending keep this bit unset while PSR2 is enabled.
> @@ -628,6 +636,38 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
>  	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
>  }
>  
> +static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
> +					      struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
> +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +	struct intel_plane_state *plane_state;
> +	struct intel_plane *plane;
> +	int i;
> +
> +	if (!i915_modparams.enable_psr2_sel_fetch) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "PSR2 sel fetch not enabled, disabled by parameter\n");
> +		return false;
> +	}
> +
> +	if (crtc_state->uapi.async_flip) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "PSR2 sel fetch not enabled, async flip enabled\n");
> +		return false;
> +	}

Not supported anyway.

> +
> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> +		if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "PSR2 sel fetch not enabled, plane rotated\n");
> +			return false;
> +		}
> +	}
> +
> +	return crtc_state->enable_psr2_sel_fetch = true;
> +}
> +
>  static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>  				    struct intel_crtc_state *crtc_state)
>  {
> @@ -697,22 +737,17 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>  		return false;
>  	}
>  
> -	/*
> -	 * Some platforms lack PSR2 HW tracking and instead require manual
> -	 * tracking by software.  In this case, the driver is required to track
> -	 * the areas that need updates and program hardware to send selective
> -	 * updates.
> -	 *
> -	 * So until the software tracking is implemented, PSR2 needs to be
> -	 * disabled for platforms without PSR2 HW tracking.
> -	 */
> -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "No PSR2 HW tracking in the platform\n");
> -		return false;
> +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> +		if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
> +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
> +			return false;
> +		}
>  	}
>  
> -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
> +	if (!crtc_state->enable_psr2_sel_fetch &&
> +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
>  			    crtc_hdisplay, crtc_vdisplay,
> @@ -863,6 +898,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
>  		val |= EXITLINE_ENABLE;
>  		intel_de_write(dev_priv, EXITLINE(cpu_transcoder), val);
>  	}
> +
> +	if (HAS_PSR_HW_TRACKING(dev_priv))
> +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
> +			     dev_priv->psr.psr2_sel_fetch_enabled ?
> +			     IGNORE_PSR2_HW_TRACKING : 0);
>  }
>  
>  static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
> @@ -884,7 +924,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
>  	/* DC5/DC6 requires at least 6 idle frames */
>  	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
>  	dev_priv->psr.dc3co_exit_delay = val;
> -
> +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
>  	/*
>  	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
>  	 * will still keep the error set even after the reset done in the
> @@ -1080,6 +1120,265 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
>  		intel_psr_exit(dev_priv);
>  }
>  
> +void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> +					const struct intel_crtc_state *crtc_state,
> +					const struct intel_plane_state *plane_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	enum pipe pipe = plane->pipe;
> +
> +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> +	    !plane_state ||
> +	    !crtc_state->enable_psr2_sel_fetch)
> +		return;
> +
> +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
> +			  plane_state->psr2_sel_fetch.ctl);
> +	if (!plane_state->psr2_sel_fetch.ctl || plane->id == PLANE_CURSOR)
> +		return;
> +
> +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe, plane->id),
> +			  plane_state->psr2_sel_fetch.pos);
> +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> +			  plane_state->psr2_sel_fetch.offset);
> +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe, plane->id),
> +			  plane_state->psr2_sel_fetch.size);
> +}
> +
> +void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	struct i915_psr *psr = &dev_priv->psr;
> +
> +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> +	    !crtc_state->enable_psr2_sel_fetch)
> +		return;
> +
> +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
> +		       crtc_state->psr2_sw_man_track_ctl);
> +}
> +
> +static void intel_psr2_plane_sel_fetch_calc(struct intel_plane_state *plane_state,
> +					    struct drm_rect *clip)
> +{
> +	int color_plane = plane_state->planar_linked_plane && !plane_state->planar_slave;
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	u32 val;
> +
> +	if (plane->id == PLANE_CURSOR)
> +		return;
> +
> +	val = (plane_state->color_plane[color_plane].y + clip->y1) << 16;
> +	val |= plane_state->color_plane[color_plane].x;
> +	plane_state->psr2_sel_fetch.offset = val;
> +
> +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> +	val |= plane_state->uapi.crtc_x;
> +	plane_state->psr2_sel_fetch.pos = val;
> +
> +	/* Sizes are 0 based */
> +	val = (clip->y2 - clip->y1 - 1) << 16;
> +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
> +	plane_state->psr2_sel_fetch.size = val;
> +}
> +
> +static void intel_psr2_trans_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
> +					      struct drm_rect *clip,
> +					      bool full_update)
> +{
> +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> +
> +	if (full_update) {
> +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> +		goto exit;
> +	}
> +
> +	if (clip->y1 == -1)
> +		goto exit;
> +
> +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4 + 1);
> +	val |= PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4) + 1);
> +exit:
> +	crtc_state->psr2_sw_man_track_ctl = val;
> +}
> +
> +static void intel_psr2_plane_sel_fetch_ctl_calc(struct intel_plane *plane,
> +						struct intel_plane_state *plane_state,
> +						bool enable)
> +{
> +	if (!enable)
> +		plane_state->psr2_sel_fetch.ctl = 0;
> +	else if (plane->id == PLANE_CURSOR)
> +		plane_state->psr2_sel_fetch.ctl = plane->cursor.cntl;
> +	else
> +		plane_state->psr2_sel_fetch.ctl = plane_state->ctl;
> +}
> +
> +static void clip_update(struct drm_rect *overlap_damage_area,
> +			struct drm_rect *damage_area)
> +{
> +	if (overlap_damage_area->y1 == -1) {
> +		overlap_damage_area->y1 = damage_area->y1;
> +		overlap_damage_area->y2 = damage_area->y2;
> +		return;
> +	}
> +
> +	if (damage_area->y1 < overlap_damage_area->y1)
> +		overlap_damage_area->y1 = damage_area->y1;
> +
> +	if (damage_area->y2 > overlap_damage_area->y2)
> +		overlap_damage_area->y2 = damage_area->y2;
> +}
> +
> +/* Update plane damage area if planes above moved or have alpha */
> +static void intel_psr2_pipe_dirty_areas_set(struct intel_plane_state *plane_state,
> +					    struct intel_plane *plane,
> +					    const struct drm_rect *pipe_dirty_areas,
> +					    struct drm_rect *plane_clip)
> +{
> +	enum plane_id i;
> +
> +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> +		int j;
> +
> +		for (j = 0; j < 2; j++) {
> +			struct drm_rect r = pipe_dirty_areas[i * 2 + j];
> +
> +			if (!drm_rect_width(&r))
> +				continue;
> +			if (!drm_rect_intersect(&r, &plane_state->uapi.dst))
> +				continue;
> +
> +			r.y1 -= plane_state->uapi.crtc_y;
> +			r.y2 -= plane_state->uapi.crtc_y;
> +			clip_update(plane_clip, &r);
> +		}
> +	}
> +}
> +
> +void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
> +				 struct intel_crtc *crtc)
> +{
> +	struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> +	struct intel_plane_state *new_plane_state, *old_plane_state;
> +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] = {};
> +	struct drm_rect pipe_clip = { .y1 = -1 };
> +	struct intel_plane *plane;
> +	bool full_update = false;
> +	int i;
> +
> +	if (!crtc_state->enable_psr2_sel_fetch)
> +		return;
> +
> +	/*
> +	 * Load all the pipes areas where there is a plane with alpha or a plane
> +	 * that moved or plane that the visibility changed in those
> +	 * cases planes bellow it will need to be fetched in those intersection
> +	 * areas even if they are not damaged in those areas.
> +	 */
> +	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
> +					     new_plane_state, i) {
> +		bool alpha, flip, dirty;
> +
> +		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
> +			continue;
> +
> +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> +		alpha |= old_plane_state->uapi.alpha != U16_MAX;
> +		flip = new_plane_state->uapi.fb != old_plane_state->uapi.fb;
> +		dirty = alpha && flip;
> +		dirty |= !drm_rect_equals(&new_plane_state->uapi.dst,
> +					  &old_plane_state->uapi.dst);
> +		dirty |= new_plane_state->uapi.visible !=
> +			 old_plane_state->uapi.visible;
> +		if (!dirty)
> +			continue;
> +
> +		if (old_plane_state->uapi.visible)
> +			pipe_dirty_areas[plane->id * 2] = old_plane_state->uapi.dst;
> +		if (new_plane_state->uapi.visible)
> +			pipe_dirty_areas[plane->id * 2 + 1] = new_plane_state->uapi.dst;
> +	}
> +
> +	/*
> +	 * Iterate over all planes, compute the damaged clip area also including
> +	 * the pipe_dirty_areas, compute plane registers and update pipe damaged
> +	 * area
> +	 */
> +	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
> +					     new_plane_state, i) {
> +		struct drm_rect plane_clip = { .y1 = -1 };
> +		struct drm_mode_rect *clips;
> +		u32 num_clips;
> +		int j;
> +
> +		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
> +			continue;
> +
> +		/*
> +		 * TODO: Not clear how to handle planes with negative position,
> +		 * also planes are not updated if they have a negative X
> +		 * position so for now doing a full update in this cases
> +		 */
> +		if (new_plane_state->uapi.crtc_y < 0 ||
> +		    new_plane_state->uapi.crtc_x < 0) {
> +			full_update = true;
> +			break;
> +		}
> +
> +		intel_psr2_plane_sel_fetch_ctl_calc(plane, new_plane_state,
> +						    new_plane_state->uapi.visible);
> +		if (!new_plane_state->uapi.visible)
> +			continue;
> +
> +		clips = drm_plane_get_damage_clips(&new_plane_state->uapi);
> +		num_clips = drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> +
> +		/*
> +		 * If plane moved mark the whole plane area as damaged so it
> +		 * can be complete draw in the new position
> +		 */
> +		if (!drm_rect_equals(&new_plane_state->uapi.dst,
> +				     &old_plane_state->uapi.dst)) {
> +			num_clips = 0;
> +			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
> +			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
> +		} else if (!num_clips) {
> +			/*
> +			 * If plane don't have damage areas but the framebuffer
> +			 * changed mark the whole plane as damaged
> +			 */
> +			if (new_plane_state->uapi.fb == old_plane_state->uapi.fb)
> +				continue;
> +
> +			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
> +			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
> +		}
> +
> +		for (j = 0; j < num_clips; j++) {
> +			struct drm_rect damage_area;
> +
> +			damage_area.x1 = clips[j].x1;
> +			damage_area.x2 = clips[j].x2;
> +			damage_area.y1 = clips[j].y1;
> +			damage_area.y2 = clips[j].y2;
> +			clip_update(&plane_clip, &damage_area);
> +		}
> +
> +		intel_psr2_pipe_dirty_areas_set(new_plane_state, plane,
> +						pipe_dirty_areas, &plane_clip);
> +		intel_psr2_plane_sel_fetch_calc(new_plane_state, &plane_clip);
> +
> +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> +		clip_update(&pipe_clip, &plane_clip);
> +	}

This whole thing seems rather convoluted. Also using lots of uapi state
in places where I don't expect to see any.

I would suggest the correct way would be something like:
1) for_each_plane_in_state()
	hw.damage = translate_to_some_hw_coord_space(union(uapi.damages))
	or just use the full plane size if we have scaling i guess

2) need to add all affected planes to the state and set the appropriate
   bitmask, which may mean we want to track the planes' positions in the
   crtc state. I think atm we only have it in the plane state

3) translate the damage further into the final plane src coordinate
   space. Dunno if we have enough state around still to do it cleanly.
   I was thinking maybe it could be done alongside all the other plane
   surface calculations, but there might be a chicken vs. egg situation
   here since we probably want to do the plane check stuff before doing
   step 1, but plane check is also where we do the surface calculations.
   Dunno if we may just want to split the plane check into two stages

To keep things simple I guess what I'd suggest is to forget about the
damage stuff in the first version of the series and just do full
plane updates. That way we don't have to worry about so many coordinate
space transformations.

> +
> +	intel_psr2_trans_man_trk_ctl_calc(crtc_state, &pipe_clip, full_update);
> +}
> +
>  /**
>   * intel_psr_update - Update PSR state
>   * @intel_dp: Intel DP
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
> index b4515186d5f4..d80bd0e46b21 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -13,6 +13,10 @@ struct drm_connector_state;
>  struct drm_i915_private;
>  struct intel_crtc_state;
>  struct intel_dp;
> +struct intel_crtc;
> +struct intel_atomic_state;
> +struct intel_plane_state;
> +struct intel_plane;
>  
>  #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
>  void intel_psr_init_dpcd(struct intel_dp *intel_dp);
> @@ -43,5 +47,11 @@ void intel_psr_atomic_check(struct drm_connector *connector,
>  			    struct drm_connector_state *old_state,
>  			    struct drm_connector_state *new_state);
>  void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp);
> +void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
> +				 struct intel_crtc *crtc);
> +void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> +					const struct intel_crtc_state *crtc_state,
> +					const struct intel_plane_state *plane_state);
> +void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
>  
>  #endif /* __INTEL_PSR_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 8be06cb25999..afede372ac05 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -690,6 +690,8 @@ skl_program_plane(struct intel_plane *plane,
>  		intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
>  				  (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
>  
> +	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
> +
>  	/*
>  	 * The control register self-arms if the plane was previously
>  	 * disabled. Try to make the plane enable atomic by writing
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 146bfd276ce7..ae7efc922393 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -503,6 +503,7 @@ struct i915_psr {
>  	bool link_standby;
>  	bool colorimetry_support;
>  	bool psr2_enabled;
> +	bool psr2_sel_fetch_enabled;
>  	u8 sink_sync_latency;
>  	ktime_t last_entry_attempt;
>  	ktime_t last_exit;
> @@ -1634,6 +1635,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_psr)
>  #define HAS_PSR_HW_TRACKING(dev_priv) \
>  	(INTEL_INFO(dev_priv)->display.has_psr_hw_tracking)
> +#define HAS_PSR2_SEL_FETCH(dev_priv)	 (INTEL_GEN(dev_priv) >= 12)
>  #define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0)
>  
>  #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6)
> diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
> index add00ec1f787..3005451c1194 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -88,6 +88,11 @@ i915_param_named_unsafe(enable_psr, int, 0600,
>  	"(0=disabled, 1=enabled) "
>  	"Default: -1 (use per-chip default)");
>  
> +i915_param_named_unsafe(enable_psr2_sel_fetch, int, 0400,
> +	"Enable PSR2 selective fetch "
> +	"(0=disabled, 1=enabled) "
> +	"Default: 0");
> +
>  i915_param_named_unsafe(force_probe, charp, 0400,
>  	"Force probe the driver for specified devices. "
>  	"See CONFIG_DRM_I915_FORCE_PROBE for details.");
> diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
> index 45323732f099..5a0b16923016 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -53,6 +53,7 @@ struct drm_printer;
>  	param(int, enable_dc, -1, 0400) \
>  	param(int, enable_fbc, -1, 0600) \
>  	param(int, enable_psr, -1, 0600) \
> +	param(int, enable_psr2_sel_fetch, 0, 0400) \
>  	param(int, disable_power_well, -1, 0400) \
>  	param(int, enable_ips, 1, 0600) \
>  	param(int, invert_brightness, 0, 0600) \
> -- 
> 2.26.2

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-06-12 16:30   ` Ville Syrjälä
@ 2020-06-12 20:33     ` Souza, Jose
  2020-06-15 16:40       ` Ville Syrjälä
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2020-06-12 20:33 UTC (permalink / raw)
  To: ville.syrjala; +Cc: Pandiyan, Dhinakaran, intel-gfx

On Fri, 2020-06-12 at 19:30 +0300, Ville Syrjälä wrote:
> On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de Souza wrote:
> > All GEN12 platforms supports PSR2 selective fetch but not all GEN12
> > platforms supports PSR2 hardware tracking(aka RKL).
> > 
> > This feature consists in software program registers with the damaged
> > area of each plane this way hardware will only fetch from memory those
> > areas and sent the PSR2 selective update blocks to panel, saving even
> > more power but to it actually happen userspace needs to send the
> > damaged areas otherwise it will still fetch the whole plane as
> > fallback.
> > As today Gnome3 do not send damaged areas and the only compositor that
> > I'm aware that sets the damaged areas is Weston.
> > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> > 
> > So here implementing page flip part, it is still completely missing
> > frontbuffer modifications, that is why the enable_psr2_sel_fetch
> > parameter was added.
> > 
> > The plan is to switch all GEN12 platforms to selective fetch when
> > ready, it will also depend in add some tests sending damaged areas.
> > I have a hacked version of kms_psr2_su with 3 planes that I can
> > cleanup and send in a few days(99% of PSR2 selective fetch changes was
> > done during my free time while bored during quarantine rainy days).
> > 
> > BSpec: 55229
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Imre Deak <imre.deak@intel.com>
> > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
> >  .../drm/i915/display/intel_display_debugfs.c  |   3 +
> >  .../drm/i915/display/intel_display_types.h    |  10 +
> >  drivers/gpu/drm/i915/display/intel_psr.c      | 329 +++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
> >  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
> >  drivers/gpu/drm/i915/i915_drv.h               |   2 +
> >  drivers/gpu/drm/i915/i915_params.c            |   5 +
> >  drivers/gpu/drm/i915/i915_params.h            |   1 +
> >  9 files changed, 352 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index b69878334040..984809208c29 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -11729,6 +11729,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> >  	if (INTEL_GEN(dev_priv) >= 9)
> >  		skl_write_cursor_wm(plane, crtc_state);
> >  
> > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
> > +
> >  	if (plane->cursor.base != base ||
> >  	    plane->cursor.size != fbc_ctl ||
> >  	    plane->cursor.cntl != cntl) {
> > @@ -15115,6 +15117,8 @@ static void commit_pipe_config(struct intel_atomic_state *state,
> >  
> >  		if (new_crtc_state->update_pipe)
> >  			intel_pipe_fastset(old_crtc_state, new_crtc_state);
> > +
> > +		intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
> >  	}
> >  
> >  	if (dev_priv->display.atomic_update_watermarks)
> > @@ -15156,6 +15160,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> >  			intel_color_load_luts(new_crtc_state);
> >  
> >  		intel_pre_plane_update(state, crtc);
> > +		intel_psr2_sel_fetch_update(state, crtc);
> >  
> >  		if (new_crtc_state->update_pipe)
> >  			intel_encoders_update_pipe(state, crtc);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index 70525623bcdf..0f600974462b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
> >  			su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
> >  			seq_printf(m, "%d\t%d\n", frame, su_blocks);
> >  		}
> > +
> > +		seq_printf(m, "PSR2 selective fetch: %s\n",
> > +			   enableddisabled(psr->psr2_sel_fetch_enabled));
> >  	}
> >  
> >  unlock:
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 30b2767578dc..b77a512e5362 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -586,6 +586,13 @@ struct intel_plane_state {
> >  	u32 planar_slave;
> >  
> >  	struct drm_intel_sprite_colorkey ckey;
> > +
> > +	struct {
> > +		u32 ctl;
> > +		u32 pos;
> > +		u32 offset;
> > +		u32 size;
> > +	} psr2_sel_fetch;
> 
> Do we really need all that here? We don't store them for the normal
> plane updates either.

For ctl we do, anyways could be removed if we store overlapping damage are in here so intel_psr2_program_plane_sel_fetch() would incorporate
intel_psr2_plane_sel_fetch_calc() code, both looks good to me.

> 
> >  };
> >  
> >  struct intel_initial_plane_config {
> > @@ -931,6 +938,7 @@ struct intel_crtc_state {
> >  
> >  	bool has_psr;
> >  	bool has_psr2;
> > +	bool enable_psr2_sel_fetch;
> >  	u32 dc3co_exitline;
> >  
> >  	/*
> > @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
> >  
> >  	/* For DSB related info */
> >  	struct intel_dsb *dsb;
> > +
> > +	u32 psr2_sw_man_track_ctl;
> >  };
> >  
> >  enum intel_pipe_crc_source {
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> > index 0c86e9e341a2..bc2a2e64fe2a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
> >  	else
> >  		val |= EDP_PSR2_TP2_TIME_2500us;
> >  
> > +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> > +		intel_de_write(dev_priv,
> > +			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
> > +			       PSR2_MAN_TRK_CTL_ENABLE);
> > +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> > +		intel_de_write(dev_priv,
> > +			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
> > +
> >  	/*
> >  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
> >  	 * recommending keep this bit unset while PSR2 is enabled.
> > @@ -628,6 +636,38 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
> >  	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
> >  }
> >  
> > +static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
> > +					      struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
> > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > +	struct intel_plane_state *plane_state;
> > +	struct intel_plane *plane;
> > +	int i;
> > +
> > +	if (!i915_modparams.enable_psr2_sel_fetch) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "PSR2 sel fetch not enabled, disabled by parameter\n");
> > +		return false;
> > +	}
> > +
> > +	if (crtc_state->uapi.async_flip) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "PSR2 sel fetch not enabled, async flip enabled\n");
> > +		return false;
> > +	}
> 
> Not supported anyway.
> 
> > +
> > +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> > +		if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) {
> > +			drm_dbg_kms(&dev_priv->drm,
> > +				    "PSR2 sel fetch not enabled, plane rotated\n");
> > +			return false;
> > +		}
> > +	}
> > +
> > +	return crtc_state->enable_psr2_sel_fetch = true;
> > +}
> > +
> >  static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
> >  				    struct intel_crtc_state *crtc_state)
> >  {
> > @@ -697,22 +737,17 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
> >  		return false;
> >  	}
> >  
> > -	/*
> > -	 * Some platforms lack PSR2 HW tracking and instead require manual
> > -	 * tracking by software.  In this case, the driver is required to track
> > -	 * the areas that need updates and program hardware to send selective
> > -	 * updates.
> > -	 *
> > -	 * So until the software tracking is implemented, PSR2 needs to be
> > -	 * disabled for platforms without PSR2 HW tracking.
> > -	 */
> > -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> > -		drm_dbg_kms(&dev_priv->drm,
> > -			    "No PSR2 HW tracking in the platform\n");
> > -		return false;
> > +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> > +		if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
> > +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> > +			drm_dbg_kms(&dev_priv->drm,
> > +				    "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
> > +			return false;
> > +		}
> >  	}
> >  
> > -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
> > +	if (!crtc_state->enable_psr2_sel_fetch &&
> > +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
> >  		drm_dbg_kms(&dev_priv->drm,
> >  			    "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
> >  			    crtc_hdisplay, crtc_vdisplay,
> > @@ -863,6 +898,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
> >  		val |= EXITLINE_ENABLE;
> >  		intel_de_write(dev_priv, EXITLINE(cpu_transcoder), val);
> >  	}
> > +
> > +	if (HAS_PSR_HW_TRACKING(dev_priv))
> > +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
> > +			     dev_priv->psr.psr2_sel_fetch_enabled ?
> > +			     IGNORE_PSR2_HW_TRACKING : 0);
> >  }
> >  
> >  static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
> > @@ -884,7 +924,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
> >  	/* DC5/DC6 requires at least 6 idle frames */
> >  	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> >  	dev_priv->psr.dc3co_exit_delay = val;
> > -
> > +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
> >  	/*
> >  	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
> >  	 * will still keep the error set even after the reset done in the
> > @@ -1080,6 +1120,265 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
> >  		intel_psr_exit(dev_priv);
> >  }
> >  
> > +void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> > +					const struct intel_crtc_state *crtc_state,
> > +					const struct intel_plane_state *plane_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > +	enum pipe pipe = plane->pipe;
> > +
> > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > +	    !plane_state ||
> > +	    !crtc_state->enable_psr2_sel_fetch)
> > +		return;
> > +
> > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
> > +			  plane_state->psr2_sel_fetch.ctl);
> > +	if (!plane_state->psr2_sel_fetch.ctl || plane->id == PLANE_CURSOR)
> > +		return;
> > +
> > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe, plane->id),
> > +			  plane_state->psr2_sel_fetch.pos);
> > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> > +			  plane_state->psr2_sel_fetch.offset);
> > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe, plane->id),
> > +			  plane_state->psr2_sel_fetch.size);
> > +}
> > +
> > +void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct i915_psr *psr = &dev_priv->psr;
> > +
> > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > +	    !crtc_state->enable_psr2_sel_fetch)
> > +		return;
> > +
> > +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
> > +		       crtc_state->psr2_sw_man_track_ctl);
> > +}
> > +
> > +static void intel_psr2_plane_sel_fetch_calc(struct intel_plane_state *plane_state,
> > +					    struct drm_rect *clip)
> > +{
> > +	int color_plane = plane_state->planar_linked_plane && !plane_state->planar_slave;
> > +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> > +	u32 val;
> > +
> > +	if (plane->id == PLANE_CURSOR)
> > +		return;
> > +
> > +	val = (plane_state->color_plane[color_plane].y + clip->y1) << 16;
> > +	val |= plane_state->color_plane[color_plane].x;
> > +	plane_state->psr2_sel_fetch.offset = val;
> > +
> > +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> > +	val |= plane_state->uapi.crtc_x;
> > +	plane_state->psr2_sel_fetch.pos = val;
> > +
> > +	/* Sizes are 0 based */
> > +	val = (clip->y2 - clip->y1 - 1) << 16;
> > +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
> > +	plane_state->psr2_sel_fetch.size = val;
> > +}
> > +
> > +static void intel_psr2_trans_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
> > +					      struct drm_rect *clip,
> > +					      bool full_update)
> > +{
> > +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> > +
> > +	if (full_update) {
> > +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> > +		goto exit;
> > +	}
> > +
> > +	if (clip->y1 == -1)
> > +		goto exit;
> > +
> > +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> > +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4 + 1);
> > +	val |= PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4) + 1);
> > +exit:
> > +	crtc_state->psr2_sw_man_track_ctl = val;
> > +}
> > +
> > +static void intel_psr2_plane_sel_fetch_ctl_calc(struct intel_plane *plane,
> > +						struct intel_plane_state *plane_state,
> > +						bool enable)
> > +{
> > +	if (!enable)
> > +		plane_state->psr2_sel_fetch.ctl = 0;
> > +	else if (plane->id == PLANE_CURSOR)
> > +		plane_state->psr2_sel_fetch.ctl = plane->cursor.cntl;
> > +	else
> > +		plane_state->psr2_sel_fetch.ctl = plane_state->ctl;
> > +}
> > +
> > +static void clip_update(struct drm_rect *overlap_damage_area,
> > +			struct drm_rect *damage_area)
> > +{
> > +	if (overlap_damage_area->y1 == -1) {
> > +		overlap_damage_area->y1 = damage_area->y1;
> > +		overlap_damage_area->y2 = damage_area->y2;
> > +		return;
> > +	}
> > +
> > +	if (damage_area->y1 < overlap_damage_area->y1)
> > +		overlap_damage_area->y1 = damage_area->y1;
> > +
> > +	if (damage_area->y2 > overlap_damage_area->y2)
> > +		overlap_damage_area->y2 = damage_area->y2;
> > +}
> > +
> > +/* Update plane damage area if planes above moved or have alpha */
> > +static void intel_psr2_pipe_dirty_areas_set(struct intel_plane_state *plane_state,
> > +					    struct intel_plane *plane,
> > +					    const struct drm_rect *pipe_dirty_areas,
> > +					    struct drm_rect *plane_clip)
> > +{
> > +	enum plane_id i;
> > +
> > +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> > +		int j;
> > +
> > +		for (j = 0; j < 2; j++) {
> > +			struct drm_rect r = pipe_dirty_areas[i * 2 + j];
> > +
> > +			if (!drm_rect_width(&r))
> > +				continue;
> > +			if (!drm_rect_intersect(&r, &plane_state->uapi.dst))
> > +				continue;
> > +
> > +			r.y1 -= plane_state->uapi.crtc_y;
> > +			r.y2 -= plane_state->uapi.crtc_y;
> > +			clip_update(plane_clip, &r);
> > +		}
> > +	}
> > +}
> > +
> > +void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
> > +				 struct intel_crtc *crtc)
> > +{
> > +	struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > +	struct intel_plane_state *new_plane_state, *old_plane_state;
> > +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] = {};
> > +	struct drm_rect pipe_clip = { .y1 = -1 };
> > +	struct intel_plane *plane;
> > +	bool full_update = false;
> > +	int i;
> > +
> > +	if (!crtc_state->enable_psr2_sel_fetch)
> > +		return;
> > +
> > +	/*
> > +	 * Load all the pipes areas where there is a plane with alpha or a plane
> > +	 * that moved or plane that the visibility changed in those
> > +	 * cases planes bellow it will need to be fetched in those intersection
> > +	 * areas even if they are not damaged in those areas.
> > +	 */
> > +	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
> > +					     new_plane_state, i) {
> > +		bool alpha, flip, dirty;
> > +
> > +		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
> > +			continue;
> > +
> > +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> > +		alpha |= old_plane_state->uapi.alpha != U16_MAX;
> > +		flip = new_plane_state->uapi.fb != old_plane_state->uapi.fb;
> > +		dirty = alpha && flip;
> > +		dirty |= !drm_rect_equals(&new_plane_state->uapi.dst,
> > +					  &old_plane_state->uapi.dst);
> > +		dirty |= new_plane_state->uapi.visible !=
> > +			 old_plane_state->uapi.visible;
> > +		if (!dirty)
> > +			continue;
> > +
> > +		if (old_plane_state->uapi.visible)
> > +			pipe_dirty_areas[plane->id * 2] = old_plane_state->uapi.dst;
> > +		if (new_plane_state->uapi.visible)
> > +			pipe_dirty_areas[plane->id * 2 + 1] = new_plane_state->uapi.dst;
> > +	}
> > +
> > +	/*
> > +	 * Iterate over all planes, compute the damaged clip area also including
> > +	 * the pipe_dirty_areas, compute plane registers and update pipe damaged
> > +	 * area
> > +	 */
> > +	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
> > +					     new_plane_state, i) {
> > +		struct drm_rect plane_clip = { .y1 = -1 };
> > +		struct drm_mode_rect *clips;
> > +		u32 num_clips;
> > +		int j;
> > +
> > +		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
> > +			continue;
> > +
> > +		/*
> > +		 * TODO: Not clear how to handle planes with negative position,
> > +		 * also planes are not updated if they have a negative X
> > +		 * position so for now doing a full update in this cases
> > +		 */
> > +		if (new_plane_state->uapi.crtc_y < 0 ||
> > +		    new_plane_state->uapi.crtc_x < 0) {
> > +			full_update = true;
> > +			break;
> > +		}
> > +
> > +		intel_psr2_plane_sel_fetch_ctl_calc(plane, new_plane_state,
> > +						    new_plane_state->uapi.visible);
> > +		if (!new_plane_state->uapi.visible)
> > +			continue;
> > +
> > +		clips = drm_plane_get_damage_clips(&new_plane_state->uapi);
> > +		num_clips = drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> > +
> > +		/*
> > +		 * If plane moved mark the whole plane area as damaged so it
> > +		 * can be complete draw in the new position
> > +		 */
> > +		if (!drm_rect_equals(&new_plane_state->uapi.dst,
> > +				     &old_plane_state->uapi.dst)) {
> > +			num_clips = 0;
> > +			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
> > +			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
> > +		} else if (!num_clips) {
> > +			/*
> > +			 * If plane don't have damage areas but the framebuffer
> > +			 * changed mark the whole plane as damaged
> > +			 */
> > +			if (new_plane_state->uapi.fb == old_plane_state->uapi.fb)
> > +				continue;
> > +
> > +			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
> > +			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
> > +		}
> > +
> > +		for (j = 0; j < num_clips; j++) {
> > +			struct drm_rect damage_area;
> > +
> > +			damage_area.x1 = clips[j].x1;
> > +			damage_area.x2 = clips[j].x2;
> > +			damage_area.y1 = clips[j].y1;
> > +			damage_area.y2 = clips[j].y2;
> > +			clip_update(&plane_clip, &damage_area);
> > +		}
> > +
> > +		intel_psr2_pipe_dirty_areas_set(new_plane_state, plane,
> > +						pipe_dirty_areas, &plane_clip);
> > +		intel_psr2_plane_sel_fetch_calc(new_plane_state, &plane_clip);
> > +
> > +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> > +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> > +		clip_update(&pipe_clip, &plane_clip);
> > +	}
> 
> This whole thing seems rather convoluted. Also using lots of uapi state
> in places where I don't expect to see any.

Not sure from where I should get this information then, intel_plane_state don't have it.

> 
> I would suggest the correct way would be something like:
> 1) for_each_plane_in_state()
> 	hw.damage = translate_to_some_hw_coord_space(union(uapi.damages))
> 	or just use the full plane size if we have scaling i guess

99% of the time the coordinates used are based on pipe coord space, only to calculate the plane overlapping damaged area is used plane coord space.

> 
> 2) need to add all affected planes to the state and set the appropriate
>    bitmask, which may mean we want to track the planes' positions in the
>    crtc state. I think atm we only have it in the plane state

This looks a "or" to me, have all the planes added to the state when psr2 sel fetch is enabled or add track all the planes position in pipe.

Although the second one would avoid us to do plane calculations and plane register sometimes, in some cases where a plane above a non-modified plane
moves the non-modified plane bellow will need to be added to the state so the plane sel_fetch registers are written.
We could go with the easy one(add all planes to the state) and then move to the second one latter.

> 
> 3) translate the damage further into the final plane src coordinate
>    space. Dunno if we have enough state around still to do it cleanly.
>    I was thinking maybe it could be done alongside all the other plane
>    surface calculations, but there might be a chicken vs. egg situation
>    here since we probably want to do the plane check stuff before doing
>    step 1, but plane check is also where we do the surface calculations.
>    Dunno if we may just want to split the plane check into two stages

As right now it depends mostly in uapi this could be moved to the check phase, did not left there because this will never have a error or a conflict
that will cause us to reject the state.

> 
> To keep things simple I guess what I'd suggest is to forget about the
> damage stuff in the first version of the series and just do full
> plane updates. That way we don't have to worry about so many coordinate
> space transformations.

Do that would only save us the for bellow and the if to check if plane moved:

for (j = 0; j < num_clips; j++) {
	struct drm_rect damage_area;

	damage_area.x1 = clips[j].x1;
	damage_area.x2 = clips[j].x2;
	damage_area.y1 = clips[j].y1;
	damage_area.y2 = clips[j].y2;
	clip_update(&plane_clip, &damage_area);
}
Anyways thanks for the initial feedback.

> 
> > +
> > +	intel_psr2_trans_man_trk_ctl_calc(crtc_state, &pipe_clip, full_update);
> > +}
> > +
> >  /**
> >   * intel_psr_update - Update PSR state
> >   * @intel_dp: Intel DP
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
> > index b4515186d5f4..d80bd0e46b21 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.h
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> > @@ -13,6 +13,10 @@ struct drm_connector_state;
> >  struct drm_i915_private;
> >  struct intel_crtc_state;
> >  struct intel_dp;
> > +struct intel_crtc;
> > +struct intel_atomic_state;
> > +struct intel_plane_state;
> > +struct intel_plane;
> >  
> >  #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
> >  void intel_psr_init_dpcd(struct intel_dp *intel_dp);
> > @@ -43,5 +47,11 @@ void intel_psr_atomic_check(struct drm_connector *connector,
> >  			    struct drm_connector_state *old_state,
> >  			    struct drm_connector_state *new_state);
> >  void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp);
> > +void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
> > +				 struct intel_crtc *crtc);
> > +void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> > +					const struct intel_crtc_state *crtc_state,
> > +					const struct intel_plane_state *plane_state);
> > +void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
> >  
> >  #endif /* __INTEL_PSR_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> > index 8be06cb25999..afede372ac05 100644
> > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > @@ -690,6 +690,8 @@ skl_program_plane(struct intel_plane *plane,
> >  		intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
> >  				  (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
> >  
> > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
> > +
> >  	/*
> >  	 * The control register self-arms if the plane was previously
> >  	 * disabled. Try to make the plane enable atomic by writing
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 146bfd276ce7..ae7efc922393 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -503,6 +503,7 @@ struct i915_psr {
> >  	bool link_standby;
> >  	bool colorimetry_support;
> >  	bool psr2_enabled;
> > +	bool psr2_sel_fetch_enabled;
> >  	u8 sink_sync_latency;
> >  	ktime_t last_entry_attempt;
> >  	ktime_t last_exit;
> > @@ -1634,6 +1635,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
> >  #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_psr)
> >  #define HAS_PSR_HW_TRACKING(dev_priv) \
> >  	(INTEL_INFO(dev_priv)->display.has_psr_hw_tracking)
> > +#define HAS_PSR2_SEL_FETCH(dev_priv)	 (INTEL_GEN(dev_priv) >= 12)
> >  #define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0)
> >  
> >  #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6)
> > diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
> > index add00ec1f787..3005451c1194 100644
> > --- a/drivers/gpu/drm/i915/i915_params.c
> > +++ b/drivers/gpu/drm/i915/i915_params.c
> > @@ -88,6 +88,11 @@ i915_param_named_unsafe(enable_psr, int, 0600,
> >  	"(0=disabled, 1=enabled) "
> >  	"Default: -1 (use per-chip default)");
> >  
> > +i915_param_named_unsafe(enable_psr2_sel_fetch, int, 0400,
> > +	"Enable PSR2 selective fetch "
> > +	"(0=disabled, 1=enabled) "
> > +	"Default: 0");
> > +
> >  i915_param_named_unsafe(force_probe, charp, 0400,
> >  	"Force probe the driver for specified devices. "
> >  	"See CONFIG_DRM_I915_FORCE_PROBE for details.");
> > diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
> > index 45323732f099..5a0b16923016 100644
> > --- a/drivers/gpu/drm/i915/i915_params.h
> > +++ b/drivers/gpu/drm/i915/i915_params.h
> > @@ -53,6 +53,7 @@ struct drm_printer;
> >  	param(int, enable_dc, -1, 0400) \
> >  	param(int, enable_fbc, -1, 0600) \
> >  	param(int, enable_psr, -1, 0600) \
> > +	param(int, enable_psr2_sel_fetch, 0, 0400) \
> >  	param(int, disable_power_well, -1, 0400) \
> >  	param(int, enable_ips, 1, 0600) \
> >  	param(int, invert_brightness, 0, 0600) \
> > -- 
> > 2.26.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-05-26 22:14 ` [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers José Roberto de Souza
@ 2020-06-12 20:57   ` Mun, Gwan-gyeong
  2020-06-12 21:18     ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-12 20:57 UTC (permalink / raw)
  To: intel-gfx, Souza, Jose

On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> This registers will be used to implement PSR2 software tracking.
> 
> BSpec: 55229
> BSpec: 50424
> BSpec: 50420
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 68 ++++++++++++++++++++++++++++++-
> --
>  1 file changed, 63 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index e9d50fe0f375..6f547e459d30 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4566,6 +4566,18 @@ enum {
>  #define PSR2_SU_STATUS_MASK(frame)	(0x3ff <<
> PSR2_SU_STATUS_SHIFT(frame))
>  #define PSR2_SU_STATUS_FRAMES		8
>  
> +#define _PSR2_MAN_TRK_CTL_A				0x60910
> +#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
> +#define PSR2_MAN_TRK_CTL(tran)				_MMIO_T
> RANS2(tran, _PSR2_MAN_TRK_CTL_A)
> +#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT(31)
> +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GENMASK(30,
> 21)
> +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIELD_PREP(
> PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
> +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GEN
> MASK(20, 11)
> +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIE
> LD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
> +#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT(3)
> +#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT
> (2)
> +#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT
> (1)
> +
As per Bspec, it would be better that the names of bit as below.

PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME
PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME
PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_ENABLE

>  /* VGA port control */
>  #define ADPA			_MMIO(0x61100)
>  #define PCH_ADPA                _MMIO(0xe1100)
> @@ -7129,7 +7141,52 @@ enum {
>  #define PLANE_COLOR_CTL(pipe, plane)	\
>  	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe),
> _PLANE_COLOR_CTL_2(pipe))
>  
> -#/* SKL new cursor registers */
> +#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
> +#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
> +#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
> +#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
> +#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
> +#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
> +#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
> +#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
> +#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
> +
And as per Bspec, the prefix _SEL_FETCH_PLANE_ is better than
_PLANE_SEL_FETCH_ .

> +#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
> +					     _PLANE_SEL_FETCH_BASE_1_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_2_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_3_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_4_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_5_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_6_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_7_A,
> \
> +					     _PLANE_SEL_FETCH_BASE_CUR_
> A)
> +#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe,
> _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)
> +#define PLANE_SEL_FETCH_BASE(pipe, plane)
> (_PLANE_SEL_FETCH_BASE_1(pipe) - \
> +					   _PLANE_SEL_FETCH_BASE_1_A +
> \
> +					   _PLANE_SEL_FETCH_BASE_A(plan
> e))
> +
> +#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
> +#define PLANE_SEL_FETCH_CTL(pipe, plane)
> _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> +					       _PLANE_SEL_FETCH_CTL_1_A
> - \
> +					       _PLANE_SEL_FETCH_BASE_1_
> A)
> +#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
> +
> +#define _PLANE_SEL_FETCH_POS_1_A		0x70894
> +#define PLANE_SEL_FETCH_POS(pipe, plane)
> _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> +					       _PLANE_SEL_FETCH_POS_1_A
> - \
> +					       _PLANE_SEL_FETCH_BASE_1_
> A)
> +
> +#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
> +#define PLANE_SEL_FETCH_SIZE(pipe, plane)
> _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> +						_PLANE_SEL_FETCH_SIZE_1
> _A - \
> +						_PLANE_SEL_FETCH_BASE_1
> _A)
> +
> +#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
> +#define PLANE_SEL_FETCH_OFFSET(pipe, plane)
> _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> +						  _PLANE_SEL_FETCH_OFFS
> ET_1_A - \
> +						  _PLANE_SEL_FETCH_BASE
> _1_A)
> +
> +/* SKL new cursor registers */
>  #define _CUR_BUF_CFG_A				0x7017c
>  #define _CUR_BUF_CFG_B				0x7117c
>  #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe, _CUR_BUF_CFG_A,
> _CUR_BUF_CFG_B)
> @@ -7775,11 +7832,12 @@ enum {
>  # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
>  # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
>  
> -#define CHICKEN_PAR1_1		_MMIO(0x42080)
> +#define CHICKEN_PAR1_1			_MMIO(0x42080)
>  #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
> -#define  DPA_MASK_VBLANK_SRD	(1 << 15)
> -#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
> -#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
> +#define  DPA_MASK_VBLANK_SRD		(1 << 15)
> +#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
> +#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
> +#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
>  
>  #define CHICKEN_PAR2_1		_MMIO(0x42090)
>  #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-06-12 20:57   ` Mun, Gwan-gyeong
@ 2020-06-12 21:18     ` Souza, Jose
  2020-06-12 21:49       ` Mun, Gwan-gyeong
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2020-06-12 21:18 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx

On Fri, 2020-06-12 at 21:57 +0100, Mun, Gwan-gyeong wrote:
> On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> > This registers will be used to implement PSR2 software tracking.
> > 
> > BSpec: 55229
> > BSpec: 50424
> > BSpec: 50420
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h | 68 ++++++++++++++++++++++++++++++-
> > --
> >  1 file changed, 63 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index e9d50fe0f375..6f547e459d30 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -4566,6 +4566,18 @@ enum {
> >  #define PSR2_SU_STATUS_MASK(frame)	(0x3ff <<
> > PSR2_SU_STATUS_SHIFT(frame))
> >  #define PSR2_SU_STATUS_FRAMES		8
> >  
> > +#define _PSR2_MAN_TRK_CTL_A				0x60910
> > +#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
> > +#define PSR2_MAN_TRK_CTL(tran)				_MMIO_T
> > RANS2(tran, _PSR2_MAN_TRK_CTL_A)
> > +#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT(31)
> > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GENMASK(30,
> > 21)
> > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIELD_PREP(
> > PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
> > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GEN
> > MASK(20, 11)
> > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIE
> > LD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
> > +#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT(3)
> > +#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT
> > (2)
> > +#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT
> > (1)
> > +
> As per Bspec, it would be better that the names of bit as below.
> 
> PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME
> PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME
> PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_ENABLE

No problem in naming like this but MAN_TRK and SF is kind of redundant and the name was already big.
Your call.

> 
> >  /* VGA port control */
> >  #define ADPA			_MMIO(0x61100)
> >  #define PCH_ADPA                _MMIO(0xe1100)
> > @@ -7129,7 +7141,52 @@ enum {
> >  #define PLANE_COLOR_CTL(pipe, plane)	\
> >  	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe),
> > _PLANE_COLOR_CTL_2(pipe))
> >  
> > -#/* SKL new cursor registers */
> > +#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
> > +#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
> > +#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
> > +#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
> > +#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
> > +#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
> > +#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
> > +#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
> > +#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
> > +
> And as per Bspec, the prefix _SEL_FETCH_PLANE_ is better than
> _PLANE_SEL_FETCH_ .
You mean just for the "internal" ones? For PLANE_SEL_FETCH_CTL, PLANE_SEL_FETCH_SIZE... would be better keep like this to match other plane register
names.

> 
> > +#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
> > +					     _PLANE_SEL_FETCH_BASE_1_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_2_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_3_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_4_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_5_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_6_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_7_A,
> > \
> > +					     _PLANE_SEL_FETCH_BASE_CUR_
> > A)
> > +#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe,
> > _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)
> > +#define PLANE_SEL_FETCH_BASE(pipe, plane)
> > (_PLANE_SEL_FETCH_BASE_1(pipe) - \
> > +					   _PLANE_SEL_FETCH_BASE_1_A +
> > \
> > +					   _PLANE_SEL_FETCH_BASE_A(plan
> > e))
> > +
> > +#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
> > +#define PLANE_SEL_FETCH_CTL(pipe, plane)
> > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > +					       _PLANE_SEL_FETCH_CTL_1_A
> > - \
> > +					       _PLANE_SEL_FETCH_BASE_1_
> > A)
> > +#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
> > +
> > +#define _PLANE_SEL_FETCH_POS_1_A		0x70894
> > +#define PLANE_SEL_FETCH_POS(pipe, plane)
> > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > +					       _PLANE_SEL_FETCH_POS_1_A
> > - \
> > +					       _PLANE_SEL_FETCH_BASE_1_
> > A)
> > +
> > +#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
> > +#define PLANE_SEL_FETCH_SIZE(pipe, plane)
> > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > +						_PLANE_SEL_FETCH_SIZE_1
> > _A - \
> > +						_PLANE_SEL_FETCH_BASE_1
> > _A)
> > +
> > +#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
> > +#define PLANE_SEL_FETCH_OFFSET(pipe, plane)
> > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > +						  _PLANE_SEL_FETCH_OFFS
> > ET_1_A - \
> > +						  _PLANE_SEL_FETCH_BASE
> > _1_A)
> > +
> > +/* SKL new cursor registers */
> >  #define _CUR_BUF_CFG_A				0x7017c
> >  #define _CUR_BUF_CFG_B				0x7117c
> >  #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe, _CUR_BUF_CFG_A,
> > _CUR_BUF_CFG_B)
> > @@ -7775,11 +7832,12 @@ enum {
> >  # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
> >  # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
> >  
> > -#define CHICKEN_PAR1_1		_MMIO(0x42080)
> > +#define CHICKEN_PAR1_1			_MMIO(0x42080)
> >  #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
> > -#define  DPA_MASK_VBLANK_SRD	(1 << 15)
> > -#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
> > -#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
> > +#define  DPA_MASK_VBLANK_SRD		(1 << 15)
> > +#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
> > +#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
> > +#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
> >  
> >  #define CHICKEN_PAR2_1		_MMIO(0x42090)
> >  #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-06-12 21:18     ` Souza, Jose
@ 2020-06-12 21:49       ` Mun, Gwan-gyeong
  2020-06-15 18:37         ` Mun, Gwan-gyeong
  0 siblings, 1 reply; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-12 21:49 UTC (permalink / raw)
  To: intel-gfx, Souza, Jose

On Fri, 2020-06-12 at 14:18 -0700, Souza, Jose wrote:
> On Fri, 2020-06-12 at 21:57 +0100, Mun, Gwan-gyeong wrote:
> > On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> > > This registers will be used to implement PSR2 software tracking.
> > > 
> > > BSpec: 55229
> > > BSpec: 50424
> > > BSpec: 50420
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_reg.h | 68
> > > ++++++++++++++++++++++++++++++-
> > > --
> > >  1 file changed, 63 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > > b/drivers/gpu/drm/i915/i915_reg.h
> > > index e9d50fe0f375..6f547e459d30 100644
> > > --- a/drivers/gpu/drm/i915/i915_reg.h
> > > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > > @@ -4566,6 +4566,18 @@ enum {
> > >  #define PSR2_SU_STATUS_MASK(frame)	(0x3ff <<
> > > PSR2_SU_STATUS_SHIFT(frame))
> > >  #define PSR2_SU_STATUS_FRAMES		8
> > >  
> > > +#define _PSR2_MAN_TRK_CTL_A				0x60910
> > > +#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
> > > +#define PSR2_MAN_TRK_CTL(tran)				_MMIO_T
> > > RANS2(tran, _PSR2_MAN_TRK_CTL_A)
> > > +#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT(31)
> > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GENMASK(30,
> > > 21)
> > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIELD_PREP(
> > > PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
> > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GEN
> > > MASK(20, 11)
> > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIE
> > > LD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
> > > +#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT
> > > (3)
> > > +#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT
> > > (2)
> > > +#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT
> > > (1)
> > > +
> > As per Bspec, it would be better that the names of bit as below.
> > 
> > PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME
> > PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME
> > PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_ENABLE
> 
> No problem in naming like this but MAN_TRK and SF is kind of
> redundant and the name was already big.
> Your call.
> 
> > >  /* VGA port control */
> > >  #define ADPA			_MMIO(0x61100)
> > >  #define PCH_ADPA                _MMIO(0xe1100)
> > > @@ -7129,7 +7141,52 @@ enum {
> > >  #define PLANE_COLOR_CTL(pipe, plane)	\
> > >  	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe),
> > > _PLANE_COLOR_CTL_2(pipe))
> > >  
> > > -#/* SKL new cursor registers */
> > > +#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
> > > +#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
> > > +#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
> > > +#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
> > > +#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
> > > +#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
> > > +#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
> > > +#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
> > > +#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
> > > +
> > And as per Bspec, the prefix _SEL_FETCH_PLANE_ is better than
> > _PLANE_SEL_FETCH_ .
> You mean just for the "internal" ones? For PLANE_SEL_FETCH_CTL,
> PLANE_SEL_FETCH_SIZE... would be better keep like this to match other
> plane register
> names.
Internals and externals. I also noticed your intention (match other
plane related registers), but when I checked other plane related
resiters, they followed bspec names. (But I am not confident on
register naming policy; we always have to follow documented register
names or not. )
> 
> > > +#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
> > > +					     _PLANE_SEL_FETCH_BASE_1_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_2_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_3_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_4_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_5_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_6_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_7_A,
> > > \
> > > +					     _PLANE_SEL_FETCH_BASE_CUR_
> > > A)
> > > +#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe,
> > > _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)
> > > +#define PLANE_SEL_FETCH_BASE(pipe, plane)
> > > (_PLANE_SEL_FETCH_BASE_1(pipe) - \
> > > +					   _PLANE_SEL_FETCH_BASE_1_A +
> > > \
> > > +					   _PLANE_SEL_FETCH_BASE_A(plan
> > > e))
> > > +
> > > +#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
> > > +#define PLANE_SEL_FETCH_CTL(pipe, plane)
> > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > +					       _PLANE_SEL_FETCH_CTL_1_A
> > > - \
> > > +					       _PLANE_SEL_FETCH_BASE_1_
> > > A)
> > > +#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
> > > +
> > > +#define _PLANE_SEL_FETCH_POS_1_A		0x70894
> > > +#define PLANE_SEL_FETCH_POS(pipe, plane)
> > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > +					       _PLANE_SEL_FETCH_POS_1_A
> > > - \
> > > +					       _PLANE_SEL_FETCH_BASE_1_
> > > A)
> > > +
> > > +#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
> > > +#define PLANE_SEL_FETCH_SIZE(pipe, plane)
> > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > +						_PLANE_SEL_FETCH_SIZE_1
> > > _A - \
> > > +						_PLANE_SEL_FETCH_BASE_1
> > > _A)
> > > +
> > > +#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
> > > +#define PLANE_SEL_FETCH_OFFSET(pipe, plane)
> > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > +						  _PLANE_SEL_FETCH_OFFS
> > > ET_1_A - \
> > > +						  _PLANE_SEL_FETCH_BASE
> > > _1_A)
> > > +
> > > +/* SKL new cursor registers */
> > >  #define _CUR_BUF_CFG_A				0x7017c
> > >  #define _CUR_BUF_CFG_B				0x7117c
> > >  #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe,
> > > _CUR_BUF_CFG_A,
> > > _CUR_BUF_CFG_B)
> > > @@ -7775,11 +7832,12 @@ enum {
> > >  # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
> > >  # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
> > >  
> > > -#define CHICKEN_PAR1_1		_MMIO(0x42080)
> > > +#define CHICKEN_PAR1_1			_MMIO(0x42080)
> > >  #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
> > > -#define  DPA_MASK_VBLANK_SRD	(1 << 15)
> > > -#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
> > > -#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
> > > +#define  DPA_MASK_VBLANK_SRD		(1 << 15)
> > > +#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
> > > +#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
> > > +#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
> > >  
> > >  #define CHICKEN_PAR2_1		_MMIO(0x42090)
> > >  #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-06-12 20:33     ` Souza, Jose
@ 2020-06-15 16:40       ` Ville Syrjälä
  2020-06-16 15:16         ` Mun, Gwan-gyeong
  0 siblings, 1 reply; 28+ messages in thread
From: Ville Syrjälä @ 2020-06-15 16:40 UTC (permalink / raw)
  To: Souza, Jose; +Cc: Pandiyan, Dhinakaran, intel-gfx

On Fri, Jun 12, 2020 at 08:33:31PM +0000, Souza, Jose wrote:
> On Fri, 2020-06-12 at 19:30 +0300, Ville Syrjälä wrote:
> > On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de Souza wrote:
> > > All GEN12 platforms supports PSR2 selective fetch but not all GEN12
> > > platforms supports PSR2 hardware tracking(aka RKL).
> > > 
> > > This feature consists in software program registers with the damaged
> > > area of each plane this way hardware will only fetch from memory those
> > > areas and sent the PSR2 selective update blocks to panel, saving even
> > > more power but to it actually happen userspace needs to send the
> > > damaged areas otherwise it will still fetch the whole plane as
> > > fallback.
> > > As today Gnome3 do not send damaged areas and the only compositor that
> > > I'm aware that sets the damaged areas is Weston.
> > > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> > > 
> > > So here implementing page flip part, it is still completely missing
> > > frontbuffer modifications, that is why the enable_psr2_sel_fetch
> > > parameter was added.
> > > 
> > > The plan is to switch all GEN12 platforms to selective fetch when
> > > ready, it will also depend in add some tests sending damaged areas.
> > > I have a hacked version of kms_psr2_su with 3 planes that I can
> > > cleanup and send in a few days(99% of PSR2 selective fetch changes was
> > > done during my free time while bored during quarantine rainy days).
> > > 
> > > BSpec: 55229
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Cc: Imre Deak <imre.deak@intel.com>
> > > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
> > >  .../drm/i915/display/intel_display_debugfs.c  |   3 +
> > >  .../drm/i915/display/intel_display_types.h    |  10 +
> > >  drivers/gpu/drm/i915/display/intel_psr.c      | 329 +++++++++++++++++-
> > >  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
> > >  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
> > >  drivers/gpu/drm/i915/i915_drv.h               |   2 +
> > >  drivers/gpu/drm/i915/i915_params.c            |   5 +
> > >  drivers/gpu/drm/i915/i915_params.h            |   1 +
> > >  9 files changed, 352 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index b69878334040..984809208c29 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -11729,6 +11729,8 @@ static void i9xx_update_cursor(struct intel_plane *plane,
> > >  	if (INTEL_GEN(dev_priv) >= 9)
> > >  		skl_write_cursor_wm(plane, crtc_state);
> > >  
> > > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state);
> > > +
> > >  	if (plane->cursor.base != base ||
> > >  	    plane->cursor.size != fbc_ctl ||
> > >  	    plane->cursor.cntl != cntl) {
> > > @@ -15115,6 +15117,8 @@ static void commit_pipe_config(struct intel_atomic_state *state,
> > >  
> > >  		if (new_crtc_state->update_pipe)
> > >  			intel_pipe_fastset(old_crtc_state, new_crtc_state);
> > > +
> > > +		intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
> > >  	}
> > >  
> > >  	if (dev_priv->display.atomic_update_watermarks)
> > > @@ -15156,6 +15160,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> > >  			intel_color_load_luts(new_crtc_state);
> > >  
> > >  		intel_pre_plane_update(state, crtc);
> > > +		intel_psr2_sel_fetch_update(state, crtc);
> > >  
> > >  		if (new_crtc_state->update_pipe)
> > >  			intel_encoders_update_pipe(state, crtc);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > index 70525623bcdf..0f600974462b 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
> > >  			su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
> > >  			seq_printf(m, "%d\t%d\n", frame, su_blocks);
> > >  		}
> > > +
> > > +		seq_printf(m, "PSR2 selective fetch: %s\n",
> > > +			   enableddisabled(psr->psr2_sel_fetch_enabled));
> > >  	}
> > >  
> > >  unlock:
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 30b2767578dc..b77a512e5362 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -586,6 +586,13 @@ struct intel_plane_state {
> > >  	u32 planar_slave;
> > >  
> > >  	struct drm_intel_sprite_colorkey ckey;
> > > +
> > > +	struct {
> > > +		u32 ctl;
> > > +		u32 pos;
> > > +		u32 offset;
> > > +		u32 size;
> > > +	} psr2_sel_fetch;
> > 
> > Do we really need all that here? We don't store them for the normal
> > plane updates either.
> 
> For ctl we do, anyways could be removed if we store overlapping damage are in here so intel_psr2_program_plane_sel_fetch() would incorporate
> intel_psr2_plane_sel_fetch_calc() code, both looks good to me.
> 
> > 
> > >  };
> > >  
> > >  struct intel_initial_plane_config {
> > > @@ -931,6 +938,7 @@ struct intel_crtc_state {
> > >  
> > >  	bool has_psr;
> > >  	bool has_psr2;
> > > +	bool enable_psr2_sel_fetch;
> > >  	u32 dc3co_exitline;
> > >  
> > >  	/*
> > > @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
> > >  
> > >  	/* For DSB related info */
> > >  	struct intel_dsb *dsb;
> > > +
> > > +	u32 psr2_sw_man_track_ctl;
> > >  };
> > >  
> > >  enum intel_pipe_crc_source {
> > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> > > index 0c86e9e341a2..bc2a2e64fe2a 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
> > >  	else
> > >  		val |= EDP_PSR2_TP2_TIME_2500us;
> > >  
> > > +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> > > +		intel_de_write(dev_priv,
> > > +			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
> > > +			       PSR2_MAN_TRK_CTL_ENABLE);
> > > +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> > > +		intel_de_write(dev_priv,
> > > +			       PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
> > > +
> > >  	/*
> > >  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
> > >  	 * recommending keep this bit unset while PSR2 is enabled.
> > > @@ -628,6 +636,38 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
> > >  	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
> > >  }
> > >  
> > > +static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
> > > +					      struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
> > > +	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > +	struct intel_plane_state *plane_state;
> > > +	struct intel_plane *plane;
> > > +	int i;
> > > +
> > > +	if (!i915_modparams.enable_psr2_sel_fetch) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "PSR2 sel fetch not enabled, disabled by parameter\n");
> > > +		return false;
> > > +	}
> > > +
> > > +	if (crtc_state->uapi.async_flip) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "PSR2 sel fetch not enabled, async flip enabled\n");
> > > +		return false;
> > > +	}
> > 
> > Not supported anyway.
> > 
> > > +
> > > +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> > > +		if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) {
> > > +			drm_dbg_kms(&dev_priv->drm,
> > > +				    "PSR2 sel fetch not enabled, plane rotated\n");
> > > +			return false;
> > > +		}
> > > +	}
> > > +
> > > +	return crtc_state->enable_psr2_sel_fetch = true;
> > > +}
> > > +
> > >  static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
> > >  				    struct intel_crtc_state *crtc_state)
> > >  {
> > > @@ -697,22 +737,17 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
> > >  		return false;
> > >  	}
> > >  
> > > -	/*
> > > -	 * Some platforms lack PSR2 HW tracking and instead require manual
> > > -	 * tracking by software.  In this case, the driver is required to track
> > > -	 * the areas that need updates and program hardware to send selective
> > > -	 * updates.
> > > -	 *
> > > -	 * So until the software tracking is implemented, PSR2 needs to be
> > > -	 * disabled for platforms without PSR2 HW tracking.
> > > -	 */
> > > -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> > > -		drm_dbg_kms(&dev_priv->drm,
> > > -			    "No PSR2 HW tracking in the platform\n");
> > > -		return false;
> > > +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> > > +		if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
> > > +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> > > +			drm_dbg_kms(&dev_priv->drm,
> > > +				    "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
> > > +			return false;
> > > +		}
> > >  	}
> > >  
> > > -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
> > > +	if (!crtc_state->enable_psr2_sel_fetch &&
> > > +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
> > >  		drm_dbg_kms(&dev_priv->drm,
> > >  			    "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
> > >  			    crtc_hdisplay, crtc_vdisplay,
> > > @@ -863,6 +898,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
> > >  		val |= EXITLINE_ENABLE;
> > >  		intel_de_write(dev_priv, EXITLINE(cpu_transcoder), val);
> > >  	}
> > > +
> > > +	if (HAS_PSR_HW_TRACKING(dev_priv))
> > > +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
> > > +			     dev_priv->psr.psr2_sel_fetch_enabled ?
> > > +			     IGNORE_PSR2_HW_TRACKING : 0);
> > >  }
> > >  
> > >  static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
> > > @@ -884,7 +924,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
> > >  	/* DC5/DC6 requires at least 6 idle frames */
> > >  	val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> > >  	dev_priv->psr.dc3co_exit_delay = val;
> > > -
> > > +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
> > >  	/*
> > >  	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
> > >  	 * will still keep the error set even after the reset done in the
> > > @@ -1080,6 +1120,265 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
> > >  		intel_psr_exit(dev_priv);
> > >  }
> > >  
> > > +void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
> > > +					const struct intel_crtc_state *crtc_state,
> > > +					const struct intel_plane_state *plane_state)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > > +	enum pipe pipe = plane->pipe;
> > > +
> > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > +	    !plane_state ||
> > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > +		return;
> > > +
> > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
> > > +			  plane_state->psr2_sel_fetch.ctl);
> > > +	if (!plane_state->psr2_sel_fetch.ctl || plane->id == PLANE_CURSOR)
> > > +		return;
> > > +
> > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe, plane->id),
> > > +			  plane_state->psr2_sel_fetch.pos);
> > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> > > +			  plane_state->psr2_sel_fetch.offset);
> > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe, plane->id),
> > > +			  plane_state->psr2_sel_fetch.size);
> > > +}
> > > +
> > > +void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
> > > +{
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > +	struct i915_psr *psr = &dev_priv->psr;
> > > +
> > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > +		return;
> > > +
> > > +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
> > > +		       crtc_state->psr2_sw_man_track_ctl);
> > > +}
> > > +
> > > +static void intel_psr2_plane_sel_fetch_calc(struct intel_plane_state *plane_state,
> > > +					    struct drm_rect *clip)
> > > +{
> > > +	int color_plane = plane_state->planar_linked_plane && !plane_state->planar_slave;
> > > +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> > > +	u32 val;
> > > +
> > > +	if (plane->id == PLANE_CURSOR)
> > > +		return;
> > > +
> > > +	val = (plane_state->color_plane[color_plane].y + clip->y1) << 16;
> > > +	val |= plane_state->color_plane[color_plane].x;
> > > +	plane_state->psr2_sel_fetch.offset = val;
> > > +
> > > +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> > > +	val |= plane_state->uapi.crtc_x;
> > > +	plane_state->psr2_sel_fetch.pos = val;
> > > +
> > > +	/* Sizes are 0 based */
> > > +	val = (clip->y2 - clip->y1 - 1) << 16;
> > > +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
> > > +	plane_state->psr2_sel_fetch.size = val;
> > > +}
> > > +
> > > +static void intel_psr2_trans_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
> > > +					      struct drm_rect *clip,
> > > +					      bool full_update)
> > > +{
> > > +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> > > +
> > > +	if (full_update) {
> > > +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> > > +		goto exit;
> > > +	}
> > > +
> > > +	if (clip->y1 == -1)
> > > +		goto exit;
> > > +
> > > +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> > > +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4 + 1);
> > > +	val |= PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4) + 1);
> > > +exit:
> > > +	crtc_state->psr2_sw_man_track_ctl = val;
> > > +}
> > > +
> > > +static void intel_psr2_plane_sel_fetch_ctl_calc(struct intel_plane *plane,
> > > +						struct intel_plane_state *plane_state,
> > > +						bool enable)
> > > +{
> > > +	if (!enable)
> > > +		plane_state->psr2_sel_fetch.ctl = 0;
> > > +	else if (plane->id == PLANE_CURSOR)
> > > +		plane_state->psr2_sel_fetch.ctl = plane->cursor.cntl;
> > > +	else
> > > +		plane_state->psr2_sel_fetch.ctl = plane_state->ctl;
> > > +}
> > > +
> > > +static void clip_update(struct drm_rect *overlap_damage_area,
> > > +			struct drm_rect *damage_area)
> > > +{
> > > +	if (overlap_damage_area->y1 == -1) {
> > > +		overlap_damage_area->y1 = damage_area->y1;
> > > +		overlap_damage_area->y2 = damage_area->y2;
> > > +		return;
> > > +	}
> > > +
> > > +	if (damage_area->y1 < overlap_damage_area->y1)
> > > +		overlap_damage_area->y1 = damage_area->y1;
> > > +
> > > +	if (damage_area->y2 > overlap_damage_area->y2)
> > > +		overlap_damage_area->y2 = damage_area->y2;
> > > +}
> > > +
> > > +/* Update plane damage area if planes above moved or have alpha */
> > > +static void intel_psr2_pipe_dirty_areas_set(struct intel_plane_state *plane_state,
> > > +					    struct intel_plane *plane,
> > > +					    const struct drm_rect *pipe_dirty_areas,
> > > +					    struct drm_rect *plane_clip)
> > > +{
> > > +	enum plane_id i;
> > > +
> > > +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> > > +		int j;
> > > +
> > > +		for (j = 0; j < 2; j++) {
> > > +			struct drm_rect r = pipe_dirty_areas[i * 2 + j];
> > > +
> > > +			if (!drm_rect_width(&r))
> > > +				continue;
> > > +			if (!drm_rect_intersect(&r, &plane_state->uapi.dst))
> > > +				continue;
> > > +
> > > +			r.y1 -= plane_state->uapi.crtc_y;
> > > +			r.y2 -= plane_state->uapi.crtc_y;
> > > +			clip_update(plane_clip, &r);
> > > +		}
> > > +	}
> > > +}
> > > +
> > > +void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
> > > +				 struct intel_crtc *crtc)
> > > +{
> > > +	struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > +	struct intel_plane_state *new_plane_state, *old_plane_state;
> > > +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] = {};
> > > +	struct drm_rect pipe_clip = { .y1 = -1 };
> > > +	struct intel_plane *plane;
> > > +	bool full_update = false;
> > > +	int i;
> > > +
> > > +	if (!crtc_state->enable_psr2_sel_fetch)
> > > +		return;
> > > +
> > > +	/*
> > > +	 * Load all the pipes areas where there is a plane with alpha or a plane
> > > +	 * that moved or plane that the visibility changed in those
> > > +	 * cases planes bellow it will need to be fetched in those intersection
> > > +	 * areas even if they are not damaged in those areas.
> > > +	 */
> > > +	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
> > > +					     new_plane_state, i) {
> > > +		bool alpha, flip, dirty;
> > > +
> > > +		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
> > > +			continue;
> > > +
> > > +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> > > +		alpha |= old_plane_state->uapi.alpha != U16_MAX;
> > > +		flip = new_plane_state->uapi.fb != old_plane_state->uapi.fb;
> > > +		dirty = alpha && flip;
> > > +		dirty |= !drm_rect_equals(&new_plane_state->uapi.dst,
> > > +					  &old_plane_state->uapi.dst);
> > > +		dirty |= new_plane_state->uapi.visible !=
> > > +			 old_plane_state->uapi.visible;
> > > +		if (!dirty)
> > > +			continue;
> > > +
> > > +		if (old_plane_state->uapi.visible)
> > > +			pipe_dirty_areas[plane->id * 2] = old_plane_state->uapi.dst;
> > > +		if (new_plane_state->uapi.visible)
> > > +			pipe_dirty_areas[plane->id * 2 + 1] = new_plane_state->uapi.dst;
> > > +	}
> > > +
> > > +	/*
> > > +	 * Iterate over all planes, compute the damaged clip area also including
> > > +	 * the pipe_dirty_areas, compute plane registers and update pipe damaged
> > > +	 * area
> > > +	 */
> > > +	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
> > > +					     new_plane_state, i) {
> > > +		struct drm_rect plane_clip = { .y1 = -1 };
> > > +		struct drm_mode_rect *clips;
> > > +		u32 num_clips;
> > > +		int j;
> > > +
> > > +		if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
> > > +			continue;
> > > +
> > > +		/*
> > > +		 * TODO: Not clear how to handle planes with negative position,
> > > +		 * also planes are not updated if they have a negative X
> > > +		 * position so for now doing a full update in this cases
> > > +		 */
> > > +		if (new_plane_state->uapi.crtc_y < 0 ||
> > > +		    new_plane_state->uapi.crtc_x < 0) {
> > > +			full_update = true;
> > > +			break;
> > > +		}
> > > +
> > > +		intel_psr2_plane_sel_fetch_ctl_calc(plane, new_plane_state,
> > > +						    new_plane_state->uapi.visible);
> > > +		if (!new_plane_state->uapi.visible)
> > > +			continue;
> > > +
> > > +		clips = drm_plane_get_damage_clips(&new_plane_state->uapi);
> > > +		num_clips = drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> > > +
> > > +		/*
> > > +		 * If plane moved mark the whole plane area as damaged so it
> > > +		 * can be complete draw in the new position
> > > +		 */
> > > +		if (!drm_rect_equals(&new_plane_state->uapi.dst,
> > > +				     &old_plane_state->uapi.dst)) {
> > > +			num_clips = 0;
> > > +			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
> > > +			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
> > > +		} else if (!num_clips) {
> > > +			/*
> > > +			 * If plane don't have damage areas but the framebuffer
> > > +			 * changed mark the whole plane as damaged
> > > +			 */
> > > +			if (new_plane_state->uapi.fb == old_plane_state->uapi.fb)
> > > +				continue;
> > > +
> > > +			plane_clip.y1 = new_plane_state->uapi.src.y1 >> 16;
> > > +			plane_clip.y2 = new_plane_state->uapi.src.y2 >> 16;
> > > +		}
> > > +
> > > +		for (j = 0; j < num_clips; j++) {
> > > +			struct drm_rect damage_area;
> > > +
> > > +			damage_area.x1 = clips[j].x1;
> > > +			damage_area.x2 = clips[j].x2;
> > > +			damage_area.y1 = clips[j].y1;
> > > +			damage_area.y2 = clips[j].y2;
> > > +			clip_update(&plane_clip, &damage_area);
> > > +		}
> > > +
> > > +		intel_psr2_pipe_dirty_areas_set(new_plane_state, plane,
> > > +						pipe_dirty_areas, &plane_clip);
> > > +		intel_psr2_plane_sel_fetch_calc(new_plane_state, &plane_clip);
> > > +
> > > +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> > > +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> > > +		clip_update(&pipe_clip, &plane_clip);
> > > +	}
> > 
> > This whole thing seems rather convoluted. Also using lots of uapi state
> > in places where I don't expect to see any.
> 
> Not sure from where I should get this information then, intel_plane_state don't have it.
> 
> > 
> > I would suggest the correct way would be something like:
> > 1) for_each_plane_in_state()
> > 	hw.damage = translate_to_some_hw_coord_space(union(uapi.damages))
> > 	or just use the full plane size if we have scaling i guess
> 
> 99% of the time the coordinates used are based on pipe coord space, only to calculate the plane overlapping damaged area is used plane coord space.
> 
> > 
> > 2) need to add all affected planes to the state and set the appropriate
> >    bitmask, which may mean we want to track the planes' positions in the
> >    crtc state. I think atm we only have it in the plane state
> 
> This looks a "or" to me, have all the planes added to the state when psr2 sel fetch is enabled or add track all the planes position in pipe.

*Affected* planes, not all planes. Hmm. I guess affected planes are
actually the ones whose selective fetch coordinates change. If they
don't change then no need to add them to the state. Plane updates are
rather expensive (lots of mmio) so I've generally tried to avoid
pointless plane updates.

But this whole thing might turn a bit annoying since we'd to keep
adding affected planes until the total selective fetch region stops
growing. I think that would probably want the two stage plane state
compuation. So just blindly adding all of them would probably be
simpler, albeit less efficient.

> 
> Although the second one would avoid us to do plane calculations and plane register sometimes, in some cases where a plane above a non-modified plane
> moves the non-modified plane bellow will need to be added to the state so the plane sel_fetch registers are written.
> We could go with the easy one(add all planes to the state) and then move to the second one latter.
> 
> > 
> > 3) translate the damage further into the final plane src coordinate
> >    space. Dunno if we have enough state around still to do it cleanly.
> >    I was thinking maybe it could be done alongside all the other plane
> >    surface calculations, but there might be a chicken vs. egg situation
> >    here since we probably want to do the plane check stuff before doing
> >    step 1, but plane check is also where we do the surface calculations.
> >    Dunno if we may just want to split the plane check into two stages
> 
> As right now it depends mostly in uapi this could be moved to the check phase, did not left there because this will never have a error or a conflict
> that will cause us to reject the state.
> 
> > 
> > To keep things simple I guess what I'd suggest is to forget about the
> > damage stuff in the first version of the series and just do full
> > plane updates. That way we don't have to worry about so many coordinate
> > space transformations.
> 
> Do that would only save us the for bellow and the if to check if plane moved:
> 
> for (j = 0; j < num_clips; j++) {
> 	struct drm_rect damage_area;
> 
> 	damage_area.x1 = clips[j].x1;
> 	damage_area.x2 = clips[j].x2;
> 	damage_area.y1 = clips[j].y1;
> 	damage_area.y2 = clips[j].y2;
> 	clip_update(&plane_clip, &damage_area);
> }

That's just some minor detail. The real issue is converting the damage
between the various coordinate spaces we have for planes (original fb
relative src coordiantes, final SURF relative src coordinates,
crtc relative dst coordinates, and also the hw vs. uapi stuff affects
this stuff).

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-06-12 21:49       ` Mun, Gwan-gyeong
@ 2020-06-15 18:37         ` Mun, Gwan-gyeong
  2020-06-15 19:23           ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-15 18:37 UTC (permalink / raw)
  To: intel-gfx, Souza, Jose

On Fri, 2020-06-12 at 21:49 +0000, Mun, Gwan-gyeong wrote:
> On Fri, 2020-06-12 at 14:18 -0700, Souza, Jose wrote:
> > On Fri, 2020-06-12 at 21:57 +0100, Mun, Gwan-gyeong wrote:
> > > On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> > > > This registers will be used to implement PSR2 software
> > > > tracking.
> > > > 
> > > > BSpec: 55229
> > > > BSpec: 50424
> > > > BSpec: 50420
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/i915_reg.h | 68
> > > > ++++++++++++++++++++++++++++++-
> > > > --
> > > >  1 file changed, 63 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > > > b/drivers/gpu/drm/i915/i915_reg.h
> > > > index e9d50fe0f375..6f547e459d30 100644
> > > > --- a/drivers/gpu/drm/i915/i915_reg.h
> > > > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > > > @@ -4566,6 +4566,18 @@ enum {
> > > >  #define PSR2_SU_STATUS_MASK(frame)	(0x3ff <<
> > > > PSR2_SU_STATUS_SHIFT(frame))
> > > >  #define PSR2_SU_STATUS_FRAMES		8
> > > >  
> > > > +#define _PSR2_MAN_TRK_CTL_A				0x60910
> > > > +#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
> > > > +#define PSR2_MAN_TRK_CTL(tran)				_MMIO_T
> > > > RANS2(tran, _PSR2_MAN_TRK_CTL_A)
> > > > +#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT
> > > > (31)
> > > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GEN
> > > > MASK(30,
> > > > 21)
> > > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIE
> > > > LD_PREP(
> > > > PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
> > > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GEN
> > > > MASK(20, 11)
> > > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIE
> > > > LD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
> > > > +#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT
> > > > (3)
> > > > +#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT
> > > > (2)
> > > > +#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT
> > > > (1)
> > > > +
> > > As per Bspec, it would be better that the names of bit as below.
> > > 
> > > PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME
> > > PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME
> > > PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_ENABLE
> > 
> > No problem in naming like this but MAN_TRK and SF is kind of
> > redundant and the name was already big.
> > Your call.
> > 
> > > >  /* VGA port control */
> > > >  #define ADPA			_MMIO(0x61100)
> > > >  #define PCH_ADPA                _MMIO(0xe1100)
> > > > @@ -7129,7 +7141,52 @@ enum {
> > > >  #define PLANE_COLOR_CTL(pipe, plane)	\
> > > >  	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe),
> > > > _PLANE_COLOR_CTL_2(pipe))
> > > >  
> > > > -#/* SKL new cursor registers */
> > > > +#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
> > > > +#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
> > > > +#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
> > > > +#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
> > > > +#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
> > > > +#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
> > > > +#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
> > > > +#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
> > > > +#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
> > > > +
> > > And as per Bspec, the prefix _SEL_FETCH_PLANE_ is better than
> > > _PLANE_SEL_FETCH_ .
> > You mean just for the "internal" ones? For PLANE_SEL_FETCH_CTL,
> > PLANE_SEL_FETCH_SIZE... would be better keep like this to match
> > other
> > plane register
> > names.
> Internals and externals. I also noticed your intention (match other
> plane related registers), but when I checked other plane related
> resiters, they followed bspec names. (But I am not confident on
> register naming policy; we always have to follow documented register
> names or not. )
> > > > +#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_1_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_2_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_3_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_4_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_5_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_6_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_7_A,
> > > > \
> > > > +					     _PLANE_SEL_FETCH_B
> > > > ASE_CUR_
> > > > A)
> > > > +#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe,
> > > > _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)

It seems that indicates an wrong register name.
IMHO, is it your intention like this? " #define
_PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe, _PLANE_SEL_FETCH_BASE_1_A,
_PLANE_SEL_FETCH_BASE_1_B) "?

> > > > +#define PLANE_SEL_FETCH_BASE(pipe, plane)
> > > > (_PLANE_SEL_FETCH_BASE_1(pipe) - \
> > > > +					   _PLANE_SEL_FETCH_BAS
> > > > E_1_A +
> > > > \
> > > > +					   _PLANE_SEL_FETCH_BAS
> > > > E_A(plan
> > > > e))
> > > > +
> > > > +#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
> > > > +#define PLANE_SEL_FETCH_CTL(pipe, plane)
> > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > +					       _PLANE_SEL_FETCH
> > > > _CTL_1_A
> > > > - \
> > > > +					       _PLANE_SEL_FETCH
> > > > _BASE_1_
> > > > A)
> > > > +#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
> > > > +
> > > > +#define _PLANE_SEL_FETCH_POS_1_A		0x70894
> > > > +#define PLANE_SEL_FETCH_POS(pipe, plane)
> > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > +					       _PLANE_SEL_FETCH
> > > > _POS_1_A
> > > > - \
> > > > +					       _PLANE_SEL_FETCH
> > > > _BASE_1_
> > > > A)
> > > > +
> > > > +#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
> > > > +#define PLANE_SEL_FETCH_SIZE(pipe, plane)
> > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > +						_PLANE_SEL_FETC
> > > > H_SIZE_1
> > > > _A - \
> > > > +						_PLANE_SEL_FETC
> > > > H_BASE_1
> > > > _A)
> > > > +
> > > > +#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
> > > > +#define PLANE_SEL_FETCH_OFFSET(pipe, plane)
> > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > +						  _PLANE_SEL_FE
> > > > TCH_OFFS
> > > > ET_1_A - \
> > > > +						  _PLANE_SEL_FE
> > > > TCH_BASE
> > > > _1_A)
> > > > +
> > > > +/* SKL new cursor registers */
> > > >  #define _CUR_BUF_CFG_A				0x7017c
> > > >  #define _CUR_BUF_CFG_B				0x7117c
> > > >  #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe,
> > > > _CUR_BUF_CFG_A,
> > > > _CUR_BUF_CFG_B)
> > > > @@ -7775,11 +7832,12 @@ enum {
> > > >  # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
> > > >  # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 <<
> > > > 2)
> > > >  
> > > > -#define CHICKEN_PAR1_1		_MMIO(0x42080)
> > > > +#define CHICKEN_PAR1_1			_MMIO(0x42080)
> > > >  #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
> > > > -#define  DPA_MASK_VBLANK_SRD	(1 << 15)
> > > > -#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
> > > > -#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
> > > > +#define  DPA_MASK_VBLANK_SRD		(1 << 15)
> > > > +#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
> > > > +#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
> > > > +#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
> > > >  
> > > >  #define CHICKEN_PAR2_1		_MMIO(0x42090)
> > > >  #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-06-15 18:37         ` Mun, Gwan-gyeong
@ 2020-06-15 19:23           ` Souza, Jose
  2020-06-25 21:41             ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2020-06-15 19:23 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx

On Mon, 2020-06-15 at 19:37 +0100, Mun, Gwan-gyeong wrote:
> On Fri, 2020-06-12 at 21:49 +0000, Mun, Gwan-gyeong wrote:
> > On Fri, 2020-06-12 at 14:18 -0700, Souza, Jose wrote:
> > > On Fri, 2020-06-12 at 21:57 +0100, Mun, Gwan-gyeong wrote:
> > > > On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> > > > > This registers will be used to implement PSR2 software
> > > > > tracking.
> > > > > 
> > > > > BSpec: 55229
> > > > > BSpec: 50424
> > > > > BSpec: 50420
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/i915_reg.h | 68
> > > > > ++++++++++++++++++++++++++++++-
> > > > > --
> > > > >  1 file changed, 63 insertions(+), 5 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > > > > b/drivers/gpu/drm/i915/i915_reg.h
> > > > > index e9d50fe0f375..6f547e459d30 100644
> > > > > --- a/drivers/gpu/drm/i915/i915_reg.h
> > > > > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > > > > @@ -4566,6 +4566,18 @@ enum {
> > > > >  #define PSR2_SU_STATUS_MASK(frame)	(0x3ff <<
> > > > > PSR2_SU_STATUS_SHIFT(frame))
> > > > >  #define PSR2_SU_STATUS_FRAMES		8
> > > > >  
> > > > > +#define _PSR2_MAN_TRK_CTL_A				0x60910
> > > > > +#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
> > > > > +#define PSR2_MAN_TRK_CTL(tran)				_MMIO_T
> > > > > RANS2(tran, _PSR2_MAN_TRK_CTL_A)
> > > > > +#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT
> > > > > (31)
> > > > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GEN
> > > > > MASK(30,
> > > > > 21)
> > > > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIE
> > > > > LD_PREP(
> > > > > PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
> > > > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GEN
> > > > > MASK(20, 11)
> > > > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIE
> > > > > LD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
> > > > > +#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT
> > > > > (3)
> > > > > +#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT
> > > > > (2)
> > > > > +#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT
> > > > > (1)
> > > > > +
> > > > As per Bspec, it would be better that the names of bit as below.
> > > > 
> > > > PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME
> > > > PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME
> > > > PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_ENABLE
> > > 
> > > No problem in naming like this but MAN_TRK and SF is kind of
> > > redundant and the name was already big.
> > > Your call.
> > > 
> > > > >  /* VGA port control */
> > > > >  #define ADPA			_MMIO(0x61100)
> > > > >  #define PCH_ADPA                _MMIO(0xe1100)
> > > > > @@ -7129,7 +7141,52 @@ enum {
> > > > >  #define PLANE_COLOR_CTL(pipe, plane)	\
> > > > >  	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe),
> > > > > _PLANE_COLOR_CTL_2(pipe))
> > > > >  
> > > > > -#/* SKL new cursor registers */
> > > > > +#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
> > > > > +#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
> > > > > +#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
> > > > > +#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
> > > > > +#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
> > > > > +#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
> > > > > +#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
> > > > > +#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
> > > > > +#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
> > > > > +
> > > > And as per Bspec, the prefix _SEL_FETCH_PLANE_ is better than
> > > > _PLANE_SEL_FETCH_ .
> > > You mean just for the "internal" ones? For PLANE_SEL_FETCH_CTL,
> > > PLANE_SEL_FETCH_SIZE... would be better keep like this to match
> > > other
> > > plane register
> > > names.
> > Internals and externals. I also noticed your intention (match other
> > plane related registers), but when I checked other plane related
> > resiters, they followed bspec names. (But I am not confident on
> > register naming policy; we always have to follow documented register
> > names or not. )
> > > > > +#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_1_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_2_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_3_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_4_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_5_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_6_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_7_A,
> > > > > \
> > > > > +					     _PLANE_SEL_FETCH_B
> > > > > ASE_CUR_
> > > > > A)
> > > > > +#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe,
> > > > > _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)
> 
> It seems that indicates an wrong register name.
> IMHO, is it your intention like this? " #define
> _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe, _PLANE_SEL_FETCH_BASE_1_A,
> _PLANE_SEL_FETCH_BASE_1_B) "?

Yes, it should be _PLANE_SEL_FETCH_BASE_1_B, thanks for catching this.
Will send this 4 patches in a few days with the requested fixes.

> 
> > > > > +#define PLANE_SEL_FETCH_BASE(pipe, plane)
> > > > > (_PLANE_SEL_FETCH_BASE_1(pipe) - \
> > > > > +					   _PLANE_SEL_FETCH_BAS
> > > > > E_1_A +
> > > > > \
> > > > > +					   _PLANE_SEL_FETCH_BAS
> > > > > E_A(plan
> > > > > e))
> > > > > +
> > > > > +#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
> > > > > +#define PLANE_SEL_FETCH_CTL(pipe, plane)
> > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > +					       _PLANE_SEL_FETCH
> > > > > _CTL_1_A
> > > > > - \
> > > > > +					       _PLANE_SEL_FETCH
> > > > > _BASE_1_
> > > > > A)
> > > > > +#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
> > > > > +
> > > > > +#define _PLANE_SEL_FETCH_POS_1_A		0x70894
> > > > > +#define PLANE_SEL_FETCH_POS(pipe, plane)
> > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > +					       _PLANE_SEL_FETCH
> > > > > _POS_1_A
> > > > > - \
> > > > > +					       _PLANE_SEL_FETCH
> > > > > _BASE_1_
> > > > > A)
> > > > > +
> > > > > +#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
> > > > > +#define PLANE_SEL_FETCH_SIZE(pipe, plane)
> > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > +						_PLANE_SEL_FETC
> > > > > H_SIZE_1
> > > > > _A - \
> > > > > +						_PLANE_SEL_FETC
> > > > > H_BASE_1
> > > > > _A)
> > > > > +
> > > > > +#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
> > > > > +#define PLANE_SEL_FETCH_OFFSET(pipe, plane)
> > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > +						  _PLANE_SEL_FE
> > > > > TCH_OFFS
> > > > > ET_1_A - \
> > > > > +						  _PLANE_SEL_FE
> > > > > TCH_BASE
> > > > > _1_A)
> > > > > +
> > > > > +/* SKL new cursor registers */
> > > > >  #define _CUR_BUF_CFG_A				0x7017c
> > > > >  #define _CUR_BUF_CFG_B				0x7117c
> > > > >  #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe,
> > > > > _CUR_BUF_CFG_A,
> > > > > _CUR_BUF_CFG_B)
> > > > > @@ -7775,11 +7832,12 @@ enum {
> > > > >  # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
> > > > >  # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 <<
> > > > > 2)
> > > > >  
> > > > > -#define CHICKEN_PAR1_1		_MMIO(0x42080)
> > > > > +#define CHICKEN_PAR1_1			_MMIO(0x42080)
> > > > >  #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
> > > > > -#define  DPA_MASK_VBLANK_SRD	(1 << 15)
> > > > > -#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
> > > > > -#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
> > > > > +#define  DPA_MASK_VBLANK_SRD		(1 << 15)
> > > > > +#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
> > > > > +#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
> > > > > +#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
> > > > >  
> > > > >  #define CHICKEN_PAR2_1		_MMIO(0x42090)
> > > > >  #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-06-15 16:40       ` Ville Syrjälä
@ 2020-06-16 15:16         ` Mun, Gwan-gyeong
  2020-06-16 17:29           ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-16 15:16 UTC (permalink / raw)
  To: ville.syrjala, Souza, Jose; +Cc: Pandiyan, Dhinakaran, intel-gfx

On Mon, 2020-06-15 at 19:40 +0300, Ville Syrjälä wrote:
> On Fri, Jun 12, 2020 at 08:33:31PM +0000, Souza, Jose wrote:
> > On Fri, 2020-06-12 at 19:30 +0300, Ville Syrjälä wrote:
> > > On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de Souza
> > > wrote:
> > > > All GEN12 platforms supports PSR2 selective fetch but not all
> > > > GEN12
> > > > platforms supports PSR2 hardware tracking(aka RKL).
> > > > 
> > > > This feature consists in software program registers with the
> > > > damaged
> > > > area of each plane this way hardware will only fetch from
> > > > memory those
> > > > areas and sent the PSR2 selective update blocks to panel,
> > > > saving even
> > > > more power but to it actually happen userspace needs to send
> > > > the
> > > > damaged areas otherwise it will still fetch the whole plane as
> > > > fallback.
> > > > As today Gnome3 do not send damaged areas and the only
> > > > compositor that
> > > > I'm aware that sets the damaged areas is Weston.
> > > > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> > > > 
> > > > So here implementing page flip part, it is still completely
> > > > missing
> > > > frontbuffer modifications, that is why the
> > > > enable_psr2_sel_fetch
> > > > parameter was added.
> > > > 
> > > > The plan is to switch all GEN12 platforms to selective fetch
> > > > when
> > > > ready, it will also depend in add some tests sending damaged
> > > > areas.
> > > > I have a hacked version of kms_psr2_su with 3 planes that I can
> > > > cleanup and send in a few days(99% of PSR2 selective fetch
> > > > changes was
> > > > done during my free time while bored during quarantine rainy
> > > > days).
> > > > 
> > > > BSpec: 55229
> > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > Cc: Imre Deak <imre.deak@intel.com>
> > > > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
> > > >  .../drm/i915/display/intel_display_debugfs.c  |   3 +
> > > >  .../drm/i915/display/intel_display_types.h    |  10 +
> > > >  drivers/gpu/drm/i915/display/intel_psr.c      | 329
> > > > +++++++++++++++++-
> > > >  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
> > > >  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
> > > >  drivers/gpu/drm/i915/i915_drv.h               |   2 +
> > > >  drivers/gpu/drm/i915/i915_params.c            |   5 +
> > > >  drivers/gpu/drm/i915/i915_params.h            |   1 +
> > > >  9 files changed, 352 insertions(+), 15 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index b69878334040..984809208c29 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -11729,6 +11729,8 @@ static void i9xx_update_cursor(struct
> > > > intel_plane *plane,
> > > >  	if (INTEL_GEN(dev_priv) >= 9)
> > > >  		skl_write_cursor_wm(plane, crtc_state);
> > > >  
> > > > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state,
> > > > plane_state);
> > > > +
> > > >  	if (plane->cursor.base != base ||
> > > >  	    plane->cursor.size != fbc_ctl ||
> > > >  	    plane->cursor.cntl != cntl) {
> > > > @@ -15115,6 +15117,8 @@ static void commit_pipe_config(struct
> > > > intel_atomic_state *state,
> > > >  
> > > >  		if (new_crtc_state->update_pipe)
> > > >  			intel_pipe_fastset(old_crtc_state,
> > > > new_crtc_state);
> > > > +
> > > > +		intel_psr2_program_trans_man_trk_ctl(new_crtc_s
> > > > tate);
> > > >  	}
> > > >  
> > > >  	if (dev_priv->display.atomic_update_watermarks)
> > > > @@ -15156,6 +15160,7 @@ static void intel_update_crtc(struct
> > > > intel_atomic_state *state,
> > > >  			intel_color_load_luts(new_crtc_state);
> > > >  
> > > >  		intel_pre_plane_update(state, crtc);
> > > > +		intel_psr2_sel_fetch_update(state, crtc);
> > > >  
> > > >  		if (new_crtc_state->update_pipe)
> > > >  			intel_encoders_update_pipe(state,
> > > > crtc);
> > > > diff --git
> > > > a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > index 70525623bcdf..0f600974462b 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct
> > > > seq_file *m, void *data)
> > > >  			su_blocks = su_blocks >>
> > > > PSR2_SU_STATUS_SHIFT(frame);
> > > >  			seq_printf(m, "%d\t%d\n", frame,
> > > > su_blocks);
> > > >  		}
> > > > +
> > > > +		seq_printf(m, "PSR2 selective fetch: %s\n",
> > > > +			   enableddisabled(psr-
> > > > >psr2_sel_fetch_enabled));
> > > >  	}
> > > >  
> > > >  unlock:
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > index 30b2767578dc..b77a512e5362 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -586,6 +586,13 @@ struct intel_plane_state {
> > > >  	u32 planar_slave;
> > > >  
> > > >  	struct drm_intel_sprite_colorkey ckey;
> > > > +
> > > > +	struct {
> > > > +		u32 ctl;
> > > > +		u32 pos;
> > > > +		u32 offset;
> > > > +		u32 size;
> > > > +	} psr2_sel_fetch;
> > > 
> > > Do we really need all that here? We don't store them for the
> > > normal
> > > plane updates either.
> > 
> > For ctl we do, anyways could be removed if we store overlapping
> > damage are in here so intel_psr2_program_plane_sel_fetch() would
> > incorporate
> > intel_psr2_plane_sel_fetch_calc() code, both looks good to me.
> > 
> > > >  };
> > > >  
> > > >  struct intel_initial_plane_config {
> > > > @@ -931,6 +938,7 @@ struct intel_crtc_state {
> > > >  
> > > >  	bool has_psr;
> > > >  	bool has_psr2;
> > > > +	bool enable_psr2_sel_fetch;
> > > >  	u32 dc3co_exitline;
> > > >  
> > > >  	/*
> > > > @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
> > > >  
> > > >  	/* For DSB related info */
> > > >  	struct intel_dsb *dsb;
> > > > +
> > > > +	u32 psr2_sw_man_track_ctl;
> > > >  };
> > > >  
> > > >  enum intel_pipe_crc_source {
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > index 0c86e9e341a2..bc2a2e64fe2a 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct
> > > > intel_dp *intel_dp)
> > > >  	else
> > > >  		val |= EDP_PSR2_TP2_TIME_2500us;
> > > >  
> > > > +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> > > > +		intel_de_write(dev_priv,
> > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > >psr.transcoder),
> > > > +			       PSR2_MAN_TRK_CTL_ENABLE);
> > > > +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> > > > +		intel_de_write(dev_priv,
> > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > >psr.transcoder), 0);
> > > > +
> > > >  	/*
> > > >  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and
> > > > BSpec is
> > > >  	 * recommending keep this bit unset while PSR2 is
> > > > enabled.
> > > > @@ -628,6 +636,38 @@ tgl_dc3co_exitline_compute_config(struct
> > > > intel_dp *intel_dp,
> > > >  	crtc_state->dc3co_exitline = crtc_vdisplay -
> > > > exit_scanlines;
> > > >  }
> > > >  
> > > > +static bool intel_psr2_sel_fetch_config_valid(struct intel_dp
> > > > *intel_dp,
> > > > +					      struct
> > > > intel_crtc_state *crtc_state)
> > > > +{
> > > > +	struct intel_atomic_state *state =
> > > > to_intel_atomic_state(crtc_state->uapi.state);
> > > > +	struct drm_i915_private *dev_priv =
> > > > dp_to_i915(intel_dp);
> > > > +	struct intel_plane_state *plane_state;
> > > > +	struct intel_plane *plane;
> > > > +	int i;
> > > > +
> > > > +	if (!i915_modparams.enable_psr2_sel_fetch) {
> > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > +			    "PSR2 sel fetch not enabled,
> > > > disabled by parameter\n");
> > > > +		return false;
> > > > +	}
> > > > +
> > > > +	if (crtc_state->uapi.async_flip) {
> > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > +			    "PSR2 sel fetch not enabled, async
> > > > flip enabled\n");
> > > > +		return false;
> > > > +	}
> > > 
> > > Not supported anyway.
> > > 
> > > > +
> > > > +	for_each_new_intel_plane_in_state(state, plane,
> > > > plane_state, i) {
> > > > +		if (plane_state->uapi.rotation !=
> > > > DRM_MODE_ROTATE_0) {
> > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > +				    "PSR2 sel fetch not
> > > > enabled, plane rotated\n");
> > > > +			return false;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	return crtc_state->enable_psr2_sel_fetch = true;
> > > > +}
> > > > +
> > > >  static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
> > > >  				    struct intel_crtc_state
> > > > *crtc_state)
> > > >  {
> > > > @@ -697,22 +737,17 @@ static bool
> > > > intel_psr2_config_valid(struct intel_dp *intel_dp,
> > > >  		return false;
> > > >  	}
> > > >  
> > > > -	/*
> > > > -	 * Some platforms lack PSR2 HW tracking and instead
> > > > require manual
> > > > -	 * tracking by software.  In this case, the driver is
> > > > required to track
> > > > -	 * the areas that need updates and program hardware to
> > > > send selective
> > > > -	 * updates.
> > > > -	 *
> > > > -	 * So until the software tracking is implemented, PSR2
> > > > needs to be
> > > > -	 * disabled for platforms without PSR2 HW tracking.
> > > > -	 */
> > > > -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > -		drm_dbg_kms(&dev_priv->drm,
> > > > -			    "No PSR2 HW tracking in the
> > > > platform\n");
> > > > -		return false;
> > > > +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> > > > +		if
> > > > (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
> > > > +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > +				    "PSR2 not enabled,
> > > > selective fetch not valid and no HW tracking available\n");
> > > > +			return false;
> > > > +		}
> > > >  	}
> > > >  
> > > > -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > psr_max_v) {
> > > > +	if (!crtc_state->enable_psr2_sel_fetch &&
> > > > +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > psr_max_v)) {
> > > >  		drm_dbg_kms(&dev_priv->drm,
> > > >  			    "PSR2 not enabled, resolution %dx%d
> > > > > max supported %dx%d\n",
> > > >  			    crtc_hdisplay, crtc_vdisplay,
> > > > @@ -863,6 +898,11 @@ static void intel_psr_enable_source(struct
> > > > intel_dp *intel_dp,
> > > >  		val |= EXITLINE_ENABLE;
> > > >  		intel_de_write(dev_priv,
> > > > EXITLINE(cpu_transcoder), val);
> > > >  	}
> > > > +
> > > > +	if (HAS_PSR_HW_TRACKING(dev_priv))
> > > > +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> > > > IGNORE_PSR2_HW_TRACKING,
> > > > +			     dev_priv-
> > > > >psr.psr2_sel_fetch_enabled ?
> > > > +			     IGNORE_PSR2_HW_TRACKING : 0);
> > > >  }
> > > >  
> > > >  static void intel_psr_enable_locked(struct drm_i915_private
> > > > *dev_priv,
> > > > @@ -884,7 +924,7 @@ static void intel_psr_enable_locked(struct
> > > > drm_i915_private *dev_priv,
> > > >  	/* DC5/DC6 requires at least 6 idle frames */
> > > >  	val =
> > > > usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> > > >  	dev_priv->psr.dc3co_exit_delay = val;
> > > > -
> > > > +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state-
> > > > >enable_psr2_sel_fetch;
> > > >  	/*
> > > >  	 * If a PSR error happened and the driver is reloaded,
> > > > the EDP_PSR_IIR
> > > >  	 * will still keep the error set even after the reset
> > > > done in the
> > > > @@ -1080,6 +1120,265 @@ static void
> > > > psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
> > > >  		intel_psr_exit(dev_priv);
> > > >  }
> > > >  
> > > > +void intel_psr2_program_plane_sel_fetch(struct intel_plane
> > > > *plane,
> > > > +					const struct
> > > > intel_crtc_state *crtc_state,
> > > > +					const struct
> > > > intel_plane_state *plane_state)
> > > > +{
> > > > +	struct drm_i915_private *dev_priv = to_i915(plane-
> > > > >base.dev);
> > > > +	enum pipe pipe = plane->pipe;
> > > > +
> > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > +	    !plane_state ||
> > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > +		return;
> > > > +
> > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe,
> > > > plane->id),
> > > > +			  plane_state->psr2_sel_fetch.ctl);
> > > > +	if (!plane_state->psr2_sel_fetch.ctl || plane->id ==
> > > > PLANE_CURSOR)
> > > > +		return;
> > > > +
> > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe,
> > > > plane->id),
> > > > +			  plane_state->psr2_sel_fetch.pos);
> > > > +	intel_de_write_fw(dev_priv,
> > > > PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> > > > +			  plane_state->psr2_sel_fetch.offset);
> > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe,
> > > > plane->id),
> > > > +			  plane_state->psr2_sel_fetch.size);
> > > > +}
> > > > +
> > > > +void intel_psr2_program_trans_man_trk_ctl(const struct
> > > > intel_crtc_state *crtc_state)
> > > > +{
> > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > >uapi.crtc);
> > > > +	struct drm_i915_private *dev_priv = to_i915(crtc-
> > > > >base.dev);
> > > > +	struct i915_psr *psr = &dev_priv->psr;
> > > > +
> > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > +		return;
> > > > +
> > > > +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr-
> > > > >transcoder),
> > > > +		       crtc_state->psr2_sw_man_track_ctl);
> > > > +}
> > > > +
> > > > +static void intel_psr2_plane_sel_fetch_calc(struct
> > > > intel_plane_state *plane_state,
> > > > +					    struct drm_rect
> > > > *clip)
> > > > +{
> > > > +	int color_plane = plane_state->planar_linked_plane &&
> > > > !plane_state->planar_slave;
> > > > +	struct intel_plane *plane = to_intel_plane(plane_state-
> > > > >uapi.plane);
> > > > +	u32 val;
> > > > +
> > > > +	if (plane->id == PLANE_CURSOR)
> > > > +		return;
> > > > +
> > > > +	val = (plane_state->color_plane[color_plane].y + clip-
> > > > >y1) << 16;
> > > > +	val |= plane_state->color_plane[color_plane].x;
> > > > +	plane_state->psr2_sel_fetch.offset = val;
> > > > +
> > > > +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> > > > +	val |= plane_state->uapi.crtc_x;
> > > > +	plane_state->psr2_sel_fetch.pos = val;
> > > > +
> > > > +	/* Sizes are 0 based */
> > > > +	val = (clip->y2 - clip->y1 - 1) << 16;
> > > > +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) -
> > > > 1;
> > > > +	plane_state->psr2_sel_fetch.size = val;
> > > > +}
> > > > +
> > > > +static void intel_psr2_trans_man_trk_ctl_calc(struct
> > > > intel_crtc_state *crtc_state,
> > > > +					      struct drm_rect
> > > > *clip,
> > > > +					      bool full_update)
> > > > +{
> > > > +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> > > > +
> > > > +	if (full_update) {
> > > > +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> > > > +		goto exit;
> > > > +	}
> > > > +
> > > > +	if (clip->y1 == -1)
> > > > +		goto exit;
> > > > +
> > > > +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> > > > +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4
> > > > + 1);
> > > > +	val |=
> > > > PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4) +
> > > > 1);
> > > > +exit:
> > > > +	crtc_state->psr2_sw_man_track_ctl = val;
> > > > +}
> > > > +
> > > > +static void intel_psr2_plane_sel_fetch_ctl_calc(struct
> > > > intel_plane *plane,
> > > > +						struct
> > > > intel_plane_state *plane_state,
> > > > +						bool enable)
> > > > +{
> > > > +	if (!enable)
> > > > +		plane_state->psr2_sel_fetch.ctl = 0;
> > > > +	else if (plane->id == PLANE_CURSOR)
> > > > +		plane_state->psr2_sel_fetch.ctl = plane-
> > > > >cursor.cntl;
> > > > +	else
> > > > +		plane_state->psr2_sel_fetch.ctl = plane_state-
> > > > >ctl;
> > > > +}
> > > > +
> > > > +static void clip_update(struct drm_rect *overlap_damage_area,
> > > > +			struct drm_rect *damage_area)
> > > > +{
> > > > +	if (overlap_damage_area->y1 == -1) {
> > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	if (damage_area->y1 < overlap_damage_area->y1)
> > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > +
> > > > +	if (damage_area->y2 > overlap_damage_area->y2)
> > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > +}
> > > > +
> > > > +/* Update plane damage area if planes above moved or have
> > > > alpha */
> > > > +static void intel_psr2_pipe_dirty_areas_set(struct
> > > > intel_plane_state *plane_state,
> > > > +					    struct intel_plane
> > > > *plane,
> > > > +					    const struct
> > > > drm_rect *pipe_dirty_areas,
> > > > +					    struct drm_rect
> > > > *plane_clip)
> > > > +{
> > > > +	enum plane_id i;
> > > > +
> > > > +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> > > > +		int j;
> > > > +
> > > > +		for (j = 0; j < 2; j++) {
> > > > +			struct drm_rect r = pipe_dirty_areas[i
> > > > * 2 + j];
> > > > +
> > > > +			if (!drm_rect_width(&r))
> > > > +				continue;
> > > > +			if (!drm_rect_intersect(&r,
> > > > &plane_state->uapi.dst))
> > > > +				continue;
> > > > +
> > > > +			r.y1 -= plane_state->uapi.crtc_y;
> > > > +			r.y2 -= plane_state->uapi.crtc_y;
> > > > +			clip_update(plane_clip, &r);
> > > > +		}
> > > > +	}
> > > > +}
> > > > +
> > > > +void intel_psr2_sel_fetch_update(struct intel_atomic_state
> > > > *state,
> > > > +				 struct intel_crtc *crtc)
> > > > +{
> > > > +	struct intel_crtc_state *crtc_state =
> > > > intel_atomic_get_new_crtc_state(state, crtc);
> > > > +	struct intel_plane_state *new_plane_state,
> > > > *old_plane_state;
> > > > +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] =
> > > > {};
> > > > +	struct drm_rect pipe_clip = { .y1 = -1 };
> > > > +	struct intel_plane *plane;
> > > > +	bool full_update = false;
> > > > +	int i;
> > > > +
> > > > +	if (!crtc_state->enable_psr2_sel_fetch)
> > > > +		return;
> > > > +
> > > > +	/*
> > > > +	 * Load all the pipes areas where there is a plane with
> > > > alpha or a plane
> > > > +	 * that moved or plane that the visibility changed in
> > > > those
> > > > +	 * cases planes bellow it will need to be fetched in
> > > > those intersection
> > > > +	 * areas even if they are not damaged in those areas.
> > > > +	 */
> > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > old_plane_state,
> > > > +					     new_plane_state,
> > > > i) {
> > > > +		bool alpha, flip, dirty;
> > > > +
> > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > >uapi.crtc)
> > > > +			continue;
> > > > +
> > > > +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> > > > +		alpha |= old_plane_state->uapi.alpha !=
> > > > U16_MAX;
> > > > +		flip = new_plane_state->uapi.fb !=
> > > > old_plane_state->uapi.fb;
> > > > +		dirty = alpha && flip;
> > > > +		dirty |= !drm_rect_equals(&new_plane_state-
> > > > >uapi.dst,
> > > > +					  &old_plane_state-
> > > > >uapi.dst);
> > > > +		dirty |= new_plane_state->uapi.visible !=
> > > > +			 old_plane_state->uapi.visible;
> > > > +		if (!dirty)
> > > > +			continue;
> > > > +
> > > > +		if (old_plane_state->uapi.visible)
> > > > +			pipe_dirty_areas[plane->id * 2] =
> > > > old_plane_state->uapi.dst;
> > > > +		if (new_plane_state->uapi.visible)
> > > > +			pipe_dirty_areas[plane->id * 2 + 1] =
> > > > new_plane_state->uapi.dst;
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * Iterate over all planes, compute the damaged clip
> > > > area also including
> > > > +	 * the pipe_dirty_areas, compute plane registers and
> > > > update pipe damaged
> > > > +	 * area
> > > > +	 */
> > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > old_plane_state,
> > > > +					     new_plane_state,
> > > > i) {
> > > > +		struct drm_rect plane_clip = { .y1 = -1 };
> > > > +		struct drm_mode_rect *clips;
> > > > +		u32 num_clips;
> > > > +		int j;
> > > > +
> > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > >uapi.crtc)
> > > > +			continue;
> > > > +
> > > > +		/*
> > > > +		 * TODO: Not clear how to handle planes with
> > > > negative position,
> > > > +		 * also planes are not updated if they have a
> > > > negative X
> > > > +		 * position so for now doing a full update in
> > > > this cases
> > > > +		 */
> > > > +		if (new_plane_state->uapi.crtc_y < 0 ||
> > > > +		    new_plane_state->uapi.crtc_x < 0) {
> > > > +			full_update = true;
> > > > +			break;
> > > > +		}
> > > > +
> > > > +		intel_psr2_plane_sel_fetch_ctl_calc(plane,
> > > > new_plane_state,
> > > > +						    new_plane_s
> > > > tate->uapi.visible);
> > > > +		if (!new_plane_state->uapi.visible)
> > > > +			continue;
> > > > +
> > > > +		clips =
> > > > drm_plane_get_damage_clips(&new_plane_state->uapi);
> > > > +		num_clips =
> > > > drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> > > > +
> > > > +		/*
> > > > +		 * If plane moved mark the whole plane area as
> > > > damaged so it
> > > > +		 * can be complete draw in the new position
> > > > +		 */
> > > > +		if (!drm_rect_equals(&new_plane_state-
> > > > >uapi.dst,
> > > > +				     &old_plane_state-
> > > > >uapi.dst)) {
> > > > +			num_clips = 0;
> > > > +			plane_clip.y1 = new_plane_state-
> > > > >uapi.src.y1 >> 16;
> > > > +			plane_clip.y2 = new_plane_state-
> > > > >uapi.src.y2 >> 16;
> > > > +		} else if (!num_clips) {
> > > > +			/*
> > > > +			 * If plane don't have damage areas but
> > > > the framebuffer
> > > > +			 * changed mark the whole plane as
> > > > damaged
> > > > +			 */
> > > > +			if (new_plane_state->uapi.fb ==
> > > > old_plane_state->uapi.fb)
> > > > +				continue;
> > > > +
> > > > +			plane_clip.y1 = new_plane_state-
> > > > >uapi.src.y1 >> 16;
> > > > +			plane_clip.y2 = new_plane_state-
> > > > >uapi.src.y2 >> 16;
> > > > +		}
> > > > +
> > > > +		for (j = 0; j < num_clips; j++) {
> > > > +			struct drm_rect damage_area;
> > > > +
> > > > +			damage_area.x1 = clips[j].x1;
> > > > +			damage_area.x2 = clips[j].x2;
> > > > +			damage_area.y1 = clips[j].y1;
> > > > +			damage_area.y2 = clips[j].y2;
> > > > +			clip_update(&plane_clip, &damage_area);
> > > > +		}
> > > > +
> > > > +		intel_psr2_pipe_dirty_areas_set(new_plane_state
> > > > , plane,
> > > > +						pipe_dirty_area
> > > > s, &plane_clip);
> > > > +		intel_psr2_plane_sel_fetch_calc(new_plane_state
> > > > , &plane_clip);
> > > > +
> > > > +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> > > > +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> > > > +		clip_update(&pipe_clip, &plane_clip);
> > > > +	}
> > > 
> > > This whole thing seems rather convoluted. Also using lots of uapi
> > > state
> > > in places where I don't expect to see any.
> > 
> > Not sure from where I should get this information then,
> > intel_plane_state don't have it.
> > 
> > > I would suggest the correct way would be something like:
> > > 1) for_each_plane_in_state()
> > > 	hw.damage =
> > > translate_to_some_hw_coord_space(union(uapi.damages))
> > > 	or just use the full plane size if we have scaling i guess
> > 
> > 99% of the time the coordinates used are based on pipe coord space,
> > only to calculate the plane overlapping damaged area is used plane
> > coord space.
> > 
> > > 2) need to add all affected planes to the state and set the
> > > appropriate
> > >    bitmask, which may mean we want to track the planes' positions
> > > in the
> > >    crtc state. I think atm we only have it in the plane state
> > 
> > This looks a "or" to me, have all the planes added to the state
> > when psr2 sel fetch is enabled or add track all the planes position
> > in pipe.
> 
> *Affected* planes, not all planes. Hmm. I guess affected planes are
> actually the ones whose selective fetch coordinates change. If they
> don't change then no need to add them to the state. Plane updates are
> rather expensive (lots of mmio) so I've generally tried to avoid
> pointless plane updates.
> 
> But this whole thing might turn a bit annoying since we'd to keep
> adding affected planes until the total selective fetch region stops
> growing. I think that would probably want the two stage plane state
> compuation. So just blindly adding all of them would probably be
> simpler, albeit less efficient.
> 
> > Although the second one would avoid us to do plane calculations and
> > plane register sometimes, in some cases where a plane above a non-
> > modified plane
> > moves the non-modified plane bellow will need to be added to the
> > state so the plane sel_fetch registers are written.
> > We could go with the easy one(add all planes to the state) and then
> > move to the second one latter.
> > 
> > > 3) translate the damage further into the final plane src
> > > coordinate
> > >    space. Dunno if we have enough state around still to do it
> > > cleanly.
> > >    I was thinking maybe it could be done alongside all the other
> > > plane
> > >    surface calculations, but there might be a chicken vs. egg
> > > situation
> > >    here since we probably want to do the plane check stuff before
> > > doing
> > >    step 1, but plane check is also where we do the surface
> > > calculations.
> > >    Dunno if we may just want to split the plane check into two
> > > stages
> > 
> > As right now it depends mostly in uapi this could be moved to the
> > check phase, did not left there because this will never have a
> > error or a conflict
> > that will cause us to reject the state.
> > 
> > > To keep things simple I guess what I'd suggest is to forget about
> > > the
> > > damage stuff in the first version of the series and just do full
> > > plane updates. That way we don't have to worry about so many
> > > coordinate
> > > space transformations.
> > 
> > Do that would only save us the for bellow and the if to check if
> > plane moved:
> > 
> > for (j = 0; j < num_clips; j++) {
> > 	struct drm_rect damage_area;
> > 
> > 	damage_area.x1 = clips[j].x1;
> > 	damage_area.x2 = clips[j].x2;
> > 	damage_area.y1 = clips[j].y1;
> > 	damage_area.y2 = clips[j].y2;
> > 	clip_update(&plane_clip, &damage_area);
> > }
> 
> That's just some minor detail. The real issue is converting the
> damage
> between the various coordinate spaces we have for planes (original fb
> relative src coordiantes, final SURF relative src coordinates,
> crtc relative dst coordinates, and also the hw vs. uapi stuff affects
> this stuff).
> 
For the most efficient power comsumption and usage of bandthwidth, we
can use Selective Fetch of Plane and PSR2 Manual Tracking together.
But PSR2 Manual Tracking can be enabled without Selective Fetch of
Plane. (And pre GEN12 does not have a feature "Selective Fetch of
Plane".)
So can you split this commit to Selective Fetch and PSR2 Manual
Tracking?
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-06-16 15:16         ` Mun, Gwan-gyeong
@ 2020-06-16 17:29           ` Souza, Jose
  2020-06-16 20:33             ` Mun, Gwan-gyeong
  0 siblings, 1 reply; 28+ messages in thread
From: Souza, Jose @ 2020-06-16 17:29 UTC (permalink / raw)
  To: ville.syrjala, Mun, Gwan-gyeong; +Cc: Pandiyan, Dhinakaran, intel-gfx

On Tue, 2020-06-16 at 16:16 +0100, Mun, Gwan-gyeong wrote:
> On Mon, 2020-06-15 at 19:40 +0300, Ville Syrjälä wrote:
> > On Fri, Jun 12, 2020 at 08:33:31PM +0000, Souza, Jose wrote:
> > > On Fri, 2020-06-12 at 19:30 +0300, Ville Syrjälä wrote:
> > > > On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de Souza
> > > > wrote:
> > > > > All GEN12 platforms supports PSR2 selective fetch but not all
> > > > > GEN12
> > > > > platforms supports PSR2 hardware tracking(aka RKL).
> > > > > 
> > > > > This feature consists in software program registers with the
> > > > > damaged
> > > > > area of each plane this way hardware will only fetch from
> > > > > memory those
> > > > > areas and sent the PSR2 selective update blocks to panel,
> > > > > saving even
> > > > > more power but to it actually happen userspace needs to send
> > > > > the
> > > > > damaged areas otherwise it will still fetch the whole plane as
> > > > > fallback.
> > > > > As today Gnome3 do not send damaged areas and the only
> > > > > compositor that
> > > > > I'm aware that sets the damaged areas is Weston.
> > > > > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> > > > > 
> > > > > So here implementing page flip part, it is still completely
> > > > > missing
> > > > > frontbuffer modifications, that is why the
> > > > > enable_psr2_sel_fetch
> > > > > parameter was added.
> > > > > 
> > > > > The plan is to switch all GEN12 platforms to selective fetch
> > > > > when
> > > > > ready, it will also depend in add some tests sending damaged
> > > > > areas.
> > > > > I have a hacked version of kms_psr2_su with 3 planes that I can
> > > > > cleanup and send in a few days(99% of PSR2 selective fetch
> > > > > changes was
> > > > > done during my free time while bored during quarantine rainy
> > > > > days).
> > > > > 
> > > > > BSpec: 55229
> > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > Cc: Imre Deak <imre.deak@intel.com>
> > > > > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > > Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
> > > > >  .../drm/i915/display/intel_display_debugfs.c  |   3 +
> > > > >  .../drm/i915/display/intel_display_types.h    |  10 +
> > > > >  drivers/gpu/drm/i915/display/intel_psr.c      | 329
> > > > > +++++++++++++++++-
> > > > >  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
> > > > >  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
> > > > >  drivers/gpu/drm/i915/i915_drv.h               |   2 +
> > > > >  drivers/gpu/drm/i915/i915_params.c            |   5 +
> > > > >  drivers/gpu/drm/i915/i915_params.h            |   1 +
> > > > >  9 files changed, 352 insertions(+), 15 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index b69878334040..984809208c29 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -11729,6 +11729,8 @@ static void i9xx_update_cursor(struct
> > > > > intel_plane *plane,
> > > > >  	if (INTEL_GEN(dev_priv) >= 9)
> > > > >  		skl_write_cursor_wm(plane, crtc_state);
> > > > >  
> > > > > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state,
> > > > > plane_state);
> > > > > +
> > > > >  	if (plane->cursor.base != base ||
> > > > >  	    plane->cursor.size != fbc_ctl ||
> > > > >  	    plane->cursor.cntl != cntl) {
> > > > > @@ -15115,6 +15117,8 @@ static void commit_pipe_config(struct
> > > > > intel_atomic_state *state,
> > > > >  
> > > > >  		if (new_crtc_state->update_pipe)
> > > > >  			intel_pipe_fastset(old_crtc_state,
> > > > > new_crtc_state);
> > > > > +
> > > > > +		intel_psr2_program_trans_man_trk_ctl(new_crtc_s
> > > > > tate);
> > > > >  	}
> > > > >  
> > > > >  	if (dev_priv->display.atomic_update_watermarks)
> > > > > @@ -15156,6 +15160,7 @@ static void intel_update_crtc(struct
> > > > > intel_atomic_state *state,
> > > > >  			intel_color_load_luts(new_crtc_state);
> > > > >  
> > > > >  		intel_pre_plane_update(state, crtc);
> > > > > +		intel_psr2_sel_fetch_update(state, crtc);
> > > > >  
> > > > >  		if (new_crtc_state->update_pipe)
> > > > >  			intel_encoders_update_pipe(state,
> > > > > crtc);
> > > > > diff --git
> > > > > a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > index 70525623bcdf..0f600974462b 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct
> > > > > seq_file *m, void *data)
> > > > >  			su_blocks = su_blocks >>
> > > > > PSR2_SU_STATUS_SHIFT(frame);
> > > > >  			seq_printf(m, "%d\t%d\n", frame,
> > > > > su_blocks);
> > > > >  		}
> > > > > +
> > > > > +		seq_printf(m, "PSR2 selective fetch: %s\n",
> > > > > +			   enableddisabled(psr-
> > > > > > psr2_sel_fetch_enabled));
> > > > >  	}
> > > > >  
> > > > >  unlock:
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > index 30b2767578dc..b77a512e5362 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > @@ -586,6 +586,13 @@ struct intel_plane_state {
> > > > >  	u32 planar_slave;
> > > > >  
> > > > >  	struct drm_intel_sprite_colorkey ckey;
> > > > > +
> > > > > +	struct {
> > > > > +		u32 ctl;
> > > > > +		u32 pos;
> > > > > +		u32 offset;
> > > > > +		u32 size;
> > > > > +	} psr2_sel_fetch;
> > > > 
> > > > Do we really need all that here? We don't store them for the
> > > > normal
> > > > plane updates either.
> > > 
> > > For ctl we do, anyways could be removed if we store overlapping
> > > damage are in here so intel_psr2_program_plane_sel_fetch() would
> > > incorporate
> > > intel_psr2_plane_sel_fetch_calc() code, both looks good to me.
> > > 
> > > > >  };
> > > > >  
> > > > >  struct intel_initial_plane_config {
> > > > > @@ -931,6 +938,7 @@ struct intel_crtc_state {
> > > > >  
> > > > >  	bool has_psr;
> > > > >  	bool has_psr2;
> > > > > +	bool enable_psr2_sel_fetch;
> > > > >  	u32 dc3co_exitline;
> > > > >  
> > > > >  	/*
> > > > > @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
> > > > >  
> > > > >  	/* For DSB related info */
> > > > >  	struct intel_dsb *dsb;
> > > > > +
> > > > > +	u32 psr2_sw_man_track_ctl;
> > > > >  };
> > > > >  
> > > > >  enum intel_pipe_crc_source {
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > index 0c86e9e341a2..bc2a2e64fe2a 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct
> > > > > intel_dp *intel_dp)
> > > > >  	else
> > > > >  		val |= EDP_PSR2_TP2_TIME_2500us;
> > > > >  
> > > > > +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> > > > > +		intel_de_write(dev_priv,
> > > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > > > psr.transcoder),
> > > > > +			       PSR2_MAN_TRK_CTL_ENABLE);
> > > > > +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> > > > > +		intel_de_write(dev_priv,
> > > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > > > psr.transcoder), 0);
> > > > > +
> > > > >  	/*
> > > > >  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and
> > > > > BSpec is
> > > > >  	 * recommending keep this bit unset while PSR2 is
> > > > > enabled.
> > > > > @@ -628,6 +636,38 @@ tgl_dc3co_exitline_compute_config(struct
> > > > > intel_dp *intel_dp,
> > > > >  	crtc_state->dc3co_exitline = crtc_vdisplay -
> > > > > exit_scanlines;
> > > > >  }
> > > > >  
> > > > > +static bool intel_psr2_sel_fetch_config_valid(struct intel_dp
> > > > > *intel_dp,
> > > > > +					      struct
> > > > > intel_crtc_state *crtc_state)
> > > > > +{
> > > > > +	struct intel_atomic_state *state =
> > > > > to_intel_atomic_state(crtc_state->uapi.state);
> > > > > +	struct drm_i915_private *dev_priv =
> > > > > dp_to_i915(intel_dp);
> > > > > +	struct intel_plane_state *plane_state;
> > > > > +	struct intel_plane *plane;
> > > > > +	int i;
> > > > > +
> > > > > +	if (!i915_modparams.enable_psr2_sel_fetch) {
> > > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > > +			    "PSR2 sel fetch not enabled,
> > > > > disabled by parameter\n");
> > > > > +		return false;
> > > > > +	}
> > > > > +
> > > > > +	if (crtc_state->uapi.async_flip) {
> > > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > > +			    "PSR2 sel fetch not enabled, async
> > > > > flip enabled\n");
> > > > > +		return false;
> > > > > +	}
> > > > 
> > > > Not supported anyway.
> > > > 
> > > > > +
> > > > > +	for_each_new_intel_plane_in_state(state, plane,
> > > > > plane_state, i) {
> > > > > +		if (plane_state->uapi.rotation !=
> > > > > DRM_MODE_ROTATE_0) {
> > > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > > +				    "PSR2 sel fetch not
> > > > > enabled, plane rotated\n");
> > > > > +			return false;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	return crtc_state->enable_psr2_sel_fetch = true;
> > > > > +}
> > > > > +
> > > > >  static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
> > > > >  				    struct intel_crtc_state
> > > > > *crtc_state)
> > > > >  {
> > > > > @@ -697,22 +737,17 @@ static bool
> > > > > intel_psr2_config_valid(struct intel_dp *intel_dp,
> > > > >  		return false;
> > > > >  	}
> > > > >  
> > > > > -	/*
> > > > > -	 * Some platforms lack PSR2 HW tracking and instead
> > > > > require manual
> > > > > -	 * tracking by software.  In this case, the driver is
> > > > > required to track
> > > > > -	 * the areas that need updates and program hardware to
> > > > > send selective
> > > > > -	 * updates.
> > > > > -	 *
> > > > > -	 * So until the software tracking is implemented, PSR2
> > > > > needs to be
> > > > > -	 * disabled for platforms without PSR2 HW tracking.
> > > > > -	 */
> > > > > -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > > -		drm_dbg_kms(&dev_priv->drm,
> > > > > -			    "No PSR2 HW tracking in the
> > > > > platform\n");
> > > > > -		return false;
> > > > > +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> > > > > +		if
> > > > > (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
> > > > > +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > > +				    "PSR2 not enabled,
> > > > > selective fetch not valid and no HW tracking available\n");
> > > > > +			return false;
> > > > > +		}
> > > > >  	}
> > > > >  
> > > > > -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > > psr_max_v) {
> > > > > +	if (!crtc_state->enable_psr2_sel_fetch &&
> > > > > +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > > psr_max_v)) {
> > > > >  		drm_dbg_kms(&dev_priv->drm,
> > > > >  			    "PSR2 not enabled, resolution %dx%d
> > > > > > max supported %dx%d\n",
> > > > >  			    crtc_hdisplay, crtc_vdisplay,
> > > > > @@ -863,6 +898,11 @@ static void intel_psr_enable_source(struct
> > > > > intel_dp *intel_dp,
> > > > >  		val |= EXITLINE_ENABLE;
> > > > >  		intel_de_write(dev_priv,
> > > > > EXITLINE(cpu_transcoder), val);
> > > > >  	}
> > > > > +
> > > > > +	if (HAS_PSR_HW_TRACKING(dev_priv))
> > > > > +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> > > > > IGNORE_PSR2_HW_TRACKING,
> > > > > +			     dev_priv-
> > > > > > psr.psr2_sel_fetch_enabled ?
> > > > > +			     IGNORE_PSR2_HW_TRACKING : 0);
> > > > >  }
> > > > >  
> > > > >  static void intel_psr_enable_locked(struct drm_i915_private
> > > > > *dev_priv,
> > > > > @@ -884,7 +924,7 @@ static void intel_psr_enable_locked(struct
> > > > > drm_i915_private *dev_priv,
> > > > >  	/* DC5/DC6 requires at least 6 idle frames */
> > > > >  	val =
> > > > > usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> > > > >  	dev_priv->psr.dc3co_exit_delay = val;
> > > > > -
> > > > > +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state-
> > > > > > enable_psr2_sel_fetch;
> > > > >  	/*
> > > > >  	 * If a PSR error happened and the driver is reloaded,
> > > > > the EDP_PSR_IIR
> > > > >  	 * will still keep the error set even after the reset
> > > > > done in the
> > > > > @@ -1080,6 +1120,265 @@ static void
> > > > > psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
> > > > >  		intel_psr_exit(dev_priv);
> > > > >  }
> > > > >  
> > > > > +void intel_psr2_program_plane_sel_fetch(struct intel_plane
> > > > > *plane,
> > > > > +					const struct
> > > > > intel_crtc_state *crtc_state,
> > > > > +					const struct
> > > > > intel_plane_state *plane_state)
> > > > > +{
> > > > > +	struct drm_i915_private *dev_priv = to_i915(plane-
> > > > > > base.dev);
> > > > > +	enum pipe pipe = plane->pipe;
> > > > > +
> > > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > > +	    !plane_state ||
> > > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > > +		return;
> > > > > +
> > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe,
> > > > > plane->id),
> > > > > +			  plane_state->psr2_sel_fetch.ctl);
> > > > > +	if (!plane_state->psr2_sel_fetch.ctl || plane->id ==
> > > > > PLANE_CURSOR)
> > > > > +		return;
> > > > > +
> > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe,
> > > > > plane->id),
> > > > > +			  plane_state->psr2_sel_fetch.pos);
> > > > > +	intel_de_write_fw(dev_priv,
> > > > > PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> > > > > +			  plane_state->psr2_sel_fetch.offset);
> > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe,
> > > > > plane->id),
> > > > > +			  plane_state->psr2_sel_fetch.size);
> > > > > +}
> > > > > +
> > > > > +void intel_psr2_program_trans_man_trk_ctl(const struct
> > > > > intel_crtc_state *crtc_state)
> > > > > +{
> > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > > uapi.crtc);
> > > > > +	struct drm_i915_private *dev_priv = to_i915(crtc-
> > > > > > base.dev);
> > > > > +	struct i915_psr *psr = &dev_priv->psr;
> > > > > +
> > > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > > +		return;
> > > > > +
> > > > > +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr-
> > > > > > transcoder),
> > > > > +		       crtc_state->psr2_sw_man_track_ctl);
> > > > > +}
> > > > > +
> > > > > +static void intel_psr2_plane_sel_fetch_calc(struct
> > > > > intel_plane_state *plane_state,
> > > > > +					    struct drm_rect
> > > > > *clip)
> > > > > +{
> > > > > +	int color_plane = plane_state->planar_linked_plane &&
> > > > > !plane_state->planar_slave;
> > > > > +	struct intel_plane *plane = to_intel_plane(plane_state-
> > > > > > uapi.plane);
> > > > > +	u32 val;
> > > > > +
> > > > > +	if (plane->id == PLANE_CURSOR)
> > > > > +		return;
> > > > > +
> > > > > +	val = (plane_state->color_plane[color_plane].y + clip-
> > > > > > y1) << 16;
> > > > > +	val |= plane_state->color_plane[color_plane].x;
> > > > > +	plane_state->psr2_sel_fetch.offset = val;
> > > > > +
> > > > > +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> > > > > +	val |= plane_state->uapi.crtc_x;
> > > > > +	plane_state->psr2_sel_fetch.pos = val;
> > > > > +
> > > > > +	/* Sizes are 0 based */
> > > > > +	val = (clip->y2 - clip->y1 - 1) << 16;
> > > > > +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) -
> > > > > 1;
> > > > > +	plane_state->psr2_sel_fetch.size = val;
> > > > > +}
> > > > > +
> > > > > +static void intel_psr2_trans_man_trk_ctl_calc(struct
> > > > > intel_crtc_state *crtc_state,
> > > > > +					      struct drm_rect
> > > > > *clip,
> > > > > +					      bool full_update)
> > > > > +{
> > > > > +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> > > > > +
> > > > > +	if (full_update) {
> > > > > +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> > > > > +		goto exit;
> > > > > +	}
> > > > > +
> > > > > +	if (clip->y1 == -1)
> > > > > +		goto exit;
> > > > > +
> > > > > +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> > > > > +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4
> > > > > + 1);
> > > > > +	val |=
> > > > > PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4) +
> > > > > 1);
> > > > > +exit:
> > > > > +	crtc_state->psr2_sw_man_track_ctl = val;
> > > > > +}
> > > > > +
> > > > > +static void intel_psr2_plane_sel_fetch_ctl_calc(struct
> > > > > intel_plane *plane,
> > > > > +						struct
> > > > > intel_plane_state *plane_state,
> > > > > +						bool enable)
> > > > > +{
> > > > > +	if (!enable)
> > > > > +		plane_state->psr2_sel_fetch.ctl = 0;
> > > > > +	else if (plane->id == PLANE_CURSOR)
> > > > > +		plane_state->psr2_sel_fetch.ctl = plane-
> > > > > > cursor.cntl;
> > > > > +	else
> > > > > +		plane_state->psr2_sel_fetch.ctl = plane_state-
> > > > > > ctl;
> > > > > +}
> > > > > +
> > > > > +static void clip_update(struct drm_rect *overlap_damage_area,
> > > > > +			struct drm_rect *damage_area)
> > > > > +{
> > > > > +	if (overlap_damage_area->y1 == -1) {
> > > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > > +		return;
> > > > > +	}
> > > > > +
> > > > > +	if (damage_area->y1 < overlap_damage_area->y1)
> > > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > > +
> > > > > +	if (damage_area->y2 > overlap_damage_area->y2)
> > > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > > +}
> > > > > +
> > > > > +/* Update plane damage area if planes above moved or have
> > > > > alpha */
> > > > > +static void intel_psr2_pipe_dirty_areas_set(struct
> > > > > intel_plane_state *plane_state,
> > > > > +					    struct intel_plane
> > > > > *plane,
> > > > > +					    const struct
> > > > > drm_rect *pipe_dirty_areas,
> > > > > +					    struct drm_rect
> > > > > *plane_clip)
> > > > > +{
> > > > > +	enum plane_id i;
> > > > > +
> > > > > +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> > > > > +		int j;
> > > > > +
> > > > > +		for (j = 0; j < 2; j++) {
> > > > > +			struct drm_rect r = pipe_dirty_areas[i
> > > > > * 2 + j];
> > > > > +
> > > > > +			if (!drm_rect_width(&r))
> > > > > +				continue;
> > > > > +			if (!drm_rect_intersect(&r,
> > > > > &plane_state->uapi.dst))
> > > > > +				continue;
> > > > > +
> > > > > +			r.y1 -= plane_state->uapi.crtc_y;
> > > > > +			r.y2 -= plane_state->uapi.crtc_y;
> > > > > +			clip_update(plane_clip, &r);
> > > > > +		}
> > > > > +	}
> > > > > +}
> > > > > +
> > > > > +void intel_psr2_sel_fetch_update(struct intel_atomic_state
> > > > > *state,
> > > > > +				 struct intel_crtc *crtc)
> > > > > +{
> > > > > +	struct intel_crtc_state *crtc_state =
> > > > > intel_atomic_get_new_crtc_state(state, crtc);
> > > > > +	struct intel_plane_state *new_plane_state,
> > > > > *old_plane_state;
> > > > > +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] =
> > > > > {};
> > > > > +	struct drm_rect pipe_clip = { .y1 = -1 };
> > > > > +	struct intel_plane *plane;
> > > > > +	bool full_update = false;
> > > > > +	int i;
> > > > > +
> > > > > +	if (!crtc_state->enable_psr2_sel_fetch)
> > > > > +		return;
> > > > > +
> > > > > +	/*
> > > > > +	 * Load all the pipes areas where there is a plane with
> > > > > alpha or a plane
> > > > > +	 * that moved or plane that the visibility changed in
> > > > > those
> > > > > +	 * cases planes bellow it will need to be fetched in
> > > > > those intersection
> > > > > +	 * areas even if they are not damaged in those areas.
> > > > > +	 */
> > > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > > old_plane_state,
> > > > > +					     new_plane_state,
> > > > > i) {
> > > > > +		bool alpha, flip, dirty;
> > > > > +
> > > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > > > uapi.crtc)
> > > > > +			continue;
> > > > > +
> > > > > +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> > > > > +		alpha |= old_plane_state->uapi.alpha !=
> > > > > U16_MAX;
> > > > > +		flip = new_plane_state->uapi.fb !=
> > > > > old_plane_state->uapi.fb;
> > > > > +		dirty = alpha && flip;
> > > > > +		dirty |= !drm_rect_equals(&new_plane_state-
> > > > > > uapi.dst,
> > > > > +					  &old_plane_state-
> > > > > > uapi.dst);
> > > > > +		dirty |= new_plane_state->uapi.visible !=
> > > > > +			 old_plane_state->uapi.visible;
> > > > > +		if (!dirty)
> > > > > +			continue;
> > > > > +
> > > > > +		if (old_plane_state->uapi.visible)
> > > > > +			pipe_dirty_areas[plane->id * 2] =
> > > > > old_plane_state->uapi.dst;
> > > > > +		if (new_plane_state->uapi.visible)
> > > > > +			pipe_dirty_areas[plane->id * 2 + 1] =
> > > > > new_plane_state->uapi.dst;
> > > > > +	}
> > > > > +
> > > > > +	/*
> > > > > +	 * Iterate over all planes, compute the damaged clip
> > > > > area also including
> > > > > +	 * the pipe_dirty_areas, compute plane registers and
> > > > > update pipe damaged
> > > > > +	 * area
> > > > > +	 */
> > > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > > old_plane_state,
> > > > > +					     new_plane_state,
> > > > > i) {
> > > > > +		struct drm_rect plane_clip = { .y1 = -1 };
> > > > > +		struct drm_mode_rect *clips;
> > > > > +		u32 num_clips;
> > > > > +		int j;
> > > > > +
> > > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > > > uapi.crtc)
> > > > > +			continue;
> > > > > +
> > > > > +		/*
> > > > > +		 * TODO: Not clear how to handle planes with
> > > > > negative position,
> > > > > +		 * also planes are not updated if they have a
> > > > > negative X
> > > > > +		 * position so for now doing a full update in
> > > > > this cases
> > > > > +		 */
> > > > > +		if (new_plane_state->uapi.crtc_y < 0 ||
> > > > > +		    new_plane_state->uapi.crtc_x < 0) {
> > > > > +			full_update = true;
> > > > > +			break;
> > > > > +		}
> > > > > +
> > > > > +		intel_psr2_plane_sel_fetch_ctl_calc(plane,
> > > > > new_plane_state,
> > > > > +						    new_plane_s
> > > > > tate->uapi.visible);
> > > > > +		if (!new_plane_state->uapi.visible)
> > > > > +			continue;
> > > > > +
> > > > > +		clips =
> > > > > drm_plane_get_damage_clips(&new_plane_state->uapi);
> > > > > +		num_clips =
> > > > > drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> > > > > +
> > > > > +		/*
> > > > > +		 * If plane moved mark the whole plane area as
> > > > > damaged so it
> > > > > +		 * can be complete draw in the new position
> > > > > +		 */
> > > > > +		if (!drm_rect_equals(&new_plane_state-
> > > > > > uapi.dst,
> > > > > +				     &old_plane_state-
> > > > > > uapi.dst)) {
> > > > > +			num_clips = 0;
> > > > > +			plane_clip.y1 = new_plane_state-
> > > > > > uapi.src.y1 >> 16;
> > > > > +			plane_clip.y2 = new_plane_state-
> > > > > > uapi.src.y2 >> 16;
> > > > > +		} else if (!num_clips) {
> > > > > +			/*
> > > > > +			 * If plane don't have damage areas but
> > > > > the framebuffer
> > > > > +			 * changed mark the whole plane as
> > > > > damaged
> > > > > +			 */
> > > > > +			if (new_plane_state->uapi.fb ==
> > > > > old_plane_state->uapi.fb)
> > > > > +				continue;
> > > > > +
> > > > > +			plane_clip.y1 = new_plane_state-
> > > > > > uapi.src.y1 >> 16;
> > > > > +			plane_clip.y2 = new_plane_state-
> > > > > > uapi.src.y2 >> 16;
> > > > > +		}
> > > > > +
> > > > > +		for (j = 0; j < num_clips; j++) {
> > > > > +			struct drm_rect damage_area;
> > > > > +
> > > > > +			damage_area.x1 = clips[j].x1;
> > > > > +			damage_area.x2 = clips[j].x2;
> > > > > +			damage_area.y1 = clips[j].y1;
> > > > > +			damage_area.y2 = clips[j].y2;
> > > > > +			clip_update(&plane_clip, &damage_area);
> > > > > +		}
> > > > > +
> > > > > +		intel_psr2_pipe_dirty_areas_set(new_plane_state
> > > > > , plane,
> > > > > +						pipe_dirty_area
> > > > > s, &plane_clip);
> > > > > +		intel_psr2_plane_sel_fetch_calc(new_plane_state
> > > > > , &plane_clip);
> > > > > +
> > > > > +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> > > > > +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> > > > > +		clip_update(&pipe_clip, &plane_clip);
> > > > > +	}
> > > > 
> > > > This whole thing seems rather convoluted. Also using lots of uapi
> > > > state
> > > > in places where I don't expect to see any.
> > > 
> > > Not sure from where I should get this information then,
> > > intel_plane_state don't have it.
> > > 
> > > > I would suggest the correct way would be something like:
> > > > 1) for_each_plane_in_state()
> > > > 	hw.damage =
> > > > translate_to_some_hw_coord_space(union(uapi.damages))
> > > > 	or just use the full plane size if we have scaling i guess
> > > 
> > > 99% of the time the coordinates used are based on pipe coord space,
> > > only to calculate the plane overlapping damaged area is used plane
> > > coord space.
> > > 
> > > > 2) need to add all affected planes to the state and set the
> > > > appropriate
> > > >    bitmask, which may mean we want to track the planes' positions
> > > > in the
> > > >    crtc state. I think atm we only have it in the plane state
> > > 
> > > This looks a "or" to me, have all the planes added to the state
> > > when psr2 sel fetch is enabled or add track all the planes position
> > > in pipe.
> > 
> > *Affected* planes, not all planes. Hmm. I guess affected planes are
> > actually the ones whose selective fetch coordinates change. If they
> > don't change then no need to add them to the state. Plane updates are
> > rather expensive (lots of mmio) so I've generally tried to avoid
> > pointless plane updates.
> > 
> > But this whole thing might turn a bit annoying since we'd to keep
> > adding affected planes until the total selective fetch region stops
> > growing. I think that would probably want the two stage plane state
> > compuation. So just blindly adding all of them would probably be
> > simpler, albeit less efficient.
> > 
> > > Although the second one would avoid us to do plane calculations and
> > > plane register sometimes, in some cases where a plane above a non-
> > > modified plane
> > > moves the non-modified plane bellow will need to be added to the
> > > state so the plane sel_fetch registers are written.
> > > We could go with the easy one(add all planes to the state) and then
> > > move to the second one latter.
> > > 
> > > > 3) translate the damage further into the final plane src
> > > > coordinate
> > > >    space. Dunno if we have enough state around still to do it
> > > > cleanly.
> > > >    I was thinking maybe it could be done alongside all the other
> > > > plane
> > > >    surface calculations, but there might be a chicken vs. egg
> > > > situation
> > > >    here since we probably want to do the plane check stuff before
> > > > doing
> > > >    step 1, but plane check is also where we do the surface
> > > > calculations.
> > > >    Dunno if we may just want to split the plane check into two
> > > > stages
> > > 
> > > As right now it depends mostly in uapi this could be moved to the
> > > check phase, did not left there because this will never have a
> > > error or a conflict
> > > that will cause us to reject the state.
> > > 
> > > > To keep things simple I guess what I'd suggest is to forget about
> > > > the
> > > > damage stuff in the first version of the series and just do full
> > > > plane updates. That way we don't have to worry about so many
> > > > coordinate
> > > > space transformations.
> > > 
> > > Do that would only save us the for bellow and the if to check if
> > > plane moved:
> > > 
> > > for (j = 0; j < num_clips; j++) {
> > > 	struct drm_rect damage_area;
> > > 
> > > 	damage_area.x1 = clips[j].x1;
> > > 	damage_area.x2 = clips[j].x2;
> > > 	damage_area.y1 = clips[j].y1;
> > > 	damage_area.y2 = clips[j].y2;
> > > 	clip_update(&plane_clip, &damage_area);
> > > }
> > 
> > That's just some minor detail. The real issue is converting the
> > damage
> > between the various coordinate spaces we have for planes (original fb
> > relative src coordiantes, final SURF relative src coordinates,
> > crtc relative dst coordinates, and also the hw vs. uapi stuff affects
> > this stuff).
> > 
> For the most efficient power comsumption and usage of bandthwidth, we
> can use Selective Fetch of Plane and PSR2 Manual Tracking together.
> But PSR2 Manual Tracking can be enabled without Selective Fetch of
> Plane. (And pre GEN12 does not have a feature "Selective Fetch of
> Plane".)
> So can you split this commit to Selective Fetch and PSR2 Manual
> Tracking?

Pre GEN12 have selective fetch of plane, check BSpec: 33712 and 33711.
The programming sequences states that program plane selective fetch registers and PSR2 Manual tracking must be combined, otherwise HW don't know if
regular plane registers or selective fetch registers needs to be used.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-06-16 17:29           ` Souza, Jose
@ 2020-06-16 20:33             ` Mun, Gwan-gyeong
  2020-06-16 21:00               ` Souza, Jose
  0 siblings, 1 reply; 28+ messages in thread
From: Mun, Gwan-gyeong @ 2020-06-16 20:33 UTC (permalink / raw)
  To: ville.syrjala, Souza, Jose; +Cc: Pandiyan, Dhinakaran, intel-gfx

On Tue, 2020-06-16 at 10:29 -0700, Souza, Jose wrote:
> On Tue, 2020-06-16 at 16:16 +0100, Mun, Gwan-gyeong wrote:
> > On Mon, 2020-06-15 at 19:40 +0300, Ville Syrjälä wrote:
> > > On Fri, Jun 12, 2020 at 08:33:31PM +0000, Souza, Jose wrote:
> > > > On Fri, 2020-06-12 at 19:30 +0300, Ville Syrjälä wrote:
> > > > > On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de
> > > > > Souza
> > > > > wrote:
> > > > > > All GEN12 platforms supports PSR2 selective fetch but not
> > > > > > all
> > > > > > GEN12
> > > > > > platforms supports PSR2 hardware tracking(aka RKL).
> > > > > > 
> > > > > > This feature consists in software program registers with
> > > > > > the
> > > > > > damaged
> > > > > > area of each plane this way hardware will only fetch from
> > > > > > memory those
> > > > > > areas and sent the PSR2 selective update blocks to panel,
> > > > > > saving even
> > > > > > more power but to it actually happen userspace needs to
> > > > > > send
> > > > > > the
> > > > > > damaged areas otherwise it will still fetch the whole plane
> > > > > > as
> > > > > > fallback.
> > > > > > As today Gnome3 do not send damaged areas and the only
> > > > > > compositor that
> > > > > > I'm aware that sets the damaged areas is Weston.
> > > > > > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> > > > > > 
> > > > > > So here implementing page flip part, it is still completely
> > > > > > missing
> > > > > > frontbuffer modifications, that is why the
> > > > > > enable_psr2_sel_fetch
> > > > > > parameter was added.
> > > > > > 
> > > > > > The plan is to switch all GEN12 platforms to selective
> > > > > > fetch
> > > > > > when
> > > > > > ready, it will also depend in add some tests sending
> > > > > > damaged
> > > > > > areas.
> > > > > > I have a hacked version of kms_psr2_su with 3 planes that I
> > > > > > can
> > > > > > cleanup and send in a few days(99% of PSR2 selective fetch
> > > > > > changes was
> > > > > > done during my free time while bored during quarantine
> > > > > > rainy
> > > > > > days).
> > > > > > 
> > > > > > BSpec: 55229
> > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > Cc: Imre Deak <imre.deak@intel.com>
> > > > > > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > > > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > > > Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
> > > > > >  .../drm/i915/display/intel_display_debugfs.c  |   3 +
> > > > > >  .../drm/i915/display/intel_display_types.h    |  10 +
> > > > > >  drivers/gpu/drm/i915/display/intel_psr.c      | 329
> > > > > > +++++++++++++++++-
> > > > > >  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
> > > > > >  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
> > > > > >  drivers/gpu/drm/i915/i915_drv.h               |   2 +
> > > > > >  drivers/gpu/drm/i915/i915_params.c            |   5 +
> > > > > >  drivers/gpu/drm/i915/i915_params.h            |   1 +
> > > > > >  9 files changed, 352 insertions(+), 15 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > index b69878334040..984809208c29 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -11729,6 +11729,8 @@ static void
> > > > > > i9xx_update_cursor(struct
> > > > > > intel_plane *plane,
> > > > > >  	if (INTEL_GEN(dev_priv) >= 9)
> > > > > >  		skl_write_cursor_wm(plane, crtc_state);
> > > > > >  
> > > > > > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state,
> > > > > > plane_state);
> > > > > > +
> > > > > >  	if (plane->cursor.base != base ||
> > > > > >  	    plane->cursor.size != fbc_ctl ||
> > > > > >  	    plane->cursor.cntl != cntl) {
> > > > > > @@ -15115,6 +15117,8 @@ static void
> > > > > > commit_pipe_config(struct
> > > > > > intel_atomic_state *state,
> > > > > >  
> > > > > >  		if (new_crtc_state->update_pipe)
> > > > > >  			intel_pipe_fastset(old_crtc_state,
> > > > > > new_crtc_state);
> > > > > > +
> > > > > > +		intel_psr2_program_trans_man_trk_ctl(new_crtc_s
> > > > > > tate);
> > > > > >  	}
> > > > > >  
> > > > > >  	if (dev_priv->display.atomic_update_watermarks)
> > > > > > @@ -15156,6 +15160,7 @@ static void
> > > > > > intel_update_crtc(struct
> > > > > > intel_atomic_state *state,
> > > > > >  			intel_color_load_luts(new_crtc_state);
> > > > > >  
> > > > > >  		intel_pre_plane_update(state, crtc);
> > > > > > +		intel_psr2_sel_fetch_update(state, crtc);
> > > > > >  
> > > > > >  		if (new_crtc_state->update_pipe)
> > > > > >  			intel_encoders_update_pipe(state,
> > > > > > crtc);
> > > > > > diff --git
> > > > > > a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > index 70525623bcdf..0f600974462b 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct
> > > > > > seq_file *m, void *data)
> > > > > >  			su_blocks = su_blocks >>
> > > > > > PSR2_SU_STATUS_SHIFT(frame);
> > > > > >  			seq_printf(m, "%d\t%d\n", frame,
> > > > > > su_blocks);
> > > > > >  		}
> > > > > > +
> > > > > > +		seq_printf(m, "PSR2 selective fetch: %s\n",
> > > > > > +			   enableddisabled(psr-
> > > > > > > psr2_sel_fetch_enabled));
> > > > > >  	}
> > > > > >  
> > > > > >  unlock:
> > > > > > diff --git
> > > > > > a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > index 30b2767578dc..b77a512e5362 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > @@ -586,6 +586,13 @@ struct intel_plane_state {
> > > > > >  	u32 planar_slave;
> > > > > >  
> > > > > >  	struct drm_intel_sprite_colorkey ckey;
> > > > > > +
> > > > > > +	struct {
> > > > > > +		u32 ctl;
> > > > > > +		u32 pos;
> > > > > > +		u32 offset;
> > > > > > +		u32 size;
> > > > > > +	} psr2_sel_fetch;
> > > > > 
> > > > > Do we really need all that here? We don't store them for the
> > > > > normal
> > > > > plane updates either.
> > > > 
> > > > For ctl we do, anyways could be removed if we store overlapping
> > > > damage are in here so intel_psr2_program_plane_sel_fetch()
> > > > would
> > > > incorporate
> > > > intel_psr2_plane_sel_fetch_calc() code, both looks good to me.
> > > > 
> > > > > >  };
> > > > > >  
> > > > > >  struct intel_initial_plane_config {
> > > > > > @@ -931,6 +938,7 @@ struct intel_crtc_state {
> > > > > >  
> > > > > >  	bool has_psr;
> > > > > >  	bool has_psr2;
> > > > > > +	bool enable_psr2_sel_fetch;
> > > > > >  	u32 dc3co_exitline;
> > > > > >  
> > > > > >  	/*
> > > > > > @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
> > > > > >  
> > > > > >  	/* For DSB related info */
> > > > > >  	struct intel_dsb *dsb;
> > > > > > +
> > > > > > +	u32 psr2_sw_man_track_ctl;
> > > > > >  };
> > > > > >  
> > > > > >  enum intel_pipe_crc_source {
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > index 0c86e9e341a2..bc2a2e64fe2a 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct
> > > > > > intel_dp *intel_dp)
> > > > > >  	else
> > > > > >  		val |= EDP_PSR2_TP2_TIME_2500us;
> > > > > >  
> > > > > > +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> > > > > > +		intel_de_write(dev_priv,
> > > > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > > > > psr.transcoder),
> > > > > > +			       PSR2_MAN_TRK_CTL_ENABLE);
> > > > > > +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> > > > > > +		intel_de_write(dev_priv,
> > > > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > > > > psr.transcoder), 0);
> > > > > > +
> > > > > >  	/*
> > > > > >  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and
> > > > > > BSpec is
> > > > > >  	 * recommending keep this bit unset while PSR2 is
> > > > > > enabled.
> > > > > > @@ -628,6 +636,38 @@
> > > > > > tgl_dc3co_exitline_compute_config(struct
> > > > > > intel_dp *intel_dp,
> > > > > >  	crtc_state->dc3co_exitline = crtc_vdisplay -
> > > > > > exit_scanlines;
> > > > > >  }
> > > > > >  
> > > > > > +static bool intel_psr2_sel_fetch_config_valid(struct
> > > > > > intel_dp
> > > > > > *intel_dp,
> > > > > > +					      struct
> > > > > > intel_crtc_state *crtc_state)
> > > > > > +{
> > > > > > +	struct intel_atomic_state *state =
> > > > > > to_intel_atomic_state(crtc_state->uapi.state);
> > > > > > +	struct drm_i915_private *dev_priv =
> > > > > > dp_to_i915(intel_dp);
> > > > > > +	struct intel_plane_state *plane_state;
> > > > > > +	struct intel_plane *plane;
> > > > > > +	int i;
> > > > > > +
> > > > > > +	if (!i915_modparams.enable_psr2_sel_fetch) {
> > > > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > > > +			    "PSR2 sel fetch not enabled,
> > > > > > disabled by parameter\n");
> > > > > > +		return false;
> > > > > > +	}
> > > > > > +
> > > > > > +	if (crtc_state->uapi.async_flip) {
> > > > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > > > +			    "PSR2 sel fetch not enabled, async
> > > > > > flip enabled\n");
> > > > > > +		return false;
> > > > > > +	}
> > > > > 
> > > > > Not supported anyway.
> > > > > 
> > > > > > +
> > > > > > +	for_each_new_intel_plane_in_state(state, plane,
> > > > > > plane_state, i) {
> > > > > > +		if (plane_state->uapi.rotation !=
> > > > > > DRM_MODE_ROTATE_0) {
> > > > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > > > +				    "PSR2 sel fetch not
> > > > > > enabled, plane rotated\n");
> > > > > > +			return false;
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	return crtc_state->enable_psr2_sel_fetch = true;
> > > > > > +}
> > > > > > +
> > > > > >  static bool intel_psr2_config_valid(struct intel_dp
> > > > > > *intel_dp,
> > > > > >  				    struct intel_crtc_state
> > > > > > *crtc_state)
> > > > > >  {
> > > > > > @@ -697,22 +737,17 @@ static bool
> > > > > > intel_psr2_config_valid(struct intel_dp *intel_dp,
> > > > > >  		return false;
> > > > > >  	}
> > > > > >  
> > > > > > -	/*
> > > > > > -	 * Some platforms lack PSR2 HW tracking and instead
> > > > > > require manual
> > > > > > -	 * tracking by software.  In this case, the driver is
> > > > > > required to track
> > > > > > -	 * the areas that need updates and program hardware to
> > > > > > send selective
> > > > > > -	 * updates.
> > > > > > -	 *
> > > > > > -	 * So until the software tracking is implemented, PSR2
> > > > > > needs to be
> > > > > > -	 * disabled for platforms without PSR2 HW tracking.
> > > > > > -	 */
> > > > > > -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > > > -		drm_dbg_kms(&dev_priv->drm,
> > > > > > -			    "No PSR2 HW tracking in the
> > > > > > platform\n");
> > > > > > -		return false;
> > > > > > +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> > > > > > +		if
> > > > > > (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state)
> > > > > > &&
> > > > > > +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > > > +				    "PSR2 not enabled,
> > > > > > selective fetch not valid and no HW tracking available\n");
> > > > > > +			return false;
> > > > > > +		}
> > > > > >  	}
> > > > > >  
> > > > > > -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > > > psr_max_v) {
> > > > > > +	if (!crtc_state->enable_psr2_sel_fetch &&
> > > > > > +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > > > psr_max_v)) {
> > > > > >  		drm_dbg_kms(&dev_priv->drm,
> > > > > >  			    "PSR2 not enabled, resolution %dx%d
> > > > > > > max supported %dx%d\n",
> > > > > >  			    crtc_hdisplay, crtc_vdisplay,
> > > > > > @@ -863,6 +898,11 @@ static void
> > > > > > intel_psr_enable_source(struct
> > > > > > intel_dp *intel_dp,
> > > > > >  		val |= EXITLINE_ENABLE;
> > > > > >  		intel_de_write(dev_priv,
> > > > > > EXITLINE(cpu_transcoder), val);
> > > > > >  	}
> > > > > > +
> > > > > > +	if (HAS_PSR_HW_TRACKING(dev_priv))
> > > > > > +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> > > > > > IGNORE_PSR2_HW_TRACKING,
> > > > > > +			     dev_priv-
> > > > > > > psr.psr2_sel_fetch_enabled ?
> > > > > > +			     IGNORE_PSR2_HW_TRACKING : 0);
> > > > > >  }
> > > > > >  
> > > > > >  static void intel_psr_enable_locked(struct
> > > > > > drm_i915_private
> > > > > > *dev_priv,
> > > > > > @@ -884,7 +924,7 @@ static void
> > > > > > intel_psr_enable_locked(struct
> > > > > > drm_i915_private *dev_priv,
> > > > > >  	/* DC5/DC6 requires at least 6 idle frames */
> > > > > >  	val =
> > > > > > usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> > > > > >  	dev_priv->psr.dc3co_exit_delay = val;
> > > > > > -
> > > > > > +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state-
> > > > > > > enable_psr2_sel_fetch;
> > > > > >  	/*
> > > > > >  	 * If a PSR error happened and the driver is reloaded,
> > > > > > the EDP_PSR_IIR
> > > > > >  	 * will still keep the error set even after the reset
> > > > > > done in the
> > > > > > @@ -1080,6 +1120,265 @@ static void
> > > > > > psr_force_hw_tracking_exit(struct drm_i915_private
> > > > > > *dev_priv)
> > > > > >  		intel_psr_exit(dev_priv);
> > > > > >  }
> > > > > >  
> > > > > > +void intel_psr2_program_plane_sel_fetch(struct intel_plane
> > > > > > *plane,
> > > > > > +					const struct
> > > > > > intel_crtc_state *crtc_state,
> > > > > > +					const struct
> > > > > > intel_plane_state *plane_state)
> > > > > > +{
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(plane-
> > > > > > > base.dev);
> > > > > > +	enum pipe pipe = plane->pipe;
> > > > > > +
> > > > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > > > +	    !plane_state ||
> > > > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > > > +		return;
> > > > > > +
> > > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe,
> > > > > > plane->id),
> > > > > > +			  plane_state->psr2_sel_fetch.ctl);
> > > > > > +	if (!plane_state->psr2_sel_fetch.ctl || plane->id ==
> > > > > > PLANE_CURSOR)
> > > > > > +		return;
> > > > > > +
> > > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe,
> > > > > > plane->id),
> > > > > > +			  plane_state->psr2_sel_fetch.pos);
> > > > > > +	intel_de_write_fw(dev_priv,
> > > > > > PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> > > > > > +			  plane_state->psr2_sel_fetch.offset);
> > > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe,
> > > > > > plane->id),
> > > > > > +			  plane_state->psr2_sel_fetch.size);
> > > > > > +}
> > > > > > +
> > > > > > +void intel_psr2_program_trans_man_trk_ctl(const struct
> > > > > > intel_crtc_state *crtc_state)
> > > > > > +{
> > > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > > > uapi.crtc);
> > > > > > +	struct drm_i915_private *dev_priv = to_i915(crtc-
> > > > > > > base.dev);
> > > > > > +	struct i915_psr *psr = &dev_priv->psr;
> > > > > > +
> > > > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > > > +		return;
> > > > > > +
> > > > > > +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr-
> > > > > > > transcoder),
> > > > > > +		       crtc_state->psr2_sw_man_track_ctl);
> > > > > > +}
> > > > > > +
> > > > > > +static void intel_psr2_plane_sel_fetch_calc(struct
> > > > > > intel_plane_state *plane_state,
> > > > > > +					    struct drm_rect
> > > > > > *clip)
> > > > > > +{
> > > > > > +	int color_plane = plane_state->planar_linked_plane &&
> > > > > > !plane_state->planar_slave;
> > > > > > +	struct intel_plane *plane = to_intel_plane(plane_state-
> > > > > > > uapi.plane);
> > > > > > +	u32 val;
> > > > > > +
> > > > > > +	if (plane->id == PLANE_CURSOR)
> > > > > > +		return;
> > > > > > +
> > > > > > +	val = (plane_state->color_plane[color_plane].y + clip-
> > > > > > > y1) << 16;
> > > > > > +	val |= plane_state->color_plane[color_plane].x;
> > > > > > +	plane_state->psr2_sel_fetch.offset = val;
> > > > > > +
> > > > > > +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> > > > > > +	val |= plane_state->uapi.crtc_x;
> > > > > > +	plane_state->psr2_sel_fetch.pos = val;
> > > > > > +
> > > > > > +	/* Sizes are 0 based */
> > > > > > +	val = (clip->y2 - clip->y1 - 1) << 16;
> > > > > > +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) -
> > > > > > 1;
> > > > > > +	plane_state->psr2_sel_fetch.size = val;
> > > > > > +}
> > > > > > +
> > > > > > +static void intel_psr2_trans_man_trk_ctl_calc(struct
> > > > > > intel_crtc_state *crtc_state,
> > > > > > +					      struct drm_rect
> > > > > > *clip,
> > > > > > +					      bool full_update)
> > > > > > +{
> > > > > > +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> > > > > > +
> > > > > > +	if (full_update) {
> > > > > > +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> > > > > > +		goto exit;
> > > > > > +	}
> > > > > > +
> > > > > > +	if (clip->y1 == -1)
> > > > > > +		goto exit;
> > > > > > +
> > > > > > +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> > > > > > +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4
> > > > > > + 1);
> > > > > > +	val |=
> > > > > > PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4)
> > > > > > +
> > > > > > 1);
> > > > > > +exit:
> > > > > > +	crtc_state->psr2_sw_man_track_ctl = val;
> > > > > > +}
> > > > > > +
> > > > > > +static void intel_psr2_plane_sel_fetch_ctl_calc(struct
> > > > > > intel_plane *plane,
> > > > > > +						struct
> > > > > > intel_plane_state *plane_state,
> > > > > > +						bool enable)
> > > > > > +{
> > > > > > +	if (!enable)
> > > > > > +		plane_state->psr2_sel_fetch.ctl = 0;
> > > > > > +	else if (plane->id == PLANE_CURSOR)
> > > > > > +		plane_state->psr2_sel_fetch.ctl = plane-
> > > > > > > cursor.cntl;
> > > > > > +	else
> > > > > > +		plane_state->psr2_sel_fetch.ctl = plane_state-
> > > > > > > ctl;
> > > > > > +}
> > > > > > +
> > > > > > +static void clip_update(struct drm_rect
> > > > > > *overlap_damage_area,
> > > > > > +			struct drm_rect *damage_area)
> > > > > > +{
> > > > > > +	if (overlap_damage_area->y1 == -1) {
> > > > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > > > +		return;
> > > > > > +	}
> > > > > > +
> > > > > > +	if (damage_area->y1 < overlap_damage_area->y1)
> > > > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > > > +
> > > > > > +	if (damage_area->y2 > overlap_damage_area->y2)
> > > > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > > > +}
> > > > > > +
> > > > > > +/* Update plane damage area if planes above moved or have
> > > > > > alpha */
> > > > > > +static void intel_psr2_pipe_dirty_areas_set(struct
> > > > > > intel_plane_state *plane_state,
> > > > > > +					    struct intel_plane
> > > > > > *plane,
> > > > > > +					    const struct
> > > > > > drm_rect *pipe_dirty_areas,
> > > > > > +					    struct drm_rect
> > > > > > *plane_clip)
> > > > > > +{
> > > > > > +	enum plane_id i;
> > > > > > +
> > > > > > +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> > > > > > +		int j;
> > > > > > +
> > > > > > +		for (j = 0; j < 2; j++) {
> > > > > > +			struct drm_rect r = pipe_dirty_areas[i
> > > > > > * 2 + j];
> > > > > > +
> > > > > > +			if (!drm_rect_width(&r))
> > > > > > +				continue;
> > > > > > +			if (!drm_rect_intersect(&r,
> > > > > > &plane_state->uapi.dst))
> > > > > > +				continue;
> > > > > > +
> > > > > > +			r.y1 -= plane_state->uapi.crtc_y;
> > > > > > +			r.y2 -= plane_state->uapi.crtc_y;
> > > > > > +			clip_update(plane_clip, &r);
> > > > > > +		}
> > > > > > +	}
> > > > > > +}
> > > > > > +
> > > > > > +void intel_psr2_sel_fetch_update(struct intel_atomic_state
> > > > > > *state,
> > > > > > +				 struct intel_crtc *crtc)
> > > > > > +{
> > > > > > +	struct intel_crtc_state *crtc_state =
> > > > > > intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > +	struct intel_plane_state *new_plane_state,
> > > > > > *old_plane_state;
> > > > > > +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] =
> > > > > > {};
> > > > > > +	struct drm_rect pipe_clip = { .y1 = -1 };
> > > > > > +	struct intel_plane *plane;
> > > > > > +	bool full_update = false;
> > > > > > +	int i;
> > > > > > +
> > > > > > +	if (!crtc_state->enable_psr2_sel_fetch)
> > > > > > +		return;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * Load all the pipes areas where there is a plane with
> > > > > > alpha or a plane
> > > > > > +	 * that moved or plane that the visibility changed in
> > > > > > those
> > > > > > +	 * cases planes bellow it will need to be fetched in
> > > > > > those intersection
> > > > > > +	 * areas even if they are not damaged in those areas.
> > > > > > +	 */
> > > > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > > > old_plane_state,
> > > > > > +					     new_plane_state,
> > > > > > i) {
> > > > > > +		bool alpha, flip, dirty;
> > > > > > +
> > > > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > > > > uapi.crtc)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> > > > > > +		alpha |= old_plane_state->uapi.alpha !=
> > > > > > U16_MAX;
> > > > > > +		flip = new_plane_state->uapi.fb !=
> > > > > > old_plane_state->uapi.fb;
> > > > > > +		dirty = alpha && flip;
> > > > > > +		dirty |= !drm_rect_equals(&new_plane_state-
> > > > > > > uapi.dst,
> > > > > > +					  &old_plane_state-
> > > > > > > uapi.dst);
> > > > > > +		dirty |= new_plane_state->uapi.visible !=
> > > > > > +			 old_plane_state->uapi.visible;
> > > > > > +		if (!dirty)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		if (old_plane_state->uapi.visible)
> > > > > > +			pipe_dirty_areas[plane->id * 2] =
> > > > > > old_plane_state->uapi.dst;
> > > > > > +		if (new_plane_state->uapi.visible)
> > > > > > +			pipe_dirty_areas[plane->id * 2 + 1] =
> > > > > > new_plane_state->uapi.dst;
> > > > > > +	}
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * Iterate over all planes, compute the damaged clip
> > > > > > area also including
> > > > > > +	 * the pipe_dirty_areas, compute plane registers and
> > > > > > update pipe damaged
> > > > > > +	 * area
> > > > > > +	 */
> > > > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > > > old_plane_state,
> > > > > > +					     new_plane_state,
> > > > > > i) {
> > > > > > +		struct drm_rect plane_clip = { .y1 = -1 };
> > > > > > +		struct drm_mode_rect *clips;
> > > > > > +		u32 num_clips;
> > > > > > +		int j;
> > > > > > +
> > > > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > > > > uapi.crtc)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		/*
> > > > > > +		 * TODO: Not clear how to handle planes with
> > > > > > negative position,
> > > > > > +		 * also planes are not updated if they have a
> > > > > > negative X
> > > > > > +		 * position so for now doing a full update in
> > > > > > this cases
> > > > > > +		 */
> > > > > > +		if (new_plane_state->uapi.crtc_y < 0 ||
> > > > > > +		    new_plane_state->uapi.crtc_x < 0) {
> > > > > > +			full_update = true;
> > > > > > +			break;
> > > > > > +		}
> > > > > > +
> > > > > > +		intel_psr2_plane_sel_fetch_ctl_calc(plane,
> > > > > > new_plane_state,
> > > > > > +						    new_plane_s
> > > > > > tate->uapi.visible);
> > > > > > +		if (!new_plane_state->uapi.visible)
> > > > > > +			continue;
> > > > > > +
> > > > > > +		clips =
> > > > > > drm_plane_get_damage_clips(&new_plane_state->uapi);
> > > > > > +		num_clips =
> > > > > > drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> > > > > > +
> > > > > > +		/*
> > > > > > +		 * If plane moved mark the whole plane area as
> > > > > > damaged so it
> > > > > > +		 * can be complete draw in the new position
> > > > > > +		 */
> > > > > > +		if (!drm_rect_equals(&new_plane_state-
> > > > > > > uapi.dst,
> > > > > > +				     &old_plane_state-
> > > > > > > uapi.dst)) {
> > > > > > +			num_clips = 0;
> > > > > > +			plane_clip.y1 = new_plane_state-
> > > > > > > uapi.src.y1 >> 16;
> > > > > > +			plane_clip.y2 = new_plane_state-
> > > > > > > uapi.src.y2 >> 16;
> > > > > > +		} else if (!num_clips) {
> > > > > > +			/*
> > > > > > +			 * If plane don't have damage areas but
> > > > > > the framebuffer
> > > > > > +			 * changed mark the whole plane as
> > > > > > damaged
> > > > > > +			 */
> > > > > > +			if (new_plane_state->uapi.fb ==
> > > > > > old_plane_state->uapi.fb)
> > > > > > +				continue;
> > > > > > +
> > > > > > +			plane_clip.y1 = new_plane_state-
> > > > > > > uapi.src.y1 >> 16;
> > > > > > +			plane_clip.y2 = new_plane_state-
> > > > > > > uapi.src.y2 >> 16;
> > > > > > +		}
> > > > > > +
> > > > > > +		for (j = 0; j < num_clips; j++) {
> > > > > > +			struct drm_rect damage_area;
> > > > > > +
> > > > > > +			damage_area.x1 = clips[j].x1;
> > > > > > +			damage_area.x2 = clips[j].x2;
> > > > > > +			damage_area.y1 = clips[j].y1;
> > > > > > +			damage_area.y2 = clips[j].y2;
> > > > > > +			clip_update(&plane_clip, &damage_area);
> > > > > > +		}
> > > > > > +
> > > > > > +		intel_psr2_pipe_dirty_areas_set(new_plane_state
> > > > > > , plane,
> > > > > > +						pipe_dirty_area
> > > > > > s, &plane_clip);
> > > > > > +		intel_psr2_plane_sel_fetch_calc(new_plane_state
> > > > > > , &plane_clip);
> > > > > > +
> > > > > > +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> > > > > > +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> > > > > > +		clip_update(&pipe_clip, &plane_clip);
> > > > > > +	}
> > > > > 
> > > > > This whole thing seems rather convoluted. Also using lots of
> > > > > uapi
> > > > > state
> > > > > in places where I don't expect to see any.
> > > > 
> > > > Not sure from where I should get this information then,
> > > > intel_plane_state don't have it.
> > > > 
> > > > > I would suggest the correct way would be something like:
> > > > > 1) for_each_plane_in_state()
> > > > > 	hw.damage =
> > > > > translate_to_some_hw_coord_space(union(uapi.damages))
> > > > > 	or just use the full plane size if we have scaling i
> > > > > guess
> > > > 
> > > > 99% of the time the coordinates used are based on pipe coord
> > > > space,
> > > > only to calculate the plane overlapping damaged area is used
> > > > plane
> > > > coord space.
> > > > 
> > > > > 2) need to add all affected planes to the state and set the
> > > > > appropriate
> > > > >    bitmask, which may mean we want to track the planes'
> > > > > positions
> > > > > in the
> > > > >    crtc state. I think atm we only have it in the plane state
> > > > 
> > > > This looks a "or" to me, have all the planes added to the state
> > > > when psr2 sel fetch is enabled or add track all the planes
> > > > position
> > > > in pipe.
> > > 
> > > *Affected* planes, not all planes. Hmm. I guess affected planes
> > > are
> > > actually the ones whose selective fetch coordinates change. If
> > > they
> > > don't change then no need to add them to the state. Plane updates
> > > are
> > > rather expensive (lots of mmio) so I've generally tried to avoid
> > > pointless plane updates.
> > > 
> > > But this whole thing might turn a bit annoying since we'd to keep
> > > adding affected planes until the total selective fetch region
> > > stops
> > > growing. I think that would probably want the two stage plane
> > > state
> > > compuation. So just blindly adding all of them would probably be
> > > simpler, albeit less efficient.
> > > 
> > > > Although the second one would avoid us to do plane calculations
> > > > and
> > > > plane register sometimes, in some cases where a plane above a
> > > > non-
> > > > modified plane
> > > > moves the non-modified plane bellow will need to be added to
> > > > the
> > > > state so the plane sel_fetch registers are written.
> > > > We could go with the easy one(add all planes to the state) and
> > > > then
> > > > move to the second one latter.
> > > > 
> > > > > 3) translate the damage further into the final plane src
> > > > > coordinate
> > > > >    space. Dunno if we have enough state around still to do it
> > > > > cleanly.
> > > > >    I was thinking maybe it could be done alongside all the
> > > > > other
> > > > > plane
> > > > >    surface calculations, but there might be a chicken vs. egg
> > > > > situation
> > > > >    here since we probably want to do the plane check stuff
> > > > > before
> > > > > doing
> > > > >    step 1, but plane check is also where we do the surface
> > > > > calculations.
> > > > >    Dunno if we may just want to split the plane check into
> > > > > two
> > > > > stages
> > > > 
> > > > As right now it depends mostly in uapi this could be moved to
> > > > the
> > > > check phase, did not left there because this will never have a
> > > > error or a conflict
> > > > that will cause us to reject the state.
> > > > 
> > > > > To keep things simple I guess what I'd suggest is to forget
> > > > > about
> > > > > the
> > > > > damage stuff in the first version of the series and just do
> > > > > full
> > > > > plane updates. That way we don't have to worry about so many
> > > > > coordinate
> > > > > space transformations.
> > > > 
> > > > Do that would only save us the for bellow and the if to check
> > > > if
> > > > plane moved:
> > > > 
> > > > for (j = 0; j < num_clips; j++) {
> > > > 	struct drm_rect damage_area;
> > > > 
> > > > 	damage_area.x1 = clips[j].x1;
> > > > 	damage_area.x2 = clips[j].x2;
> > > > 	damage_area.y1 = clips[j].y1;
> > > > 	damage_area.y2 = clips[j].y2;
> > > > 	clip_update(&plane_clip, &damage_area);
> > > > }
> > > 
> > > That's just some minor detail. The real issue is converting the
> > > damage
> > > between the various coordinate spaces we have for planes
> > > (original fb
> > > relative src coordiantes, final SURF relative src coordinates,
> > > crtc relative dst coordinates, and also the hw vs. uapi stuff
> > > affects
> > > this stuff).
> > > 
> > For the most efficient power comsumption and usage of bandthwidth,
> > we
> > can use Selective Fetch of Plane and PSR2 Manual Tracking together.
> > But PSR2 Manual Tracking can be enabled without Selective Fetch of
> > Plane. (And pre GEN12 does not have a feature "Selective Fetch of
> > Plane".)
> > So can you split this commit to Selective Fetch and PSR2 Manual
> > Tracking?
> 
> Pre GEN12 have selective fetch of plane, check BSpec: 33712 and
> 33711.
> The programming sequences states that program plane selective fetch
> registers and PSR2 Manual tracking must be combined, otherwise HW
> don't know if
> regular plane registers or selective fetch registers needs to be
> used.
Hi,
(Such as SKL and ICL LP platforms, they don't have a feature of
Selective Fetch Plane, therefore when PSR2_MAN_TRK is used, regular
plane registers will be used on that platforms. - but PreGEN12 is not
scope of this series.)
GEN12 (such as  TGL LP )platform has "BitField: SF Partial Frame
Enable" on Register_PSR2_MAN_TRK_CTL. 
The desciptions says "This field enables the planes to use the
SEL_FETCH registers for selective fetch on selective update frames.".
IMHO, this bit can be used to select a plane register (regular or
selective fetch) for PSR2_MAN_TRK.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch
  2020-06-16 20:33             ` Mun, Gwan-gyeong
@ 2020-06-16 21:00               ` Souza, Jose
  0 siblings, 0 replies; 28+ messages in thread
From: Souza, Jose @ 2020-06-16 21:00 UTC (permalink / raw)
  To: ville.syrjala, Mun, Gwan-gyeong; +Cc: Pandiyan, Dhinakaran, intel-gfx

On Tue, 2020-06-16 at 21:33 +0100, Mun, Gwan-gyeong wrote:
> On Tue, 2020-06-16 at 10:29 -0700, Souza, Jose wrote:
> > On Tue, 2020-06-16 at 16:16 +0100, Mun, Gwan-gyeong wrote:
> > > On Mon, 2020-06-15 at 19:40 +0300, Ville Syrjälä wrote:
> > > > On Fri, Jun 12, 2020 at 08:33:31PM +0000, Souza, Jose wrote:
> > > > > On Fri, 2020-06-12 at 19:30 +0300, Ville Syrjälä wrote:
> > > > > > On Tue, May 26, 2020 at 03:14:46PM -0700, José Roberto de
> > > > > > Souza
> > > > > > wrote:
> > > > > > > All GEN12 platforms supports PSR2 selective fetch but not
> > > > > > > all
> > > > > > > GEN12
> > > > > > > platforms supports PSR2 hardware tracking(aka RKL).
> > > > > > > 
> > > > > > > This feature consists in software program registers with
> > > > > > > the
> > > > > > > damaged
> > > > > > > area of each plane this way hardware will only fetch from
> > > > > > > memory those
> > > > > > > areas and sent the PSR2 selective update blocks to panel,
> > > > > > > saving even
> > > > > > > more power but to it actually happen userspace needs to
> > > > > > > send
> > > > > > > the
> > > > > > > damaged areas otherwise it will still fetch the whole plane
> > > > > > > as
> > > > > > > fallback.
> > > > > > > As today Gnome3 do not send damaged areas and the only
> > > > > > > compositor that
> > > > > > > I'm aware that sets the damaged areas is Weston.
> > > > > > > https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/17
> > > > > > > 
> > > > > > > So here implementing page flip part, it is still completely
> > > > > > > missing
> > > > > > > frontbuffer modifications, that is why the
> > > > > > > enable_psr2_sel_fetch
> > > > > > > parameter was added.
> > > > > > > 
> > > > > > > The plan is to switch all GEN12 platforms to selective
> > > > > > > fetch
> > > > > > > when
> > > > > > > ready, it will also depend in add some tests sending
> > > > > > > damaged
> > > > > > > areas.
> > > > > > > I have a hacked version of kms_psr2_su with 3 planes that I
> > > > > > > can
> > > > > > > cleanup and send in a few days(99% of PSR2 selective fetch
> > > > > > > changes was
> > > > > > > done during my free time while bored during quarantine
> > > > > > > rainy
> > > > > > > days).
> > > > > > > 
> > > > > > > BSpec: 55229
> > > > > > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > > > Cc: Imre Deak <imre.deak@intel.com>
> > > > > > > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
> > > > > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > > > > Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  |   5 +
> > > > > > >  .../drm/i915/display/intel_display_debugfs.c  |   3 +
> > > > > > >  .../drm/i915/display/intel_display_types.h    |  10 +
> > > > > > >  drivers/gpu/drm/i915/display/intel_psr.c      | 329
> > > > > > > +++++++++++++++++-
> > > > > > >  drivers/gpu/drm/i915/display/intel_psr.h      |  10 +
> > > > > > >  drivers/gpu/drm/i915/display/intel_sprite.c   |   2 +
> > > > > > >  drivers/gpu/drm/i915/i915_drv.h               |   2 +
> > > > > > >  drivers/gpu/drm/i915/i915_params.c            |   5 +
> > > > > > >  drivers/gpu/drm/i915/i915_params.h            |   1 +
> > > > > > >  9 files changed, 352 insertions(+), 15 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > index b69878334040..984809208c29 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > @@ -11729,6 +11729,8 @@ static void
> > > > > > > i9xx_update_cursor(struct
> > > > > > > intel_plane *plane,
> > > > > > >  	if (INTEL_GEN(dev_priv) >= 9)
> > > > > > >  		skl_write_cursor_wm(plane, crtc_state);
> > > > > > >  
> > > > > > > +	intel_psr2_program_plane_sel_fetch(plane, crtc_state,
> > > > > > > plane_state);
> > > > > > > +
> > > > > > >  	if (plane->cursor.base != base ||
> > > > > > >  	    plane->cursor.size != fbc_ctl ||
> > > > > > >  	    plane->cursor.cntl != cntl) {
> > > > > > > @@ -15115,6 +15117,8 @@ static void
> > > > > > > commit_pipe_config(struct
> > > > > > > intel_atomic_state *state,
> > > > > > >  
> > > > > > >  		if (new_crtc_state->update_pipe)
> > > > > > >  			intel_pipe_fastset(old_crtc_state,
> > > > > > > new_crtc_state);
> > > > > > > +
> > > > > > > +		intel_psr2_program_trans_man_trk_ctl(new_crtc_s
> > > > > > > tate);
> > > > > > >  	}
> > > > > > >  
> > > > > > >  	if (dev_priv->display.atomic_update_watermarks)
> > > > > > > @@ -15156,6 +15160,7 @@ static void
> > > > > > > intel_update_crtc(struct
> > > > > > > intel_atomic_state *state,
> > > > > > >  			intel_color_load_luts(new_crtc_state);
> > > > > > >  
> > > > > > >  		intel_pre_plane_update(state, crtc);
> > > > > > > +		intel_psr2_sel_fetch_update(state, crtc);
> > > > > > >  
> > > > > > >  		if (new_crtc_state->update_pipe)
> > > > > > >  			intel_encoders_update_pipe(state,
> > > > > > > crtc);
> > > > > > > diff --git
> > > > > > > a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > > index 70525623bcdf..0f600974462b 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > > > > > @@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct
> > > > > > > seq_file *m, void *data)
> > > > > > >  			su_blocks = su_blocks >>
> > > > > > > PSR2_SU_STATUS_SHIFT(frame);
> > > > > > >  			seq_printf(m, "%d\t%d\n", frame,
> > > > > > > su_blocks);
> > > > > > >  		}
> > > > > > > +
> > > > > > > +		seq_printf(m, "PSR2 selective fetch: %s\n",
> > > > > > > +			   enableddisabled(psr-
> > > > > > > > psr2_sel_fetch_enabled));
> > > > > > >  	}
> > > > > > >  
> > > > > > >  unlock:
> > > > > > > diff --git
> > > > > > > a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > index 30b2767578dc..b77a512e5362 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > @@ -586,6 +586,13 @@ struct intel_plane_state {
> > > > > > >  	u32 planar_slave;
> > > > > > >  
> > > > > > >  	struct drm_intel_sprite_colorkey ckey;
> > > > > > > +
> > > > > > > +	struct {
> > > > > > > +		u32 ctl;
> > > > > > > +		u32 pos;
> > > > > > > +		u32 offset;
> > > > > > > +		u32 size;
> > > > > > > +	} psr2_sel_fetch;
> > > > > > 
> > > > > > Do we really need all that here? We don't store them for the
> > > > > > normal
> > > > > > plane updates either.
> > > > > 
> > > > > For ctl we do, anyways could be removed if we store overlapping
> > > > > damage are in here so intel_psr2_program_plane_sel_fetch()
> > > > > would
> > > > > incorporate
> > > > > intel_psr2_plane_sel_fetch_calc() code, both looks good to me.
> > > > > 
> > > > > > >  };
> > > > > > >  
> > > > > > >  struct intel_initial_plane_config {
> > > > > > > @@ -931,6 +938,7 @@ struct intel_crtc_state {
> > > > > > >  
> > > > > > >  	bool has_psr;
> > > > > > >  	bool has_psr2;
> > > > > > > +	bool enable_psr2_sel_fetch;
> > > > > > >  	u32 dc3co_exitline;
> > > > > > >  
> > > > > > >  	/*
> > > > > > > @@ -1070,6 +1078,8 @@ struct intel_crtc_state {
> > > > > > >  
> > > > > > >  	/* For DSB related info */
> > > > > > >  	struct intel_dsb *dsb;
> > > > > > > +
> > > > > > > +	u32 psr2_sw_man_track_ctl;
> > > > > > >  };
> > > > > > >  
> > > > > > >  enum intel_pipe_crc_source {
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > > index 0c86e9e341a2..bc2a2e64fe2a 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > > > @@ -518,6 +518,14 @@ static void hsw_activate_psr2(struct
> > > > > > > intel_dp *intel_dp)
> > > > > > >  	else
> > > > > > >  		val |= EDP_PSR2_TP2_TIME_2500us;
> > > > > > >  
> > > > > > > +	if (dev_priv->psr.psr2_sel_fetch_enabled)
> > > > > > > +		intel_de_write(dev_priv,
> > > > > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > > > > > psr.transcoder),
> > > > > > > +			       PSR2_MAN_TRK_CTL_ENABLE);
> > > > > > > +	else if (HAS_PSR2_SEL_FETCH(dev_priv))
> > > > > > > +		intel_de_write(dev_priv,
> > > > > > > +			       PSR2_MAN_TRK_CTL(dev_priv-
> > > > > > > > psr.transcoder), 0);
> > > > > > > +
> > > > > > >  	/*
> > > > > > >  	 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and
> > > > > > > BSpec is
> > > > > > >  	 * recommending keep this bit unset while PSR2 is
> > > > > > > enabled.
> > > > > > > @@ -628,6 +636,38 @@
> > > > > > > tgl_dc3co_exitline_compute_config(struct
> > > > > > > intel_dp *intel_dp,
> > > > > > >  	crtc_state->dc3co_exitline = crtc_vdisplay -
> > > > > > > exit_scanlines;
> > > > > > >  }
> > > > > > >  
> > > > > > > +static bool intel_psr2_sel_fetch_config_valid(struct
> > > > > > > intel_dp
> > > > > > > *intel_dp,
> > > > > > > +					      struct
> > > > > > > intel_crtc_state *crtc_state)
> > > > > > > +{
> > > > > > > +	struct intel_atomic_state *state =
> > > > > > > to_intel_atomic_state(crtc_state->uapi.state);
> > > > > > > +	struct drm_i915_private *dev_priv =
> > > > > > > dp_to_i915(intel_dp);
> > > > > > > +	struct intel_plane_state *plane_state;
> > > > > > > +	struct intel_plane *plane;
> > > > > > > +	int i;
> > > > > > > +
> > > > > > > +	if (!i915_modparams.enable_psr2_sel_fetch) {
> > > > > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > > > > +			    "PSR2 sel fetch not enabled,
> > > > > > > disabled by parameter\n");
> > > > > > > +		return false;
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	if (crtc_state->uapi.async_flip) {
> > > > > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > > > > +			    "PSR2 sel fetch not enabled, async
> > > > > > > flip enabled\n");
> > > > > > > +		return false;
> > > > > > > +	}
> > > > > > 
> > > > > > Not supported anyway.
> > > > > > 
> > > > > > > +
> > > > > > > +	for_each_new_intel_plane_in_state(state, plane,
> > > > > > > plane_state, i) {
> > > > > > > +		if (plane_state->uapi.rotation !=
> > > > > > > DRM_MODE_ROTATE_0) {
> > > > > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > > > > +				    "PSR2 sel fetch not
> > > > > > > enabled, plane rotated\n");
> > > > > > > +			return false;
> > > > > > > +		}
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	return crtc_state->enable_psr2_sel_fetch = true;
> > > > > > > +}
> > > > > > > +
> > > > > > >  static bool intel_psr2_config_valid(struct intel_dp
> > > > > > > *intel_dp,
> > > > > > >  				    struct intel_crtc_state
> > > > > > > *crtc_state)
> > > > > > >  {
> > > > > > > @@ -697,22 +737,17 @@ static bool
> > > > > > > intel_psr2_config_valid(struct intel_dp *intel_dp,
> > > > > > >  		return false;
> > > > > > >  	}
> > > > > > >  
> > > > > > > -	/*
> > > > > > > -	 * Some platforms lack PSR2 HW tracking and instead
> > > > > > > require manual
> > > > > > > -	 * tracking by software.  In this case, the driver is
> > > > > > > required to track
> > > > > > > -	 * the areas that need updates and program hardware to
> > > > > > > send selective
> > > > > > > -	 * updates.
> > > > > > > -	 *
> > > > > > > -	 * So until the software tracking is implemented, PSR2
> > > > > > > needs to be
> > > > > > > -	 * disabled for platforms without PSR2 HW tracking.
> > > > > > > -	 */
> > > > > > > -	if (!HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > > > > -		drm_dbg_kms(&dev_priv->drm,
> > > > > > > -			    "No PSR2 HW tracking in the
> > > > > > > platform\n");
> > > > > > > -		return false;
> > > > > > > +	if (HAS_PSR2_SEL_FETCH(dev_priv)) {
> > > > > > > +		if
> > > > > > > (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state)
> > > > > > > &&
> > > > > > > +		    !HAS_PSR_HW_TRACKING(dev_priv)) {
> > > > > > > +			drm_dbg_kms(&dev_priv->drm,
> > > > > > > +				    "PSR2 not enabled,
> > > > > > > selective fetch not valid and no HW tracking available\n");
> > > > > > > +			return false;
> > > > > > > +		}
> > > > > > >  	}
> > > > > > >  
> > > > > > > -	if (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > > > > psr_max_v) {
> > > > > > > +	if (!crtc_state->enable_psr2_sel_fetch &&
> > > > > > > +	    (crtc_hdisplay > psr_max_h || crtc_vdisplay >
> > > > > > > psr_max_v)) {
> > > > > > >  		drm_dbg_kms(&dev_priv->drm,
> > > > > > >  			    "PSR2 not enabled, resolution %dx%d
> > > > > > > > max supported %dx%d\n",
> > > > > > >  			    crtc_hdisplay, crtc_vdisplay,
> > > > > > > @@ -863,6 +898,11 @@ static void
> > > > > > > intel_psr_enable_source(struct
> > > > > > > intel_dp *intel_dp,
> > > > > > >  		val |= EXITLINE_ENABLE;
> > > > > > >  		intel_de_write(dev_priv,
> > > > > > > EXITLINE(cpu_transcoder), val);
> > > > > > >  	}
> > > > > > > +
> > > > > > > +	if (HAS_PSR_HW_TRACKING(dev_priv))
> > > > > > > +		intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
> > > > > > > IGNORE_PSR2_HW_TRACKING,
> > > > > > > +			     dev_priv-
> > > > > > > > psr.psr2_sel_fetch_enabled ?
> > > > > > > +			     IGNORE_PSR2_HW_TRACKING : 0);
> > > > > > >  }
> > > > > > >  
> > > > > > >  static void intel_psr_enable_locked(struct
> > > > > > > drm_i915_private
> > > > > > > *dev_priv,
> > > > > > > @@ -884,7 +924,7 @@ static void
> > > > > > > intel_psr_enable_locked(struct
> > > > > > > drm_i915_private *dev_priv,
> > > > > > >  	/* DC5/DC6 requires at least 6 idle frames */
> > > > > > >  	val =
> > > > > > > usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
> > > > > > >  	dev_priv->psr.dc3co_exit_delay = val;
> > > > > > > -
> > > > > > > +	dev_priv->psr.psr2_sel_fetch_enabled = crtc_state-
> > > > > > > > enable_psr2_sel_fetch;
> > > > > > >  	/*
> > > > > > >  	 * If a PSR error happened and the driver is reloaded,
> > > > > > > the EDP_PSR_IIR
> > > > > > >  	 * will still keep the error set even after the reset
> > > > > > > done in the
> > > > > > > @@ -1080,6 +1120,265 @@ static void
> > > > > > > psr_force_hw_tracking_exit(struct drm_i915_private
> > > > > > > *dev_priv)
> > > > > > >  		intel_psr_exit(dev_priv);
> > > > > > >  }
> > > > > > >  
> > > > > > > +void intel_psr2_program_plane_sel_fetch(struct intel_plane
> > > > > > > *plane,
> > > > > > > +					const struct
> > > > > > > intel_crtc_state *crtc_state,
> > > > > > > +					const struct
> > > > > > > intel_plane_state *plane_state)
> > > > > > > +{
> > > > > > > +	struct drm_i915_private *dev_priv = to_i915(plane-
> > > > > > > > base.dev);
> > > > > > > +	enum pipe pipe = plane->pipe;
> > > > > > > +
> > > > > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > > > > +	    !plane_state ||
> > > > > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > > > > +		return;
> > > > > > > +
> > > > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe,
> > > > > > > plane->id),
> > > > > > > +			  plane_state->psr2_sel_fetch.ctl);
> > > > > > > +	if (!plane_state->psr2_sel_fetch.ctl || plane->id ==
> > > > > > > PLANE_CURSOR)
> > > > > > > +		return;
> > > > > > > +
> > > > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe,
> > > > > > > plane->id),
> > > > > > > +			  plane_state->psr2_sel_fetch.pos);
> > > > > > > +	intel_de_write_fw(dev_priv,
> > > > > > > PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
> > > > > > > +			  plane_state->psr2_sel_fetch.offset);
> > > > > > > +	intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe,
> > > > > > > plane->id),
> > > > > > > +			  plane_state->psr2_sel_fetch.size);
> > > > > > > +}
> > > > > > > +
> > > > > > > +void intel_psr2_program_trans_man_trk_ctl(const struct
> > > > > > > intel_crtc_state *crtc_state)
> > > > > > > +{
> > > > > > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state-
> > > > > > > > uapi.crtc);
> > > > > > > +	struct drm_i915_private *dev_priv = to_i915(crtc-
> > > > > > > > base.dev);
> > > > > > > +	struct i915_psr *psr = &dev_priv->psr;
> > > > > > > +
> > > > > > > +	if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
> > > > > > > +	    !crtc_state->enable_psr2_sel_fetch)
> > > > > > > +		return;
> > > > > > > +
> > > > > > > +	intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr-
> > > > > > > > transcoder),
> > > > > > > +		       crtc_state->psr2_sw_man_track_ctl);
> > > > > > > +}
> > > > > > > +
> > > > > > > +static void intel_psr2_plane_sel_fetch_calc(struct
> > > > > > > intel_plane_state *plane_state,
> > > > > > > +					    struct drm_rect
> > > > > > > *clip)
> > > > > > > +{
> > > > > > > +	int color_plane = plane_state->planar_linked_plane &&
> > > > > > > !plane_state->planar_slave;
> > > > > > > +	struct intel_plane *plane = to_intel_plane(plane_state-
> > > > > > > > uapi.plane);
> > > > > > > +	u32 val;
> > > > > > > +
> > > > > > > +	if (plane->id == PLANE_CURSOR)
> > > > > > > +		return;
> > > > > > > +
> > > > > > > +	val = (plane_state->color_plane[color_plane].y + clip-
> > > > > > > > y1) << 16;
> > > > > > > +	val |= plane_state->color_plane[color_plane].x;
> > > > > > > +	plane_state->psr2_sel_fetch.offset = val;
> > > > > > > +
> > > > > > > +	val = (clip->y1 + plane_state->uapi.crtc_y) << 16;
> > > > > > > +	val |= plane_state->uapi.crtc_x;
> > > > > > > +	plane_state->psr2_sel_fetch.pos = val;
> > > > > > > +
> > > > > > > +	/* Sizes are 0 based */
> > > > > > > +	val = (clip->y2 - clip->y1 - 1) << 16;
> > > > > > > +	val |= (drm_rect_width(&plane_state->uapi.src) >> 16) -
> > > > > > > 1;
> > > > > > > +	plane_state->psr2_sel_fetch.size = val;
> > > > > > > +}
> > > > > > > +
> > > > > > > +static void intel_psr2_trans_man_trk_ctl_calc(struct
> > > > > > > intel_crtc_state *crtc_state,
> > > > > > > +					      struct drm_rect
> > > > > > > *clip,
> > > > > > > +					      bool full_update)
> > > > > > > +{
> > > > > > > +	u32 val = PSR2_MAN_TRK_CTL_ENABLE;
> > > > > > > +
> > > > > > > +	if (full_update) {
> > > > > > > +		val |= PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME;
> > > > > > > +		goto exit;
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	if (clip->y1 == -1)
> > > > > > > +		goto exit;
> > > > > > > +
> > > > > > > +	val |= PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE;
> > > > > > > +	val |= PSR2_MAN_TRK_CTL_REGION_START_ADDR(clip->y1 / 4
> > > > > > > + 1);
> > > > > > > +	val |=
> > > > > > > PSR2_MAN_TRK_CTL_REGION_END_ADDR(DIV_ROUND_UP(clip->y2, 4)
> > > > > > > +
> > > > > > > 1);
> > > > > > > +exit:
> > > > > > > +	crtc_state->psr2_sw_man_track_ctl = val;
> > > > > > > +}
> > > > > > > +
> > > > > > > +static void intel_psr2_plane_sel_fetch_ctl_calc(struct
> > > > > > > intel_plane *plane,
> > > > > > > +						struct
> > > > > > > intel_plane_state *plane_state,
> > > > > > > +						bool enable)
> > > > > > > +{
> > > > > > > +	if (!enable)
> > > > > > > +		plane_state->psr2_sel_fetch.ctl = 0;
> > > > > > > +	else if (plane->id == PLANE_CURSOR)
> > > > > > > +		plane_state->psr2_sel_fetch.ctl = plane-
> > > > > > > > cursor.cntl;
> > > > > > > +	else
> > > > > > > +		plane_state->psr2_sel_fetch.ctl = plane_state-
> > > > > > > > ctl;
> > > > > > > +}
> > > > > > > +
> > > > > > > +static void clip_update(struct drm_rect
> > > > > > > *overlap_damage_area,
> > > > > > > +			struct drm_rect *damage_area)
> > > > > > > +{
> > > > > > > +	if (overlap_damage_area->y1 == -1) {
> > > > > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > > > > +		return;
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	if (damage_area->y1 < overlap_damage_area->y1)
> > > > > > > +		overlap_damage_area->y1 = damage_area->y1;
> > > > > > > +
> > > > > > > +	if (damage_area->y2 > overlap_damage_area->y2)
> > > > > > > +		overlap_damage_area->y2 = damage_area->y2;
> > > > > > > +}
> > > > > > > +
> > > > > > > +/* Update plane damage area if planes above moved or have
> > > > > > > alpha */
> > > > > > > +static void intel_psr2_pipe_dirty_areas_set(struct
> > > > > > > intel_plane_state *plane_state,
> > > > > > > +					    struct intel_plane
> > > > > > > *plane,
> > > > > > > +					    const struct
> > > > > > > drm_rect *pipe_dirty_areas,
> > > > > > > +					    struct drm_rect
> > > > > > > *plane_clip)
> > > > > > > +{
> > > > > > > +	enum plane_id i;
> > > > > > > +
> > > > > > > +	for (i = PLANE_CURSOR; i > plane->id; i--) {
> > > > > > > +		int j;
> > > > > > > +
> > > > > > > +		for (j = 0; j < 2; j++) {
> > > > > > > +			struct drm_rect r = pipe_dirty_areas[i
> > > > > > > * 2 + j];
> > > > > > > +
> > > > > > > +			if (!drm_rect_width(&r))
> > > > > > > +				continue;
> > > > > > > +			if (!drm_rect_intersect(&r,
> > > > > > > &plane_state->uapi.dst))
> > > > > > > +				continue;
> > > > > > > +
> > > > > > > +			r.y1 -= plane_state->uapi.crtc_y;
> > > > > > > +			r.y2 -= plane_state->uapi.crtc_y;
> > > > > > > +			clip_update(plane_clip, &r);
> > > > > > > +		}
> > > > > > > +	}
> > > > > > > +}
> > > > > > > +
> > > > > > > +void intel_psr2_sel_fetch_update(struct intel_atomic_state
> > > > > > > *state,
> > > > > > > +				 struct intel_crtc *crtc)
> > > > > > > +{
> > > > > > > +	struct intel_crtc_state *crtc_state =
> > > > > > > intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > > +	struct intel_plane_state *new_plane_state,
> > > > > > > *old_plane_state;
> > > > > > > +	struct drm_rect pipe_dirty_areas[I915_MAX_PLANES * 2] =
> > > > > > > {};
> > > > > > > +	struct drm_rect pipe_clip = { .y1 = -1 };
> > > > > > > +	struct intel_plane *plane;
> > > > > > > +	bool full_update = false;
> > > > > > > +	int i;
> > > > > > > +
> > > > > > > +	if (!crtc_state->enable_psr2_sel_fetch)
> > > > > > > +		return;
> > > > > > > +
> > > > > > > +	/*
> > > > > > > +	 * Load all the pipes areas where there is a plane with
> > > > > > > alpha or a plane
> > > > > > > +	 * that moved or plane that the visibility changed in
> > > > > > > those
> > > > > > > +	 * cases planes bellow it will need to be fetched in
> > > > > > > those intersection
> > > > > > > +	 * areas even if they are not damaged in those areas.
> > > > > > > +	 */
> > > > > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > > > > old_plane_state,
> > > > > > > +					     new_plane_state,
> > > > > > > i) {
> > > > > > > +		bool alpha, flip, dirty;
> > > > > > > +
> > > > > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > > > > > uapi.crtc)
> > > > > > > +			continue;
> > > > > > > +
> > > > > > > +		alpha = new_plane_state->uapi.alpha != U16_MAX;
> > > > > > > +		alpha |= old_plane_state->uapi.alpha !=
> > > > > > > U16_MAX;
> > > > > > > +		flip = new_plane_state->uapi.fb !=
> > > > > > > old_plane_state->uapi.fb;
> > > > > > > +		dirty = alpha && flip;
> > > > > > > +		dirty |= !drm_rect_equals(&new_plane_state-
> > > > > > > > uapi.dst,
> > > > > > > +					  &old_plane_state-
> > > > > > > > uapi.dst);
> > > > > > > +		dirty |= new_plane_state->uapi.visible !=
> > > > > > > +			 old_plane_state->uapi.visible;
> > > > > > > +		if (!dirty)
> > > > > > > +			continue;
> > > > > > > +
> > > > > > > +		if (old_plane_state->uapi.visible)
> > > > > > > +			pipe_dirty_areas[plane->id * 2] =
> > > > > > > old_plane_state->uapi.dst;
> > > > > > > +		if (new_plane_state->uapi.visible)
> > > > > > > +			pipe_dirty_areas[plane->id * 2 + 1] =
> > > > > > > new_plane_state->uapi.dst;
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	/*
> > > > > > > +	 * Iterate over all planes, compute the damaged clip
> > > > > > > area also including
> > > > > > > +	 * the pipe_dirty_areas, compute plane registers and
> > > > > > > update pipe damaged
> > > > > > > +	 * area
> > > > > > > +	 */
> > > > > > > +	for_each_oldnew_intel_plane_in_state(state, plane,
> > > > > > > old_plane_state,
> > > > > > > +					     new_plane_state,
> > > > > > > i) {
> > > > > > > +		struct drm_rect plane_clip = { .y1 = -1 };
> > > > > > > +		struct drm_mode_rect *clips;
> > > > > > > +		u32 num_clips;
> > > > > > > +		int j;
> > > > > > > +
> > > > > > > +		if (new_plane_state->uapi.crtc != crtc_state-
> > > > > > > > uapi.crtc)
> > > > > > > +			continue;
> > > > > > > +
> > > > > > > +		/*
> > > > > > > +		 * TODO: Not clear how to handle planes with
> > > > > > > negative position,
> > > > > > > +		 * also planes are not updated if they have a
> > > > > > > negative X
> > > > > > > +		 * position so for now doing a full update in
> > > > > > > this cases
> > > > > > > +		 */
> > > > > > > +		if (new_plane_state->uapi.crtc_y < 0 ||
> > > > > > > +		    new_plane_state->uapi.crtc_x < 0) {
> > > > > > > +			full_update = true;
> > > > > > > +			break;
> > > > > > > +		}
> > > > > > > +
> > > > > > > +		intel_psr2_plane_sel_fetch_ctl_calc(plane,
> > > > > > > new_plane_state,
> > > > > > > +						    new_plane_s
> > > > > > > tate->uapi.visible);
> > > > > > > +		if (!new_plane_state->uapi.visible)
> > > > > > > +			continue;
> > > > > > > +
> > > > > > > +		clips =
> > > > > > > drm_plane_get_damage_clips(&new_plane_state->uapi);
> > > > > > > +		num_clips =
> > > > > > > drm_plane_get_damage_clips_count(&new_plane_state->uapi);
> > > > > > > +
> > > > > > > +		/*
> > > > > > > +		 * If plane moved mark the whole plane area as
> > > > > > > damaged so it
> > > > > > > +		 * can be complete draw in the new position
> > > > > > > +		 */
> > > > > > > +		if (!drm_rect_equals(&new_plane_state-
> > > > > > > > uapi.dst,
> > > > > > > +				     &old_plane_state-
> > > > > > > > uapi.dst)) {
> > > > > > > +			num_clips = 0;
> > > > > > > +			plane_clip.y1 = new_plane_state-
> > > > > > > > uapi.src.y1 >> 16;
> > > > > > > +			plane_clip.y2 = new_plane_state-
> > > > > > > > uapi.src.y2 >> 16;
> > > > > > > +		} else if (!num_clips) {
> > > > > > > +			/*
> > > > > > > +			 * If plane don't have damage areas but
> > > > > > > the framebuffer
> > > > > > > +			 * changed mark the whole plane as
> > > > > > > damaged
> > > > > > > +			 */
> > > > > > > +			if (new_plane_state->uapi.fb ==
> > > > > > > old_plane_state->uapi.fb)
> > > > > > > +				continue;
> > > > > > > +
> > > > > > > +			plane_clip.y1 = new_plane_state-
> > > > > > > > uapi.src.y1 >> 16;
> > > > > > > +			plane_clip.y2 = new_plane_state-
> > > > > > > > uapi.src.y2 >> 16;
> > > > > > > +		}
> > > > > > > +
> > > > > > > +		for (j = 0; j < num_clips; j++) {
> > > > > > > +			struct drm_rect damage_area;
> > > > > > > +
> > > > > > > +			damage_area.x1 = clips[j].x1;
> > > > > > > +			damage_area.x2 = clips[j].x2;
> > > > > > > +			damage_area.y1 = clips[j].y1;
> > > > > > > +			damage_area.y2 = clips[j].y2;
> > > > > > > +			clip_update(&plane_clip, &damage_area);
> > > > > > > +		}
> > > > > > > +
> > > > > > > +		intel_psr2_pipe_dirty_areas_set(new_plane_state
> > > > > > > , plane,
> > > > > > > +						pipe_dirty_area
> > > > > > > s, &plane_clip);
> > > > > > > +		intel_psr2_plane_sel_fetch_calc(new_plane_state
> > > > > > > , &plane_clip);
> > > > > > > +
> > > > > > > +		plane_clip.y1 += new_plane_state->uapi.crtc_y;
> > > > > > > +		plane_clip.y2 += new_plane_state->uapi.crtc_y;
> > > > > > > +		clip_update(&pipe_clip, &plane_clip);
> > > > > > > +	}
> > > > > > 
> > > > > > This whole thing seems rather convoluted. Also using lots of
> > > > > > uapi
> > > > > > state
> > > > > > in places where I don't expect to see any.
> > > > > 
> > > > > Not sure from where I should get this information then,
> > > > > intel_plane_state don't have it.
> > > > > 
> > > > > > I would suggest the correct way would be something like:
> > > > > > 1) for_each_plane_in_state()
> > > > > > 	hw.damage =
> > > > > > translate_to_some_hw_coord_space(union(uapi.damages))
> > > > > > 	or just use the full plane size if we have scaling i
> > > > > > guess
> > > > > 
> > > > > 99% of the time the coordinates used are based on pipe coord
> > > > > space,
> > > > > only to calculate the plane overlapping damaged area is used
> > > > > plane
> > > > > coord space.
> > > > > 
> > > > > > 2) need to add all affected planes to the state and set the
> > > > > > appropriate
> > > > > >    bitmask, which may mean we want to track the planes'
> > > > > > positions
> > > > > > in the
> > > > > >    crtc state. I think atm we only have it in the plane state
> > > > > 
> > > > > This looks a "or" to me, have all the planes added to the state
> > > > > when psr2 sel fetch is enabled or add track all the planes
> > > > > position
> > > > > in pipe.
> > > > 
> > > > *Affected* planes, not all planes. Hmm. I guess affected planes
> > > > are
> > > > actually the ones whose selective fetch coordinates change. If
> > > > they
> > > > don't change then no need to add them to the state. Plane updates
> > > > are
> > > > rather expensive (lots of mmio) so I've generally tried to avoid
> > > > pointless plane updates.
> > > > 
> > > > But this whole thing might turn a bit annoying since we'd to keep
> > > > adding affected planes until the total selective fetch region
> > > > stops
> > > > growing. I think that would probably want the two stage plane
> > > > state
> > > > compuation. So just blindly adding all of them would probably be
> > > > simpler, albeit less efficient.
> > > > 
> > > > > Although the second one would avoid us to do plane calculations
> > > > > and
> > > > > plane register sometimes, in some cases where a plane above a
> > > > > non-
> > > > > modified plane
> > > > > moves the non-modified plane bellow will need to be added to
> > > > > the
> > > > > state so the plane sel_fetch registers are written.
> > > > > We could go with the easy one(add all planes to the state) and
> > > > > then
> > > > > move to the second one latter.
> > > > > 
> > > > > > 3) translate the damage further into the final plane src
> > > > > > coordinate
> > > > > >    space. Dunno if we have enough state around still to do it
> > > > > > cleanly.
> > > > > >    I was thinking maybe it could be done alongside all the
> > > > > > other
> > > > > > plane
> > > > > >    surface calculations, but there might be a chicken vs. egg
> > > > > > situation
> > > > > >    here since we probably want to do the plane check stuff
> > > > > > before
> > > > > > doing
> > > > > >    step 1, but plane check is also where we do the surface
> > > > > > calculations.
> > > > > >    Dunno if we may just want to split the plane check into
> > > > > > two
> > > > > > stages
> > > > > 
> > > > > As right now it depends mostly in uapi this could be moved to
> > > > > the
> > > > > check phase, did not left there because this will never have a
> > > > > error or a conflict
> > > > > that will cause us to reject the state.
> > > > > 
> > > > > > To keep things simple I guess what I'd suggest is to forget
> > > > > > about
> > > > > > the
> > > > > > damage stuff in the first version of the series and just do
> > > > > > full
> > > > > > plane updates. That way we don't have to worry about so many
> > > > > > coordinate
> > > > > > space transformations.
> > > > > 
> > > > > Do that would only save us the for bellow and the if to check
> > > > > if
> > > > > plane moved:
> > > > > 
> > > > > for (j = 0; j < num_clips; j++) {
> > > > > 	struct drm_rect damage_area;
> > > > > 
> > > > > 	damage_area.x1 = clips[j].x1;
> > > > > 	damage_area.x2 = clips[j].x2;
> > > > > 	damage_area.y1 = clips[j].y1;
> > > > > 	damage_area.y2 = clips[j].y2;
> > > > > 	clip_update(&plane_clip, &damage_area);
> > > > > }
> > > > 
> > > > That's just some minor detail. The real issue is converting the
> > > > damage
> > > > between the various coordinate spaces we have for planes
> > > > (original fb
> > > > relative src coordiantes, final SURF relative src coordinates,
> > > > crtc relative dst coordinates, and also the hw vs. uapi stuff
> > > > affects
> > > > this stuff).
> > > > 
> > > For the most efficient power comsumption and usage of bandthwidth,
> > > we
> > > can use Selective Fetch of Plane and PSR2 Manual Tracking together.
> > > But PSR2 Manual Tracking can be enabled without Selective Fetch of
> > > Plane. (And pre GEN12 does not have a feature "Selective Fetch of
> > > Plane".)
> > > So can you split this commit to Selective Fetch and PSR2 Manual
> > > Tracking?
> > 
> > Pre GEN12 have selective fetch of plane, check BSpec: 33712 and
> > 33711.
> > The programming sequences states that program plane selective fetch
> > registers and PSR2 Manual tracking must be combined, otherwise HW
> > don't know if
> > regular plane registers or selective fetch registers needs to be
> > used.
> Hi,
> (Such as SKL and ICL LP platforms, they don't have a feature of
> Selective Fetch Plane, therefore when PSR2_MAN_TRK is used, regular
> plane registers will be used on that platforms. - but PreGEN12 is not
> scope of this series.)
> GEN12 (such as  TGL LP )platform has "BitField: SF Partial Frame
> Enable" on Register_PSR2_MAN_TRK_CTL. 
> The desciptions says "This field enables the planes to use the
> SEL_FETCH registers for selective fetch on selective update frames.".
> IMHO, this bit can be used to select a plane register (regular or
> selective fetch) for PSR2_MAN_TRK.

Will only focus in GEN12 in my comments.
One of the following must be set to have the panel refreshed: "SF Partial Frame Enable", "SF Continuous full frame" and "SF Continuous full frame".
Have a patch that only sets "SF Continuous full frame" or "SF Continuous full frame" would be very simple but then almost complete overwritten for the
one using "SF Partial Frame Enable" and like you said the power savings and bandwidth would be at the same level as PSR1, not sure how useful it is.
Anyways will check if useful when sending a new version of first 4 patches with comments addressed separated.

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers
  2020-06-15 19:23           ` Souza, Jose
@ 2020-06-25 21:41             ` Souza, Jose
  0 siblings, 0 replies; 28+ messages in thread
From: Souza, Jose @ 2020-06-25 21:41 UTC (permalink / raw)
  To: Mun, Gwan-gyeong, intel-gfx

On Mon, 2020-06-15 at 19:23 +0000, Souza, Jose wrote:
> On Mon, 2020-06-15 at 19:37 +0100, Mun, Gwan-gyeong wrote:
> > On Fri, 2020-06-12 at 21:49 +0000, Mun, Gwan-gyeong wrote:
> > > On Fri, 2020-06-12 at 14:18 -0700, Souza, Jose wrote:
> > > > On Fri, 2020-06-12 at 21:57 +0100, Mun, Gwan-gyeong wrote:
> > > > > On Tue, 2020-05-26 at 15:14 -0700, José Roberto de Souza wrote:
> > > > > > This registers will be used to implement PSR2 software
> > > > > > tracking.
> > > > > > 
> > > > > > BSpec: 55229
> > > > > > BSpec: 50424
> > > > > > BSpec: 50420
> > > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/i915_reg.h | 68
> > > > > > ++++++++++++++++++++++++++++++-
> > > > > > --
> > > > > >  1 file changed, 63 insertions(+), 5 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > > > > > b/drivers/gpu/drm/i915/i915_reg.h
> > > > > > index e9d50fe0f375..6f547e459d30 100644
> > > > > > --- a/drivers/gpu/drm/i915/i915_reg.h
> > > > > > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > > > > > @@ -4566,6 +4566,18 @@ enum {
> > > > > >  #define PSR2_SU_STATUS_MASK(frame)	(0x3ff <<
> > > > > > PSR2_SU_STATUS_SHIFT(frame))
> > > > > >  #define PSR2_SU_STATUS_FRAMES		8
> > > > > >  
> > > > > > +#define _PSR2_MAN_TRK_CTL_A				0x60910
> > > > > > +#define _PSR2_MAN_TRK_CTL_EDP				0x6f910
> > > > > > +#define PSR2_MAN_TRK_CTL(tran)				_MMIO_T
> > > > > > RANS2(tran, _PSR2_MAN_TRK_CTL_A)
> > > > > > +#define  PSR2_MAN_TRK_CTL_ENABLE			REG_BIT
> > > > > > (31)
> > > > > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK	REG_GEN
> > > > > > MASK(30,
> > > > > > 21)
> > > > > > +#define  PSR2_MAN_TRK_CTL_REGION_START_ADDR(val)	REG_FIE
> > > > > > LD_PREP(
> > > > > > PSR2_MAN_TRK_CTL_REGION_START_ADDR_MASK, val)
> > > > > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK		REG_GEN
> > > > > > MASK(20, 11)
> > > > > > +#define  PSR2_MAN_TRK_CTL_REGION_END_ADDR(val)		REG_FIE
> > > > > > LD_PREP(PSR2_MAN_TRK_CTL_REGION_END_ADDR_MASK, val)
> > > > > > +#define  PSR2_MAN_TRK_CTL_SINGLE_FULL_FRAME		REG_BIT
> > > > > > (3)
> > > > > > +#define  PSR2_MAN_TRK_CTL_CONTINUOS_FULL_FRAME		REG_BIT
> > > > > > (2)
> > > > > > +#define  PSR2_MAN_TRK_CTL_PARTIAL_FRAME_UPDATE		REG_BIT
> > > > > > (1)
> > > > > > +
> > > > > As per Bspec, it would be better that the names of bit as below.
> > > > > 
> > > > > PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME
> > > > > PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME
> > > > > PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_ENABLE
> > > > 
> > > > No problem in naming like this but MAN_TRK and SF is kind of
> > > > redundant and the name was already big.
> > > > Your call.
> > > > 
> > > > > >  /* VGA port control */
> > > > > >  #define ADPA			_MMIO(0x61100)
> > > > > >  #define PCH_ADPA                _MMIO(0xe1100)
> > > > > > @@ -7129,7 +7141,52 @@ enum {
> > > > > >  #define PLANE_COLOR_CTL(pipe, plane)	\
> > > > > >  	_MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe),
> > > > > > _PLANE_COLOR_CTL_2(pipe))
> > > > > >  
> > > > > > -#/* SKL new cursor registers */
> > > > > > +#define _PLANE_SEL_FETCH_BASE_1_A		0x70890
> > > > > > +#define _PLANE_SEL_FETCH_BASE_2_A		0x708B0
> > > > > > +#define _PLANE_SEL_FETCH_BASE_3_A		0x708D0
> > > > > > +#define _PLANE_SEL_FETCH_BASE_4_A		0x708F0
> > > > > > +#define _PLANE_SEL_FETCH_BASE_5_A		0x70920
> > > > > > +#define _PLANE_SEL_FETCH_BASE_6_A		0x70940
> > > > > > +#define _PLANE_SEL_FETCH_BASE_7_A		0x70960
> > > > > > +#define _PLANE_SEL_FETCH_BASE_CUR_A		0x70880
> > > > > > +#define _PLANE_SEL_FETCH_BASE_1_B		0x70990
> > > > > > +
> > > > > And as per Bspec, the prefix _SEL_FETCH_PLANE_ is better than
> > > > > _PLANE_SEL_FETCH_ .
> > > > You mean just for the "internal" ones? For PLANE_SEL_FETCH_CTL,
> > > > PLANE_SEL_FETCH_SIZE... would be better keep like this to match
> > > > other
> > > > plane register
> > > > names.
> > > Internals and externals. I also noticed your intention (match other
> > > plane related registers), but when I checked other plane related
> > > resiters, they followed bspec names. (But I am not confident on
> > > register naming policy; we always have to follow documented register
> > > names or not. )

I don't think we are that restrict as there is several registers that don't match.
Will update the internal ones, anyone searching by BSpec name will find the internal ones and reach the exported ones.


> > > > > > +#define _PLANE_SEL_FETCH_BASE_A(plane) _PICK(plane, \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_1_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_2_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_3_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_4_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_5_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_6_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_7_A,
> > > > > > \
> > > > > > +					     _PLANE_SEL_FETCH_B
> > > > > > ASE_CUR_
> > > > > > A)
> > > > > > +#define _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe,
> > > > > > _PLANE_SEL_FETCH_BASE_1_A, _PLANE_SEL_FETCH_BASE_1_A)
> > 
> > It seems that indicates an wrong register name.
> > IMHO, is it your intention like this? " #define
> > _PLANE_SEL_FETCH_BASE_1(pipe) _PIPE(pipe, _PLANE_SEL_FETCH_BASE_1_A,
> > _PLANE_SEL_FETCH_BASE_1_B) "?
> 
> Yes, it should be _PLANE_SEL_FETCH_BASE_1_B, thanks for catching this.
> Will send this 4 patches in a few days with the requested fixes.
> 
> > > > > > +#define PLANE_SEL_FETCH_BASE(pipe, plane)
> > > > > > (_PLANE_SEL_FETCH_BASE_1(pipe) - \
> > > > > > +					   _PLANE_SEL_FETCH_BAS
> > > > > > E_1_A +
> > > > > > \
> > > > > > +					   _PLANE_SEL_FETCH_BAS
> > > > > > E_A(plan
> > > > > > e))
> > > > > > +
> > > > > > +#define _PLANE_SEL_FETCH_CTL_1_A		0x70890
> > > > > > +#define PLANE_SEL_FETCH_CTL(pipe, plane)
> > > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > > +					       _PLANE_SEL_FETCH
> > > > > > _CTL_1_A
> > > > > > - \
> > > > > > +					       _PLANE_SEL_FETCH
> > > > > > _BASE_1_
> > > > > > A)
> > > > > > +#define PLANE_SET_FETCH_CTL_ENABLE		REG_BIT(31)
> > > > > > +
> > > > > > +#define _PLANE_SEL_FETCH_POS_1_A		0x70894
> > > > > > +#define PLANE_SEL_FETCH_POS(pipe, plane)
> > > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > > +					       _PLANE_SEL_FETCH
> > > > > > _POS_1_A
> > > > > > - \
> > > > > > +					       _PLANE_SEL_FETCH
> > > > > > _BASE_1_
> > > > > > A)
> > > > > > +
> > > > > > +#define _PLANE_SEL_FETCH_SIZE_1_A		0x70898
> > > > > > +#define PLANE_SEL_FETCH_SIZE(pipe, plane)
> > > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > > +						_PLANE_SEL_FETC
> > > > > > H_SIZE_1
> > > > > > _A - \
> > > > > > +						_PLANE_SEL_FETC
> > > > > > H_BASE_1
> > > > > > _A)
> > > > > > +
> > > > > > +#define _PLANE_SEL_FETCH_OFFSET_1_A		0x7089C
> > > > > > +#define PLANE_SEL_FETCH_OFFSET(pipe, plane)
> > > > > > _MMIO(PLANE_SEL_FETCH_BASE(pipe, plane) + \
> > > > > > +						  _PLANE_SEL_FE
> > > > > > TCH_OFFS
> > > > > > ET_1_A - \
> > > > > > +						  _PLANE_SEL_FE
> > > > > > TCH_BASE
> > > > > > _1_A)
> > > > > > +
> > > > > > +/* SKL new cursor registers */
> > > > > >  #define _CUR_BUF_CFG_A				0x7017c
> > > > > >  #define _CUR_BUF_CFG_B				0x7117c
> > > > > >  #define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe,
> > > > > > _CUR_BUF_CFG_A,
> > > > > > _CUR_BUF_CFG_B)
> > > > > > @@ -7775,11 +7832,12 @@ enum {
> > > > > >  # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
> > > > > >  # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 <<
> > > > > > 2)
> > > > > >  
> > > > > > -#define CHICKEN_PAR1_1		_MMIO(0x42080)
> > > > > > +#define CHICKEN_PAR1_1			_MMIO(0x42080)
> > > > > >  #define  SKL_DE_COMPRESSED_HASH_MODE	(1 << 15)
> > > > > > -#define  DPA_MASK_VBLANK_SRD	(1 << 15)
> > > > > > -#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
> > > > > > -#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
> > > > > > +#define  DPA_MASK_VBLANK_SRD		(1 << 15)
> > > > > > +#define  FORCE_ARB_IDLE_PLANES		(1 << 14)
> > > > > > +#define  SKL_EDP_PSR_FIX_RDWRAP		(1 << 3)
> > > > > > +#define  IGNORE_PSR2_HW_TRACKING	(1 << 1)
> > > > > >  
> > > > > >  #define CHICKEN_PAR2_1		_MMIO(0x42090)
> > > > > >  #define  KVM_CONFIG_CHANGE_NOTIFICATION_SELECT	(1 << 14)
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2020-06-25 21:41 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-26 22:14 [Intel-gfx] [PATCH 1/6] drm/i915/rkl: Disable PSR2 José Roberto de Souza
2020-05-26 22:14 ` [Intel-gfx] [PATCH 2/6] drm/i915: Add plane damage clips property José Roberto de Souza
2020-06-12 15:15   ` Mun, Gwan-gyeong
2020-06-12 15:25   ` Ville Syrjälä
2020-06-12 15:30     ` Souza, Jose
2020-06-12 15:37       ` Ville Syrjälä
2020-06-12 15:42         ` Souza, Jose
2020-05-26 22:14 ` [Intel-gfx] [PATCH 3/6] drm/i915: Reorder intel_psr2_config_valid() José Roberto de Souza
2020-06-12 15:42   ` Mun, Gwan-gyeong
2020-05-26 22:14 ` [Intel-gfx] [PATCH 4/6] drm/i915: Add PSR2 software tracking registers José Roberto de Souza
2020-06-12 20:57   ` Mun, Gwan-gyeong
2020-06-12 21:18     ` Souza, Jose
2020-06-12 21:49       ` Mun, Gwan-gyeong
2020-06-15 18:37         ` Mun, Gwan-gyeong
2020-06-15 19:23           ` Souza, Jose
2020-06-25 21:41             ` Souza, Jose
2020-05-26 22:14 ` [Intel-gfx] [PATCH 5/6] drm/i915: Implement PSR2 selective fetch José Roberto de Souza
2020-06-12 16:30   ` Ville Syrjälä
2020-06-12 20:33     ` Souza, Jose
2020-06-15 16:40       ` Ville Syrjälä
2020-06-16 15:16         ` Mun, Gwan-gyeong
2020-06-16 17:29           ` Souza, Jose
2020-06-16 20:33             ` Mun, Gwan-gyeong
2020-06-16 21:00               ` Souza, Jose
2020-05-26 22:14 ` [Intel-gfx] [PATCH 6/6] drm/i915: Implement PSR2 selective fetch WAs José Roberto de Souza
2020-05-26 22:31 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] drm/i915/rkl: Disable PSR2 Patchwork
2020-05-26 22:54 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-05-27  1:33 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

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).