intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD
@ 2025-10-22  0:28 Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 01/32] drm/i915/xe3p_lpd: Add Xe3p_LPD display IP features Gustavo Sousa
                   ` (32 more replies)
  0 siblings, 33 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu,
	Jani Nikula, Ville Syrjälä, Chaitanya Kumar Borah,
	Suraj Kandpal

This series adds initial support for Xe3p_LPD, Intel's display
architecture with IP version 35.

This series contains basic enabling patches and does not provide
complete support for the display IP yet. More involved features, like
the new PHY implementation and ALPM will come as separate patch series.

Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
Changes in v2:
- Incorporated review feedback. Please check the changelog in the
  patches for details.
- Link to v1: https://lore.kernel.org/r/20251015-xe3p_lpd-basic-enabling-v1-0-d2d1e26520aa@intel.com

---
Ankit Nautiyal (1):
      drm/i915/xe3p_lpd: Drop support for interlace mode

Gustavo Sousa (13):
      drm/i915/display: Use braces for if-ladder in intel_bw_init_hw()
      drm/i915/dram: Add field ecc_impacting_de_bw
      drm/i915/xe3p_lpd: Wait for AUX channel power status
      drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
      drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment
      drm/i915/xe3p_lpd: Add CDCLK table
      drm/i915/xe3p_lpd: Load DMC firmware
      drm/i915/xe3p_lpd: Extend Wa_16025573575
      drm/i915/xe3p_lpd: Reload DMC MMIO for pipes C and D
      drm/i915/vbt: Add fields dedicated_external and dyn_port_over_tc
      drm/i915/power: Use intel_encoder_is_tc()
      drm/i915/display: Handle dedicated external ports in intel_encoder_is_tc()
      drm/i915/xe3p_lpd: Extend Type-C flow for static DDI allocation

Jouni Högander (1):
      drm/i915/xe3p_lpd: PSR SU minimum lines is 4

Juha-pekka Heikkila (1):
      drm/i915/xe3p_lpd: Don't allow odd ypan or ysize with semiplanar format

Luca Coelho (1):
      drm/i915/wm: don't use method1 in Xe3p_LPD onwards

Matt Atwood (1):
      drm/i915/xe3p_lpd: Update bandwidth parameters

Matt Roper (1):
      drm/i915/xe3p_lpd: Drop north display reset option programming

Ravi Kumar Vodapalli (1):
      drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers

Sai Teja Pottumuttu (8):
      drm/i915/xe3p_lpd: Add Xe3p_LPD display IP features
      drm/i915/xe3p_lpd: Expand bifield masks dbuf blocks fields
      drm/i915/xe3p_lpd: Support UINT16 formats
      drm/i915/xe3p_lpd: Extend FBC support to UINT16 formats
      drm/i915/xe3p_lpd: Horizontal flip support for linear surfaces
      drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
      drm/i915/xe3p_lpd: Remove gamma,csc bottom color checks
      drm/i915/nvls: Add NVL-S display support

Vinod Govindapillai (4):
      drm/i915/xe3p_lpd: Enable system caching for FBC
      drm/i915/xe3p_lpd: Introduce pixel normalizer config support
      drm/i915/xe3p_lpd: Add FBC support for FP16 formats
      drm/i915/xe3p_lpd: Enable pixel normalizer for fp16 formats for FBC

 drivers/gpu/drm/i915/display/intel_bios.c          |  54 ++++++-
 drivers/gpu/drm/i915/display/intel_bios.h          |   2 +
 drivers/gpu/drm/i915/display/intel_bw.c            |  39 +++--
 drivers/gpu/drm/i915/display/intel_cdclk.c         |  44 +++++-
 drivers/gpu/drm/i915/display/intel_color.c         |  13 +-
 drivers/gpu/drm/i915/display/intel_ddi.c           |  11 ++
 drivers/gpu/drm/i915/display/intel_display.c       |  33 ++++-
 .../gpu/drm/i915/display/intel_display_device.c    |   6 +
 .../gpu/drm/i915/display/intel_display_device.h    |   4 +-
 drivers/gpu/drm/i915/display/intel_display_power.c |   3 +
 .../drm/i915/display/intel_display_power_well.c    |  58 ++++++--
 drivers/gpu/drm/i915/display/intel_display_regs.h  |  40 ++++-
 drivers/gpu/drm/i915/display/intel_display_types.h |   4 +
 drivers/gpu/drm/i915/display/intel_display_wa.c    |   3 +-
 drivers/gpu/drm/i915/display/intel_dmc.c           |  13 +-
 drivers/gpu/drm/i915/display/intel_fbc.c           | 126 +++++++++++++++-
 drivers/gpu/drm/i915/display/intel_fbc.h           |   1 +
 drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  11 ++
 drivers/gpu/drm/i915/display/intel_fifo_underrun.c |  87 +++++++++++
 drivers/gpu/drm/i915/display/intel_plane.c         |   3 +
 drivers/gpu/drm/i915/display/intel_psr.c           |  25 ++++
 drivers/gpu/drm/i915/display/intel_tc.c            | 151 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_vbt_defs.h      |   3 +-
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 162 +++++++++++++++------
 .../drm/i915/display/skl_universal_plane_regs.h    |  25 +++-
 drivers/gpu/drm/i915/display/skl_watermark.c       |  55 +++++--
 drivers/gpu/drm/i915/display/skl_watermark_regs.h  |  52 ++++---
 drivers/gpu/drm/i915/i915_reg.h                    |   1 +
 drivers/gpu/drm/i915/soc/intel_dram.c              |   4 +
 drivers/gpu/drm/i915/soc/intel_dram.h              |   1 +
 30 files changed, 882 insertions(+), 152 deletions(-)
---
base-commit: fb0f56ad8a2c9953c57c3337a72ccbf9c5050687
change-id: 20251014-xe3p_lpd-basic-enabling-eb4424698b44

Best regards,
--  
Gustavo Sousa <gustavo.sousa@intel.com>


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

* [PATCH v2 01/32] drm/i915/xe3p_lpd: Add Xe3p_LPD display IP features
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 02/32] drm/i915/xe3p_lpd: Drop north display reset option programming Gustavo Sousa
                   ` (31 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

Xe3p_LPD (display version 35) is similar to Xe2_LPD with respect to the
features described by struct intel_display_device_info, so reuse its
device descriptor.

v2:
  - Add reference to Bspec 74201. (Shekhar)

Bspec: 74201, 74304
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_device.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index f3f1f25b0f38..a38de39ed98c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -1507,6 +1507,7 @@ static const struct {
 	{ 20,  0, &xe2_lpd_display },
 	{ 30,  0, &xe2_lpd_display },
 	{ 30,  2, &wcl_display },
+	{ 35,  0, &xe2_lpd_display },
 };
 
 static const struct intel_display_device_info *

-- 
2.51.0


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

* [PATCH v2 02/32] drm/i915/xe3p_lpd: Drop north display reset option programming
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 01/32] drm/i915/xe3p_lpd: Add Xe3p_LPD display IP features Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 03/32] drm/i915/display: Use braces for if-ladder in intel_bw_init_hw() Gustavo Sousa
                   ` (30 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Matt Roper <matthew.d.roper@intel.com>

The NDE_RSTWRN_OPT has been removed on Xe3p platforms and reset option
programming is no longer necessary during display init.

Bspec: 68846, 69137
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_power.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index da4babfd6bcb..821f5097e9c0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -1436,6 +1436,9 @@ static void intel_pch_reset_handshake(struct intel_display *display,
 	i915_reg_t reg;
 	u32 reset_bits;
 
+	if (DISPLAY_VER(display) >= 35)
+		return;
+
 	if (display->platform.ivybridge) {
 		reg = GEN7_MSG_CTL;
 		reset_bits = WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK;

-- 
2.51.0


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

* [PATCH v2 03/32] drm/i915/display: Use braces for if-ladder in intel_bw_init_hw()
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 01/32] drm/i915/xe3p_lpd: Add Xe3p_LPD display IP features Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 02/32] drm/i915/xe3p_lpd: Drop north display reset option programming Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw Gustavo Sousa
                   ` (29 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Looking at the current if-ladder in intel_bw_init_hw(), we see that
Xe2_HPD contains two entries, differing only for ECC memories.  Let's
improve readability by using braces and allowing adding extra conditions
for each case.

v2:
  - Tweaked commit message, since we are not going to add the ECC case
    for Xe3p_LPD anymore.

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 92a060e02cf3..fc173b2a1ad9 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -802,29 +802,30 @@ void intel_bw_init_hw(struct intel_display *display)
 	if (!HAS_DISPLAY(display))
 		return;
 
-	if (DISPLAY_VERx100(display) >= 3002)
+	if (DISPLAY_VERx100(display) >= 3002) {
 		tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
-	else if (DISPLAY_VER(display) >= 30)
+	} else if (DISPLAY_VER(display) >= 30) {
 		tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
-	else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx &&
-		 dram_info->type == INTEL_DRAM_GDDR_ECC)
-		xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_ecc_sa_info);
-	else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx)
-		xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info);
-	else if (DISPLAY_VER(display) >= 14)
+	} else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) {
+		if (dram_info->type == INTEL_DRAM_GDDR_ECC)
+			xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_ecc_sa_info);
+		else
+			xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info);
+	} else if (DISPLAY_VER(display) >= 14) {
 		tgl_get_bw_info(display, dram_info, &mtl_sa_info);
-	else if (display->platform.dg2)
+	} else if (display->platform.dg2) {
 		dg2_get_bw_info(display);
-	else if (display->platform.alderlake_p)
+	} else if (display->platform.alderlake_p) {
 		tgl_get_bw_info(display, dram_info, &adlp_sa_info);
-	else if (display->platform.alderlake_s)
+	} else if (display->platform.alderlake_s) {
 		tgl_get_bw_info(display, dram_info, &adls_sa_info);
-	else if (display->platform.rocketlake)
+	} else if (display->platform.rocketlake) {
 		tgl_get_bw_info(display, dram_info, &rkl_sa_info);
-	else if (DISPLAY_VER(display) == 12)
+	} else if (DISPLAY_VER(display) == 12) {
 		tgl_get_bw_info(display, dram_info, &tgl_sa_info);
-	else if (DISPLAY_VER(display) == 11)
+	} else if (DISPLAY_VER(display) == 11) {
 		icl_get_bw_info(display, dram_info, &icl_sa_info);
+	}
 }
 
 static unsigned int intel_bw_num_active_planes(struct intel_display *display,

-- 
2.51.0


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

* [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (2 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 03/32] drm/i915/display: Use braces for if-ladder in intel_bw_init_hw() Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22 11:37   ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters Gustavo Sousa
                   ` (28 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

Starting with Xe3p_LPD, we now have a new field in MEM_SS_INFO_GLOBAL
that indicates whether the memory has enabled ECC that limits display
bandwidth.  Add the field ecc_impacting_de_bw to struct dram_info to
contain that information and set it appropriately when probing for
memory info.

Currently there are no instructions in Bspec on how to handle that case,
so let's throw a warning if we ever find such a scenario.

v2:
  - s/ecc_impacting_de/ecc_impacting_de_bw/ to be more specific. (Matt
    Atwood)
  - Add warning if ecc_impacting_de_bw is true, since we currently do
    not have instructions on how to handle it. (Matt Roper)

Bspec: 69131
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Matt Atwood <matthew.s.atwood@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 8 ++++++++
 drivers/gpu/drm/i915/i915_reg.h         | 1 +
 drivers/gpu/drm/i915/soc/intel_dram.c   | 4 ++++
 drivers/gpu/drm/i915/soc/intel_dram.h   | 1 +
 4 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index fc173b2a1ad9..57d65e6e5429 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -802,6 +802,14 @@ void intel_bw_init_hw(struct intel_display *display)
 	if (!HAS_DISPLAY(display))
 		return;
 
+	/*
+	 * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC
+	 * enabled that would impact display bandwidth.  However, so far there
+	 * are no instructions in Bspec on how to handle that case.  Let's
+	 * complain if we ever find such a scenario.
+	 */
+	drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);
+
 	if (DISPLAY_VERx100(display) >= 3002) {
 		tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
 	} else if (DISPLAY_VER(display) >= 30) {
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 354ef75ef6a5..5bf3b4ab2baa 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1233,6 +1233,7 @@
 #define   OROM_OFFSET_MASK			REG_GENMASK(20, 16)
 
 #define MTL_MEM_SS_INFO_GLOBAL			_MMIO(0x45700)
+#define   XE3P_ECC_IMPACTING_DE			REG_BIT(12)
 #define   MTL_N_OF_ENABLED_QGV_POINTS_MASK	REG_GENMASK(11, 8)
 #define   MTL_N_OF_POPULATED_CH_MASK		REG_GENMASK(7, 4)
 #define   MTL_DDR_TYPE_MASK			REG_GENMASK(3, 0)
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
index 8841cfe1cac8..73e8ad1a28e0 100644
--- a/drivers/gpu/drm/i915/soc/intel_dram.c
+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
@@ -685,6 +685,7 @@ static int gen12_get_dram_info(struct drm_i915_private *i915, struct dram_info *
 
 static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info)
 {
+	struct intel_display *display = i915->display;
 	u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
 
 	switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) {
@@ -723,6 +724,9 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info
 	dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
 	/* PSF GV points not supported in D14+ */
 
+	if (DISPLAY_VER(display) >= 35)
+		dram_info->ecc_impacting_de_bw = REG_FIELD_GET(XE3P_ECC_IMPACTING_DE, val);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.h b/drivers/gpu/drm/i915/soc/intel_dram.h
index 03a973f1c941..8475ee379daa 100644
--- a/drivers/gpu/drm/i915/soc/intel_dram.h
+++ b/drivers/gpu/drm/i915/soc/intel_dram.h
@@ -30,6 +30,7 @@ struct dram_info {
 	u8 num_channels;
 	u8 num_qgv_points;
 	u8 num_psf_gv_points;
+	bool ecc_impacting_de_bw; /* Only valid from Xe3p_LPD onward. */
 	bool symmetric_memory;
 	bool has_16gb_dimms;
 };

-- 
2.51.0


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

* [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (3 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22 14:56   ` Matt Roper
  2025-10-22  0:28 ` [PATCH v2 06/32] drm/i915/xe3p_lpd: Expand bifield masks dbuf blocks fields Gustavo Sousa
                   ` (27 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Matt Atwood <matthew.s.atwood@intel.com>

Bandwidth parameters for Xe3p_LPD are the same as for Xe3_LPD. Re-use
them.

v2:
  - Do not have a special case for ecc_impacting_de_bw, since there are
    no specific instructions in Bspec for this scenario. (Matt Roper)

Bspec: 68859
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 57d65e6e5429..57cb8a23188f 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -810,7 +810,9 @@ void intel_bw_init_hw(struct intel_display *display)
 	 */
 	drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);
 
-	if (DISPLAY_VERx100(display) >= 3002) {
+	if (DISPLAY_VER(display) >= 35) {
+		tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
+	} else if (DISPLAY_VERx100(display) >= 3002) {
 		tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
 	} else if (DISPLAY_VER(display) >= 30) {
 		tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);

-- 
2.51.0


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

* [PATCH v2 06/32] drm/i915/xe3p_lpd: Expand bifield masks dbuf blocks fields
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (4 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats Gustavo Sousa
                   ` (26 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

On Xe3p_LPD, the dbuf blocks fields of different registers are now
documented as 13-bit fields. The dbuf isn't really large enough to need
the 13th bit, but let's go ahead and update the definition now just in
case some new display IP in future ends up needing the larger size. The
extra bit is an unused bit in previous display versions, so we can
safely just extend the existing definition.

Bspec: 69847, 69880, 72053
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_universal_plane_regs.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
index ca9fdfbbe57c..479bb3f7f92b 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
@@ -324,7 +324,7 @@
 #define   PLANE_WM_IGNORE_LINES			REG_BIT(30)
 #define   PLANE_WM_AUTO_MIN_ALLOC_EN		REG_BIT(29)
 #define   PLANE_WM_LINES_MASK			REG_GENMASK(26, 14)
-#define   PLANE_WM_BLOCKS_MASK			REG_GENMASK(11, 0)
+#define   PLANE_WM_BLOCKS_MASK			REG_GENMASK(12, 0)
 
 #define _PLANE_WM_SAGV_1_A			0x70258
 #define _PLANE_WM_SAGV_1_B			0x71258
@@ -375,10 +375,10 @@
 							_PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B, \
 							_PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
 
-/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
-#define   PLANE_BUF_END_MASK			REG_GENMASK(27, 16)
+/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits, xe3p_lpd 13 bits */
+#define   PLANE_BUF_END_MASK			REG_GENMASK(28, 16)
 #define   PLANE_BUF_END(end)			REG_FIELD_PREP(PLANE_BUF_END_MASK, (end))
-#define   PLANE_BUF_START_MASK			REG_GENMASK(11, 0)
+#define   PLANE_BUF_START_MASK			REG_GENMASK(12, 0)
 #define   PLANE_BUF_START(start)		REG_FIELD_PREP(PLANE_BUF_START_MASK, (start))
 
 #define _PLANE_MIN_BUF_CFG_1_A			0x70274
@@ -389,9 +389,9 @@
 							_PLANE_MIN_BUF_CFG_1_A, _PLANE_MIN_BUF_CFG_1_B, \
 							_PLANE_MIN_BUF_CFG_2_A, _PLANE_MIN_BUF_CFG_2_B)
 #define	  PLANE_AUTO_MIN_DBUF_EN		REG_BIT(31)
-#define	  PLANE_MIN_DBUF_BLOCKS_MASK		REG_GENMASK(27, 16)
+#define	  PLANE_MIN_DBUF_BLOCKS_MASK		REG_GENMASK(28, 16)
 #define	  PLANE_MIN_DBUF_BLOCKS(val)		REG_FIELD_PREP(PLANE_MIN_DBUF_BLOCKS_MASK, (val))
-#define	  PLANE_INTERIM_DBUF_BLOCKS_MASK	REG_GENMASK(11, 0)
+#define	  PLANE_INTERIM_DBUF_BLOCKS_MASK	REG_GENMASK(12, 0)
 #define	  PLANE_INTERIM_DBUF_BLOCKS(val)	REG_FIELD_PREP(PLANE_INTERIM_DBUF_BLOCKS_MASK, (val))
 
 /* tgl+ */

-- 
2.51.0


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

* [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (5 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 06/32] drm/i915/xe3p_lpd: Expand bifield masks dbuf blocks fields Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22 12:28   ` Ville Syrjälä
  2025-10-22  0:28 ` [PATCH v2 08/32] drm/i915/xe3p_lpd: Extend FBC support to " Gustavo Sousa
                   ` (25 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

Starting from display Xe3p_LPD, UINT16 formats are also supported. Add
its corresponding PLANE_CTL bit and add the format in the necessary
functions.

v2:
  - Add reference to Bspec 68911. (Matt Atwood)

Bspec: 68904, 69853, 68911
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 96 +++++++++++++++-------
 .../drm/i915/display/skl_universal_plane_regs.h    |  1 +
 2 files changed, 68 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 0319174adf95..530adff81b99 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -136,36 +136,47 @@ static const u32 icl_sdr_uv_plane_formats[] = {
 	DRM_FORMAT_XVYU2101010,
 };
 
+#define ICL_HDR_PLANE_FORMATS		\
+	DRM_FORMAT_C8,			\
+	DRM_FORMAT_RGB565,		\
+	DRM_FORMAT_XRGB8888,		\
+	DRM_FORMAT_XBGR8888,		\
+	DRM_FORMAT_ARGB8888,		\
+	DRM_FORMAT_ABGR8888,		\
+	DRM_FORMAT_XRGB2101010,		\
+	DRM_FORMAT_XBGR2101010,		\
+	DRM_FORMAT_ARGB2101010,		\
+	DRM_FORMAT_ABGR2101010,		\
+	DRM_FORMAT_XRGB16161616F,	\
+	DRM_FORMAT_XBGR16161616F,	\
+	DRM_FORMAT_ARGB16161616F,	\
+	DRM_FORMAT_ABGR16161616F,	\
+	DRM_FORMAT_YUYV,		\
+	DRM_FORMAT_YVYU,		\
+	DRM_FORMAT_UYVY,		\
+	DRM_FORMAT_VYUY,		\
+	DRM_FORMAT_NV12,		\
+	DRM_FORMAT_P010,		\
+	DRM_FORMAT_P012,		\
+	DRM_FORMAT_P016,		\
+	DRM_FORMAT_Y210,		\
+	DRM_FORMAT_Y212,		\
+	DRM_FORMAT_Y216,		\
+	DRM_FORMAT_XYUV8888,		\
+	DRM_FORMAT_XVYU2101010,		\
+	DRM_FORMAT_XVYU12_16161616,	\
+	DRM_FORMAT_XVYU16161616
+
 static const u32 icl_hdr_plane_formats[] = {
-	DRM_FORMAT_C8,
-	DRM_FORMAT_RGB565,
-	DRM_FORMAT_XRGB8888,
-	DRM_FORMAT_XBGR8888,
-	DRM_FORMAT_ARGB8888,
-	DRM_FORMAT_ABGR8888,
-	DRM_FORMAT_XRGB2101010,
-	DRM_FORMAT_XBGR2101010,
-	DRM_FORMAT_ARGB2101010,
-	DRM_FORMAT_ABGR2101010,
-	DRM_FORMAT_XRGB16161616F,
-	DRM_FORMAT_XBGR16161616F,
-	DRM_FORMAT_ARGB16161616F,
-	DRM_FORMAT_ABGR16161616F,
-	DRM_FORMAT_YUYV,
-	DRM_FORMAT_YVYU,
-	DRM_FORMAT_UYVY,
-	DRM_FORMAT_VYUY,
-	DRM_FORMAT_NV12,
-	DRM_FORMAT_P010,
-	DRM_FORMAT_P012,
-	DRM_FORMAT_P016,
-	DRM_FORMAT_Y210,
-	DRM_FORMAT_Y212,
-	DRM_FORMAT_Y216,
-	DRM_FORMAT_XYUV8888,
-	DRM_FORMAT_XVYU2101010,
-	DRM_FORMAT_XVYU12_16161616,
-	DRM_FORMAT_XVYU16161616,
+	ICL_HDR_PLANE_FORMATS,
+};
+
+static const u32 xe3p_lpd_hdr_plane_formats[] = {
+	ICL_HDR_PLANE_FORMATS,
+	DRM_FORMAT_XRGB16161616,
+	DRM_FORMAT_XBGR16161616,
+	DRM_FORMAT_ARGB16161616,
+	DRM_FORMAT_ABGR16161616,
 };
 
 int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
@@ -220,6 +231,18 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
 			else
 				return DRM_FORMAT_XRGB2101010;
 		}
+	case PLANE_CTL_FORMAT_XRGB_16161616:
+		if (rgb_order) {
+			if (alpha)
+				return DRM_FORMAT_ABGR16161616;
+			else
+				return DRM_FORMAT_XBGR16161616;
+		} else {
+			if (alpha)
+				return DRM_FORMAT_ARGB16161616;
+			else
+				return DRM_FORMAT_XRGB16161616;
+		}
 	case PLANE_CTL_FORMAT_XRGB_16161616F:
 		if (rgb_order) {
 			if (alpha)
@@ -960,6 +983,12 @@ static u32 skl_plane_ctl_format(u32 pixel_format)
 	case DRM_FORMAT_XRGB2101010:
 	case DRM_FORMAT_ARGB2101010:
 		return PLANE_CTL_FORMAT_XRGB_2101010;
+	case DRM_FORMAT_XBGR16161616:
+	case DRM_FORMAT_ABGR16161616:
+		return PLANE_CTL_FORMAT_XRGB_16161616 | PLANE_CTL_ORDER_RGBX;
+	case DRM_FORMAT_XRGB16161616:
+	case DRM_FORMAT_ARGB16161616:
+		return PLANE_CTL_FORMAT_XRGB_16161616;
 	case DRM_FORMAT_XBGR16161616F:
 	case DRM_FORMAT_ABGR16161616F:
 		return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
@@ -2479,6 +2508,11 @@ static const u32 *icl_get_plane_formats(struct intel_display *display,
 					int *num_formats)
 {
 	if (icl_is_hdr_plane(display, plane_id)) {
+		if (DISPLAY_VER(display) >= 35) {
+			*num_formats = ARRAY_SIZE(xe3p_lpd_hdr_plane_formats);
+			return xe3p_lpd_hdr_plane_formats;
+		}
+
 		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
 		return icl_hdr_plane_formats;
 	} else if (icl_is_nv12_y_plane(display, plane_id)) {
@@ -2637,6 +2671,10 @@ static bool tgl_plane_format_mod_supported(struct drm_plane *_plane,
 	case DRM_FORMAT_RGB565:
 	case DRM_FORMAT_XVYU2101010:
 	case DRM_FORMAT_C8:
+	case DRM_FORMAT_XBGR16161616:
+	case DRM_FORMAT_ABGR16161616:
+	case DRM_FORMAT_XRGB16161616:
+	case DRM_FORMAT_ARGB16161616:
 	case DRM_FORMAT_Y210:
 	case DRM_FORMAT_Y212:
 	case DRM_FORMAT_Y216:
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
index 479bb3f7f92b..84cf565bd653 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
@@ -64,6 +64,7 @@
 #define   PLANE_CTL_FORMAT_Y410			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
 #define   PLANE_CTL_FORMAT_Y412			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
 #define   PLANE_CTL_FORMAT_Y416			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
+#define   PLANE_CTL_FORMAT_XRGB_16161616	REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 18)
 #define   PLANE_CTL_PIPE_CSC_ENABLE		REG_BIT(23) /* Pre-GLK */
 #define   PLANE_CTL_KEY_ENABLE_MASK		REG_GENMASK(22, 21)
 #define   PLANE_CTL_KEY_ENABLE_SOURCE		REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)

-- 
2.51.0


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

* [PATCH v2 08/32] drm/i915/xe3p_lpd: Extend FBC support to UINT16 formats
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (6 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22 12:39   ` Ville Syrjälä
  2025-10-22  0:28 ` [PATCH v2 09/32] drm/i915/xe3p_lpd: Horizontal flip support for linear surfaces Gustavo Sousa
                   ` (24 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

Starting Xe3p_LPD, FBC is supported on UINT16 formats as well. Also
UINT16 being a 64bpp format, will use cpp of 8 for cfb stride and thus
size calculations.

Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
BSpec: 68881, 68904, 69560
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c | 42 ++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 10ef3136dadc..af3585aeefd3 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -141,15 +141,25 @@ static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane
 	return stride;
 }
 
-static unsigned int intel_fbc_cfb_cpp(void)
+static unsigned int intel_fbc_cfb_cpp(const struct intel_plane_state *plane_state)
 {
-	return 4; /* FBC always 4 bytes per pixel */
+	const struct drm_framebuffer *fb = plane_state->hw.fb;
+
+	switch (fb->format->format) {
+	case DRM_FORMAT_XRGB16161616:
+	case DRM_FORMAT_XBGR16161616:
+	case DRM_FORMAT_ARGB16161616:
+	case DRM_FORMAT_ABGR16161616:
+		return 8;
+	default:
+		return 4;
+	}
 }
 
 /* plane stride based cfb stride in bytes, assuming 1:1 compression limit */
 static unsigned int intel_fbc_plane_cfb_stride(const struct intel_plane_state *plane_state)
 {
-	unsigned int cpp = intel_fbc_cfb_cpp();
+	unsigned int cpp = intel_fbc_cfb_cpp(plane_state);
 
 	return intel_fbc_plane_stride(plane_state) * cpp;
 }
@@ -203,7 +213,7 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s
 	struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
 	unsigned int stride = intel_fbc_plane_cfb_stride(plane_state);
 	unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16;
-	unsigned int cpp = intel_fbc_cfb_cpp();
+	unsigned int cpp = intel_fbc_cfb_cpp(plane_state);
 
 	return _intel_fbc_cfb_stride(display, cpp, width, stride);
 }
@@ -1081,11 +1091,33 @@ static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_
 	}
 }
 
+static bool xe3p_lpd_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
+{
+	const struct drm_framebuffer *fb = plane_state->hw.fb;
+
+	switch (fb->format->format) {
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_ARGB8888:
+	case DRM_FORMAT_ABGR8888:
+	case DRM_FORMAT_RGB565:
+	case DRM_FORMAT_XRGB16161616:
+	case DRM_FORMAT_XBGR16161616:
+	case DRM_FORMAT_ARGB16161616:
+	case DRM_FORMAT_ABGR16161616:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
 {
 	struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
 
-	if (DISPLAY_VER(display) >= 20)
+	if (DISPLAY_VER(display) >= 35)
+		return xe3p_lpd_fbc_pixel_format_is_valid(plane_state);
+	else if (DISPLAY_VER(display) >= 20)
 		return lnl_fbc_pixel_format_is_valid(plane_state);
 	else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
 		return g4x_fbc_pixel_format_is_valid(plane_state);

-- 
2.51.0


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

* [PATCH v2 09/32] drm/i915/xe3p_lpd: Horizontal flip support for linear surfaces
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (7 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 08/32] drm/i915/xe3p_lpd: Extend FBC support to " Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status Gustavo Sousa
                   ` (23 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

Starting from Xe3p_LPD, linear surfaces also support horizontal flip.

Bspec: 68904
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 530adff81b99..9f1111324dab 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1753,7 +1753,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
 	}
 
 	if (rotation & DRM_MODE_REFLECT_X &&
-	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
+	    fb->modifier == DRM_FORMAT_MOD_LINEAR &&
+	    DISPLAY_VER(display) < 35) {
 		drm_dbg_kms(display->drm,
 			    "[PLANE:%d:%s] horizontal flip is not supported with linear surface formats\n",
 			    plane->base.base.id, plane->base.name);

-- 
2.51.0


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

* [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (8 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 09/32] drm/i915/xe3p_lpd: Horizontal flip support for linear surfaces Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-29 20:06   ` Matt Roper
  2025-10-22  0:28 ` [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints Gustavo Sousa
                   ` (22 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

The LT PHY in Xe3p_LPD allows polling for the AUX channel power status
to verify completion of power up and down. As such, let's use that field
to have a more precise waiting time instead of a fixed one.

Bspec: 68967
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 .../drm/i915/display/intel_display_power_well.c    | 32 +++++++++++++++++-----
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
index 5e88b930f5aa..ba2552adb58b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -1858,23 +1858,41 @@ static void xelpdp_aux_power_well_enable(struct intel_display *display,
 		     XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
 		     XELPDP_DP_AUX_CH_CTL_POWER_REQUEST);
 
-	/*
-	 * The power status flag cannot be used to determine whether aux
-	 * power wells have finished powering up.  Instead we're
-	 * expected to just wait a fixed 600us after raising the request
-	 * bit.
-	 */
-	usleep_range(600, 1200);
+	if (DISPLAY_VER(display) >= 35) {
+		if (intel_de_wait_for_set(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
+					  XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
+			drm_warn(display->drm,
+				 "Timeout waiting for PHY %c AUX channel power to be up\n",
+				 phy_name(phy));
+	} else {
+		/*
+		 * The power status flag cannot be used to determine whether aux
+		 * power wells have finished powering up.  Instead we're
+		 * expected to just wait a fixed 600us after raising the request
+		 * bit.
+		 */
+		usleep_range(600, 1200);
+	}
 }
 
 static void xelpdp_aux_power_well_disable(struct intel_display *display,
 					  struct i915_power_well *power_well)
 {
 	enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
+	enum phy phy = icl_aux_pw_to_phy(display, power_well);
 
 	intel_de_rmw(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
 		     XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
 		     0);
+
+	if (DISPLAY_VER(display) >= 35) {
+		if (intel_de_wait_for_clear(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
+					    XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
+			drm_warn(display->drm,
+				 "Timeout waiting for PHY %c AUX channel power to be down\n",
+				 phy_name(phy));
+	}
+
 	usleep_range(10, 30);
 }
 

-- 
2.51.0


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

* [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (9 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-29 20:54   ` Matt Roper
  2025-10-22  0:28 ` [PATCH v2 12/32] drm/i915/xe3p_lpd: Remove gamma,csc bottom color checks Gustavo Sousa
                   ` (21 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu,
	Jani Nikula, Ville Syrjälä

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

Starting with Xe3p_LPD, we get two new registers and some bits in
existing registers that expose hardware state information at the time of
underrun notification that can be relevant to debugging.

Add the necessary logic in the driver to print the available debug
information when an underrun happens.

v2:
  - Use seq_buf to generate planes string. (Jani)
  - Move definition of FBC_DEBUG_STATUS to intel_fbc_regs.h. (Ville)
  - Change logic for processing UNDERRUN_DBG1 to use loops and move it
    to a separate function. (Gustavo)
  - Always print underrun error message, even if there wouldn't be any
    debug info associated to the underrun. (Gustavo)

Bspec: 69111, 69561, 74411, 74412
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Co-developed-by: Gustavo Sousa <gustavo.sousa@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_regs.h  | 20 +++++
 drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
 drivers/gpu/drm/i915/display/intel_fifo_underrun.c | 87 ++++++++++++++++++++++
 3 files changed, 109 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
index 9d71e26a4fa2..c9f8b90faa42 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -882,6 +882,25 @@
 #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK		REG_GENMASK(2, 0) /* tgl+ */
 #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id)	REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
 
+#define _UNDERRUN_DBG1_A				0x70064
+#define _UNDERRUN_DBG1_B				0x71064
+#define UNDERRUN_DBG1(pipe)				_MMIO_PIPE(pipe, \
+								   _UNDERRUN_DBG1_A, \
+								   _UNDERRUN_DBG1_B)
+#define   UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK		REG_GENMASK(29, 24)
+#define   UNDERRUN_DDB_EMPTY_MASK			REG_GENMASK(21, 16)
+#define   UNDERRUN_DBUF_NOT_FILLED_MASK			REG_GENMASK(13, 8)
+#define   UNDERRUN_BELOW_WM0_MASK			REG_GENMASK(5, 0)
+
+#define _UNDERRUN_DBG2_A				0x70068
+#define _UNDERRUN_DBG2_B				0x71068
+#define UNDERRUN_DBG2(pipe)				_MMIO_PIPE(pipe, \
+								   _UNDERRUN_DBG2_A, \
+								   _UNDERRUN_DBG2_B)
+#define   UNDERRUN_FRAME_LINE_COUNTERS_FROZEN		REG_BIT(31)
+#define   UNDERRUN_PIPE_FRAME_COUNT_MASK		REG_GENMASK(30, 20)
+#define   UNDERRUN_LINE_COUNT_MASK			REG_GENMASK(19, 0)
+
 #define DPINVGTT				_MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
 #define   DPINVGTT_EN_MASK_CHV				REG_GENMASK(27, 16)
 #define   DPINVGTT_EN_MASK_VLV				REG_GENMASK(23, 16)
@@ -1416,6 +1435,7 @@
 
 #define GEN12_DCPR_STATUS_1				_MMIO(0x46440)
 #define  XELPDP_PMDEMAND_INFLIGHT_STATUS		REG_BIT(26)
+#define  XE3P_UNDERRUN_PKGC				REG_BIT(21)
 
 #define FUSE_STRAP		_MMIO(0x42014)
 #define   ILK_INTERNAL_GRAPHICS_DISABLE	REG_BIT(31)
diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
index b1d0161a3196..272dba7f9695 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
@@ -88,6 +88,8 @@
 #define DPFC_FENCE_YOFF			_MMIO(0x3218)
 #define ILK_DPFC_FENCE_YOFF(fbc_id)	_MMIO_PIPE((fbc_id), 0x43218, 0x43258)
 #define DPFC_CHICKEN			_MMIO(0x3224)
+#define FBC_DEBUG_STATUS(pipe)		_MMIO_PIPE(pipe, 0x43220, 0x43260)
+#define   FBC_UNDERRUN_DECOMPRESSION		REG_BIT(27)
 #define ILK_DPFC_CHICKEN(fbc_id)	_MMIO_PIPE((fbc_id), 0x43224, 0x43264)
 #define   DPFC_HT_MODIFY			REG_BIT(31) /* pre-ivb */
 #define   DPFC_NUKE_ON_ANY_MODIFICATION		REG_BIT(23) /* bdw+ */
diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
index c2ce8461ac9e..43cf141a59ae 100644
--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
@@ -25,6 +25,8 @@
  *
  */
 
+#include <linux/seq_buf.h>
+
 #include <drm/drm_print.h>
 
 #include "i915_reg.h"
@@ -34,6 +36,7 @@
 #include "intel_display_trace.h"
 #include "intel_display_types.h"
 #include "intel_fbc.h"
+#include "intel_fbc_regs.h"
 #include "intel_fifo_underrun.h"
 #include "intel_pch_display.h"
 
@@ -352,6 +355,87 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
 	return old;
 }
 
+#define UNDERRUN_DBG1_NUM_PLANES 6
+
+static void process_underrun_dbg1(struct intel_display *display,
+				  enum pipe pipe)
+{
+	struct {
+		u32 mask;
+		const char *info;
+	} info_masks[] = {
+		{ UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
+		{ UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
+		{ UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
+		{ UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
+	};
+	DECLARE_SEQ_BUF(planes_desc, 32);
+	u32 val;
+
+	val = intel_de_read(display, UNDERRUN_DBG1(pipe));
+	intel_de_write(display, UNDERRUN_DBG1(pipe), val);
+
+	for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
+		u32 plane_bits;
+
+		plane_bits = val & info_masks[i].mask;
+
+		if (!plane_bits)
+			continue;
+
+		plane_bits >>= ffs(info_masks[i].mask) - 1;
+
+		seq_buf_clear(&planes_desc);
+
+		for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
+			if (!(plane_bits & REG_BIT(j)))
+				continue;
+
+			if (j == 0)
+				seq_buf_puts(&planes_desc, "[C]");
+			else
+				seq_buf_printf(&planes_desc, "[%d]", j);
+		}
+
+		drm_err(display->drm,
+			"Pipe %c FIFO underrun info: %s on planes: %s\n",
+			pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
+
+		drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
+	}
+}
+
+static void xe3p_lpd_log_underrun(struct intel_display *display,
+				  enum pipe pipe)
+{
+	u32 val;
+
+	process_underrun_dbg1(display, pipe);
+
+	val = intel_de_read(display, UNDERRUN_DBG2(pipe));
+	if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {
+		intel_de_write(display, UNDERRUN_DBG2(pipe), UNDERRUN_FRAME_LINE_COUNTERS_FROZEN);
+		drm_err(display->drm, "Pipe %c FIFO underrun info: Frame count: %u, Line count: %u\n",
+			pipe_name(pipe),
+			REG_FIELD_GET(UNDERRUN_PIPE_FRAME_COUNT_MASK, val),
+			REG_FIELD_GET(UNDERRUN_LINE_COUNT_MASK, val));
+	}
+
+	val = intel_de_read(display, FBC_DEBUG_STATUS(pipe));
+	if (val & FBC_UNDERRUN_DECOMPRESSION) {
+		intel_de_write(display, FBC_DEBUG_STATUS(pipe), FBC_UNDERRUN_DECOMPRESSION);
+		drm_err(display->drm, "Pipe %c FIFO underrun info: FBC decompression\n",
+			pipe_name(pipe));
+	}
+
+	val = intel_de_read(display, GEN12_DCPR_STATUS_1);
+	if (val & XE3P_UNDERRUN_PKGC) {
+		intel_de_write(display, GEN12_DCPR_STATUS_1, XE3P_UNDERRUN_PKGC);
+		drm_err(display->drm, "Pipe %c FIFO underrun info: Pkgc blocking memory\n",
+			pipe_name(pipe));
+	}
+}
+
 /**
  * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
  * @display: display device instance
@@ -379,6 +463,9 @@ void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
 		trace_intel_cpu_fifo_underrun(display, pipe);
 
 		drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
+
+		if (DISPLAY_VER(display) >= 35)
+			xe3p_lpd_log_underrun(display, pipe);
 	}
 
 	intel_fbc_handle_fifo_underrun_irq(display);

-- 
2.51.0


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

* [PATCH v2 12/32] drm/i915/xe3p_lpd: Remove gamma,csc bottom color checks
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (10 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers Gustavo Sousa
                   ` (20 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu,
	Chaitanya Kumar Borah

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

With Xe3p_LPD, the SKL_BOTTOM_COLOR_GAMMA_ENABLE and
SKL_BOTTOM_COLOR_CSC_ENABLE bits are being removed. Thus, we need not
set gamma_enable nor csc_enable in crtc_state.

Note that GAMMA_MODE.POST_CSC_GAMMA_ENABLE and CSC_MODE.ICL_CSC_ENABLE
are the documented alternatives for the bottom color bits being removed.
But as these suggested bits are being checked in state checker as part
of gamma_mode, csc_mode fields and as gamma_enable/csc_enable are not
being used anywhere else functionally post ICL, we need not set these
fields in crtc_state.

Bspec: 69734
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Reviewed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_color.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 51db70d07fae..9102f3eb0bc4 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -1090,18 +1090,19 @@ static void skl_get_config(struct intel_crtc_state *crtc_state)
 {
 	struct intel_display *display = to_intel_display(crtc_state);
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	u32 tmp;
 
 	crtc_state->gamma_mode = hsw_read_gamma_mode(crtc);
 	crtc_state->csc_mode = ilk_read_csc_mode(crtc);
 
-	tmp = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe));
+	if (DISPLAY_VER(display) < 35) {
+		u32 tmp = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe));
 
-	if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
-		crtc_state->gamma_enable = true;
+		if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
+			crtc_state->gamma_enable = true;
 
-	if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
-		crtc_state->csc_enable = true;
+		if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
+			crtc_state->csc_enable = true;
+	}
 }
 
 static void skl_color_commit_arm(struct intel_dsb *dsb,

-- 
2.51.0


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

* [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (11 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 12/32] drm/i915/xe3p_lpd: Remove gamma,csc bottom color checks Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-29 21:22   ` Matt Roper
  2025-10-22  0:28 ` [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD Gustavo Sousa
                   ` (19 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

From: Ravi Kumar Vodapalli <ravi.kumar.vodapalli@intel.com>

Some of the register fields of MBUS_CTL and DBUF_CTL register are
changed for Xe3p_LPD platforms. Update the changed fields in the driver.
Below are the changes:

MBUS_CTL:
	Translation Throttle Min
		It changed from BIT[15:13] to BIT[16:13]

DBUF_CTL:
	Min Tracker State Service
		It changed from BIT[18:16] to BIT[20:16]
        Max Tracker State Service
		It changed to from BIT[23:19] to BIT[14:10]
		but using default value, so no need to define
		in code.

v2:
  - Keep definitions in the same line (i.e. without line continuation
    breaks) for better readability. (Jani)

Bspec: 68868, 68872
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Ravi Kumar Vodapalli <ravi.kumar.vodapalli@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c      | 16 +++++--
 drivers/gpu/drm/i915/display/skl_watermark_regs.h | 52 ++++++++++++-----------
 2 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 256162da9afc..c141d575009f 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3477,7 +3477,10 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
 	if (!HAS_MBUS_JOINING(display))
 		return;
 
-	if (DISPLAY_VER(display) >= 20)
+	if (DISPLAY_VER(display) >= 35)
+		intel_de_rmw(display, MBUS_CTL, XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK,
+			     XE3P_MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
+	else if (DISPLAY_VER(display) >= 20)
 		intel_de_rmw(display, MBUS_CTL, MBUS_TRANSLATION_THROTTLE_MIN_MASK,
 			     MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
 
@@ -3488,9 +3491,14 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
 		    ratio, str_yes_no(joined_mbus));
 
 	for_each_dbuf_slice(display, slice)
-		intel_de_rmw(display, DBUF_CTL_S(slice),
-			     DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
-			     DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
+		if (DISPLAY_VER(display) >= 35)
+			intel_de_rmw(display, DBUF_CTL_S(slice),
+				     XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
+				     XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
+		else
+			intel_de_rmw(display, DBUF_CTL_S(slice),
+				     DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
+				     DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
 }
 
 static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state)
diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
index c5572fc0e847..94915afc6b0b 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
@@ -32,16 +32,18 @@
 #define MBUS_BBOX_CTL_S1		_MMIO(0x45040)
 #define MBUS_BBOX_CTL_S2		_MMIO(0x45044)
 
-#define MBUS_CTL				_MMIO(0x4438C)
-#define   MBUS_JOIN				REG_BIT(31)
-#define   MBUS_HASHING_MODE_MASK		REG_BIT(30)
-#define   MBUS_HASHING_MODE_2x2			REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
-#define   MBUS_HASHING_MODE_1x4			REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
-#define   MBUS_JOIN_PIPE_SELECT_MASK		REG_GENMASK(28, 26)
-#define   MBUS_JOIN_PIPE_SELECT(pipe)		REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
-#define   MBUS_JOIN_PIPE_SELECT_NONE		MBUS_JOIN_PIPE_SELECT(7)
-#define   MBUS_TRANSLATION_THROTTLE_MIN_MASK	REG_GENMASK(15, 13)
-#define   MBUS_TRANSLATION_THROTTLE_MIN(val)	REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
+#define MBUS_CTL					_MMIO(0x4438C)
+#define   MBUS_JOIN					REG_BIT(31)
+#define   MBUS_HASHING_MODE_MASK			REG_BIT(30)
+#define   MBUS_HASHING_MODE_2x2				REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
+#define   MBUS_HASHING_MODE_1x4				REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
+#define   MBUS_JOIN_PIPE_SELECT_MASK			REG_GENMASK(28, 26)
+#define   MBUS_JOIN_PIPE_SELECT(pipe)			REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
+#define   MBUS_JOIN_PIPE_SELECT_NONE			MBUS_JOIN_PIPE_SELECT(7)
+#define   MBUS_TRANSLATION_THROTTLE_MIN_MASK		REG_GENMASK(15, 13)
+#define   MBUS_TRANSLATION_THROTTLE_MIN(val)		REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
+#define   XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK	REG_GENMASK(16, 13)
+#define   XE3P_MBUS_TRANSLATION_THROTTLE_MIN(val)	REG_FIELD_PREP(XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
 
 /*
  * The below are numbered starting from "S1" on gen11/gen12, but starting
@@ -51,21 +53,23 @@
  * way things will be named by the hardware team going forward, plus it's more
  * consistent with how most of the rest of our registers are named.
  */
-#define _DBUF_CTL_S0				0x45008
-#define _DBUF_CTL_S1				0x44FE8
-#define _DBUF_CTL_S2				0x44300
-#define _DBUF_CTL_S3				0x44304
-#define DBUF_CTL_S(slice)			_MMIO(_PICK(slice, \
-							    _DBUF_CTL_S0, \
-							    _DBUF_CTL_S1, \
-							    _DBUF_CTL_S2, \
-							    _DBUF_CTL_S3))
-#define  DBUF_POWER_REQUEST			REG_BIT(31)
-#define  DBUF_POWER_STATE			REG_BIT(30)
-#define  DBUF_TRACKER_STATE_SERVICE_MASK	REG_GENMASK(23, 19)
-#define  DBUF_TRACKER_STATE_SERVICE(x)		REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
-#define  DBUF_MIN_TRACKER_STATE_SERVICE_MASK	REG_GENMASK(18, 16) /* ADL-P+ */
+#define _DBUF_CTL_S0					0x45008
+#define _DBUF_CTL_S1					0x44FE8
+#define _DBUF_CTL_S2					0x44300
+#define _DBUF_CTL_S3					0x44304
+#define DBUF_CTL_S(slice)				_MMIO(_PICK(slice, \
+								    _DBUF_CTL_S0, \
+								    _DBUF_CTL_S1, \
+								    _DBUF_CTL_S2, \
+								    _DBUF_CTL_S3))
+#define  DBUF_POWER_REQUEST				REG_BIT(31)
+#define  DBUF_POWER_STATE				REG_BIT(30)
+#define  DBUF_TRACKER_STATE_SERVICE_MASK		REG_GENMASK(23, 19)
+#define  DBUF_TRACKER_STATE_SERVICE(x)			REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
+#define  DBUF_MIN_TRACKER_STATE_SERVICE_MASK		REG_GENMASK(18, 16) /* ADL-P+ */
 #define  DBUF_MIN_TRACKER_STATE_SERVICE(x)		REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */
+#define  XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK	REG_GENMASK(20, 16)
+#define  XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(x)		REG_FIELD_PREP(XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x)
 
 #define MTL_LATENCY_LP0_LP1		_MMIO(0x45780)
 #define MTL_LATENCY_LP2_LP3		_MMIO(0x45784)

-- 
2.51.0


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

* [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (12 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-29 21:53   ` Matt Roper
  2025-10-29 22:22   ` Ville Syrjälä
  2025-10-22  0:28 ` [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment Gustavo Sousa
                   ` (18 subsequent siblings)
  32 siblings, 2 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Ville Syrjälä

In an upcoming change related to Xe3p_LPD, we will need to (i) update
wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
that is currently done when (wm[0] == 0).

Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
be done before it gets called.  In order to keep (i) and (ii) as a
contiguous logical sequence, let's reorder adjust_wm_latency(), making
make_wm_latency_monotonic() the last thing to be done.

Also take this opportunity to simplify the code by doing the call to
increase_wm_latency() only once.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index c141d575009f..57260a2a765a 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3213,14 +3213,13 @@ static void
 adjust_wm_latency(struct intel_display *display)
 {
 	u16 *wm = display->wm.skl_latency;
+	int inc = 0;
 
 	if (display->platform.dg2)
 		multiply_wm_latency(display, 2);
 
 	sanitize_wm_latency(display);
 
-	make_wm_latency_monotonic(display);
-
 	/*
 	 * WaWmMemoryReadLatency
 	 *
@@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
 	 * from the punit when level 0 response data is 0us.
 	 */
 	if (wm[0] == 0)
-		increase_wm_latency(display, wm_read_latency(display));
+		inc += wm_read_latency(display);
 
 	/*
 	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
@@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
 	 * to avoid any underrun.
 	 */
 	if (need_16gb_dimm_wa(display))
-		increase_wm_latency(display, 1);
+		inc += 1;
+
+	if (inc)
+		increase_wm_latency(display, inc);
+
+	make_wm_latency_monotonic(display);
 }
 
 static void mtl_read_wm_latency(struct intel_display *display)

-- 
2.51.0


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

* [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (13 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-29 22:08   ` Matt Roper
  2025-10-22  0:28 ` [PATCH v2 16/32] drm/i915/xe3p_lpd: Add CDCLK table Gustavo Sousa
                   ` (17 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Ville Syrjälä

When reading memory latencies for watermark calculations, previous
display releases instructed to apply an adjustment of adding a certain
value (e.g. 6us) to all levels when the level 0's memory latency read
from hardware was zero.

For Xe3p_LPD, the instruction is to always use 6us for level 0 and to
add that value to the other levels.  Update adjust_wm_latency()
accordingly.

While previously the adjustment was considered a workaround by the
driver, for Xe3p_LPD that is part of the formal specification.  So,
let's make sure that we differentiate those two in the driver code, even
if there is a bit of redundancy with "inc += wm_read_latency(display)"
appearing twice in the code.

v2:
  - Rebased after addition of prep patch "drm/i915/wm: Reorder
    adjust_wm_latency() for Xe3_LPD".

Bspec: 68986, 69126
Cc: Matt Atwood <matthew.s.atwood@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 57260a2a765a..5bb6cdc4ad2c 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3220,15 +3220,24 @@ adjust_wm_latency(struct intel_display *display)
 
 	sanitize_wm_latency(display);
 
-	/*
-	 * WaWmMemoryReadLatency
-	 *
-	 * punit doesn't take into account the read latency so we need
-	 * to add proper adjustment to each valid level we retrieve
-	 * from the punit when level 0 response data is 0us.
-	 */
-	if (wm[0] == 0)
+	if (DISPLAY_VER(display) >= 35) {
+		/*
+		 * Xe3p asks to ignore wm[0] read from the register and always
+		 * use the adjustment that adds the read latency to all valid
+		 * latency values.
+		 */
+		wm[0] = 0;
 		inc += wm_read_latency(display);
+	} else if (wm[0] == 0) {
+		/*
+		 * WaWmMemoryReadLatency
+		 *
+		 * punit doesn't take into account the read latency so we need
+		 * to add proper adjustment to each valid level we retrieve
+		 * from the punit when level 0 response data is 0us.
+		 */
+		inc += wm_read_latency(display);
+	}
 
 	/*
 	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+

-- 
2.51.0


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

* [PATCH v2 16/32] drm/i915/xe3p_lpd: Add CDCLK table
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (14 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 17/32] drm/i915/xe3p_lpd: Load DMC firmware Gustavo Sousa
                   ` (16 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Add CDCLK table for Xe3p_LPD.

Just as with Xe3_LPD, we don't need to send voltage index info in the
PMDemand message, so we are able to re-use xe3lpd_cdclk_funcs.

With the new CDCLK table, we also need to update the maximum CDCLK value
returned by intel_update_max_cdclk().

Bspec: 68861, 68863
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 44 ++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index e92e7fd9fd13..2365601b89e2 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1534,6 +1534,41 @@ static const struct intel_cdclk_vals xe3lpd_cdclk_table[] = {
 	{}
 };
 
+static const struct intel_cdclk_vals xe3p_lpd_cdclk_table[] = {
+	{ .refclk = 38400, .cdclk = 151200, .ratio = 21, .waveform = 0xa4a4 },
+	{ .refclk = 38400, .cdclk = 176400, .ratio = 21, .waveform = 0xaa54 },
+	{ .refclk = 38400, .cdclk = 201600, .ratio = 21, .waveform = 0xaaaa },
+	{ .refclk = 38400, .cdclk = 226800, .ratio = 21, .waveform = 0xad5a },
+	{ .refclk = 38400, .cdclk = 252000, .ratio = 21, .waveform = 0xb6b6 },
+	{ .refclk = 38400, .cdclk = 277200, .ratio = 21, .waveform = 0xdbb6 },
+	{ .refclk = 38400, .cdclk = 302400, .ratio = 21, .waveform = 0xeeee },
+	{ .refclk = 38400, .cdclk = 327600, .ratio = 21, .waveform = 0xf7de },
+	{ .refclk = 38400, .cdclk = 352800, .ratio = 21, .waveform = 0xfefe },
+	{ .refclk = 38400, .cdclk = 378000, .ratio = 21, .waveform = 0xfffe },
+	{ .refclk = 38400, .cdclk = 403200, .ratio = 21, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 422400, .ratio = 22, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 441600, .ratio = 23, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 460800, .ratio = 24, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 480000, .ratio = 25, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 499200, .ratio = 26, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 518400, .ratio = 27, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 537600, .ratio = 28, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 556800, .ratio = 29, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 576000, .ratio = 30, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 595200, .ratio = 31, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 614400, .ratio = 32, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 633600, .ratio = 33, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 672000, .ratio = 35, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 691200, .ratio = 36, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 710400, .ratio = 37, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 729600, .ratio = 38, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 748800, .ratio = 39, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 768000, .ratio = 40, .waveform = 0xffff },
+	{ .refclk = 38400, .cdclk = 787200, .ratio = 41, .waveform = 0xffff },
+	{}
+};
+
 static const int cdclk_squash_len = 16;
 
 static int cdclk_squash_divider(u16 waveform)
@@ -3560,7 +3595,9 @@ static int intel_compute_max_dotclk(struct intel_display *display)
  */
 void intel_update_max_cdclk(struct intel_display *display)
 {
-	if (DISPLAY_VERx100(display) >= 3002) {
+	if (DISPLAY_VER(display) >= 35) {
+		display->cdclk.max_cdclk_freq = 787200;
+	} else if (DISPLAY_VERx100(display) >= 3002) {
 		display->cdclk.max_cdclk_freq = 480000;
 	} else if (DISPLAY_VER(display) >= 30) {
 		display->cdclk.max_cdclk_freq = 691200;
@@ -3911,7 +3948,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = {
  */
 void intel_init_cdclk_hooks(struct intel_display *display)
 {
-	if (DISPLAY_VER(display) >= 30) {
+	if (DISPLAY_VER(display) >= 35) {
+		display->funcs.cdclk = &xe3lpd_cdclk_funcs;
+		display->cdclk.table = xe3p_lpd_cdclk_table;
+	} else if (DISPLAY_VER(display) >= 30) {
 		display->funcs.cdclk = &xe3lpd_cdclk_funcs;
 		display->cdclk.table = xe3lpd_cdclk_table;
 	} else if (DISPLAY_VER(display) >= 20) {

-- 
2.51.0


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

* [PATCH v2 17/32] drm/i915/xe3p_lpd: Load DMC firmware
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (15 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 16/32] drm/i915/xe3p_lpd: Add CDCLK table Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 18/32] drm/i915/xe3p_lpd: Drop support for interlace mode Gustavo Sousa
                   ` (15 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Load the DMC firmware for Xe3p_LPD.

Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dmc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index be6d37ea1139..098061c6bf2c 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -127,6 +127,9 @@ static bool dmc_firmware_param_disabled(struct intel_display *display)
 #define DISPLAY_VER13_DMC_MAX_FW_SIZE	0x20000
 #define DISPLAY_VER12_DMC_MAX_FW_SIZE	ICL_DMC_MAX_FW_SIZE
 
+#define XE3P_LPD_DMC_PATH		DMC_PATH(xe3p_lpd)
+MODULE_FIRMWARE(XE3P_LPD_DMC_PATH);
+
 #define XE3LPD_3002_DMC_PATH		DMC_PATH(xe3lpd_3002)
 MODULE_FIRMWARE(XE3LPD_3002_DMC_PATH);
 
@@ -186,7 +189,11 @@ static const char *dmc_firmware_default(struct intel_display *display, u32 *size
 {
 	const char *fw_path = NULL;
 	u32 max_fw_size = 0;
-	if (DISPLAY_VERx100(display) == 3002) {
+
+	if (DISPLAY_VERx100(display) == 3500) {
+		fw_path = XE3P_LPD_DMC_PATH;
+		max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
+	} else if (DISPLAY_VERx100(display) == 3002) {
 		fw_path = XE3LPD_3002_DMC_PATH;
 		max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
 	} else if (DISPLAY_VERx100(display) == 3000) {

-- 
2.51.0


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

* [PATCH v2 18/32] drm/i915/xe3p_lpd: Drop support for interlace mode
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (16 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 17/32] drm/i915/xe3p_lpd: Load DMC firmware Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4 Gustavo Sousa
                   ` (14 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Suraj Kandpal

From: Ankit Nautiyal <ankit.k.nautiyal@intel.com>

Interlace mode is officially removed from HW from Xe3p_LPD.  The
register TRANS_VSYNCSHIFT and the bits in TRANS_CONF are now removed, so
make sure we do not set/get these anymore.

Bspec: 69961, 70000
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index a8b4619de347..5ae02bfc2148 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2633,7 +2633,7 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
 		crtc_vblank_start = 1;
 	}
 
-	if (DISPLAY_VER(display) >= 4)
+	if (DISPLAY_VER(display) >= 4 && DISPLAY_VER(display) < 35)
 		intel_de_write(display,
 			       TRANS_VSYNCSHIFT(display, cpu_transcoder),
 			       vsyncshift);
@@ -2771,7 +2771,7 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
 	struct intel_display *display = to_intel_display(crtc_state);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
-	if (DISPLAY_VER(display) == 2)
+	if (DISPLAY_VER(display) == 2 || DISPLAY_VER(display) >= 35)
 		return false;
 
 	if (DISPLAY_VER(display) >= 9 ||
@@ -3162,10 +3162,12 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
 	if (display->platform.haswell && crtc_state->dither)
 		val |= TRANSCONF_DITHER_EN | TRANSCONF_DITHER_TYPE_SP;
 
-	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
-		val |= TRANSCONF_INTERLACE_IF_ID_ILK;
-	else
-		val |= TRANSCONF_INTERLACE_PF_PD_ILK;
+	if (DISPLAY_VER(display) < 35) {
+		if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+			val |= TRANSCONF_INTERLACE_IF_ID_ILK;
+		else
+			val |= TRANSCONF_INTERLACE_PF_PD_ILK;
+	}
 
 	if (display->platform.haswell &&
 	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)

-- 
2.51.0


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

* [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (17 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 18/32] drm/i915/xe3p_lpd: Drop support for interlace mode Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-29 22:14   ` Matt Roper
  2025-10-22  0:28 ` [PATCH v2 20/32] drm/i915/xe3p_lpd: Enable system caching for FBC Gustavo Sousa
                   ` (13 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

From: Jouni Högander <jouni.hogander@intel.com>

Ensure the minimum selective update line count is 4 in case of display
version 35 and onwards.

v2:
  - Fix style by dropping extra spaces after assignment operator.
    (Jani).

Bspec: 69887
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index cfc8b04f98fa..a23519b9b388 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2804,6 +2804,29 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
 		intel_psr_apply_pr_link_on_su_wa(crtc_state);
 }
 
+static void intel_psr_su_area_min_lines(struct intel_crtc_state *crtc_state)
+{
+	struct intel_display *display = to_intel_display(crtc_state);
+	struct drm_rect damaged_area;
+
+	/*
+	 * Bspec mentions 4 being minimum lines in SU for display version
+	 * 35 and onwards.
+	 */
+	if (DISPLAY_VER(display) < 35 || drm_rect_height(&crtc_state->psr2_su_area) >= 4)
+		return;
+
+	damaged_area.x1 = crtc_state->psr2_su_area.x1;
+	damaged_area.y1 = crtc_state->psr2_su_area.y1;
+	damaged_area.x2 = crtc_state->psr2_su_area.x2;
+	damaged_area.y2 = crtc_state->psr2_su_area.y2;
+
+	damaged_area.y2 += 4 - drm_rect_height(&damaged_area);
+	drm_rect_intersect(&damaged_area, &crtc_state->pipe_src);
+	damaged_area.y1 -= 4 - drm_rect_height(&damaged_area);
+	clip_area_update(&crtc_state->psr2_su_area, &damaged_area, &crtc_state->pipe_src);
+}
+
 int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 				struct intel_crtc *crtc)
 {
@@ -2912,6 +2935,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 	if (full_update)
 		goto skip_sel_fetch_set_loop;
 
+	intel_psr_su_area_min_lines(crtc_state);
+
 	intel_psr_apply_su_area_workarounds(crtc_state);
 
 	ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);

-- 
2.51.0


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

* [PATCH v2 20/32] drm/i915/xe3p_lpd: Enable system caching for FBC
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (18 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4 Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 21/32] drm/i915/xe3p_lpd: Extend Wa_16025573575 Gustavo Sousa
                   ` (12 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Vinod Govindapillai <vinod.govindapillai@intel.com>

Configure one of the FBC instances to use system caching. FBC
read/write requests are tagged as cacheable till a programmed
limit is reached by the hw.

Bspec: 74722
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c      | 47 +++++++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_fbc_regs.h |  9 +++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index af3585aeefd3..368b1ff1dc8c 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -126,6 +126,9 @@ struct intel_fbc {
 	 */
 	struct intel_fbc_state state;
 	const char *no_fbc_reason;
+
+	/* Only one of FBC instances can use the system cache */
+	bool own_sys_cache;
 };
 
 /* plane stride in pixels */
@@ -570,12 +573,51 @@ static bool ilk_fbc_is_compressing(struct intel_fbc *fbc)
 	return intel_de_read(fbc->display, ILK_DPFC_STATUS(fbc->id)) & DPFC_COMP_SEG_MASK;
 }
 
+static void nvl_fbc_program_system_cache(struct intel_fbc *fbc, bool enable)
+{
+	struct intel_display *display = fbc->display;
+	u32 cfb_offset, usage;
+
+	lockdep_assert_held(&fbc->lock);
+
+	usage = intel_de_read(display, NVL_FBC_SYS_CACHE_USAGE_CFG);
+
+	/* System cache already being used by another pipe */
+	if (enable && (usage & FBC_SYS_CACHE_TAG_USE_RES_SPACE))
+		return;
+
+	/* Only the fbc instance which owns system cache can disable it */
+	if (!enable && !fbc->own_sys_cache)
+		return;
+
+	/*
+	 * Not programming the cache limit and cache reading enable bits explicitly
+	 * here. The default values should take care of those and that could leave
+	 * adjustments of those bits to the system hw policy
+	 *
+	 * TODO: check if we need to explicitly program these?
+	 */
+	cfb_offset = enable ? i915_gem_stolen_node_offset(fbc->compressed_fb) : 0;
+	usage |= FBC_SYS_CACHE_START_BASE(cfb_offset);
+	usage |= enable ? FBC_SYS_CACHE_TAG_USE_RES_SPACE : FBC_SYS_CACHE_TAG_DONT_CACHE;
+
+	intel_de_write(display, NVL_FBC_SYS_CACHE_USAGE_CFG, usage);
+
+	fbc->own_sys_cache = enable;
+
+	drm_dbg_kms(display->drm, "System caching for FBC[%d] %s\n",
+		    fbc->id, enable ? "configured" : "cleared");
+}
+
 static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
 {
 	struct intel_display *display = fbc->display;
 
 	intel_de_write(display, ILK_DPFC_CB_BASE(fbc->id),
 		       i915_gem_stolen_node_offset(fbc->compressed_fb));
+
+	if (DISPLAY_VER(display) >= 35)
+		nvl_fbc_program_system_cache(fbc, true);
 }
 
 static const struct intel_fbc_funcs ilk_fbc_funcs = {
@@ -953,6 +995,8 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
 
 static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
 {
+	struct intel_display *display = fbc->display;
+
 	if (WARN_ON(intel_fbc_hw_is_active(fbc)))
 		return;
 
@@ -960,6 +1004,9 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
 		i915_gem_stolen_remove_node(fbc->compressed_llb);
 	if (i915_gem_stolen_node_allocated(fbc->compressed_fb))
 		i915_gem_stolen_remove_node(fbc->compressed_fb);
+
+	if (DISPLAY_VER(display) >= 35)
+		nvl_fbc_program_system_cache(fbc, false);
 }
 
 void intel_fbc_cleanup(struct intel_display *display)
diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
index 272dba7f9695..e8d2e41ede98 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
@@ -128,4 +128,13 @@
 #define   FBC_REND_NUKE			REG_BIT(2)
 #define   FBC_REND_CACHE_CLEAN		REG_BIT(1)
 
+#define NVL_FBC_SYS_CACHE_USAGE_CFG             _MMIO(0x1344E0)
+#define   FBC_SYS_CACHE_START_BASE_MASK         REG_GENMASK(31, 16)
+#define   FBC_SYS_CACHE_START_BASE(base)        REG_FIELD_PREP(FBC_SYS_CACHE_START_BASE_MASK, (base))
+#define   FBC_SYS_CACHEABLE_RANGE_MASK          REG_GENMASK(15, 4)
+#define   FBC_SYS_CACHEABLE_RANGE(range)        REG_FIELD_PREP(FBC_SYS_CACHEABLE_RANGE_MASK, (range))
+#define   FBC_SYS_CACHE_TAG_MASK                REG_GENMASK(3, 2)
+#define   FBC_SYS_CACHE_TAG_DONT_CACHE          REG_FIELD_PREP(FBC_SYS_CACHE_TAG_MASK, 0)
+#define   FBC_SYS_CACHE_TAG_USE_RES_SPACE       REG_FIELD_PREP(FBC_SYS_CACHE_TAG_MASK, 3)
+
 #endif /* __INTEL_FBC_REGS__ */

-- 
2.51.0


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

* [PATCH v2 21/32] drm/i915/xe3p_lpd: Extend Wa_16025573575
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (19 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 20/32] drm/i915/xe3p_lpd: Enable system caching for FBC Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 22/32] drm/i915/xe3p_lpd: Don't allow odd ypan or ysize with semiplanar format Gustavo Sousa
                   ` (11 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Wa_16025573575 also applies to Xe3p_LPD, so let's include it in the IP
version checks.

Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_wa.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c
index c528aaa679ca..e38e5e87877c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_wa.c
+++ b/drivers/gpu/drm/i915/display/intel_display_wa.c
@@ -49,7 +49,8 @@ void intel_display_wa_apply(struct intel_display *display)
  */
 static bool intel_display_needs_wa_16025573575(struct intel_display *display)
 {
-	return DISPLAY_VERx100(display) == 3000 || DISPLAY_VERx100(display) == 3002;
+	return DISPLAY_VERx100(display) == 3000 || DISPLAY_VERx100(display) == 3002 ||
+		DISPLAY_VERx100(display) == 3500;
 }
 
 /*

-- 
2.51.0


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

* [PATCH v2 22/32] drm/i915/xe3p_lpd: Don't allow odd ypan or ysize with semiplanar format
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (20 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 21/32] drm/i915/xe3p_lpd: Extend Wa_16025573575 Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 23/32] drm/i915/xe3p_lpd: Reload DMC MMIO for pipes C and D Gustavo Sousa
                   ` (10 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Juha-pekka Heikkila <juha-pekka.heikkila@intel.com>

Disable support for odd panning and size in y direction when running on
display version 35 and using semiplanar formats.

Bspec: 68903
Signed-off-by: Juha-pekka Heikkila <juha-pekka.heikkila@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_plane.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index 78329deb395a..ddf8dfbf6b2f 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -1050,6 +1050,9 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
 		     DISPLAY_VERx100(display) == 3002) &&
 		     src_x % 2 != 0)
 			hsub = 2;
+
+		if (DISPLAY_VER(display) == 35)
+			vsub = 2;
 	} else {
 		hsub = fb->format->hsub;
 		vsub = fb->format->vsub;

-- 
2.51.0


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

* [PATCH v2 23/32] drm/i915/xe3p_lpd: Reload DMC MMIO for pipes C and D
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (21 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 22/32] drm/i915/xe3p_lpd: Don't allow odd ypan or ysize with semiplanar format Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 24/32] drm/i915/xe3p_lpd: Introduce pixel normalizer config support Gustavo Sousa
                   ` (9 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Xe3p_LPD has the same behavior as for Xe3_LPD with respect to DMC
context data for pipes C and D, which are lost when their power wells
are disabled.  As such, let's extend the condition for Xe3_LPD in
need_pipedmc_load_mmio() to also catch Xe3p_LPD.

Bspec: 68851
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 098061c6bf2c..8b8ed84c6a4b 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -673,11 +673,11 @@ static bool need_pipedmc_load_program(struct intel_display *display)
 static bool need_pipedmc_load_mmio(struct intel_display *display, enum pipe pipe)
 {
 	/*
-	 * PTL:
+	 * Xe3_LPD/Xe3p_LPD:
 	 * - pipe A/B DMC doesn't need save/restore
 	 * - pipe C/D DMC is in PG0, needs manual save/restore
 	 */
-	if (DISPLAY_VER(display) == 30)
+	if (IS_DISPLAY_VER(display, 30, 35))
 		return pipe >= PIPE_C;
 
 	/*

-- 
2.51.0


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

* [PATCH v2 24/32] drm/i915/xe3p_lpd: Introduce pixel normalizer config support
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (22 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 23/32] drm/i915/xe3p_lpd: Reload DMC MMIO for pipes C and D Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 25/32] drm/i915/xe3p_lpd: Add FBC support for FP16 formats Gustavo Sousa
                   ` (8 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Vinod Govindapillai <vinod.govindapillai@intel.com>

To enable FBC for FP16 formats, we need to enable the pixel normalizer
block. Introduce the register definitions and the initial steps for
configuring the pixel normalizer block. In this patch the pixel
normalizer block is kept as disabled. The follow-up patches will handle
configuring the pixel normalizer block for hdr planes for FP16 formats.

Bspec: 69863
Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_types.h      |  3 +++
 drivers/gpu/drm/i915/display/skl_universal_plane.c      | 15 +++++++++++++++
 drivers/gpu/drm/i915/display/skl_universal_plane_regs.h | 11 +++++++++++
 3 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5ae66b7444b6..bba03791f0ea 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -679,6 +679,9 @@ struct intel_plane_state {
 	/* surface address register */
 	u32 surf;
 
+	/* plane pixel normalizer config for Xe3p_LPD+ FBC FP16 */
+	u32 pixel_normalizer;
+
 	/*
 	 * scaler_id
 	 *    = -1 : not using a scaler
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 9f1111324dab..16a9c141281b 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -893,6 +893,12 @@ static void skl_write_plane_wm(struct intel_dsb *dsb,
 				   xe3_plane_min_ddb_reg_val(min_ddb, interim_ddb));
 }
 
+static void
+xe3p_lpd_plane_check_pixel_normalizer(struct intel_plane_state *plane_state)
+{
+	plane_state->pixel_normalizer = 0;
+}
+
 static void
 skl_plane_disable_arm(struct intel_dsb *dsb,
 		      struct intel_plane *plane,
@@ -1671,6 +1677,11 @@ icl_plane_update_arm(struct intel_dsb *dsb,
 
 	icl_plane_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
 
+	/* Only the HDR planes can have pixel normalizer */
+	if (DISPLAY_VER(display) >= 35 && icl_is_hdr_plane(display, plane_id))
+		intel_de_write_dsb(display, dsb,
+				   PLANE_PIXEL_NORMALIZE(plane->pipe, plane->id),
+				   plane_state->pixel_normalizer);
 	/*
 	 * The control register self-arms if the plane was previously
 	 * disabled. Try to make the plane enable atomic by writing
@@ -2385,6 +2396,10 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 		plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
 	}
 
+	/* Pixel normalizer for Xe3p_LPD+ */
+	if (DISPLAY_VER(display) >= 35 && icl_is_hdr_plane(display, plane->id))
+		xe3p_lpd_plane_check_pixel_normalizer(plane_state);
+
 	plane_state->ctl = skl_plane_ctl(plane_state);
 
 	if (DISPLAY_VER(display) >= 10)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
index 84cf565bd653..11c713f9b237 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
@@ -456,4 +456,15 @@
 								_SEL_FETCH_PLANE_OFFSET_5_A, _SEL_FETCH_PLANE_OFFSET_5_B, \
 								_SEL_FETCH_PLANE_OFFSET_6_A, _SEL_FETCH_PLANE_OFFSET_6_B)
 
+#define _PLANE_PIXEL_NORMALIZE_1_A		0x701a8
+#define _PLANE_PIXEL_NORMALIZE_2_A		0x702a8
+#define _PLANE_PIXEL_NORMALIZE_1_B		0x711a8
+#define _PLANE_PIXEL_NORMALIZE_2_B		0x712a8
+#define PLANE_PIXEL_NORMALIZE(pipe, plane)	_MMIO_SKL_PLANE((pipe), (plane), \
+								_PLANE_PIXEL_NORMALIZE_1_A, _PLANE_PIXEL_NORMALIZE_1_B, \
+								_PLANE_PIXEL_NORMALIZE_2_A, _PLANE_PIXEL_NORMALIZE_2_B)
+#define   PLANE_PIXEL_NORMALIZE_ENABLE			REG_BIT(31)
+#define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR_MASK	REG_GENMASK(15, 0)
+#define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR(val)	REG_FIELD_PREP(PLANE_PIXEL_NORMALIZE_NORM_FACTOR_MASK, (val))
+
 #endif /* __SKL_UNIVERSAL_PLANE_REGS_H__ */

-- 
2.51.0


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

* [PATCH v2 25/32] drm/i915/xe3p_lpd: Add FBC support for FP16 formats
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (23 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 24/32] drm/i915/xe3p_lpd: Introduce pixel normalizer config support Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 26/32] drm/i915/xe3p_lpd: Enable pixel normalizer for fp16 formats for FBC Gustavo Sousa
                   ` (7 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Vinod Govindapillai <vinod.govindapillai@intel.com>

Add supported FP16 formats for FBC. FBC can be enabled with FP16 formats
only when plane pixel normalizer block is enabled.

Bspec: 6881, 69863, 68904
Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c | 37 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_fbc.h |  1 +
 2 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 368b1ff1dc8c..6f31294c6a6d 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -63,6 +63,7 @@
 #include "intel_fbc.h"
 #include "intel_fbc_regs.h"
 #include "intel_frontbuffer.h"
+#include "skl_universal_plane_regs.h"
 
 #define for_each_fbc_id(__display, __fbc_id) \
 	for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \
@@ -153,6 +154,8 @@ static unsigned int intel_fbc_cfb_cpp(const struct intel_plane_state *plane_stat
 	case DRM_FORMAT_XBGR16161616:
 	case DRM_FORMAT_ARGB16161616:
 	case DRM_FORMAT_ABGR16161616:
+	case DRM_FORMAT_ARGB16161616F:
+	case DRM_FORMAT_ABGR16161616F:
 		return 8;
 	default:
 		return 4;
@@ -695,6 +698,30 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
 		     CHICKEN_FBC_STRIDE_MASK, val);
 }
 
+static bool
+xe3p_lpd_fbc_is_fp16_format(const struct intel_plane_state *plane_state)
+{
+	const struct drm_framebuffer *fb = plane_state->hw.fb;
+
+	switch (fb->format->format) {
+	case DRM_FORMAT_ARGB16161616F:
+	case DRM_FORMAT_ABGR16161616F:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+intel_fbc_is_fp16_format_supported(const struct intel_plane_state *plane_state)
+{
+	struct intel_display *display = to_intel_display(plane_state);
+
+	if (DISPLAY_VER(display) >= 35)
+		return xe3p_lpd_fbc_is_fp16_format(plane_state);
+
+	return false;
+}
 static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
 {
 	struct intel_display *display = fbc->display;
@@ -810,6 +837,8 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
 static void intel_fbc_activate(struct intel_fbc *fbc)
 {
 	struct intel_display *display = fbc->display;
+	struct intel_plane *plane = fbc->state.plane;
+	struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state);
 
 	lockdep_assert_held(&fbc->lock);
 
@@ -822,6 +851,11 @@ static void intel_fbc_activate(struct intel_fbc *fbc)
 	 */
 	drm_WARN_ON(display->drm, fbc->active && HAS_FBC_DIRTY_RECT(display));
 
+	drm_WARN_ON(display->drm,
+		    DISPLAY_VER(display) >= 35 &&
+		    xe3p_lpd_fbc_is_fp16_format(plane_state) &&
+		    (plane_state->pixel_normalizer & PLANE_PIXEL_NORMALIZE_ENABLE) == 0);
+
 	intel_fbc_hw_activate(fbc);
 	intel_fbc_nuke(fbc);
 
@@ -1142,6 +1176,9 @@ static bool xe3p_lpd_fbc_pixel_format_is_valid(const struct intel_plane_state *p
 {
 	const struct drm_framebuffer *fb = plane_state->hw.fb;
 
+	if (xe3p_lpd_fbc_is_fp16_format(plane_state))
+		return true;
+
 	switch (fb->format->format) {
 	case DRM_FORMAT_XRGB8888:
 	case DRM_FORMAT_XBGR8888:
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h
index c86562404a00..dc7c76bfd135 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc.h
@@ -53,5 +53,6 @@ void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
 				  struct intel_crtc *crtc);
 void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
 				       struct intel_plane *plane);
+bool intel_fbc_is_fp16_format_supported(const struct intel_plane_state *plane_state);
 
 #endif /* __INTEL_FBC_H__ */

-- 
2.51.0


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

* [PATCH v2 26/32] drm/i915/xe3p_lpd: Enable pixel normalizer for fp16 formats for FBC
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (24 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 25/32] drm/i915/xe3p_lpd: Add FBC support for FP16 formats Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 27/32] drm/i915/vbt: Add fields dedicated_external and dyn_port_over_tc Gustavo Sousa
                   ` (6 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Vinod Govindapillai <vinod.govindapillai@intel.com>

There is a hw restriction that we could enable the FBC for FP16
formats only if the pixel normalization block is enabled. Hence
enable the pixel normalizer block with normalzation factor as
1.0 for the supported FP16 formats to get the FBC enabled. Two
existing helper function definitions are moved up to avoid the
forward declarations as part of this patch as well.

Bspec: 69863, 68881
Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 50 ++++++++++++++--------
 .../drm/i915/display/skl_universal_plane_regs.h    |  1 +
 2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 16a9c141281b..ae1bf6beac95 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -486,6 +486,23 @@ static int skl_plane_max_height(const struct drm_framebuffer *fb,
 	return 4096;
 }
 
+static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
+{
+	return pipe - PIPE_A + INTEL_FBC_A;
+}
+
+static bool skl_plane_has_fbc(struct intel_display *display,
+			      enum intel_fbc_id fbc_id, enum plane_id plane_id)
+{
+	if ((DISPLAY_RUNTIME_INFO(display)->fbc_mask & BIT(fbc_id)) == 0)
+		return false;
+
+	if (DISPLAY_VER(display) >= 20)
+		return icl_is_hdr_plane(display, plane_id);
+	else
+		return plane_id == PLANE_1;
+}
+
 static int icl_plane_max_height(const struct drm_framebuffer *fb,
 				int color_plane,
 				unsigned int rotation)
@@ -896,7 +913,21 @@ static void skl_write_plane_wm(struct intel_dsb *dsb,
 static void
 xe3p_lpd_plane_check_pixel_normalizer(struct intel_plane_state *plane_state)
 {
-	plane_state->pixel_normalizer = 0;
+	struct intel_display *display = to_intel_display(plane_state);
+	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+	enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(plane->pipe);
+	u32 reg = 0;
+
+	/*
+	 * To enable FBC for FP16 formats, enable pixel normalizer with
+	 * normalization factor as 1.0
+	 */
+	if (skl_plane_has_fbc(display, fbc_id, plane->id) &&
+	    intel_fbc_is_fp16_format_supported(plane_state))
+		reg = PLANE_PIXEL_NORMALIZE_NORM_FACTOR(PLANE_PIXEL_NORMALIZE_NORM_FACTOR_1_0) |
+		      PLANE_PIXEL_NORMALIZE_ENABLE;
+
+	plane_state->pixel_normalizer = reg;
 }
 
 static void
@@ -2449,23 +2480,6 @@ void icl_link_nv12_planes(struct intel_plane_state *uv_plane_state,
 	}
 }
 
-static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
-{
-	return pipe - PIPE_A + INTEL_FBC_A;
-}
-
-static bool skl_plane_has_fbc(struct intel_display *display,
-			      enum intel_fbc_id fbc_id, enum plane_id plane_id)
-{
-	if ((DISPLAY_RUNTIME_INFO(display)->fbc_mask & BIT(fbc_id)) == 0)
-		return false;
-
-	if (DISPLAY_VER(display) >= 20)
-		return icl_is_hdr_plane(display, plane_id);
-	else
-		return plane_id == PLANE_1;
-}
-
 static struct intel_fbc *skl_plane_fbc(struct intel_display *display,
 				       enum pipe pipe, enum plane_id plane_id)
 {
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
index 11c713f9b237..eb25de5d1778 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
@@ -466,5 +466,6 @@
 #define   PLANE_PIXEL_NORMALIZE_ENABLE			REG_BIT(31)
 #define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR_MASK	REG_GENMASK(15, 0)
 #define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR(val)	REG_FIELD_PREP(PLANE_PIXEL_NORMALIZE_NORM_FACTOR_MASK, (val))
+#define   PLANE_PIXEL_NORMALIZE_NORM_FACTOR_1_0		0x3c00
 
 #endif /* __SKL_UNIVERSAL_PLANE_REGS_H__ */

-- 
2.51.0


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

* [PATCH v2 27/32] drm/i915/vbt: Add fields dedicated_external and dyn_port_over_tc
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (25 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 26/32] drm/i915/xe3p_lpd: Enable pixel normalizer for fp16 formats for FBC Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 28/32] drm/i915/power: Use intel_encoder_is_tc() Gustavo Sousa
                   ` (5 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

VBT version 264 adds new fields associated to Xe3p_LPD's new ways of
configuring SoC for TC ports and PHYs.  Update the code to match the
updates in VBT.

The new field dedicated_external is used to represent TC ports that are
connected to PHYs outside of the Type-C subsystem, meaning that they
behave like dedicated ports and don't require the extra Type-C
programming.  In an upcoming change, we will update the driver to take
this field into consideration when detecting the type of port.

The new field dyn_port_over_tc is used to inform that the TC port can be
dynamically allocated for a legacy connector in the Type-C subsystem,
which is a new feature in Xe3p_LPD.  In upcoming changes, we will use
that field in order to handle the IOM resource management programming
required for that.

Note that, when dedicated_external is set, the fields dp_usb_type_c and
tbt are tagged as "don't care" in the spec, so they should be ignored in
that case, so also add a sanitization function to take care of forcing
them to zero when dedicated_external is true.

v2:
  - Use sanitization function to force dp_usb_type_c and tbt fields to
    be zero instead of adding a
    intel_bios_encoder_is_dedicated_external() check in each of their
    respective accessor functions. (Jani)
  - Print info about dedicated external ports in print_ddi_port().
    (Jani)

Bspec: 20124, 68954, 74304
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c     | 54 ++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_bios.h     |  2 +
 drivers/gpu/drm/i915/display/intel_vbt_defs.h |  3 +-
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 3596dce84c28..b9022137020a 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -2529,6 +2529,36 @@ intel_bios_encoder_reject_edp_rate(const struct intel_bios_encoder_data *devdata
 	return devdata->child.edp_data_rate_override & edp_rate_override_mask(rate);
 }
 
+static void sanitize_dedicated_external(struct intel_bios_encoder_data *devdata,
+					enum port port)
+{
+	struct intel_display *display = devdata->display;
+
+	if (!intel_bios_encoder_is_dedicated_external(devdata))
+		return;
+
+	/*
+	 * Fields dp_usb_type_c and tbt must be ignored when
+	 * dedicated_external is set.  Since dedicated_external is for
+	 * ports connected to PHYs outside of the Type-C subsystem, it
+	 * is safe to force those fields to zero.
+	 */
+
+	if (devdata->child.dp_usb_type_c) {
+		drm_dbg_kms(display->drm,
+			    "VBT claims Port %c supports USB Type-C, but the port is dedicated external, ignoring\n",
+			    port_name(port));
+		devdata->child.dp_usb_type_c = 0;
+	}
+
+	if (devdata->child.tbt) {
+		drm_dbg_kms(display->drm,
+			    "VBT claims Port %c supports TBT, but the port is dedicated external, ignoring\n",
+			    port_name(port));
+		devdata->child.tbt = 0;
+	}
+}
+
 static void sanitize_device_type(struct intel_bios_encoder_data *devdata,
 				 enum port port)
 {
@@ -2667,7 +2697,8 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
 {
 	struct intel_display *display = devdata->display;
 	const struct child_device_config *child = &devdata->child;
-	bool is_dvi, is_hdmi, is_dp, is_edp, is_dsi, is_crt, supports_typec_usb, supports_tbt;
+	bool is_dvi, is_hdmi, is_dp, is_edp, is_dsi, is_crt, supports_typec_usb,
+		supports_tbt, dedicated_external;
 	int dp_boost_level, dp_max_link_rate, hdmi_boost_level, hdmi_level_shift, max_tmds_clock;
 	enum port port;
 
@@ -2693,6 +2724,12 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
 		    supports_typec_usb, supports_tbt,
 		    devdata->dsc != NULL);
 
+	dedicated_external = intel_bios_encoder_is_dedicated_external(devdata);
+	if (dedicated_external)
+		drm_dbg_kms(display->drm,
+			    "Port %c is dedicated external\n",
+			    port_name(port));
+
 	hdmi_level_shift = intel_bios_hdmi_level_shift(devdata);
 	if (hdmi_level_shift >= 0) {
 		drm_dbg_kms(display->drm,
@@ -2750,6 +2787,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
 		return;
 	}
 
+	sanitize_dedicated_external(devdata, port);
 	sanitize_device_type(devdata, port);
 	sanitize_hdmi_level_shift(devdata, port);
 }
@@ -2777,7 +2815,7 @@ static int child_device_expected_size(u16 version)
 {
 	BUILD_BUG_ON(sizeof(struct child_device_config) < 40);
 
-	if (version > 263)
+	if (version > 264)
 		return -ENOENT;
 	else if (version >= 263)
 		return 44;
@@ -3722,6 +3760,18 @@ bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devda
 	return devdata->display->vbt.version >= 209 && devdata->child.tbt;
 }
 
+bool intel_bios_encoder_is_dedicated_external(const struct intel_bios_encoder_data *devdata)
+{
+	return devdata->display->vbt.version >= 264 &&
+		devdata->child.dedicated_external;
+}
+
+bool intel_bios_encoder_supports_dyn_port_over_tc(const struct intel_bios_encoder_data *devdata)
+{
+	return devdata->display->vbt.version >= 264 &&
+		devdata->child.dyn_port_over_tc;
+}
+
 bool intel_bios_encoder_lane_reversal(const struct intel_bios_encoder_data *devdata)
 {
 	return devdata && devdata->child.lane_reversal;
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
index f9e438b2787b..75dff27b4228 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -79,6 +79,8 @@ bool intel_bios_encoder_supports_dp(const struct intel_bios_encoder_data *devdat
 bool intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata);
 bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata);
 bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devdata);
+bool intel_bios_encoder_is_dedicated_external(const struct intel_bios_encoder_data *devdata);
+bool intel_bios_encoder_supports_dyn_port_over_tc(const struct intel_bios_encoder_data *devdata);
 bool intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data *devdata);
 bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata);
 bool intel_bios_encoder_is_lspcon(const struct intel_bios_encoder_data *devdata);
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index 70e31520c560..57fda5824c9c 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -554,7 +554,8 @@ struct child_device_config {
 	u8 dvo_function;
 	u8 dp_usb_type_c:1;					/* 195+ */
 	u8 tbt:1;						/* 209+ */
-	u8 flags2_reserved:2;					/* 195+ */
+	u8 dedicated_external:1;				/* 264+ */
+	u8 dyn_port_over_tc:1;					/* 264+ */
 	u8 dp_port_trace_length:4;				/* 209+ */
 	u8 dp_gpio_index;					/* 195+ */
 	u16 dp_gpio_pin_num;					/* 195+ */

-- 
2.51.0


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

* [PATCH v2 28/32] drm/i915/power: Use intel_encoder_is_tc()
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (26 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 27/32] drm/i915/vbt: Add fields dedicated_external and dyn_port_over_tc Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 29/32] drm/i915/display: Handle dedicated external ports in intel_encoder_is_tc() Gustavo Sousa
                   ` (4 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Suraj Kandpal

Starting with Xe3p_LPD, when intel_phy_is_tc() returns true, it does
not necessarily mean that the port is connected to a PHY in the Type-C
subsystem.  The reason is that there is now a VBT field called
dedicated_external that will indicate that a Type-C capable port is
connected to a (most likely) combo/dedicated PHY.  When that's the case,
we must not do the extra programming required for Type-C connections.

In an upcoming change, we will modify intel_encoder_is_tc() to take the
VBT field dedicated_external into consideration.  Update
intel_display_power_well.c to use that function instead of
intel_phy_is_tc().

Note that, even though icl_aux_power_well_{enable,disable} are not part
of Xe3p_LPD's display paths, we modify them anyway for uniformity.

Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 .../drm/i915/display/intel_display_power_well.c    | 26 +++++++++++++++-------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
index ba2552adb58b..e8200672dcf3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -256,8 +256,9 @@ aux_ch_to_digital_port(struct intel_display *display,
 	return NULL;
 }
 
-static enum phy icl_aux_pw_to_phy(struct intel_display *display,
-				  const struct i915_power_well *power_well)
+static struct intel_encoder *
+icl_aux_pw_to_encoder(struct intel_display *display,
+		      const struct i915_power_well *power_well)
 {
 	enum aux_ch aux_ch = icl_aux_pw_to_ch(power_well);
 	struct intel_digital_port *dig_port = aux_ch_to_digital_port(display, aux_ch);
@@ -269,7 +270,15 @@ static enum phy icl_aux_pw_to_phy(struct intel_display *display,
 	 * as HDMI-only and routed to a combo PHY, the encoder either won't be
 	 * present at all or it will not have an aux_ch assigned.
 	 */
-	return dig_port ? intel_encoder_to_phy(&dig_port->base) : PHY_NONE;
+	return dig_port ? &dig_port->base : NULL;
+}
+
+static enum phy icl_aux_pw_to_phy(struct intel_display *display,
+				  const struct i915_power_well *power_well)
+{
+	struct intel_encoder *encoder = icl_aux_pw_to_encoder(display, power_well);
+
+	return encoder ? intel_encoder_to_phy(encoder) : PHY_NONE;
 }
 
 static void hsw_wait_for_power_well_enable(struct intel_display *display,
@@ -568,9 +577,9 @@ static void
 icl_aux_power_well_enable(struct intel_display *display,
 			  struct i915_power_well *power_well)
 {
-	enum phy phy = icl_aux_pw_to_phy(display, power_well);
+	struct intel_encoder *encoder = icl_aux_pw_to_encoder(display, power_well);
 
-	if (intel_phy_is_tc(display, phy))
+	if (encoder && intel_encoder_is_tc(encoder))
 		return icl_tc_phy_aux_power_well_enable(display, power_well);
 	else if (display->platform.icelake)
 		return icl_combo_phy_aux_power_well_enable(display,
@@ -583,9 +592,9 @@ static void
 icl_aux_power_well_disable(struct intel_display *display,
 			   struct i915_power_well *power_well)
 {
-	enum phy phy = icl_aux_pw_to_phy(display, power_well);
+	struct intel_encoder *encoder = icl_aux_pw_to_encoder(display, power_well);
 
-	if (intel_phy_is_tc(display, phy))
+	if (encoder && intel_encoder_is_tc(encoder))
 		return hsw_power_well_disable(display, power_well);
 	else if (display->platform.icelake)
 		return icl_combo_phy_aux_power_well_disable(display,
@@ -1847,10 +1856,11 @@ tgl_tc_cold_off_power_well_is_enabled(struct intel_display *display,
 static void xelpdp_aux_power_well_enable(struct intel_display *display,
 					 struct i915_power_well *power_well)
 {
+	struct intel_encoder *encoder = icl_aux_pw_to_encoder(display, power_well);
 	enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
 	enum phy phy = icl_aux_pw_to_phy(display, power_well);
 
-	if (intel_phy_is_tc(display, phy))
+	if (encoder && intel_encoder_is_tc(encoder))
 		icl_tc_port_assert_ref_held(display, power_well,
 					    aux_ch_to_digital_port(display, aux_ch));
 

-- 
2.51.0


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

* [PATCH v2 29/32] drm/i915/display: Handle dedicated external ports in intel_encoder_is_tc()
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (27 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 28/32] drm/i915/power: Use intel_encoder_is_tc() Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 30/32] drm/i915/wm: don't use method1 in Xe3p_LPD onwards Gustavo Sousa
                   ` (3 subsequent siblings)
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

Starting with Xe3p_LPD, the VBT has a new field, called in the driver
"dedicated_external", which tells that a Type-C capable port is
physically connected to a PHY outside of the Type-C subsystem.  When
that's the case, the driver must not do the extra Type-C programming for
that port.  Update intel_encoder_is_tc() to check for that case.

While at it, add a note to intel_phy_is_tc() to remind us that it is
about whether the respective port is a Type-C capable port rather than
the PHY itself.

(Maybe it would be a nice idea to rename intel_phy_is_tc()?)

Note that this was handled with a new bool member added to struct
intel_digital_port instead of having querying the VBT directly because
VBT memory is freed (intel_bios_driver_remove) before encoder cleanup
(intel_ddi_encoder_destroy), which would cause an oops to happen when
the latter calls intel_encoder_is_tc().  This could be fixed by keeping
VBT data around longer, but that's left for a follow-up work, if deemed
necessary.

v2:
  - Drop printing info about dedicated external, now that we are doing
    it when parsing the VBT. (Jani)
  - Add a FIXME comment on the code explaining why we need to store
    dedicated_external in struct intel_digital_port. (Jani)

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c           | 11 +++++++++++
 drivers/gpu/drm/i915/display/intel_display.c       | 19 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_display_types.h |  1 +
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 870140340342..a3dc384cfd71 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -5350,6 +5350,17 @@ void intel_ddi_init(struct intel_display *display,
 			goto err;
 	}
 
+	/*
+	 * FIXME: We currently need to store dedicated_external because devdata
+	 * does not live long enough for when intel_encoder_is_tc() is called on
+	 * the unbind path.  This needs to be fixed by making sure that the VBT
+	 * data is kept long enough, so that
+	 * intel_bios_encoder_is_dedicated_external() can be called directly
+	 * from intel_encoder_is_tc().
+	 */
+	if (intel_bios_encoder_is_dedicated_external(devdata))
+		dig_port->dedicated_external = true;
+
 	if (intel_encoder_is_tc(encoder)) {
 		bool is_legacy =
 			!intel_bios_encoder_supports_typec_usb(devdata) &&
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 5ae02bfc2148..20885b81917f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1778,7 +1778,17 @@ bool intel_phy_is_combo(struct intel_display *display, enum phy phy)
 		return false;
 }
 
-/* Prefer intel_encoder_is_tc() */
+/*
+ * This function returns true if the DDI port respective to the PHY enumeration
+ * is a Type-C capable port.
+ *
+ * Depending on the VBT, the port might be configured
+ * as a "dedicated external" port, meaning that actual physical PHY is outside
+ * of the Type-C subsystem and, as such, not really a "Type-C PHY".
+ *
+ * Prefer intel_encoder_is_tc(), especially if you really need to know if we
+ * are dealing with Type-C connections.
+ */
 bool intel_phy_is_tc(struct intel_display *display, enum phy phy)
 {
 	/*
@@ -1863,6 +1873,13 @@ bool intel_encoder_is_tc(struct intel_encoder *encoder)
 {
 	struct intel_display *display = to_intel_display(encoder);
 
+	if (intel_encoder_is_dig_port(encoder)) {
+		struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+		if (dig_port->dedicated_external)
+			return false;
+	}
+
 	return intel_phy_is_tc(display, intel_encoder_to_phy(encoder));
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index bba03791f0ea..4738439ee03d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1925,6 +1925,7 @@ struct intel_digital_port {
 	bool lane_reversal;
 	bool ddi_a_4_lanes;
 	bool release_cl2_override;
+	bool dedicated_external;
 	u8 max_lanes;
 	/* Used for DP and ICL+ TypeC/DP and TypeC/HDMI ports. */
 	enum aux_ch aux_ch;

-- 
2.51.0


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

* [PATCH v2 30/32] drm/i915/wm: don't use method1 in Xe3p_LPD onwards
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (28 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 29/32] drm/i915/display: Handle dedicated external ports in intel_encoder_is_tc() Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22 15:08   ` Shekhar Chauhan
  2025-10-22  0:28 ` [PATCH v2 31/32] drm/i915/xe3p_lpd: Extend Type-C flow for static DDI allocation Gustavo Sousa
                   ` (2 subsequent siblings)
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

From: Luca Coelho <luciano.coelho@intel.com>

Starting from display version 35, we don't need to use method1 to
calculate the watermark values anymore, so skip it.

Bspec: 68985
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 5bb6cdc4ad2c..9a063637a9af 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -1812,6 +1812,8 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 
 	if (wp->y_tiled) {
 		selected_result = max_fixed16(method2, wp->y_tile_minimum);
+	} else if (DISPLAY_VER(display) >= 35) {
+		selected_result = method2;
 	} else {
 		if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
 		     wp->dbuf_block_size < 1) &&

-- 
2.51.0


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

* [PATCH v2 31/32] drm/i915/xe3p_lpd: Extend Type-C flow for static DDI allocation
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (29 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 30/32] drm/i915/wm: don't use method1 in Xe3p_LPD onwards Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22  0:28 ` [PATCH v2 32/32] drm/i915/nvls: Add NVL-S display support Gustavo Sousa
  2025-10-22  1:46 ` ✗ i915.CI.BAT: failure for drm/i915/display: Add initial support for Xe3p_LPD (rev2) Patchwork
  32 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Xe3p_LPD has a new feature that allows the driver to allocate at runtime
the DDI (TC ones) port to drive a legacy connection on the Type-C
subsystem.  This allows better resource utilization, because now there
is no need to statically reserve ports for legacy connectors on the
Type-C subsystem.

That said, our driver is not yet ready for the dynamic allocation.
Thus, as an incremental step, let's add the logic containing the
required programming sequence for the allocation, but, instead of
selecting the first available port, we try so use the 1:1 mapping
expected by the driver today.

Bspec: 68954
Co-developed-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Signed-off-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---

NOTE: This patch is still a WIP. There are some opens to resolve here.
Nevertheless, I'm sending it here for early feedback.

For the HIP-index stuff, I have a local refactor started and need to
finish it up and send it.

The other open is about concurrent calls to iom_dp_resource_lock().  It
is likely that we need to have a software lock to prevent concurrent
access to IOM_DP_HW_RESOURCE_SEMAPHORE from our driver.
---
 drivers/gpu/drm/i915/display/intel_display_regs.h |  20 ++-
 drivers/gpu/drm/i915/display/intel_tc.c           | 151 +++++++++++++++++++++-
 2 files changed, 169 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
index c9f8b90faa42..21600dee2603 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -2912,6 +2912,25 @@ enum skl_power_gate {
 #define   DP_PIN_ASSIGNMENT(idx, x)		((x) << ((idx) * 4))
 /* See enum intel_tc_pin_assignment for the pin assignment field values. */
 
+/*
+ * FIXME: There is also a definition for this register in intel_dkl_phy_regs.h.
+ * We need to consolidate the definitions.
+ */
+#define HIP_INDEX_REG0				_MMIO(0x1010a0)
+#define   HIP_168_INDEX_MASK			REG_GENMASK(3, 0)
+#define   HIP_168_IOM_RES_MGMT			REG_FIELD_PREP(HIP_168_INDEX_MASK, 0x1)
+
+#define IOM_DP_HW_RESOURCE_SEMAPHORE		_MMIO(0x168038)
+#define   IOM_DP_HW_SEMLOCK			REG_BIT(31)
+#define   IOM_REQUESTOR_ID_MASK			REG_GENMASK(3, 0)
+#define   IOM_REQUESTOR_ID_DISPLAY_ENGINE	REG_FIELD_PREP(IOM_REQUESTOR_ID_MASK, 0x4)
+
+#define IOM_DP_RESOURCE_MNG			_MMIO(0x16802c)
+#define   IOM_DDI_CONSUMER_SHIFT(tc_port)	((tc_port) * 4)
+#define   IOM_DDI_CONSUMER_MASK(tc_port)	(0xf << IOM_DDI_CONSUMER_SHIFT(tc_port))
+#define   IOM_DDI_CONSUMER(tc_port, x)		((x) << IOM_DDI_CONSUMER_SHIFT(tc_port))
+#define   IOM_DDI_CONSUMER_STATIC_TC(tc_port)	IOM_DDI_CONSUMER(tc_port, 0x8 + (tc_port))
+
 #define _TCSS_DDI_STATUS_1			0x161500
 #define _TCSS_DDI_STATUS_2			0x161504
 #define TCSS_DDI_STATUS(tc)			_MMIO(_PICK_EVEN(tc, \
@@ -2950,5 +2969,4 @@ enum skl_power_gate {
 #define   MTL_TRDPRE_MASK		REG_GENMASK(7, 0)
 
 
-
 #endif /* __INTEL_DISPLAY_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index c4a5601c5107..5a0e2d9cccd3 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -10,6 +10,7 @@
 #include "i915_reg.h"
 #include "i915_utils.h"
 #include "intel_atomic.h"
+#include "intel_bios.h"
 #include "intel_cx0_phy_regs.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
@@ -25,6 +26,9 @@
 #include "intel_modeset_lock.h"
 #include "intel_tc.h"
 
+#define IOM_DP_RES_SEMAPHORE_LOCK_TIMEOUT_US	10
+#define IOM_DP_RES_SEMAPHORE_RETRY_TIMEOUT_US	10000
+
 enum tc_port_mode {
 	TC_PORT_DISCONNECTED,
 	TC_PORT_TBT_ALT,
@@ -1200,6 +1204,143 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc)
 	__tc_cold_unblock(tc, domain, tc_cold_wref);
 }
 
+static void iom_res_mgmt_prepare_reg_access(struct intel_display *display)
+{
+	/*
+	 * IOM resource management registers live in the 2nd 4KB page of IOM
+	 * address space. So we need to configure HIP_INDEX_REG0 with the
+	 * correct index.
+	 *
+	 * FIXME: We need to have this and dekel PHY implementation using a
+	 * common abstraction to access registers on the HIP-indexed ranges, and
+	 * this function would then be dropped.
+	 */
+	intel_de_rmw(display, HIP_INDEX_REG0,
+		     HIP_168_INDEX_MASK, HIP_168_IOM_RES_MGMT);
+}
+
+/*
+ * FIXME: This function also needs to avoid concurrent accesses from the driver
+ * itself, possibly via a software lock.
+ */
+static int iom_dp_resource_lock(struct intel_tc_port *tc)
+{
+	struct intel_display *display = to_intel_display(tc->dig_port);
+	u32 val = IOM_DP_HW_SEMLOCK | IOM_REQUESTOR_ID_DISPLAY_ENGINE;
+	int ret;
+
+	iom_res_mgmt_prepare_reg_access(display);
+	ret = poll_timeout_us(intel_de_write(display, IOM_DP_HW_RESOURCE_SEMAPHORE, val),
+			      (intel_de_read(display, IOM_DP_HW_RESOURCE_SEMAPHORE) & val) == val,
+			      IOM_DP_RES_SEMAPHORE_LOCK_TIMEOUT_US,
+			      IOM_DP_RES_SEMAPHORE_RETRY_TIMEOUT_US, false);
+
+	if (ret)
+		drm_err(display->drm, "Port %s: timeout trying to lock IOM semaphore\n",
+			tc->port_name);
+
+	return ret;
+}
+
+static void iom_dp_resource_unlock(struct intel_tc_port *tc)
+{
+	struct intel_display *display = to_intel_display(tc->dig_port);
+
+	iom_res_mgmt_prepare_reg_access(display);
+	intel_de_write(display, IOM_DP_HW_RESOURCE_SEMAPHORE, IOM_REQUESTOR_ID_DISPLAY_ENGINE);
+}
+
+static bool xe3p_tc_iom_allocate_ddi(struct intel_tc_port *tc, bool allocate)
+{
+	struct intel_display *display = to_intel_display(tc->dig_port);
+	struct intel_digital_port *dig_port = tc->dig_port;
+	enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base);
+	u32 val;
+	u32 consumer;
+	u32 expected_consumer;
+	bool ret;
+
+	if (DISPLAY_VER(display) < 35)
+		return true;
+
+	if (tc->mode != TC_PORT_LEGACY)
+		return true;
+
+	if (!intel_bios_encoder_supports_dyn_port_over_tc(dig_port->base.devdata))
+		return true;
+
+	if (iom_dp_resource_lock(tc))
+		return false;
+
+	val = intel_de_read(display, IOM_DP_RESOURCE_MNG);
+
+	consumer = val & IOM_DDI_CONSUMER_MASK(tc_port);
+	consumer >>= IOM_DDI_CONSUMER_SHIFT(tc_port);
+
+	/*
+	 * Bspec instructs to select first available DDI, but our driver is not
+	 * ready for such dynamic allocation yet. For now, we force a "static"
+	 * allocation: map the physical port (where HPD happens) to the
+	 * encoder's DDI (logical TC port, represented by tc_port).
+	 */
+	expected_consumer = IOM_DDI_CONSUMER_STATIC_TC(tc_port);
+	expected_consumer >>= IOM_DDI_CONSUMER_SHIFT(tc_port);
+
+	if (allocate) {
+		struct intel_encoder *other_encoder;
+
+		/*
+		 * Check if this encoder's DDI is already allocated for another
+		 * physical port, which could have happened prior to the driver
+		 * taking over (e.g. GOP).
+		 */
+		for_each_intel_encoder(display->drm, other_encoder) {
+			enum tc_port other_tc_port = intel_encoder_to_tc(other_encoder);
+			u32 other_consumer;
+
+			if (tc_port == TC_PORT_NONE || other_tc_port == tc_port)
+				continue;
+
+			other_consumer = val & IOM_DDI_CONSUMER_MASK(other_tc_port);
+			other_consumer >>= IOM_DDI_CONSUMER_SHIFT(other_tc_port);
+			if (other_consumer == expected_consumer) {
+				drm_err(display->drm, "Port %s: expected consumer %u already allocated another DDI; IOM_DP_RESOURCE_MNG=0x%08x\n",
+					tc->port_name, expected_consumer, val);
+				ret = false;
+				goto out_resource_unlock;
+			}
+		}
+
+		if (consumer == 0) {
+			/* DDI is free to use, let's allocate it. */
+			val &= ~IOM_DDI_CONSUMER_MASK(tc_port);
+			val |= IOM_DDI_CONSUMER(tc_port, expected_consumer);
+			intel_de_write(display, IOM_DP_RESOURCE_MNG, val);
+			ret = true;
+		} else if (consumer == expected_consumer) {
+			/*
+			 * Nothing to do, as the expected "static" DDI allocation is
+			 * already in place.
+			 */
+			ret = true;
+		} else {
+			drm_err(display->drm, "Port %s: DDI already allocated for consumer %u; IOM_DP_RESOURCE_MNG=0x%08x\n",
+				tc->port_name, consumer, val);
+			ret = false;
+		}
+	} else {
+		drm_WARN_ON(display->drm, consumer != expected_consumer);
+		val &= ~IOM_DDI_CONSUMER_MASK(tc_port);
+		intel_de_write(display, IOM_DP_RESOURCE_MNG, val);
+		ret = true;
+	}
+
+out_resource_unlock:
+	iom_dp_resource_unlock(tc);
+
+	return ret;
+}
+
 static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
 {
 	tc->lock_wakeref = tc_cold_block(tc);
@@ -1210,9 +1351,12 @@ static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
 		return true;
 	}
 
-	if (!xelpdp_tc_phy_enable_tcss_power(tc, true))
+	if (!xe3p_tc_iom_allocate_ddi(tc, true))
 		goto out_unblock_tccold;
 
+	if (!xelpdp_tc_phy_enable_tcss_power(tc, true))
+		goto out_deallocate_ddi;
+
 	xelpdp_tc_phy_take_ownership(tc, true);
 
 	read_pin_configuration(tc);
@@ -1226,6 +1370,9 @@ static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes)
 	xelpdp_tc_phy_take_ownership(tc, false);
 	xelpdp_tc_phy_wait_for_tcss_power(tc, false);
 
+out_deallocate_ddi:
+	xe3p_tc_iom_allocate_ddi(tc, false);
+
 out_unblock_tccold:
 	tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref));
 
@@ -1236,6 +1383,8 @@ static void xelpdp_tc_phy_disconnect(struct intel_tc_port *tc)
 {
 	switch (tc->mode) {
 	case TC_PORT_LEGACY:
+		xe3p_tc_iom_allocate_ddi(tc, false);
+		fallthrough;
 	case TC_PORT_DP_ALT:
 		xelpdp_tc_phy_take_ownership(tc, false);
 		xelpdp_tc_phy_enable_tcss_power(tc, false);

-- 
2.51.0


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

* [PATCH v2 32/32] drm/i915/nvls: Add NVL-S display support
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (30 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 31/32] drm/i915/xe3p_lpd: Extend Type-C flow for static DDI allocation Gustavo Sousa
@ 2025-10-22  0:28 ` Gustavo Sousa
  2025-10-22 15:12   ` Shekhar Chauhan
  2025-10-22  1:46 ` ✗ i915.CI.BAT: failure for drm/i915/display: Add initial support for Xe3p_LPD (rev2) Patchwork
  32 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22  0:28 UTC (permalink / raw)
  To: intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Gustavo Sousa,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>

Add platform description and PCI IDs for NVL-S.

BSpec: 74201
Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display_device.c | 5 +++++
 drivers/gpu/drm/i915/display/intel_display_device.h | 4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index a38de39ed98c..2350ade1419c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -1420,6 +1420,10 @@ static const struct platform_desc ptl_desc = {
 	}
 };
 
+static const struct platform_desc nvl_desc = {
+	PLATFORM(novalake),
+};
+
 __diag_pop();
 
 /*
@@ -1495,6 +1499,7 @@ static const struct {
 	INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
 	INTEL_PTL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
 	INTEL_WCL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
+	INTEL_NVLS_IDS(INTEL_DISPLAY_DEVICE, &nvl_desc),
 };
 
 static const struct {
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index 8fdb8a0a4282..ed03630f9dcc 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -102,7 +102,9 @@ struct pci_dev;
 	func(battlemage) \
 	/* Display ver 30 (based on GMD ID) */ \
 	func(pantherlake) \
-	func(pantherlake_wildcatlake)
+	func(pantherlake_wildcatlake) \
+	/* Display ver 35 (based on GMD ID) */ \
+	func(novalake)
 
 
 #define __MEMBER(name) unsigned long name:1;

-- 
2.51.0


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

* ✗ i915.CI.BAT: failure for drm/i915/display: Add initial support for Xe3p_LPD (rev2)
  2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
                   ` (31 preceding siblings ...)
  2025-10-22  0:28 ` [PATCH v2 32/32] drm/i915/nvls: Add NVL-S display support Gustavo Sousa
@ 2025-10-22  1:46 ` Patchwork
  32 siblings, 0 replies; 65+ messages in thread
From: Patchwork @ 2025-10-22  1:46 UTC (permalink / raw)
  To: Gustavo Sousa; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915/display: Add initial support for Xe3p_LPD (rev2)
URL   : https://patchwork.freedesktop.org/series/155952/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_17402 -> Patchwork_155952v2
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_155952v2 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_155952v2, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them
  to document this new failure mode, which will reduce false positives in CI.

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

Participating hosts (45 -> 43)
------------------------------

  Missing    (2): fi-glk-j4005 fi-snb-2520m 

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

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

### IGT changes ###

#### Possible regressions ####

  * igt@i915_module_load@load:
    - bat-dg2-13:         [PASS][1] -> [ABORT][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-dg2-13/igt@i915_module_load@load.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-dg2-13/igt@i915_module_load@load.html
    - bat-dg2-9:          [PASS][3] -> [ABORT][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-dg2-9/igt@i915_module_load@load.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-dg2-9/igt@i915_module_load@load.html
    - bat-dg2-11:         [PASS][5] -> [ABORT][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-dg2-11/igt@i915_module_load@load.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-dg2-11/igt@i915_module_load@load.html
    - bat-dg2-14:         [PASS][7] -> [ABORT][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-dg2-14/igt@i915_module_load@load.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-dg2-14/igt@i915_module_load@load.html
    - bat-dg2-8:          [PASS][9] -> [ABORT][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-dg2-8/igt@i915_module_load@load.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-dg2-8/igt@i915_module_load@load.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@dmabuf@all-tests@dma_fence_chain:
    - fi-bsw-n3050:       [PASS][11] -> [ABORT][12] ([i915#12904]) +1 other test abort
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/fi-bsw-n3050/igt@dmabuf@all-tests@dma_fence_chain.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/fi-bsw-n3050/igt@dmabuf@all-tests@dma_fence_chain.html

  * igt@i915_selftest@live:
    - bat-mtlp-8:         [PASS][13] -> [DMESG-FAIL][14] ([i915#12061]) +1 other test dmesg-fail
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-mtlp-8/igt@i915_selftest@live.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-mtlp-8/igt@i915_selftest@live.html

  
#### Possible fixes ####

  * igt@dmabuf@all-tests:
    - bat-apl-1:          [ABORT][15] ([i915#12904]) -> [PASS][16] +1 other test pass
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-apl-1/igt@dmabuf@all-tests.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-apl-1/igt@dmabuf@all-tests.html

  
#### Warnings ####

  * igt@i915_selftest@live:
    - bat-atsm-1:         [DMESG-FAIL][17] ([i915#12061] / [i915#13929]) -> [DMESG-FAIL][18] ([i915#12061] / [i915#14204])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-atsm-1/igt@i915_selftest@live.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-atsm-1/igt@i915_selftest@live.html

  * igt@i915_selftest@live@mman:
    - bat-atsm-1:         [DMESG-FAIL][19] ([i915#13929]) -> [DMESG-FAIL][20] ([i915#14204])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_17402/bat-atsm-1/igt@i915_selftest@live@mman.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_155952v2/bat-atsm-1/igt@i915_selftest@live@mman.html

  
  [i915#12061]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12061
  [i915#12904]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12904
  [i915#13929]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13929
  [i915#14204]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14204


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

  * Linux: CI_DRM_17402 -> Patchwork_155952v2

  CI-20190529: 20190529
  CI_DRM_17402: fb0f56ad8a2c9953c57c3337a72ccbf9c5050687 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_8594: 8594
  Patchwork_155952v2: fb0f56ad8a2c9953c57c3337a72ccbf9c5050687 @ git://anongit.freedesktop.org/gfx-ci/linux

== Logs ==

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

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

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

* Re: [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw
  2025-10-22  0:28 ` [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw Gustavo Sousa
@ 2025-10-22 11:37   ` Gustavo Sousa
  2025-10-22 11:53     ` Jani Nikula
  0 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22 11:37 UTC (permalink / raw)
  To: intel-gfx, intel-xe
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Jouni Högander,
	Juha-pekka Heikkila, Luca Coelho, Lucas De Marchi, Matt Atwood,
	Matt Roper, Ravi Kumar Vodapalli, Shekhar Chauhan,
	Vinod Govindapillai, Jani Nikula

Quoting Gustavo Sousa (2025-10-21 21:28:29-03:00)
>Starting with Xe3p_LPD, we now have a new field in MEM_SS_INFO_GLOBAL
>that indicates whether the memory has enabled ECC that limits display
>bandwidth.  Add the field ecc_impacting_de_bw to struct dram_info to
>contain that information and set it appropriately when probing for
>memory info.
>
>Currently there are no instructions in Bspec on how to handle that case,
>so let's throw a warning if we ever find such a scenario.
>
>v2:
>  - s/ecc_impacting_de/ecc_impacting_de_bw/ to be more specific. (Matt
>    Atwood)
>  - Add warning if ecc_impacting_de_bw is true, since we currently do
>    not have instructions on how to handle it. (Matt Roper)
>
>Bspec: 69131
>Cc: Jani Nikula <jani.nikula@linux.intel.com>
>Cc: Matt Atwood <matthew.s.atwood@intel.com>
>Cc: Matt Roper <matthew.d.roper@intel.com>
>Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>---
> drivers/gpu/drm/i915/display/intel_bw.c | 8 ++++++++
> drivers/gpu/drm/i915/i915_reg.h         | 1 +
> drivers/gpu/drm/i915/soc/intel_dram.c   | 4 ++++
> drivers/gpu/drm/i915/soc/intel_dram.h   | 1 +
> 4 files changed, 14 insertions(+)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
>index fc173b2a1ad9..57d65e6e5429 100644
>--- a/drivers/gpu/drm/i915/display/intel_bw.c
>+++ b/drivers/gpu/drm/i915/display/intel_bw.c
>@@ -802,6 +802,14 @@ void intel_bw_init_hw(struct intel_display *display)
>         if (!HAS_DISPLAY(display))
>                 return;
> 
>+        /*
>+         * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC
>+         * enabled that would impact display bandwidth.  However, so far there
>+         * are no instructions in Bspec on how to handle that case.  Let's
>+         * complain if we ever find such a scenario.
>+         */
>+        drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);

Oops.  Just realized that DG2 does not have dram_info.  Thanks, CI!

I'll fix this on the next version, probably with:

    drm_WARN_ON_ONCE(display->drm, dram_info && dram_info->ecc_impacting_de_bw);

--
Gustavo Sousa

>+
>         if (DISPLAY_VERx100(display) >= 3002) {
>                 tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
>         } else if (DISPLAY_VER(display) >= 30) {
>diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>index 354ef75ef6a5..5bf3b4ab2baa 100644
>--- a/drivers/gpu/drm/i915/i915_reg.h
>+++ b/drivers/gpu/drm/i915/i915_reg.h
>@@ -1233,6 +1233,7 @@
> #define   OROM_OFFSET_MASK                        REG_GENMASK(20, 16)
> 
> #define MTL_MEM_SS_INFO_GLOBAL                        _MMIO(0x45700)
>+#define   XE3P_ECC_IMPACTING_DE                        REG_BIT(12)
> #define   MTL_N_OF_ENABLED_QGV_POINTS_MASK        REG_GENMASK(11, 8)
> #define   MTL_N_OF_POPULATED_CH_MASK                REG_GENMASK(7, 4)
> #define   MTL_DDR_TYPE_MASK                        REG_GENMASK(3, 0)
>diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
>index 8841cfe1cac8..73e8ad1a28e0 100644
>--- a/drivers/gpu/drm/i915/soc/intel_dram.c
>+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
>@@ -685,6 +685,7 @@ static int gen12_get_dram_info(struct drm_i915_private *i915, struct dram_info *
> 
> static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info)
> {
>+        struct intel_display *display = i915->display;
>         u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
> 
>         switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) {
>@@ -723,6 +724,9 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info
>         dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
>         /* PSF GV points not supported in D14+ */
> 
>+        if (DISPLAY_VER(display) >= 35)
>+                dram_info->ecc_impacting_de_bw = REG_FIELD_GET(XE3P_ECC_IMPACTING_DE, val);
>+
>         return 0;
> }
> 
>diff --git a/drivers/gpu/drm/i915/soc/intel_dram.h b/drivers/gpu/drm/i915/soc/intel_dram.h
>index 03a973f1c941..8475ee379daa 100644
>--- a/drivers/gpu/drm/i915/soc/intel_dram.h
>+++ b/drivers/gpu/drm/i915/soc/intel_dram.h
>@@ -30,6 +30,7 @@ struct dram_info {
>         u8 num_channels;
>         u8 num_qgv_points;
>         u8 num_psf_gv_points;
>+        bool ecc_impacting_de_bw; /* Only valid from Xe3p_LPD onward. */
>         bool symmetric_memory;
>         bool has_16gb_dimms;
> };
>
>-- 
>2.51.0
>

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

* Re: [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw
  2025-10-22 11:37   ` Gustavo Sousa
@ 2025-10-22 11:53     ` Jani Nikula
  2025-10-22 12:12       ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Jani Nikula @ 2025-10-22 11:53 UTC (permalink / raw)
  To: Gustavo Sousa, intel-gfx, intel-xe
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Jouni Högander,
	Juha-pekka Heikkila, Luca Coelho, Lucas De Marchi, Matt Atwood,
	Matt Roper, Ravi Kumar Vodapalli, Shekhar Chauhan,
	Vinod Govindapillai

On Wed, 22 Oct 2025, Gustavo Sousa <gustavo.sousa@intel.com> wrote:
> Quoting Gustavo Sousa (2025-10-21 21:28:29-03:00)
>>Starting with Xe3p_LPD, we now have a new field in MEM_SS_INFO_GLOBAL
>>that indicates whether the memory has enabled ECC that limits display
>>bandwidth.  Add the field ecc_impacting_de_bw to struct dram_info to
>>contain that information and set it appropriately when probing for
>>memory info.
>>
>>Currently there are no instructions in Bspec on how to handle that case,
>>so let's throw a warning if we ever find such a scenario.
>>
>>v2:
>>  - s/ecc_impacting_de/ecc_impacting_de_bw/ to be more specific. (Matt
>>    Atwood)
>>  - Add warning if ecc_impacting_de_bw is true, since we currently do
>>    not have instructions on how to handle it. (Matt Roper)
>>
>>Bspec: 69131
>>Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>Cc: Matt Atwood <matthew.s.atwood@intel.com>
>>Cc: Matt Roper <matthew.d.roper@intel.com>
>>Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>>---
>> drivers/gpu/drm/i915/display/intel_bw.c | 8 ++++++++
>> drivers/gpu/drm/i915/i915_reg.h         | 1 +
>> drivers/gpu/drm/i915/soc/intel_dram.c   | 4 ++++
>> drivers/gpu/drm/i915/soc/intel_dram.h   | 1 +
>> 4 files changed, 14 insertions(+)
>>
>>diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
>>index fc173b2a1ad9..57d65e6e5429 100644
>>--- a/drivers/gpu/drm/i915/display/intel_bw.c
>>+++ b/drivers/gpu/drm/i915/display/intel_bw.c
>>@@ -802,6 +802,14 @@ void intel_bw_init_hw(struct intel_display *display)
>>         if (!HAS_DISPLAY(display))
>>                 return;
>> 
>>+        /*
>>+         * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC
>>+         * enabled that would impact display bandwidth.  However, so far there
>>+         * are no instructions in Bspec on how to handle that case.  Let's
>>+         * complain if we ever find such a scenario.
>>+         */
>>+        drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);
>
> Oops.  Just realized that DG2 does not have dram_info.  Thanks, CI!
>
> I'll fix this on the next version, probably with:
>
>     drm_WARN_ON_ONCE(display->drm, dram_info &&
>     dram_info->ecc_impacting_de_bw);

The comment I added above intel_dram_info():

/*
 * Returns NULL for platforms that don't have dram info. Avoid overzealous NULL
 * checks, and prefer not dereferencing on platforms that shouldn't look at dram
 * info, to catch accidental and incorrect dram info checks.
 */

You caught the whole thing on CI *because* there was no NULL check. With
the NULL check, you'll ignore missing dram info on future platforms that
should have it.


BR,
Jani.




>
> --
> Gustavo Sousa
>
>>+
>>         if (DISPLAY_VERx100(display) >= 3002) {
>>                 tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
>>         } else if (DISPLAY_VER(display) >= 30) {
>>diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>>index 354ef75ef6a5..5bf3b4ab2baa 100644
>>--- a/drivers/gpu/drm/i915/i915_reg.h
>>+++ b/drivers/gpu/drm/i915/i915_reg.h
>>@@ -1233,6 +1233,7 @@
>> #define   OROM_OFFSET_MASK                        REG_GENMASK(20, 16)
>> 
>> #define MTL_MEM_SS_INFO_GLOBAL                        _MMIO(0x45700)
>>+#define   XE3P_ECC_IMPACTING_DE                        REG_BIT(12)
>> #define   MTL_N_OF_ENABLED_QGV_POINTS_MASK        REG_GENMASK(11, 8)
>> #define   MTL_N_OF_POPULATED_CH_MASK                REG_GENMASK(7, 4)
>> #define   MTL_DDR_TYPE_MASK                        REG_GENMASK(3, 0)
>>diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
>>index 8841cfe1cac8..73e8ad1a28e0 100644
>>--- a/drivers/gpu/drm/i915/soc/intel_dram.c
>>+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
>>@@ -685,6 +685,7 @@ static int gen12_get_dram_info(struct drm_i915_private *i915, struct dram_info *
>> 
>> static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info)
>> {
>>+        struct intel_display *display = i915->display;
>>         u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
>> 
>>         switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) {
>>@@ -723,6 +724,9 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info
>>         dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
>>         /* PSF GV points not supported in D14+ */
>> 
>>+        if (DISPLAY_VER(display) >= 35)
>>+                dram_info->ecc_impacting_de_bw = REG_FIELD_GET(XE3P_ECC_IMPACTING_DE, val);
>>+
>>         return 0;
>> }
>> 
>>diff --git a/drivers/gpu/drm/i915/soc/intel_dram.h b/drivers/gpu/drm/i915/soc/intel_dram.h
>>index 03a973f1c941..8475ee379daa 100644
>>--- a/drivers/gpu/drm/i915/soc/intel_dram.h
>>+++ b/drivers/gpu/drm/i915/soc/intel_dram.h
>>@@ -30,6 +30,7 @@ struct dram_info {
>>         u8 num_channels;
>>         u8 num_qgv_points;
>>         u8 num_psf_gv_points;
>>+        bool ecc_impacting_de_bw; /* Only valid from Xe3p_LPD onward. */
>>         bool symmetric_memory;
>>         bool has_16gb_dimms;
>> };
>>
>>-- 
>>2.51.0
>>

-- 
Jani Nikula, Intel

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

* Re: [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw
  2025-10-22 11:53     ` Jani Nikula
@ 2025-10-22 12:12       ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-22 12:12 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx, intel-xe
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Jouni Högander,
	Juha-pekka Heikkila, Luca Coelho, Lucas De Marchi, Matt Atwood,
	Matt Roper, Ravi Kumar Vodapalli, Shekhar Chauhan,
	Vinod Govindapillai

Quoting Jani Nikula (2025-10-22 08:53:34-03:00)
>On Wed, 22 Oct 2025, Gustavo Sousa <gustavo.sousa@intel.com> wrote:
>> Quoting Gustavo Sousa (2025-10-21 21:28:29-03:00)
>>>Starting with Xe3p_LPD, we now have a new field in MEM_SS_INFO_GLOBAL
>>>that indicates whether the memory has enabled ECC that limits display
>>>bandwidth.  Add the field ecc_impacting_de_bw to struct dram_info to
>>>contain that information and set it appropriately when probing for
>>>memory info.
>>>
>>>Currently there are no instructions in Bspec on how to handle that case,
>>>so let's throw a warning if we ever find such a scenario.
>>>
>>>v2:
>>>  - s/ecc_impacting_de/ecc_impacting_de_bw/ to be more specific. (Matt
>>>    Atwood)
>>>  - Add warning if ecc_impacting_de_bw is true, since we currently do
>>>    not have instructions on how to handle it. (Matt Roper)
>>>
>>>Bspec: 69131
>>>Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>>Cc: Matt Atwood <matthew.s.atwood@intel.com>
>>>Cc: Matt Roper <matthew.d.roper@intel.com>
>>>Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>>>---
>>> drivers/gpu/drm/i915/display/intel_bw.c | 8 ++++++++
>>> drivers/gpu/drm/i915/i915_reg.h         | 1 +
>>> drivers/gpu/drm/i915/soc/intel_dram.c   | 4 ++++
>>> drivers/gpu/drm/i915/soc/intel_dram.h   | 1 +
>>> 4 files changed, 14 insertions(+)
>>>
>>>diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
>>>index fc173b2a1ad9..57d65e6e5429 100644
>>>--- a/drivers/gpu/drm/i915/display/intel_bw.c
>>>+++ b/drivers/gpu/drm/i915/display/intel_bw.c
>>>@@ -802,6 +802,14 @@ void intel_bw_init_hw(struct intel_display *display)
>>>         if (!HAS_DISPLAY(display))
>>>                 return;
>>> 
>>>+        /*
>>>+         * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC
>>>+         * enabled that would impact display bandwidth.  However, so far there
>>>+         * are no instructions in Bspec on how to handle that case.  Let's
>>>+         * complain if we ever find such a scenario.
>>>+         */
>>>+        drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);
>>
>> Oops.  Just realized that DG2 does not have dram_info.  Thanks, CI!
>>
>> I'll fix this on the next version, probably with:
>>
>>     drm_WARN_ON_ONCE(display->drm, dram_info &&
>>     dram_info->ecc_impacting_de_bw);
>
>The comment I added above intel_dram_info():
>
>/*
> * Returns NULL for platforms that don't have dram info. Avoid overzealous NULL
> * checks, and prefer not dereferencing on platforms that shouldn't look at dram
> * info, to catch accidental and incorrect dram info checks.
> */
>
>You caught the whole thing on CI *because* there was no NULL check. With
>the NULL check, you'll ignore missing dram info on future platforms that
>should have it.

Okay.  I see your point.  So, perhaps I should keep the
drm_WARN_ON_ONCE() inside the display version >= 35 case?

--
Gustavo Sousa

>
>
>BR,
>Jani.
>
>
>
>
>>
>> --
>> Gustavo Sousa
>>
>>>+
>>>         if (DISPLAY_VERx100(display) >= 3002) {
>>>                 tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
>>>         } else if (DISPLAY_VER(display) >= 30) {
>>>diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>>>index 354ef75ef6a5..5bf3b4ab2baa 100644
>>>--- a/drivers/gpu/drm/i915/i915_reg.h
>>>+++ b/drivers/gpu/drm/i915/i915_reg.h
>>>@@ -1233,6 +1233,7 @@
>>> #define   OROM_OFFSET_MASK                        REG_GENMASK(20, 16)
>>> 
>>> #define MTL_MEM_SS_INFO_GLOBAL                        _MMIO(0x45700)
>>>+#define   XE3P_ECC_IMPACTING_DE                        REG_BIT(12)
>>> #define   MTL_N_OF_ENABLED_QGV_POINTS_MASK        REG_GENMASK(11, 8)
>>> #define   MTL_N_OF_POPULATED_CH_MASK                REG_GENMASK(7, 4)
>>> #define   MTL_DDR_TYPE_MASK                        REG_GENMASK(3, 0)
>>>diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
>>>index 8841cfe1cac8..73e8ad1a28e0 100644
>>>--- a/drivers/gpu/drm/i915/soc/intel_dram.c
>>>+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
>>>@@ -685,6 +685,7 @@ static int gen12_get_dram_info(struct drm_i915_private *i915, struct dram_info *
>>> 
>>> static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info)
>>> {
>>>+        struct intel_display *display = i915->display;
>>>         u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
>>> 
>>>         switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) {
>>>@@ -723,6 +724,9 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info
>>>         dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
>>>         /* PSF GV points not supported in D14+ */
>>> 
>>>+        if (DISPLAY_VER(display) >= 35)
>>>+                dram_info->ecc_impacting_de_bw = REG_FIELD_GET(XE3P_ECC_IMPACTING_DE, val);
>>>+
>>>         return 0;
>>> }
>>> 
>>>diff --git a/drivers/gpu/drm/i915/soc/intel_dram.h b/drivers/gpu/drm/i915/soc/intel_dram.h
>>>index 03a973f1c941..8475ee379daa 100644
>>>--- a/drivers/gpu/drm/i915/soc/intel_dram.h
>>>+++ b/drivers/gpu/drm/i915/soc/intel_dram.h
>>>@@ -30,6 +30,7 @@ struct dram_info {
>>>         u8 num_channels;
>>>         u8 num_qgv_points;
>>>         u8 num_psf_gv_points;
>>>+        bool ecc_impacting_de_bw; /* Only valid from Xe3p_LPD onward. */
>>>         bool symmetric_memory;
>>>         bool has_16gb_dimms;
>>> };
>>>
>>>-- 
>>>2.51.0
>>>
>
>-- 
>Jani Nikula, Intel

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

* Re: [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats
  2025-10-22  0:28 ` [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats Gustavo Sousa
@ 2025-10-22 12:28   ` Ville Syrjälä
  2025-10-22 17:58     ` Matt Roper
  0 siblings, 1 reply; 65+ messages in thread
From: Ville Syrjälä @ 2025-10-22 12:28 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

On Tue, Oct 21, 2025 at 09:28:32PM -0300, Gustavo Sousa wrote:
> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> 
> Starting from display Xe3p_LPD, UINT16 formats are also supported. Add
> its corresponding PLANE_CTL bit and add the format in the necessary
> functions.

Those have been supported by the hardware for a lot longer
than that.

I have an old branch that adds them here:
https://github.com/vsyrjala/linux.git uint16
but I never landed that.

> 
> v2:
>   - Add reference to Bspec 68911. (Matt Atwood)
> 
> Bspec: 68904, 69853, 68911
> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/skl_universal_plane.c | 96 +++++++++++++++-------
>  .../drm/i915/display/skl_universal_plane_regs.h    |  1 +
>  2 files changed, 68 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index 0319174adf95..530adff81b99 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -136,36 +136,47 @@ static const u32 icl_sdr_uv_plane_formats[] = {
>  	DRM_FORMAT_XVYU2101010,
>  };
>  
> +#define ICL_HDR_PLANE_FORMATS		\
> +	DRM_FORMAT_C8,			\
> +	DRM_FORMAT_RGB565,		\
> +	DRM_FORMAT_XRGB8888,		\
> +	DRM_FORMAT_XBGR8888,		\
> +	DRM_FORMAT_ARGB8888,		\
> +	DRM_FORMAT_ABGR8888,		\
> +	DRM_FORMAT_XRGB2101010,		\
> +	DRM_FORMAT_XBGR2101010,		\
> +	DRM_FORMAT_ARGB2101010,		\
> +	DRM_FORMAT_ABGR2101010,		\
> +	DRM_FORMAT_XRGB16161616F,	\
> +	DRM_FORMAT_XBGR16161616F,	\
> +	DRM_FORMAT_ARGB16161616F,	\
> +	DRM_FORMAT_ABGR16161616F,	\
> +	DRM_FORMAT_YUYV,		\
> +	DRM_FORMAT_YVYU,		\
> +	DRM_FORMAT_UYVY,		\
> +	DRM_FORMAT_VYUY,		\
> +	DRM_FORMAT_NV12,		\
> +	DRM_FORMAT_P010,		\
> +	DRM_FORMAT_P012,		\
> +	DRM_FORMAT_P016,		\
> +	DRM_FORMAT_Y210,		\
> +	DRM_FORMAT_Y212,		\
> +	DRM_FORMAT_Y216,		\
> +	DRM_FORMAT_XYUV8888,		\
> +	DRM_FORMAT_XVYU2101010,		\
> +	DRM_FORMAT_XVYU12_16161616,	\
> +	DRM_FORMAT_XVYU16161616
> +
>  static const u32 icl_hdr_plane_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_ARGB2101010,
> -	DRM_FORMAT_ABGR2101010,
> -	DRM_FORMAT_XRGB16161616F,
> -	DRM_FORMAT_XBGR16161616F,
> -	DRM_FORMAT_ARGB16161616F,
> -	DRM_FORMAT_ABGR16161616F,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_NV12,
> -	DRM_FORMAT_P010,
> -	DRM_FORMAT_P012,
> -	DRM_FORMAT_P016,
> -	DRM_FORMAT_Y210,
> -	DRM_FORMAT_Y212,
> -	DRM_FORMAT_Y216,
> -	DRM_FORMAT_XYUV8888,
> -	DRM_FORMAT_XVYU2101010,
> -	DRM_FORMAT_XVYU12_16161616,
> -	DRM_FORMAT_XVYU16161616,
> +	ICL_HDR_PLANE_FORMATS,
> +};
> +
> +static const u32 xe3p_lpd_hdr_plane_formats[] = {
> +	ICL_HDR_PLANE_FORMATS,
> +	DRM_FORMAT_XRGB16161616,
> +	DRM_FORMAT_XBGR16161616,
> +	DRM_FORMAT_ARGB16161616,
> +	DRM_FORMAT_ABGR16161616,
>  };
>  
>  int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
> @@ -220,6 +231,18 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
>  			else
>  				return DRM_FORMAT_XRGB2101010;
>  		}
> +	case PLANE_CTL_FORMAT_XRGB_16161616:
> +		if (rgb_order) {
> +			if (alpha)
> +				return DRM_FORMAT_ABGR16161616;
> +			else
> +				return DRM_FORMAT_XBGR16161616;
> +		} else {
> +			if (alpha)
> +				return DRM_FORMAT_ARGB16161616;
> +			else
> +				return DRM_FORMAT_XRGB16161616;
> +		}
>  	case PLANE_CTL_FORMAT_XRGB_16161616F:
>  		if (rgb_order) {
>  			if (alpha)
> @@ -960,6 +983,12 @@ static u32 skl_plane_ctl_format(u32 pixel_format)
>  	case DRM_FORMAT_XRGB2101010:
>  	case DRM_FORMAT_ARGB2101010:
>  		return PLANE_CTL_FORMAT_XRGB_2101010;
> +	case DRM_FORMAT_XBGR16161616:
> +	case DRM_FORMAT_ABGR16161616:
> +		return PLANE_CTL_FORMAT_XRGB_16161616 | PLANE_CTL_ORDER_RGBX;
> +	case DRM_FORMAT_XRGB16161616:
> +	case DRM_FORMAT_ARGB16161616:
> +		return PLANE_CTL_FORMAT_XRGB_16161616;
>  	case DRM_FORMAT_XBGR16161616F:
>  	case DRM_FORMAT_ABGR16161616F:
>  		return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
> @@ -2479,6 +2508,11 @@ static const u32 *icl_get_plane_formats(struct intel_display *display,
>  					int *num_formats)
>  {
>  	if (icl_is_hdr_plane(display, plane_id)) {
> +		if (DISPLAY_VER(display) >= 35) {
> +			*num_formats = ARRAY_SIZE(xe3p_lpd_hdr_plane_formats);
> +			return xe3p_lpd_hdr_plane_formats;
> +		}
> +
>  		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
>  		return icl_hdr_plane_formats;
>  	} else if (icl_is_nv12_y_plane(display, plane_id)) {
> @@ -2637,6 +2671,10 @@ static bool tgl_plane_format_mod_supported(struct drm_plane *_plane,
>  	case DRM_FORMAT_RGB565:
>  	case DRM_FORMAT_XVYU2101010:
>  	case DRM_FORMAT_C8:
> +	case DRM_FORMAT_XBGR16161616:
> +	case DRM_FORMAT_ABGR16161616:
> +	case DRM_FORMAT_XRGB16161616:
> +	case DRM_FORMAT_ARGB16161616:
>  	case DRM_FORMAT_Y210:
>  	case DRM_FORMAT_Y212:
>  	case DRM_FORMAT_Y216:
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
> index 479bb3f7f92b..84cf565bd653 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
> @@ -64,6 +64,7 @@
>  #define   PLANE_CTL_FORMAT_Y410			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
>  #define   PLANE_CTL_FORMAT_Y412			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
>  #define   PLANE_CTL_FORMAT_Y416			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
> +#define   PLANE_CTL_FORMAT_XRGB_16161616	REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 18)
>  #define   PLANE_CTL_PIPE_CSC_ENABLE		REG_BIT(23) /* Pre-GLK */
>  #define   PLANE_CTL_KEY_ENABLE_MASK		REG_GENMASK(22, 21)
>  #define   PLANE_CTL_KEY_ENABLE_SOURCE		REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)
> 
> -- 
> 2.51.0

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 08/32] drm/i915/xe3p_lpd: Extend FBC support to UINT16 formats
  2025-10-22  0:28 ` [PATCH v2 08/32] drm/i915/xe3p_lpd: Extend FBC support to " Gustavo Sousa
@ 2025-10-22 12:39   ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2025-10-22 12:39 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

On Tue, Oct 21, 2025 at 09:28:33PM -0300, Gustavo Sousa wrote:
> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> 
> Starting Xe3p_LPD, FBC is supported on UINT16 formats as well. Also
> UINT16 being a 64bpp format, will use cpp of 8 for cfb stride and thus
> size calculations.
> 
> Cc: Shekhar Chauhan <shekhar.chauhan@intel.com>
> BSpec: 68881, 68904, 69560
> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_fbc.c | 42 ++++++++++++++++++++++++++++----
>  1 file changed, 37 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
> index 10ef3136dadc..af3585aeefd3 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
> @@ -141,15 +141,25 @@ static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane
>  	return stride;
>  }
>  
> -static unsigned int intel_fbc_cfb_cpp(void)
> +static unsigned int intel_fbc_cfb_cpp(const struct intel_plane_state *plane_state)
>  {
> -	return 4; /* FBC always 4 bytes per pixel */
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +
> +	switch (fb->format->format) {
> +	case DRM_FORMAT_XRGB16161616:
> +	case DRM_FORMAT_XBGR16161616:
> +	case DRM_FORMAT_ARGB16161616:
> +	case DRM_FORMAT_ABGR16161616:
> +		return 8;
> +	default:
> +		return 4;
> +	}

return max(cpp, 4);

>  }
>  
>  /* plane stride based cfb stride in bytes, assuming 1:1 compression limit */
>  static unsigned int intel_fbc_plane_cfb_stride(const struct intel_plane_state *plane_state)
>  {
> -	unsigned int cpp = intel_fbc_cfb_cpp();
> +	unsigned int cpp = intel_fbc_cfb_cpp(plane_state);
>  
>  	return intel_fbc_plane_stride(plane_state) * cpp;
>  }
> @@ -203,7 +213,7 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s
>  	struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
>  	unsigned int stride = intel_fbc_plane_cfb_stride(plane_state);
>  	unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16;
> -	unsigned int cpp = intel_fbc_cfb_cpp();
> +	unsigned int cpp = intel_fbc_cfb_cpp(plane_state);
>  
>  	return _intel_fbc_cfb_stride(display, cpp, width, stride);
>  }
> @@ -1081,11 +1091,33 @@ static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_
>  	}
>  }
>  
> +static bool xe3p_lpd_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
> +{
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +
> +	switch (fb->format->format) {
> +	case DRM_FORMAT_XRGB8888:
> +	case DRM_FORMAT_XBGR8888:
> +	case DRM_FORMAT_ARGB8888:
> +	case DRM_FORMAT_ABGR8888:
> +	case DRM_FORMAT_RGB565:
> +	case DRM_FORMAT_XRGB16161616:
> +	case DRM_FORMAT_XBGR16161616:
> +	case DRM_FORMAT_ARGB16161616:
> +	case DRM_FORMAT_ABGR16161616:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
>  static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
>  {
>  	struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
>  
> -	if (DISPLAY_VER(display) >= 20)
> +	if (DISPLAY_VER(display) >= 35)
> +		return xe3p_lpd_fbc_pixel_format_is_valid(plane_state);
> +	else if (DISPLAY_VER(display) >= 20)
>  		return lnl_fbc_pixel_format_is_valid(plane_state);
>  	else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
>  		return g4x_fbc_pixel_format_is_valid(plane_state);
> 
> -- 
> 2.51.0

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters
  2025-10-22  0:28 ` [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters Gustavo Sousa
@ 2025-10-22 14:56   ` Matt Roper
  2025-10-27 22:26     ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-22 14:56 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

On Tue, Oct 21, 2025 at 09:28:30PM -0300, Gustavo Sousa wrote:
> From: Matt Atwood <matthew.s.atwood@intel.com>
> 
> Bandwidth parameters for Xe3p_LPD are the same as for Xe3_LPD. Re-use
> them.
> 
> v2:
>   - Do not have a special case for ecc_impacting_de_bw, since there are
>     no specific instructions in Bspec for this scenario. (Matt Roper)
> 
> Bspec: 68859
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index 57d65e6e5429..57cb8a23188f 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -810,7 +810,9 @@ void intel_bw_init_hw(struct intel_display *display)
>  	 */
>  	drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);
>  
> -	if (DISPLAY_VERx100(display) >= 3002) {
> +	if (DISPLAY_VER(display) >= 35) {
> +		tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
> +	} else if (DISPLAY_VERx100(display) >= 3002) {

We could change 30.02 to a "==" since it's a one-off special case, and
let everything else continue to fall into to the ">= 30" branch below.
Up to you; either way,

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

As I mentioned before, we probably should think about moving the
bandwidth / memory stuff back to being platform-based rather than
IP-based, but that's something we can look at as a folow-up; it doesn't
need to be part of this series.


Matt

>  		tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
>  	} else if (DISPLAY_VER(display) >= 30) {
>  		tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 30/32] drm/i915/wm: don't use method1 in Xe3p_LPD onwards
  2025-10-22  0:28 ` [PATCH v2 30/32] drm/i915/wm: don't use method1 in Xe3p_LPD onwards Gustavo Sousa
@ 2025-10-22 15:08   ` Shekhar Chauhan
  0 siblings, 0 replies; 65+ messages in thread
From: Shekhar Chauhan @ 2025-10-22 15:08 UTC (permalink / raw)
  To: Gustavo Sousa, intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Jouni Högander,
	Juha-pekka Heikkila, Luca Coelho, Lucas De Marchi, Matt Atwood,
	Matt Roper, Ravi Kumar Vodapalli, Vinod Govindapillai


On 10/22/2025 5:58, Gustavo Sousa wrote:
> From: Luca Coelho <luciano.coelho@intel.com>
>
> Starting from display version 35, we don't need to use method1 to
> calculate the watermark values anymore, so skip it.
>
> Bspec: 68985
> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>

The change itself looks fine to me, so I'll give the RB. But, I'm still 
unconvinced on the wordings of this commit title and it's message.

Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>

> ---
>   drivers/gpu/drm/i915/display/skl_watermark.c | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 5bb6cdc4ad2c..9a063637a9af 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -1812,6 +1812,8 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>   
>   	if (wp->y_tiled) {
>   		selected_result = max_fixed16(method2, wp->y_tile_minimum);
> +	} else if (DISPLAY_VER(display) >= 35) {
> +		selected_result = method2;
>   	} else {
>   		if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
>   		     wp->dbuf_block_size < 1) &&
>

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

* Re: [PATCH v2 32/32] drm/i915/nvls: Add NVL-S display support
  2025-10-22  0:28 ` [PATCH v2 32/32] drm/i915/nvls: Add NVL-S display support Gustavo Sousa
@ 2025-10-22 15:12   ` Shekhar Chauhan
  0 siblings, 0 replies; 65+ messages in thread
From: Shekhar Chauhan @ 2025-10-22 15:12 UTC (permalink / raw)
  To: Gustavo Sousa, intel-xe, intel-gfx
  Cc: Ankit Nautiyal, Dnyaneshwar Bhadane, Jouni Högander,
	Juha-pekka Heikkila, Luca Coelho, Lucas De Marchi, Matt Atwood,
	Matt Roper, Ravi Kumar Vodapalli, Vinod Govindapillai,
	Sai Teja Pottumuttu


On 10/22/2025 5:58, Gustavo Sousa wrote:
> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>
> Add platform description and PCI IDs for NVL-S.
>
> BSpec: 74201
> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>

LGTM,

Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>

> ---
>   drivers/gpu/drm/i915/display/intel_display_device.c | 5 +++++
>   drivers/gpu/drm/i915/display/intel_display_device.h | 4 +++-
>   2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
> index a38de39ed98c..2350ade1419c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_device.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_device.c
> @@ -1420,6 +1420,10 @@ static const struct platform_desc ptl_desc = {
>   	}
>   };
>   
> +static const struct platform_desc nvl_desc = {
> +	PLATFORM(novalake),
> +};
> +
>   __diag_pop();
>   
>   /*
> @@ -1495,6 +1499,7 @@ static const struct {
>   	INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
>   	INTEL_PTL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
>   	INTEL_WCL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
> +	INTEL_NVLS_IDS(INTEL_DISPLAY_DEVICE, &nvl_desc),
>   };
>   
>   static const struct {
> diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
> index 8fdb8a0a4282..ed03630f9dcc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_device.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
> @@ -102,7 +102,9 @@ struct pci_dev;
>   	func(battlemage) \
>   	/* Display ver 30 (based on GMD ID) */ \
>   	func(pantherlake) \
> -	func(pantherlake_wildcatlake)
> +	func(pantherlake_wildcatlake) \
> +	/* Display ver 35 (based on GMD ID) */ \
> +	func(novalake)
>   
>   
>   #define __MEMBER(name) unsigned long name:1;
>

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

* Re: [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats
  2025-10-22 12:28   ` Ville Syrjälä
@ 2025-10-22 17:58     ` Matt Roper
  2025-10-27 19:41       ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-22 17:58 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Gustavo Sousa, intel-xe, intel-gfx, Ankit Nautiyal,
	Dnyaneshwar Bhadane, Jouni Högander, Juha-pekka Heikkila,
	Luca Coelho, Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu

On Wed, Oct 22, 2025 at 03:28:26PM +0300, Ville Syrjälä wrote:
> On Tue, Oct 21, 2025 at 09:28:32PM -0300, Gustavo Sousa wrote:
> > From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> > 
> > Starting from display Xe3p_LPD, UINT16 formats are also supported. Add
> > its corresponding PLANE_CTL bit and add the format in the necessary
> > functions.
> 
> Those have been supported by the hardware for a lot longer
> than that.

Agreed.  General support was added back in ICL (bspec 7656), although it
appears that it was unofficial and not productized or fully
hardware-validated.  It appears that support has remained unofficial
even up through these current platforms.  So I'm not sure we really want
to enable this if we don't have a specific use case asking for it; it
will _probably_ work, but there may be corner cases that have problems
because it wasn't intended for real use.

The only thing that seems to have changed is that UINT16 formats got
added to the list of formats that FBC can handle as part of the same
change that added the FP16 formats to that list.


Matt

> 
> I have an old branch that adds them here:
> https://github.com/vsyrjala/linux.git uint16
> but I never landed that.
> 
> > 
> > v2:
> >   - Add reference to Bspec 68911. (Matt Atwood)
> > 
> > Bspec: 68904, 69853, 68911
> > Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> > Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/skl_universal_plane.c | 96 +++++++++++++++-------
> >  .../drm/i915/display/skl_universal_plane_regs.h    |  1 +
> >  2 files changed, 68 insertions(+), 29 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > index 0319174adf95..530adff81b99 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > @@ -136,36 +136,47 @@ static const u32 icl_sdr_uv_plane_formats[] = {
> >  	DRM_FORMAT_XVYU2101010,
> >  };
> >  
> > +#define ICL_HDR_PLANE_FORMATS		\
> > +	DRM_FORMAT_C8,			\
> > +	DRM_FORMAT_RGB565,		\
> > +	DRM_FORMAT_XRGB8888,		\
> > +	DRM_FORMAT_XBGR8888,		\
> > +	DRM_FORMAT_ARGB8888,		\
> > +	DRM_FORMAT_ABGR8888,		\
> > +	DRM_FORMAT_XRGB2101010,		\
> > +	DRM_FORMAT_XBGR2101010,		\
> > +	DRM_FORMAT_ARGB2101010,		\
> > +	DRM_FORMAT_ABGR2101010,		\
> > +	DRM_FORMAT_XRGB16161616F,	\
> > +	DRM_FORMAT_XBGR16161616F,	\
> > +	DRM_FORMAT_ARGB16161616F,	\
> > +	DRM_FORMAT_ABGR16161616F,	\
> > +	DRM_FORMAT_YUYV,		\
> > +	DRM_FORMAT_YVYU,		\
> > +	DRM_FORMAT_UYVY,		\
> > +	DRM_FORMAT_VYUY,		\
> > +	DRM_FORMAT_NV12,		\
> > +	DRM_FORMAT_P010,		\
> > +	DRM_FORMAT_P012,		\
> > +	DRM_FORMAT_P016,		\
> > +	DRM_FORMAT_Y210,		\
> > +	DRM_FORMAT_Y212,		\
> > +	DRM_FORMAT_Y216,		\
> > +	DRM_FORMAT_XYUV8888,		\
> > +	DRM_FORMAT_XVYU2101010,		\
> > +	DRM_FORMAT_XVYU12_16161616,	\
> > +	DRM_FORMAT_XVYU16161616
> > +
> >  static const u32 icl_hdr_plane_formats[] = {
> > -	DRM_FORMAT_C8,
> > -	DRM_FORMAT_RGB565,
> > -	DRM_FORMAT_XRGB8888,
> > -	DRM_FORMAT_XBGR8888,
> > -	DRM_FORMAT_ARGB8888,
> > -	DRM_FORMAT_ABGR8888,
> > -	DRM_FORMAT_XRGB2101010,
> > -	DRM_FORMAT_XBGR2101010,
> > -	DRM_FORMAT_ARGB2101010,
> > -	DRM_FORMAT_ABGR2101010,
> > -	DRM_FORMAT_XRGB16161616F,
> > -	DRM_FORMAT_XBGR16161616F,
> > -	DRM_FORMAT_ARGB16161616F,
> > -	DRM_FORMAT_ABGR16161616F,
> > -	DRM_FORMAT_YUYV,
> > -	DRM_FORMAT_YVYU,
> > -	DRM_FORMAT_UYVY,
> > -	DRM_FORMAT_VYUY,
> > -	DRM_FORMAT_NV12,
> > -	DRM_FORMAT_P010,
> > -	DRM_FORMAT_P012,
> > -	DRM_FORMAT_P016,
> > -	DRM_FORMAT_Y210,
> > -	DRM_FORMAT_Y212,
> > -	DRM_FORMAT_Y216,
> > -	DRM_FORMAT_XYUV8888,
> > -	DRM_FORMAT_XVYU2101010,
> > -	DRM_FORMAT_XVYU12_16161616,
> > -	DRM_FORMAT_XVYU16161616,
> > +	ICL_HDR_PLANE_FORMATS,
> > +};
> > +
> > +static const u32 xe3p_lpd_hdr_plane_formats[] = {
> > +	ICL_HDR_PLANE_FORMATS,
> > +	DRM_FORMAT_XRGB16161616,
> > +	DRM_FORMAT_XBGR16161616,
> > +	DRM_FORMAT_ARGB16161616,
> > +	DRM_FORMAT_ABGR16161616,
> >  };
> >  
> >  int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
> > @@ -220,6 +231,18 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
> >  			else
> >  				return DRM_FORMAT_XRGB2101010;
> >  		}
> > +	case PLANE_CTL_FORMAT_XRGB_16161616:
> > +		if (rgb_order) {
> > +			if (alpha)
> > +				return DRM_FORMAT_ABGR16161616;
> > +			else
> > +				return DRM_FORMAT_XBGR16161616;
> > +		} else {
> > +			if (alpha)
> > +				return DRM_FORMAT_ARGB16161616;
> > +			else
> > +				return DRM_FORMAT_XRGB16161616;
> > +		}
> >  	case PLANE_CTL_FORMAT_XRGB_16161616F:
> >  		if (rgb_order) {
> >  			if (alpha)
> > @@ -960,6 +983,12 @@ static u32 skl_plane_ctl_format(u32 pixel_format)
> >  	case DRM_FORMAT_XRGB2101010:
> >  	case DRM_FORMAT_ARGB2101010:
> >  		return PLANE_CTL_FORMAT_XRGB_2101010;
> > +	case DRM_FORMAT_XBGR16161616:
> > +	case DRM_FORMAT_ABGR16161616:
> > +		return PLANE_CTL_FORMAT_XRGB_16161616 | PLANE_CTL_ORDER_RGBX;
> > +	case DRM_FORMAT_XRGB16161616:
> > +	case DRM_FORMAT_ARGB16161616:
> > +		return PLANE_CTL_FORMAT_XRGB_16161616;
> >  	case DRM_FORMAT_XBGR16161616F:
> >  	case DRM_FORMAT_ABGR16161616F:
> >  		return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
> > @@ -2479,6 +2508,11 @@ static const u32 *icl_get_plane_formats(struct intel_display *display,
> >  					int *num_formats)
> >  {
> >  	if (icl_is_hdr_plane(display, plane_id)) {
> > +		if (DISPLAY_VER(display) >= 35) {
> > +			*num_formats = ARRAY_SIZE(xe3p_lpd_hdr_plane_formats);
> > +			return xe3p_lpd_hdr_plane_formats;
> > +		}
> > +
> >  		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
> >  		return icl_hdr_plane_formats;
> >  	} else if (icl_is_nv12_y_plane(display, plane_id)) {
> > @@ -2637,6 +2671,10 @@ static bool tgl_plane_format_mod_supported(struct drm_plane *_plane,
> >  	case DRM_FORMAT_RGB565:
> >  	case DRM_FORMAT_XVYU2101010:
> >  	case DRM_FORMAT_C8:
> > +	case DRM_FORMAT_XBGR16161616:
> > +	case DRM_FORMAT_ABGR16161616:
> > +	case DRM_FORMAT_XRGB16161616:
> > +	case DRM_FORMAT_ARGB16161616:
> >  	case DRM_FORMAT_Y210:
> >  	case DRM_FORMAT_Y212:
> >  	case DRM_FORMAT_Y216:
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
> > index 479bb3f7f92b..84cf565bd653 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
> > @@ -64,6 +64,7 @@
> >  #define   PLANE_CTL_FORMAT_Y410			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
> >  #define   PLANE_CTL_FORMAT_Y412			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
> >  #define   PLANE_CTL_FORMAT_Y416			REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
> > +#define   PLANE_CTL_FORMAT_XRGB_16161616	REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 18)
> >  #define   PLANE_CTL_PIPE_CSC_ENABLE		REG_BIT(23) /* Pre-GLK */
> >  #define   PLANE_CTL_KEY_ENABLE_MASK		REG_GENMASK(22, 21)
> >  #define   PLANE_CTL_KEY_ENABLE_SOURCE		REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)
> > 
> > -- 
> > 2.51.0
> 
> -- 
> Ville Syrjälä
> Intel

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats
  2025-10-22 17:58     ` Matt Roper
@ 2025-10-27 19:41       ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-27 19:41 UTC (permalink / raw)
  To: Ville Syrjälä, Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Quoting Matt Roper (2025-10-22 14:58:05-03:00)
>On Wed, Oct 22, 2025 at 03:28:26PM +0300, Ville Syrjälä wrote:
>> On Tue, Oct 21, 2025 at 09:28:32PM -0300, Gustavo Sousa wrote:
>> > From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> > 
>> > Starting from display Xe3p_LPD, UINT16 formats are also supported. Add
>> > its corresponding PLANE_CTL bit and add the format in the necessary
>> > functions.
>> 
>> Those have been supported by the hardware for a lot longer
>> than that.

Yeah, Bspec shows that the support for UINT16 formats was already there
before Xe3p_LPD.

>
>Agreed.  General support was added back in ICL (bspec 7656), although it
>appears that it was unofficial and not productized or fully
>hardware-validated.  It appears that support has remained unofficial
>even up through these current platforms.  So I'm not sure we really want
>to enable this if we don't have a specific use case asking for it; it
>will _probably_ work, but there may be corner cases that have problems
>because it wasn't intended for real use.

Yeah. I think I'll just drop the UINT16-related patches from this
series.

Thanks!

--
Gustavo Sousa

>
>The only thing that seems to have changed is that UINT16 formats got
>added to the list of formats that FBC can handle as part of the same
>change that added the FP16 formats to that list.
>
>
>Matt
>
>> 
>> I have an old branch that adds them here:
>> https://github.com/vsyrjala/linux.git uint16
>> but I never landed that.
>> 
>> > 
>> > v2:
>> >   - Add reference to Bspec 68911. (Matt Atwood)
>> > 
>> > Bspec: 68904, 69853, 68911
>> > Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> > Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
>> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> > ---
>> >  drivers/gpu/drm/i915/display/skl_universal_plane.c | 96 +++++++++++++++-------
>> >  .../drm/i915/display/skl_universal_plane_regs.h    |  1 +
>> >  2 files changed, 68 insertions(+), 29 deletions(-)
>> > 
>> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> > index 0319174adf95..530adff81b99 100644
>> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
>> > @@ -136,36 +136,47 @@ static const u32 icl_sdr_uv_plane_formats[] = {
>> >          DRM_FORMAT_XVYU2101010,
>> >  };
>> >  
>> > +#define ICL_HDR_PLANE_FORMATS                \
>> > +        DRM_FORMAT_C8,                        \
>> > +        DRM_FORMAT_RGB565,                \
>> > +        DRM_FORMAT_XRGB8888,                \
>> > +        DRM_FORMAT_XBGR8888,                \
>> > +        DRM_FORMAT_ARGB8888,                \
>> > +        DRM_FORMAT_ABGR8888,                \
>> > +        DRM_FORMAT_XRGB2101010,                \
>> > +        DRM_FORMAT_XBGR2101010,                \
>> > +        DRM_FORMAT_ARGB2101010,                \
>> > +        DRM_FORMAT_ABGR2101010,                \
>> > +        DRM_FORMAT_XRGB16161616F,        \
>> > +        DRM_FORMAT_XBGR16161616F,        \
>> > +        DRM_FORMAT_ARGB16161616F,        \
>> > +        DRM_FORMAT_ABGR16161616F,        \
>> > +        DRM_FORMAT_YUYV,                \
>> > +        DRM_FORMAT_YVYU,                \
>> > +        DRM_FORMAT_UYVY,                \
>> > +        DRM_FORMAT_VYUY,                \
>> > +        DRM_FORMAT_NV12,                \
>> > +        DRM_FORMAT_P010,                \
>> > +        DRM_FORMAT_P012,                \
>> > +        DRM_FORMAT_P016,                \
>> > +        DRM_FORMAT_Y210,                \
>> > +        DRM_FORMAT_Y212,                \
>> > +        DRM_FORMAT_Y216,                \
>> > +        DRM_FORMAT_XYUV8888,                \
>> > +        DRM_FORMAT_XVYU2101010,                \
>> > +        DRM_FORMAT_XVYU12_16161616,        \
>> > +        DRM_FORMAT_XVYU16161616
>> > +
>> >  static const u32 icl_hdr_plane_formats[] = {
>> > -        DRM_FORMAT_C8,
>> > -        DRM_FORMAT_RGB565,
>> > -        DRM_FORMAT_XRGB8888,
>> > -        DRM_FORMAT_XBGR8888,
>> > -        DRM_FORMAT_ARGB8888,
>> > -        DRM_FORMAT_ABGR8888,
>> > -        DRM_FORMAT_XRGB2101010,
>> > -        DRM_FORMAT_XBGR2101010,
>> > -        DRM_FORMAT_ARGB2101010,
>> > -        DRM_FORMAT_ABGR2101010,
>> > -        DRM_FORMAT_XRGB16161616F,
>> > -        DRM_FORMAT_XBGR16161616F,
>> > -        DRM_FORMAT_ARGB16161616F,
>> > -        DRM_FORMAT_ABGR16161616F,
>> > -        DRM_FORMAT_YUYV,
>> > -        DRM_FORMAT_YVYU,
>> > -        DRM_FORMAT_UYVY,
>> > -        DRM_FORMAT_VYUY,
>> > -        DRM_FORMAT_NV12,
>> > -        DRM_FORMAT_P010,
>> > -        DRM_FORMAT_P012,
>> > -        DRM_FORMAT_P016,
>> > -        DRM_FORMAT_Y210,
>> > -        DRM_FORMAT_Y212,
>> > -        DRM_FORMAT_Y216,
>> > -        DRM_FORMAT_XYUV8888,
>> > -        DRM_FORMAT_XVYU2101010,
>> > -        DRM_FORMAT_XVYU12_16161616,
>> > -        DRM_FORMAT_XVYU16161616,
>> > +        ICL_HDR_PLANE_FORMATS,
>> > +};
>> > +
>> > +static const u32 xe3p_lpd_hdr_plane_formats[] = {
>> > +        ICL_HDR_PLANE_FORMATS,
>> > +        DRM_FORMAT_XRGB16161616,
>> > +        DRM_FORMAT_XBGR16161616,
>> > +        DRM_FORMAT_ARGB16161616,
>> > +        DRM_FORMAT_ABGR16161616,
>> >  };
>> >  
>> >  int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
>> > @@ -220,6 +231,18 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
>> >                          else
>> >                                  return DRM_FORMAT_XRGB2101010;
>> >                  }
>> > +        case PLANE_CTL_FORMAT_XRGB_16161616:
>> > +                if (rgb_order) {
>> > +                        if (alpha)
>> > +                                return DRM_FORMAT_ABGR16161616;
>> > +                        else
>> > +                                return DRM_FORMAT_XBGR16161616;
>> > +                } else {
>> > +                        if (alpha)
>> > +                                return DRM_FORMAT_ARGB16161616;
>> > +                        else
>> > +                                return DRM_FORMAT_XRGB16161616;
>> > +                }
>> >          case PLANE_CTL_FORMAT_XRGB_16161616F:
>> >                  if (rgb_order) {
>> >                          if (alpha)
>> > @@ -960,6 +983,12 @@ static u32 skl_plane_ctl_format(u32 pixel_format)
>> >          case DRM_FORMAT_XRGB2101010:
>> >          case DRM_FORMAT_ARGB2101010:
>> >                  return PLANE_CTL_FORMAT_XRGB_2101010;
>> > +        case DRM_FORMAT_XBGR16161616:
>> > +        case DRM_FORMAT_ABGR16161616:
>> > +                return PLANE_CTL_FORMAT_XRGB_16161616 | PLANE_CTL_ORDER_RGBX;
>> > +        case DRM_FORMAT_XRGB16161616:
>> > +        case DRM_FORMAT_ARGB16161616:
>> > +                return PLANE_CTL_FORMAT_XRGB_16161616;
>> >          case DRM_FORMAT_XBGR16161616F:
>> >          case DRM_FORMAT_ABGR16161616F:
>> >                  return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
>> > @@ -2479,6 +2508,11 @@ static const u32 *icl_get_plane_formats(struct intel_display *display,
>> >                                          int *num_formats)
>> >  {
>> >          if (icl_is_hdr_plane(display, plane_id)) {
>> > +                if (DISPLAY_VER(display) >= 35) {
>> > +                        *num_formats = ARRAY_SIZE(xe3p_lpd_hdr_plane_formats);
>> > +                        return xe3p_lpd_hdr_plane_formats;
>> > +                }
>> > +
>> >                  *num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
>> >                  return icl_hdr_plane_formats;
>> >          } else if (icl_is_nv12_y_plane(display, plane_id)) {
>> > @@ -2637,6 +2671,10 @@ static bool tgl_plane_format_mod_supported(struct drm_plane *_plane,
>> >          case DRM_FORMAT_RGB565:
>> >          case DRM_FORMAT_XVYU2101010:
>> >          case DRM_FORMAT_C8:
>> > +        case DRM_FORMAT_XBGR16161616:
>> > +        case DRM_FORMAT_ABGR16161616:
>> > +        case DRM_FORMAT_XRGB16161616:
>> > +        case DRM_FORMAT_ARGB16161616:
>> >          case DRM_FORMAT_Y210:
>> >          case DRM_FORMAT_Y212:
>> >          case DRM_FORMAT_Y216:
>> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
>> > index 479bb3f7f92b..84cf565bd653 100644
>> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
>> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
>> > @@ -64,6 +64,7 @@
>> >  #define   PLANE_CTL_FORMAT_Y410                        REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
>> >  #define   PLANE_CTL_FORMAT_Y412                        REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
>> >  #define   PLANE_CTL_FORMAT_Y416                        REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
>> > +#define   PLANE_CTL_FORMAT_XRGB_16161616        REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 18)
>> >  #define   PLANE_CTL_PIPE_CSC_ENABLE                REG_BIT(23) /* Pre-GLK */
>> >  #define   PLANE_CTL_KEY_ENABLE_MASK                REG_GENMASK(22, 21)
>> >  #define   PLANE_CTL_KEY_ENABLE_SOURCE                REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)
>> > 
>> > -- 
>> > 2.51.0
>> 
>> -- 
>> Ville Syrjälä
>> Intel
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters
  2025-10-22 14:56   ` Matt Roper
@ 2025-10-27 22:26     ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-27 22:26 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Quoting Matt Roper (2025-10-22 11:56:40-03:00)
>On Tue, Oct 21, 2025 at 09:28:30PM -0300, Gustavo Sousa wrote:
>> From: Matt Atwood <matthew.s.atwood@intel.com>
>> 
>> Bandwidth parameters for Xe3p_LPD are the same as for Xe3_LPD. Re-use
>> them.
>> 
>> v2:
>>   - Do not have a special case for ecc_impacting_de_bw, since there are
>>     no specific instructions in Bspec for this scenario. (Matt Roper)
>> 
>> Bspec: 68859
>> Cc: Matt Roper <matthew.d.roper@intel.com>
>> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com>
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_bw.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
>> index 57d65e6e5429..57cb8a23188f 100644
>> --- a/drivers/gpu/drm/i915/display/intel_bw.c
>> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
>> @@ -810,7 +810,9 @@ void intel_bw_init_hw(struct intel_display *display)
>>           */
>>          drm_WARN_ON_ONCE(display->drm, dram_info->ecc_impacting_de_bw);
>>  
>> -        if (DISPLAY_VERx100(display) >= 3002) {
>> +        if (DISPLAY_VER(display) >= 35) {
>> +                tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
>> +        } else if (DISPLAY_VERx100(display) >= 3002) {
>
>We could change 30.02 to a "==" since it's a one-off special case, and
>let everything else continue to fall into to the ">= 30" branch below.

Yeah, that sounds good.  I'll go with your suggestion.

>Up to you; either way,
>
>Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

Thanks!

--
Gustavo Sousa

>
>As I mentioned before, we probably should think about moving the
>bandwidth / memory stuff back to being platform-based rather than
>IP-based, but that's something we can look at as a folow-up; it doesn't
>need to be part of this series.
>
>
>Matt
>
>>                  tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
>>          } else if (DISPLAY_VER(display) >= 30) {
>>                  tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
>> 
>> -- 
>> 2.51.0
>> 
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status
  2025-10-22  0:28 ` [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status Gustavo Sousa
@ 2025-10-29 20:06   ` Matt Roper
  2025-10-29 20:50     ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-29 20:06 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

On Tue, Oct 21, 2025 at 09:28:35PM -0300, Gustavo Sousa wrote:
> The LT PHY in Xe3p_LPD allows polling for the AUX channel power status
> to verify completion of power up and down. As such, let's use that field
> to have a more precise waiting time instead of a fixed one.
> 
> Bspec: 68967
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  .../drm/i915/display/intel_display_power_well.c    | 32 +++++++++++++++++-----
>  1 file changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> index 5e88b930f5aa..ba2552adb58b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
> @@ -1858,23 +1858,41 @@ static void xelpdp_aux_power_well_enable(struct intel_display *display,
>  		     XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
>  		     XELPDP_DP_AUX_CH_CTL_POWER_REQUEST);
>  
> -	/*
> -	 * The power status flag cannot be used to determine whether aux
> -	 * power wells have finished powering up.  Instead we're
> -	 * expected to just wait a fixed 600us after raising the request
> -	 * bit.
> -	 */
> -	usleep_range(600, 1200);
> +	if (DISPLAY_VER(display) >= 35) {

Since the bspec specifically calls this out as a flow for LT PHY, it
seems like it would make more sense to make the condition here a feature
flag check for LT PHY.  As I understand it, the selection of one type of
PHY over another is more of a business / per-platform decision than an
IP progression thing, so it's quite possible that some future platforms
past Xe3p may not have LT PHYs.


Matt

> +		if (intel_de_wait_for_set(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
> +					  XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
> +			drm_warn(display->drm,
> +				 "Timeout waiting for PHY %c AUX channel power to be up\n",
> +				 phy_name(phy));
> +	} else {
> +		/*
> +		 * The power status flag cannot be used to determine whether aux
> +		 * power wells have finished powering up.  Instead we're
> +		 * expected to just wait a fixed 600us after raising the request
> +		 * bit.
> +		 */
> +		usleep_range(600, 1200);
> +	}
>  }
>  
>  static void xelpdp_aux_power_well_disable(struct intel_display *display,
>  					  struct i915_power_well *power_well)
>  {
>  	enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
> +	enum phy phy = icl_aux_pw_to_phy(display, power_well);
>  
>  	intel_de_rmw(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
>  		     XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
>  		     0);
> +
> +	if (DISPLAY_VER(display) >= 35) {
> +		if (intel_de_wait_for_clear(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
> +					    XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
> +			drm_warn(display->drm,
> +				 "Timeout waiting for PHY %c AUX channel power to be down\n",
> +				 phy_name(phy));
> +	}
> +
>  	usleep_range(10, 30);
>  }
>  
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status
  2025-10-29 20:06   ` Matt Roper
@ 2025-10-29 20:50     ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-29 20:50 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Quoting Matt Roper (2025-10-29 17:06:28-03:00)
>On Tue, Oct 21, 2025 at 09:28:35PM -0300, Gustavo Sousa wrote:
>> The LT PHY in Xe3p_LPD allows polling for the AUX channel power status
>> to verify completion of power up and down. As such, let's use that field
>> to have a more precise waiting time instead of a fixed one.
>> 
>> Bspec: 68967
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  .../drm/i915/display/intel_display_power_well.c    | 32 +++++++++++++++++-----
>>  1 file changed, 25 insertions(+), 7 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> index 5e88b930f5aa..ba2552adb58b 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
>> @@ -1858,23 +1858,41 @@ static void xelpdp_aux_power_well_enable(struct intel_display *display,
>>                       XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
>>                       XELPDP_DP_AUX_CH_CTL_POWER_REQUEST);
>>  
>> -        /*
>> -         * The power status flag cannot be used to determine whether aux
>> -         * power wells have finished powering up.  Instead we're
>> -         * expected to just wait a fixed 600us after raising the request
>> -         * bit.
>> -         */
>> -        usleep_range(600, 1200);
>> +        if (DISPLAY_VER(display) >= 35) {
>
>Since the bspec specifically calls this out as a flow for LT PHY, it
>seems like it would make more sense to make the condition here a feature
>flag check for LT PHY.  As I understand it, the selection of one type of
>PHY over another is more of a business / per-platform decision than an
>IP progression thing, so it's quite possible that some future platforms
>past Xe3p may not have LT PHYs.

Yeah, makes sense.

I know that the LT PHY series[1] does include a HAS_LT_PHY() macro, but
it does the same IP version check.  Perhaps we should define that macro
using a platform check.

For this series, I think I'll add a patch to include the HAS_LT_PHY()
macro with platform check and use it here.

In the long term, I was thinking we could have an enum intel_phy_type
and have a function that returns the correct value based on the port.

--
Gustavo Sousa

>
>
>Matt
>
>> +                if (intel_de_wait_for_set(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
>> +                                          XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
>> +                        drm_warn(display->drm,
>> +                                 "Timeout waiting for PHY %c AUX channel power to be up\n",
>> +                                 phy_name(phy));
>> +        } else {
>> +                /*
>> +                 * The power status flag cannot be used to determine whether aux
>> +                 * power wells have finished powering up.  Instead we're
>> +                 * expected to just wait a fixed 600us after raising the request
>> +                 * bit.
>> +                 */
>> +                usleep_range(600, 1200);
>> +        }
>>  }
>>  
>>  static void xelpdp_aux_power_well_disable(struct intel_display *display,
>>                                            struct i915_power_well *power_well)
>>  {
>>          enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
>> +        enum phy phy = icl_aux_pw_to_phy(display, power_well);
>>  
>>          intel_de_rmw(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
>>                       XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
>>                       0);
>> +
>> +        if (DISPLAY_VER(display) >= 35) {
>> +                if (intel_de_wait_for_clear(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
>> +                                            XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
>> +                        drm_warn(display->drm,
>> +                                 "Timeout waiting for PHY %c AUX channel power to be down\n",
>> +                                 phy_name(phy));
>> +        }
>> +
>>          usleep_range(10, 30);
>>  }
>>  
>> 
>> -- 
>> 2.51.0
>> 
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
  2025-10-22  0:28 ` [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints Gustavo Sousa
@ 2025-10-29 20:54   ` Matt Roper
  2025-10-30 21:56     ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-29 20:54 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Sai Teja Pottumuttu,
	Jani Nikula, Ville Syrjälä

On Tue, Oct 21, 2025 at 09:28:36PM -0300, Gustavo Sousa wrote:
> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> 
> Starting with Xe3p_LPD, we get two new registers and some bits in
> existing registers that expose hardware state information at the time of
> underrun notification that can be relevant to debugging.
> 
> Add the necessary logic in the driver to print the available debug
> information when an underrun happens.
> 
> v2:
>   - Use seq_buf to generate planes string. (Jani)
>   - Move definition of FBC_DEBUG_STATUS to intel_fbc_regs.h. (Ville)
>   - Change logic for processing UNDERRUN_DBG1 to use loops and move it
>     to a separate function. (Gustavo)
>   - Always print underrun error message, even if there wouldn't be any
>     debug info associated to the underrun. (Gustavo)
> 
> Bspec: 69111, 69561, 74411, 74412
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> Co-developed-by: Gustavo Sousa <gustavo.sousa@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display_regs.h  | 20 +++++
>  drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
>  drivers/gpu/drm/i915/display/intel_fifo_underrun.c | 87 ++++++++++++++++++++++
>  3 files changed, 109 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
> index 9d71e26a4fa2..c9f8b90faa42 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
> @@ -882,6 +882,25 @@
>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK		REG_GENMASK(2, 0) /* tgl+ */
>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id)	REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
>  
> +#define _UNDERRUN_DBG1_A				0x70064
> +#define _UNDERRUN_DBG1_B				0x71064
> +#define UNDERRUN_DBG1(pipe)				_MMIO_PIPE(pipe, \
> +								   _UNDERRUN_DBG1_A, \
> +								   _UNDERRUN_DBG1_B)
> +#define   UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK		REG_GENMASK(29, 24)
> +#define   UNDERRUN_DDB_EMPTY_MASK			REG_GENMASK(21, 16)
> +#define   UNDERRUN_DBUF_NOT_FILLED_MASK			REG_GENMASK(13, 8)
> +#define   UNDERRUN_BELOW_WM0_MASK			REG_GENMASK(5, 0)
> +
> +#define _UNDERRUN_DBG2_A				0x70068
> +#define _UNDERRUN_DBG2_B				0x71068
> +#define UNDERRUN_DBG2(pipe)				_MMIO_PIPE(pipe, \
> +								   _UNDERRUN_DBG2_A, \
> +								   _UNDERRUN_DBG2_B)
> +#define   UNDERRUN_FRAME_LINE_COUNTERS_FROZEN		REG_BIT(31)
> +#define   UNDERRUN_PIPE_FRAME_COUNT_MASK		REG_GENMASK(30, 20)
> +#define   UNDERRUN_LINE_COUNT_MASK			REG_GENMASK(19, 0)
> +
>  #define DPINVGTT				_MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
>  #define   DPINVGTT_EN_MASK_CHV				REG_GENMASK(27, 16)
>  #define   DPINVGTT_EN_MASK_VLV				REG_GENMASK(23, 16)
> @@ -1416,6 +1435,7 @@
>  
>  #define GEN12_DCPR_STATUS_1				_MMIO(0x46440)
>  #define  XELPDP_PMDEMAND_INFLIGHT_STATUS		REG_BIT(26)
> +#define  XE3P_UNDERRUN_PKGC				REG_BIT(21)
>  
>  #define FUSE_STRAP		_MMIO(0x42014)
>  #define   ILK_INTERNAL_GRAPHICS_DISABLE	REG_BIT(31)
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
> index b1d0161a3196..272dba7f9695 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
> @@ -88,6 +88,8 @@
>  #define DPFC_FENCE_YOFF			_MMIO(0x3218)
>  #define ILK_DPFC_FENCE_YOFF(fbc_id)	_MMIO_PIPE((fbc_id), 0x43218, 0x43258)
>  #define DPFC_CHICKEN			_MMIO(0x3224)
> +#define FBC_DEBUG_STATUS(pipe)		_MMIO_PIPE(pipe, 0x43220, 0x43260)

Is 'pipe' correct here?  Most of the other FBC registers are
parameterized by FBC instance rather than pipe.

> +#define   FBC_UNDERRUN_DECOMPRESSION		REG_BIT(27)
>  #define ILK_DPFC_CHICKEN(fbc_id)	_MMIO_PIPE((fbc_id), 0x43224, 0x43264)
>  #define   DPFC_HT_MODIFY			REG_BIT(31) /* pre-ivb */
>  #define   DPFC_NUKE_ON_ANY_MODIFICATION		REG_BIT(23) /* bdw+ */
> diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
> index c2ce8461ac9e..43cf141a59ae 100644
> --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
> +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
> @@ -25,6 +25,8 @@
>   *
>   */
>  
> +#include <linux/seq_buf.h>
> +
>  #include <drm/drm_print.h>
>  
>  #include "i915_reg.h"
> @@ -34,6 +36,7 @@
>  #include "intel_display_trace.h"
>  #include "intel_display_types.h"
>  #include "intel_fbc.h"
> +#include "intel_fbc_regs.h"
>  #include "intel_fifo_underrun.h"
>  #include "intel_pch_display.h"
>  
> @@ -352,6 +355,87 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>  	return old;
>  }
>  
> +#define UNDERRUN_DBG1_NUM_PLANES 6
> +
> +static void process_underrun_dbg1(struct intel_display *display,
> +				  enum pipe pipe)
> +{
> +	struct {
> +		u32 mask;
> +		const char *info;
> +	} info_masks[] = {
> +		{ UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
> +		{ UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
> +		{ UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
> +		{ UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
> +	};
> +	DECLARE_SEQ_BUF(planes_desc, 32);
> +	u32 val;
> +
> +	val = intel_de_read(display, UNDERRUN_DBG1(pipe));
> +	intel_de_write(display, UNDERRUN_DBG1(pipe), val);
> +
> +	for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
> +		u32 plane_bits;
> +
> +		plane_bits = val & info_masks[i].mask;
> +
> +		if (!plane_bits)
> +			continue;
> +
> +		plane_bits >>= ffs(info_masks[i].mask) - 1;

Nitpick:  It seems like we're just open-coding REG_FIELD_GET here.  Any
reason not to simplify down to something like this?

        u32 plane_bits = REG_FIELD_GET(info_masks[i].mask, val);

        if (!plane_bits)
                continue;

> +
> +		seq_buf_clear(&planes_desc);
> +
> +		for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
> +			if (!(plane_bits & REG_BIT(j)))
> +				continue;
> +
> +			if (j == 0)
> +				seq_buf_puts(&planes_desc, "[C]");
> +			else
> +				seq_buf_printf(&planes_desc, "[%d]", j);
> +		}
> +
> +		drm_err(display->drm,
> +			"Pipe %c FIFO underrun info: %s on planes: %s\n",
> +			pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
> +
> +		drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
> +	}
> +}
> +
> +static void xe3p_lpd_log_underrun(struct intel_display *display,
> +				  enum pipe pipe)
> +{
> +	u32 val;
> +
> +	process_underrun_dbg1(display, pipe);
> +
> +	val = intel_de_read(display, UNDERRUN_DBG2(pipe));
> +	if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {
> +		intel_de_write(display, UNDERRUN_DBG2(pipe), UNDERRUN_FRAME_LINE_COUNTERS_FROZEN);
> +		drm_err(display->drm, "Pipe %c FIFO underrun info: Frame count: %u, Line count: %u\n",
> +			pipe_name(pipe),
> +			REG_FIELD_GET(UNDERRUN_PIPE_FRAME_COUNT_MASK, val),
> +			REG_FIELD_GET(UNDERRUN_LINE_COUNT_MASK, val));
> +	}
> +
> +	val = intel_de_read(display, FBC_DEBUG_STATUS(pipe));
> +	if (val & FBC_UNDERRUN_DECOMPRESSION) {
> +		intel_de_write(display, FBC_DEBUG_STATUS(pipe), FBC_UNDERRUN_DECOMPRESSION);
> +		drm_err(display->drm, "Pipe %c FIFO underrun info: FBC decompression\n",
> +			pipe_name(pipe));
> +	}

As noted above, I'm not sure if 'pipe' is technically correct for this
register.  I think it always winds up with a 1:1 relationship on current
platforms, but would it make more sense to just move this check and
print into intel_fbc_handle_fifo_underrun_irq() where we're already
handling the FBC stuff on a per-FBC unit basis?


Matt

> +
> +	val = intel_de_read(display, GEN12_DCPR_STATUS_1);
> +	if (val & XE3P_UNDERRUN_PKGC) {
> +		intel_de_write(display, GEN12_DCPR_STATUS_1, XE3P_UNDERRUN_PKGC);
> +		drm_err(display->drm, "Pipe %c FIFO underrun info: Pkgc blocking memory\n",
> +			pipe_name(pipe));
> +	}
> +}
> +
>  /**
>   * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
>   * @display: display device instance
> @@ -379,6 +463,9 @@ void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
>  		trace_intel_cpu_fifo_underrun(display, pipe);
>  
>  		drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
> +
> +		if (DISPLAY_VER(display) >= 35)
> +			xe3p_lpd_log_underrun(display, pipe);
>  	}
>  
>  	intel_fbc_handle_fifo_underrun_irq(display);
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers
  2025-10-22  0:28 ` [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers Gustavo Sousa
@ 2025-10-29 21:22   ` Matt Roper
  2025-10-31  2:48     ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-29 21:22 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

On Tue, Oct 21, 2025 at 09:28:38PM -0300, Gustavo Sousa wrote:
> From: Ravi Kumar Vodapalli <ravi.kumar.vodapalli@intel.com>
> 
> Some of the register fields of MBUS_CTL and DBUF_CTL register are
> changed for Xe3p_LPD platforms. Update the changed fields in the driver.
> Below are the changes:
> 
> MBUS_CTL:
> 	Translation Throttle Min
> 		It changed from BIT[15:13] to BIT[16:13]
> 
> DBUF_CTL:
> 	Min Tracker State Service
> 		It changed from BIT[18:16] to BIT[20:16]
>         Max Tracker State Service
> 		It changed to from BIT[23:19] to BIT[14:10]
> 		but using default value, so no need to define
> 		in code.

In a lot of cases when a register field picks up extra high bit(s), the
extra bits were previously reserved, so it's fine to just adjust the
existing definition (since reserved bits are required to always read out
of hardware as zeroes).  However in these cases, the new bits these
fields are extending into were actively used by the hardware for other
purposes on previous platforms, which is why it's necessary to keep the
existing pre-Xe3p definitions unchanged and create separate Xe3p ones
that can be used only on the newer Xe3p platforms.  You should make some
mention of that in the commit message so it's clear why we're handling
these a bit differently than a lot of other registers.

> 
> v2:
>   - Keep definitions in the same line (i.e. without line continuation
>     breaks) for better readability. (Jani)
> 
> Bspec: 68868, 68872
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Signed-off-by: Ravi Kumar Vodapalli <ravi.kumar.vodapalli@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/skl_watermark.c      | 16 +++++--
>  drivers/gpu/drm/i915/display/skl_watermark_regs.h | 52 ++++++++++++-----------
>  2 files changed, 40 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 256162da9afc..c141d575009f 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3477,7 +3477,10 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
>  	if (!HAS_MBUS_JOINING(display))
>  		return;
>  
> -	if (DISPLAY_VER(display) >= 20)
> +	if (DISPLAY_VER(display) >= 35)
> +		intel_de_rmw(display, MBUS_CTL, XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK,
> +			     XE3P_MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
> +	else if (DISPLAY_VER(display) >= 20)
>  		intel_de_rmw(display, MBUS_CTL, MBUS_TRANSLATION_THROTTLE_MIN_MASK,
>  			     MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
>  
> @@ -3488,9 +3491,14 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
>  		    ratio, str_yes_no(joined_mbus));
>  
>  	for_each_dbuf_slice(display, slice)
> -		intel_de_rmw(display, DBUF_CTL_S(slice),
> -			     DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
> -			     DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
> +		if (DISPLAY_VER(display) >= 35)
> +			intel_de_rmw(display, DBUF_CTL_S(slice),
> +				     XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
> +				     XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
> +		else
> +			intel_de_rmw(display, DBUF_CTL_S(slice),
> +				     DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
> +				     DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
>  }
>  
>  static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state)
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
> index c5572fc0e847..94915afc6b0b 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark_regs.h
> +++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
> @@ -32,16 +32,18 @@
>  #define MBUS_BBOX_CTL_S1		_MMIO(0x45040)
>  #define MBUS_BBOX_CTL_S2		_MMIO(0x45044)
>  
> -#define MBUS_CTL				_MMIO(0x4438C)
> -#define   MBUS_JOIN				REG_BIT(31)
> -#define   MBUS_HASHING_MODE_MASK		REG_BIT(30)
> -#define   MBUS_HASHING_MODE_2x2			REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
> -#define   MBUS_HASHING_MODE_1x4			REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
> -#define   MBUS_JOIN_PIPE_SELECT_MASK		REG_GENMASK(28, 26)
> -#define   MBUS_JOIN_PIPE_SELECT(pipe)		REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
> -#define   MBUS_JOIN_PIPE_SELECT_NONE		MBUS_JOIN_PIPE_SELECT(7)
> -#define   MBUS_TRANSLATION_THROTTLE_MIN_MASK	REG_GENMASK(15, 13)
> -#define   MBUS_TRANSLATION_THROTTLE_MIN(val)	REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
> +#define MBUS_CTL					_MMIO(0x4438C)
> +#define   MBUS_JOIN					REG_BIT(31)
> +#define   MBUS_HASHING_MODE_MASK			REG_BIT(30)
> +#define   MBUS_HASHING_MODE_2x2				REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
> +#define   MBUS_HASHING_MODE_1x4				REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
> +#define   MBUS_JOIN_PIPE_SELECT_MASK			REG_GENMASK(28, 26)
> +#define   MBUS_JOIN_PIPE_SELECT(pipe)			REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
> +#define   MBUS_JOIN_PIPE_SELECT_NONE			MBUS_JOIN_PIPE_SELECT(7)
> +#define   MBUS_TRANSLATION_THROTTLE_MIN_MASK		REG_GENMASK(15, 13)
> +#define   MBUS_TRANSLATION_THROTTLE_MIN(val)		REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
> +#define   XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK	REG_GENMASK(16, 13)
> +#define   XE3P_MBUS_TRANSLATION_THROTTLE_MIN(val)	REG_FIELD_PREP(XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)

Nitpick:  I'm not sure if we're 100% consistent, but I feel like we
usually sort bitfields based on their upper bound rather than their
lower bound.  So even though xe3p and pre-xe3p start at the same bit 13,
the xe3p should probably be sorted first since it ends at a higher bit
(16 vs 15).

>  
>  /*
>   * The below are numbered starting from "S1" on gen11/gen12, but starting
> @@ -51,21 +53,23 @@
>   * way things will be named by the hardware team going forward, plus it's more
>   * consistent with how most of the rest of our registers are named.
>   */
> -#define _DBUF_CTL_S0				0x45008
> -#define _DBUF_CTL_S1				0x44FE8
> -#define _DBUF_CTL_S2				0x44300
> -#define _DBUF_CTL_S3				0x44304
> -#define DBUF_CTL_S(slice)			_MMIO(_PICK(slice, \
> -							    _DBUF_CTL_S0, \
> -							    _DBUF_CTL_S1, \
> -							    _DBUF_CTL_S2, \
> -							    _DBUF_CTL_S3))
> -#define  DBUF_POWER_REQUEST			REG_BIT(31)
> -#define  DBUF_POWER_STATE			REG_BIT(30)
> -#define  DBUF_TRACKER_STATE_SERVICE_MASK	REG_GENMASK(23, 19)
> -#define  DBUF_TRACKER_STATE_SERVICE(x)		REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
> -#define  DBUF_MIN_TRACKER_STATE_SERVICE_MASK	REG_GENMASK(18, 16) /* ADL-P+ */
> +#define _DBUF_CTL_S0					0x45008
> +#define _DBUF_CTL_S1					0x44FE8
> +#define _DBUF_CTL_S2					0x44300
> +#define _DBUF_CTL_S3					0x44304
> +#define DBUF_CTL_S(slice)				_MMIO(_PICK(slice, \
> +								    _DBUF_CTL_S0, \
> +								    _DBUF_CTL_S1, \
> +								    _DBUF_CTL_S2, \
> +								    _DBUF_CTL_S3))
> +#define  DBUF_POWER_REQUEST				REG_BIT(31)
> +#define  DBUF_POWER_STATE				REG_BIT(30)
> +#define  DBUF_TRACKER_STATE_SERVICE_MASK		REG_GENMASK(23, 19)
> +#define  DBUF_TRACKER_STATE_SERVICE(x)			REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
> +#define  DBUF_MIN_TRACKER_STATE_SERVICE_MASK		REG_GENMASK(18, 16) /* ADL-P+ */
>  #define  DBUF_MIN_TRACKER_STATE_SERVICE(x)		REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */
> +#define  XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK	REG_GENMASK(20, 16)
> +#define  XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(x)		REG_FIELD_PREP(XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x)

Same here.


Matt

>  
>  #define MTL_LATENCY_LP0_LP1		_MMIO(0x45780)
>  #define MTL_LATENCY_LP2_LP3		_MMIO(0x45784)
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-22  0:28 ` [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD Gustavo Sousa
@ 2025-10-29 21:53   ` Matt Roper
  2025-10-29 22:22   ` Ville Syrjälä
  1 sibling, 0 replies; 65+ messages in thread
From: Matt Roper @ 2025-10-29 21:53 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Ville Syrjälä

On Tue, Oct 21, 2025 at 09:28:39PM -0300, Gustavo Sousa wrote:
> In an upcoming change related to Xe3p_LPD, we will need to (i) update
> wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
> that is currently done when (wm[0] == 0).
> 
> Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
> be done before it gets called.  In order to keep (i) and (ii) as a
> contiguous logical sequence, let's reorder adjust_wm_latency(), making
> make_wm_latency_monotonic() the last thing to be done.
> 
> Also take this opportunity to simplify the code by doing the call to
> increase_wm_latency() only once.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index c141d575009f..57260a2a765a 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3213,14 +3213,13 @@ static void
>  adjust_wm_latency(struct intel_display *display)
>  {
>  	u16 *wm = display->wm.skl_latency;
> +	int inc = 0;
>  
>  	if (display->platform.dg2)
>  		multiply_wm_latency(display, 2);
>  
>  	sanitize_wm_latency(display);
>  
> -	make_wm_latency_monotonic(display);
> -
>  	/*
>  	 * WaWmMemoryReadLatency
>  	 *
> @@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
>  	 * from the punit when level 0 response data is 0us.
>  	 */
>  	if (wm[0] == 0)
> -		increase_wm_latency(display, wm_read_latency(display));
> +		inc += wm_read_latency(display);
>  
>  	/*
>  	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
> @@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
>  	 * to avoid any underrun.
>  	 */
>  	if (need_16gb_dimm_wa(display))
> -		increase_wm_latency(display, 1);
> +		inc += 1;
> +
> +	if (inc)
> +		increase_wm_latency(display, inc);
> +
> +	make_wm_latency_monotonic(display);
>  }
>  
>  static void mtl_read_wm_latency(struct intel_display *display)
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment
  2025-10-22  0:28 ` [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment Gustavo Sousa
@ 2025-10-29 22:08   ` Matt Roper
  2025-10-29 22:39     ` Ville Syrjälä
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-29 22:08 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Ville Syrjälä

On Tue, Oct 21, 2025 at 09:28:40PM -0300, Gustavo Sousa wrote:
> When reading memory latencies for watermark calculations, previous
> display releases instructed to apply an adjustment of adding a certain
> value (e.g. 6us) to all levels when the level 0's memory latency read
> from hardware was zero.
> 
> For Xe3p_LPD, the instruction is to always use 6us for level 0 and to
> add that value to the other levels.  Update adjust_wm_latency()
> accordingly.
> 
> While previously the adjustment was considered a workaround by the
> driver, for Xe3p_LPD that is part of the formal specification.  So,
> let's make sure that we differentiate those two in the driver code, even
> if there is a bit of redundancy with "inc += wm_read_latency(display)"
> appearing twice in the code.
> 
> v2:
>   - Rebased after addition of prep patch "drm/i915/wm: Reorder
>     adjust_wm_latency() for Xe3_LPD".
> 
> Bspec: 68986, 69126
> Cc: Matt Atwood <matthew.s.atwood@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/skl_watermark.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 57260a2a765a..5bb6cdc4ad2c 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3220,15 +3220,24 @@ adjust_wm_latency(struct intel_display *display)
>  
>  	sanitize_wm_latency(display);
>  
> -	/*
> -	 * WaWmMemoryReadLatency
> -	 *
> -	 * punit doesn't take into account the read latency so we need
> -	 * to add proper adjustment to each valid level we retrieve
> -	 * from the punit when level 0 response data is 0us.
> -	 */
> -	if (wm[0] == 0)
> +	if (DISPLAY_VER(display) >= 35) {
> +		/*
> +		 * Xe3p asks to ignore wm[0] read from the register and always
> +		 * use the adjustment that adds the read latency to all valid
> +		 * latency values.
> +		 */
> +		wm[0] = 0;
>  		inc += wm_read_latency(display);
> +	} else if (wm[0] == 0) {
> +		/*
> +		 * WaWmMemoryReadLatency
> +		 *
> +		 * punit doesn't take into account the read latency so we need
> +		 * to add proper adjustment to each valid level we retrieve
> +		 * from the punit when level 0 response data is 0us.
> +		 */
> +		inc += wm_read_latency(display);
> +	}

Wouldn't it be simpler to just have a separate

        /*
         * Xe3p and beyond should ignore level 0's reported latency and
         * always apply WaWmMemoryReadLatency logic.
         */
        if (DISPLAY_VER(display) >= 35)
                wm[0] = 0;

and leave the rest of the code unchanged?

Either way, matches the spec so

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>


Matt

>  
>  	/*
>  	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4
  2025-10-22  0:28 ` [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4 Gustavo Sousa
@ 2025-10-29 22:14   ` Matt Roper
  2025-10-31 17:36     ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Matt Roper @ 2025-10-29 22:14 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

On Tue, Oct 21, 2025 at 09:28:44PM -0300, Gustavo Sousa wrote:
> From: Jouni Högander <jouni.hogander@intel.com>
> 
> Ensure the minimum selective update line count is 4 in case of display
> version 35 and onwards.

I don't think this is true for Xe3p (at least based on what's shown
at the bottom of bspec 69887).


Matt

> 
> v2:
>   - Fix style by dropping extra spaces after assignment operator.
>     (Jani).
> 
> Bspec: 69887
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index cfc8b04f98fa..a23519b9b388 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -2804,6 +2804,29 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
>  		intel_psr_apply_pr_link_on_su_wa(crtc_state);
>  }
>  
> +static void intel_psr_su_area_min_lines(struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_display *display = to_intel_display(crtc_state);
> +	struct drm_rect damaged_area;
> +
> +	/*
> +	 * Bspec mentions 4 being minimum lines in SU for display version
> +	 * 35 and onwards.
> +	 */
> +	if (DISPLAY_VER(display) < 35 || drm_rect_height(&crtc_state->psr2_su_area) >= 4)
> +		return;
> +
> +	damaged_area.x1 = crtc_state->psr2_su_area.x1;
> +	damaged_area.y1 = crtc_state->psr2_su_area.y1;
> +	damaged_area.x2 = crtc_state->psr2_su_area.x2;
> +	damaged_area.y2 = crtc_state->psr2_su_area.y2;
> +
> +	damaged_area.y2 += 4 - drm_rect_height(&damaged_area);
> +	drm_rect_intersect(&damaged_area, &crtc_state->pipe_src);
> +	damaged_area.y1 -= 4 - drm_rect_height(&damaged_area);
> +	clip_area_update(&crtc_state->psr2_su_area, &damaged_area, &crtc_state->pipe_src);
> +}
> +
>  int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
>  				struct intel_crtc *crtc)
>  {
> @@ -2912,6 +2935,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
>  	if (full_update)
>  		goto skip_sel_fetch_set_loop;
>  
> +	intel_psr_su_area_min_lines(crtc_state);
> +
>  	intel_psr_apply_su_area_workarounds(crtc_state);
>  
>  	ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
> 
> -- 
> 2.51.0
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-22  0:28 ` [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD Gustavo Sousa
  2025-10-29 21:53   ` Matt Roper
@ 2025-10-29 22:22   ` Ville Syrjälä
  2025-10-29 22:36     ` Ville Syrjälä
  2025-10-30 13:48     ` Gustavo Sousa
  1 sibling, 2 replies; 65+ messages in thread
From: Ville Syrjälä @ 2025-10-29 22:22 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

On Tue, Oct 21, 2025 at 09:28:39PM -0300, Gustavo Sousa wrote:
> In an upcoming change related to Xe3p_LPD, we will need to (i) update
> wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
> that is currently done when (wm[0] == 0).
> 
> Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
> be done before it gets called.  In order to keep (i) and (ii) as a
> contiguous logical sequence, let's reorder adjust_wm_latency(), making
> make_wm_latency_monotonic() the last thing to be done.
> 
> Also take this opportunity to simplify the code by doing the call to
> increase_wm_latency() only once.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index c141d575009f..57260a2a765a 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3213,14 +3213,13 @@ static void
>  adjust_wm_latency(struct intel_display *display)
>  {
>  	u16 *wm = display->wm.skl_latency;
> +	int inc = 0;
>  
>  	if (display->platform.dg2)
>  		multiply_wm_latency(display, 2);
>  
>  	sanitize_wm_latency(display);
>  
> -	make_wm_latency_monotonic(display);
> -

I was thinking that by doing this early we avoid potentially papering
over our own bugs in the later adjustments. But Windows does appear to
do this after the read latency adjustment.

And it looks like Windows actually stopped doing this for xe3 and now
it rejects non-monotonic values. And it also does that after the read
latency adjustment.

So I guess what we want to do is move this later, only call it for 
pre-xe3, and add another step after it to validate that the latencies
are indeed monotonic.

>  	/*
>  	 * WaWmMemoryReadLatency
>  	 *
> @@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
>  	 * from the punit when level 0 response data is 0us.
>  	 */
>  	if (wm[0] == 0)
> -		increase_wm_latency(display, wm_read_latency(display));
> +		inc += wm_read_latency(display);
>  
>  	/*
>  	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
> @@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
>  	 * to avoid any underrun.
>  	 */
>  	if (need_16gb_dimm_wa(display))
> -		increase_wm_latency(display, 1);
> +		inc += 1;
> +
> +	if (inc)
> +		increase_wm_latency(display, inc);

I don't see that variable being helpful in any real way.
Just makes the function more complicated for no good reason.
It also has nothing to do with the rest of this patch.

> +
> +	make_wm_latency_monotonic(display);
>  }
>  
>  static void mtl_read_wm_latency(struct intel_display *display)
> 
> -- 
> 2.51.0

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-29 22:22   ` Ville Syrjälä
@ 2025-10-29 22:36     ` Ville Syrjälä
  2025-10-30 13:45       ` Gustavo Sousa
  2025-10-30 13:48     ` Gustavo Sousa
  1 sibling, 1 reply; 65+ messages in thread
From: Ville Syrjälä @ 2025-10-29 22:36 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

On Thu, Oct 30, 2025 at 12:22:01AM +0200, Ville Syrjälä wrote:
> On Tue, Oct 21, 2025 at 09:28:39PM -0300, Gustavo Sousa wrote:
> > In an upcoming change related to Xe3p_LPD, we will need to (i) update
> > wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
> > that is currently done when (wm[0] == 0).
> > 
> > Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
> > be done before it gets called.  In order to keep (i) and (ii) as a
> > contiguous logical sequence, let's reorder adjust_wm_latency(), making
> > make_wm_latency_monotonic() the last thing to be done.
> > 
> > Also take this opportunity to simplify the code by doing the call to
> > increase_wm_latency() only once.
> > 
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> > index c141d575009f..57260a2a765a 100644
> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > @@ -3213,14 +3213,13 @@ static void
> >  adjust_wm_latency(struct intel_display *display)
> >  {
> >  	u16 *wm = display->wm.skl_latency;
> > +	int inc = 0;
> >  
> >  	if (display->platform.dg2)
> >  		multiply_wm_latency(display, 2);
> >  
> >  	sanitize_wm_latency(display);
> >  
> > -	make_wm_latency_monotonic(display);
> > -
> 
> I was thinking that by doing this early we avoid potentially papering
> over our own bugs in the later adjustments. But Windows does appear to
> do this after the read latency adjustment.

Hmm, I suppose it doesn't really matter whether it's before or after
since the read latency adjustment applies to all wm levels. So I think
I still prefer to keep it early to avoid papering over our own bugs.

> 
> And it looks like Windows actually stopped doing this for xe3 and now
> it rejects non-monotonic values. And it also does that after the read
> latency adjustment.
> 
> So I guess what we want to do is move this later, only call it for 
> pre-xe3, and add another step after it to validate that the latencies
> are indeed monotonic.
> 
> >  	/*
> >  	 * WaWmMemoryReadLatency
> >  	 *
> > @@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
> >  	 * from the punit when level 0 response data is 0us.
> >  	 */
> >  	if (wm[0] == 0)
> > -		increase_wm_latency(display, wm_read_latency(display));
> > +		inc += wm_read_latency(display);
> >  
> >  	/*
> >  	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
> > @@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
> >  	 * to avoid any underrun.
> >  	 */
> >  	if (need_16gb_dimm_wa(display))
> > -		increase_wm_latency(display, 1);
> > +		inc += 1;
> > +
> > +	if (inc)
> > +		increase_wm_latency(display, inc);
> 
> I don't see that variable being helpful in any real way.
> Just makes the function more complicated for no good reason.
> It also has nothing to do with the rest of this patch.
> 
> > +
> > +	make_wm_latency_monotonic(display);
> >  }
> >  
> >  static void mtl_read_wm_latency(struct intel_display *display)
> > 
> > -- 
> > 2.51.0
> 
> -- 
> Ville Syrjälä
> Intel

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment
  2025-10-29 22:08   ` Matt Roper
@ 2025-10-29 22:39     ` Ville Syrjälä
  2025-10-30 13:53       ` Gustavo Sousa
  0 siblings, 1 reply; 65+ messages in thread
From: Ville Syrjälä @ 2025-10-29 22:39 UTC (permalink / raw)
  To: Matt Roper
  Cc: Gustavo Sousa, intel-xe, intel-gfx, Ankit Nautiyal,
	Dnyaneshwar Bhadane, Jouni Högander, Juha-pekka Heikkila,
	Luca Coelho, Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

On Wed, Oct 29, 2025 at 03:08:00PM -0700, Matt Roper wrote:
> On Tue, Oct 21, 2025 at 09:28:40PM -0300, Gustavo Sousa wrote:
> > When reading memory latencies for watermark calculations, previous
> > display releases instructed to apply an adjustment of adding a certain
> > value (e.g. 6us) to all levels when the level 0's memory latency read
> > from hardware was zero.
> > 
> > For Xe3p_LPD, the instruction is to always use 6us for level 0 and to
> > add that value to the other levels.  Update adjust_wm_latency()
> > accordingly.
> > 
> > While previously the adjustment was considered a workaround by the
> > driver, for Xe3p_LPD that is part of the formal specification.  So,
> > let's make sure that we differentiate those two in the driver code, even
> > if there is a bit of redundancy with "inc += wm_read_latency(display)"
> > appearing twice in the code.
> > 
> > v2:
> >   - Rebased after addition of prep patch "drm/i915/wm: Reorder
> >     adjust_wm_latency() for Xe3_LPD".
> > 
> > Bspec: 68986, 69126
> > Cc: Matt Atwood <matthew.s.atwood@intel.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/skl_watermark.c | 25 +++++++++++++++++--------
> >  1 file changed, 17 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> > index 57260a2a765a..5bb6cdc4ad2c 100644
> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > @@ -3220,15 +3220,24 @@ adjust_wm_latency(struct intel_display *display)
> >  
> >  	sanitize_wm_latency(display);
> >  
> > -	/*
> > -	 * WaWmMemoryReadLatency
> > -	 *
> > -	 * punit doesn't take into account the read latency so we need
> > -	 * to add proper adjustment to each valid level we retrieve
> > -	 * from the punit when level 0 response data is 0us.
> > -	 */
> > -	if (wm[0] == 0)
> > +	if (DISPLAY_VER(display) >= 35) {
> > +		/*
> > +		 * Xe3p asks to ignore wm[0] read from the register and always
> > +		 * use the adjustment that adds the read latency to all valid
> > +		 * latency values.
> > +		 */
> > +		wm[0] = 0;
> >  		inc += wm_read_latency(display);
> > +	} else if (wm[0] == 0) {
> > +		/*
> > +		 * WaWmMemoryReadLatency
> > +		 *
> > +		 * punit doesn't take into account the read latency so we need
> > +		 * to add proper adjustment to each valid level we retrieve
> > +		 * from the punit when level 0 response data is 0us.
> > +		 */
> > +		inc += wm_read_latency(display);
> > +	}
> 
> Wouldn't it be simpler to just have a separate
> 
>         /*
>          * Xe3p and beyond should ignore level 0's reported latency and
>          * always apply WaWmMemoryReadLatency logic.
>          */
>         if (DISPLAY_VER(display) >= 35)
>                 wm[0] = 0;
> 
> and leave the rest of the code unchanged?

That, and I think just stuff it into sanitize_wm_latency() so that
the bogus value gets nuked before we use it for anything.

> 
> Either way, matches the spec so
> 
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> 
> 
> Matt
> 
> >  
> >  	/*
> >  	 * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
> > 
> > -- 
> > 2.51.0
> > 
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> Linux GPU Platform Enablement
> Intel Corporation

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-29 22:36     ` Ville Syrjälä
@ 2025-10-30 13:45       ` Gustavo Sousa
  2025-10-30 15:38         ` Ville Syrjälä
  0 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-30 13:45 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Quoting Ville Syrjälä (2025-10-29 19:36:14-03:00)
>On Thu, Oct 30, 2025 at 12:22:01AM +0200, Ville Syrjälä wrote:
>> On Tue, Oct 21, 2025 at 09:28:39PM -0300, Gustavo Sousa wrote:
>> > In an upcoming change related to Xe3p_LPD, we will need to (i) update
>> > wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
>> > that is currently done when (wm[0] == 0).
>> > 
>> > Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
>> > be done before it gets called.  In order to keep (i) and (ii) as a
>> > contiguous logical sequence, let's reorder adjust_wm_latency(), making
>> > make_wm_latency_monotonic() the last thing to be done.
>> > 
>> > Also take this opportunity to simplify the code by doing the call to
>> > increase_wm_latency() only once.
>> > 
>> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> > ---
>> >  drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
>> >  1 file changed, 8 insertions(+), 4 deletions(-)
>> > 
>> > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
>> > index c141d575009f..57260a2a765a 100644
>> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
>> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
>> > @@ -3213,14 +3213,13 @@ static void
>> >  adjust_wm_latency(struct intel_display *display)
>> >  {
>> >          u16 *wm = display->wm.skl_latency;
>> > +        int inc = 0;
>> >  
>> >          if (display->platform.dg2)
>> >                  multiply_wm_latency(display, 2);
>> >  
>> >          sanitize_wm_latency(display);
>> >  
>> > -        make_wm_latency_monotonic(display);
>> > -
>> 
>> I was thinking that by doing this early we avoid potentially papering
>> over our own bugs in the later adjustments. But Windows does appear to
>> do this after the read latency adjustment.
>
>Hmm, I suppose it doesn't really matter whether it's before or after
>since the read latency adjustment applies to all wm levels. So I think
>I still prefer to keep it early to avoid papering over our own bugs.

Okay.  In this case, I guess I can drop this patch then and go back to
the original approach + moving the assignment of "wm[0] = 0" to be done
earlier.

>
>> 
>> And it looks like Windows actually stopped doing this for xe3 and now
>> it rejects non-monotonic values. And it also does that after the read
>> latency adjustment.
>> 
>> So I guess what we want to do is move this later, only call it for 
>> pre-xe3, and add another step after it to validate that the latencies
>> are indeed monotonic.

I guess in our case, we would reject them in sanitize_wm_latency(),
making everything after the invalid level (i.e. wm[level] < wm[level -
1]) be forced to zero, right?

In summary, with keeping make_wm_latency_monotonic() early, something
like this?

    |diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
    |index c141d575009f..6cf1565dcefd 100644
    |--- a/drivers/gpu/drm/i915/display/skl_watermark.c
    |+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
    |@@ -3183,11 +3183,16 @@ static void sanitize_wm_latency(struct intel_display *display)
    | 	int level, num_levels = display->wm.num_levels;
    | 
    | 	/*
    |-	 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
    |-	 * need to be disabled. We make sure to sanitize the values out
    |-	 * of the punit to satisfy this requirement.
    |+	 * Two types of sanitization are done here:
    |+	 * 1) If a level n (n > 1) has a 0us latency, all levels m (m >= n)
    |+	 *    need to be disabled. We make sure to sanitize the values out of
    |+	 *    the punit to satisfy this requirement.
    |+	 * 2) For Xe3 onward, only accept monotonic ranges.
    | 	 */
    | 	for (level = 1; level < num_levels; level++) {
    |+		if (DISPLAY_VER(display) >= 30 && wm[level] < wm[level - 1])
    |+			wm[level] = 0;
    |+
    | 		if (wm[level] == 0)
    | 			break;
    | 	}
    |@@ -3201,6 +3206,9 @@ static void make_wm_latency_monotonic(struct intel_display *display)
    | 	u16 *wm = display->wm.skl_latency;
    | 	int level, num_levels = display->wm.num_levels;
    | 
    |+	if (DISPLAY_VER(display) < 30)
    |+		return;
    |+
    | 	for (level = 1; level < num_levels; level++) {
    | 		if (wm[level] == 0)
    | 			break;

If so, I could include this patch as part of this series to avoid
conflicts or keep it as a separate patch...

--
Gustavo Sousa

>> 
>> >          /*
>> >           * WaWmMemoryReadLatency
>> >           *
>> > @@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
>> >           * from the punit when level 0 response data is 0us.
>> >           */
>> >          if (wm[0] == 0)
>> > -                increase_wm_latency(display, wm_read_latency(display));
>> > +                inc += wm_read_latency(display);
>> >  
>> >          /*
>> >           * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
>> > @@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
>> >           * to avoid any underrun.
>> >           */
>> >          if (need_16gb_dimm_wa(display))
>> > -                increase_wm_latency(display, 1);
>> > +                inc += 1;
>> > +
>> > +        if (inc)
>> > +                increase_wm_latency(display, inc);
>> 
>> I don't see that variable being helpful in any real way.
>> Just makes the function more complicated for no good reason.
>> It also has nothing to do with the rest of this patch.
>> 
>> > +
>> > +        make_wm_latency_monotonic(display);
>> >  }
>> >  
>> >  static void mtl_read_wm_latency(struct intel_display *display)
>> > 
>> > -- 
>> > 2.51.0
>> 
>> -- 
>> Ville Syrjälä
>> Intel
>
>-- 
>Ville Syrjälä
>Intel

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

* Re: [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-29 22:22   ` Ville Syrjälä
  2025-10-29 22:36     ` Ville Syrjälä
@ 2025-10-30 13:48     ` Gustavo Sousa
  1 sibling, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-30 13:48 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Quoting Ville Syrjälä (2025-10-29 19:22:01-03:00)
>On Tue, Oct 21, 2025 at 09:28:39PM -0300, Gustavo Sousa wrote:
>> In an upcoming change related to Xe3p_LPD, we will need to (i) update
>> wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
>> that is currently done when (wm[0] == 0).
>> 
>> Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
>> be done before it gets called.  In order to keep (i) and (ii) as a
>> contiguous logical sequence, let's reorder adjust_wm_latency(), making
>> make_wm_latency_monotonic() the last thing to be done.
>> 
>> Also take this opportunity to simplify the code by doing the call to
>> increase_wm_latency() only once.
>> 
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
>>  1 file changed, 8 insertions(+), 4 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
>> index c141d575009f..57260a2a765a 100644
>> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
>> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
>> @@ -3213,14 +3213,13 @@ static void
>>  adjust_wm_latency(struct intel_display *display)
>>  {
>>          u16 *wm = display->wm.skl_latency;
>> +        int inc = 0;
>>  
>>          if (display->platform.dg2)
>>                  multiply_wm_latency(display, 2);
>>  
>>          sanitize_wm_latency(display);
>>  
>> -        make_wm_latency_monotonic(display);
>> -
>
>I was thinking that by doing this early we avoid potentially papering
>over our own bugs in the later adjustments. But Windows does appear to
>do this after the read latency adjustment.
>
>And it looks like Windows actually stopped doing this for xe3 and now
>it rejects non-monotonic values. And it also does that after the read
>latency adjustment.
>
>So I guess what we want to do is move this later, only call it for 
>pre-xe3, and add another step after it to validate that the latencies
>are indeed monotonic.
>
>>          /*
>>           * WaWmMemoryReadLatency
>>           *
>> @@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
>>           * from the punit when level 0 response data is 0us.
>>           */
>>          if (wm[0] == 0)
>> -                increase_wm_latency(display, wm_read_latency(display));
>> +                inc += wm_read_latency(display);
>>  
>>          /*
>>           * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
>> @@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
>>           * to avoid any underrun.
>>           */
>>          if (need_16gb_dimm_wa(display))
>> -                increase_wm_latency(display, 1);
>> +                inc += 1;
>> +
>> +        if (inc)
>> +                increase_wm_latency(display, inc);
>
>I don't see that variable being helpful in any real way.
>Just makes the function more complicated for no good reason.

I liked the fact that we would be calling increase_wm_latency() only
once... Not a big deal though.

--
Gustavo Sousa

>It also has nothing to do with the rest of this patch.
>
>> +
>> +        make_wm_latency_monotonic(display);
>>  }
>>  
>>  static void mtl_read_wm_latency(struct intel_display *display)
>> 
>> -- 
>> 2.51.0
>
>-- 
>Ville Syrjälä
>Intel

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

* Re: [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment
  2025-10-29 22:39     ` Ville Syrjälä
@ 2025-10-30 13:53       ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-30 13:53 UTC (permalink / raw)
  To: Ville Syrjälä, Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

Quoting Ville Syrjälä (2025-10-29 19:39:47-03:00)
>On Wed, Oct 29, 2025 at 03:08:00PM -0700, Matt Roper wrote:
>> On Tue, Oct 21, 2025 at 09:28:40PM -0300, Gustavo Sousa wrote:
>> > When reading memory latencies for watermark calculations, previous
>> > display releases instructed to apply an adjustment of adding a certain
>> > value (e.g. 6us) to all levels when the level 0's memory latency read
>> > from hardware was zero.
>> > 
>> > For Xe3p_LPD, the instruction is to always use 6us for level 0 and to
>> > add that value to the other levels.  Update adjust_wm_latency()
>> > accordingly.
>> > 
>> > While previously the adjustment was considered a workaround by the
>> > driver, for Xe3p_LPD that is part of the formal specification.  So,
>> > let's make sure that we differentiate those two in the driver code, even
>> > if there is a bit of redundancy with "inc += wm_read_latency(display)"
>> > appearing twice in the code.
>> > 
>> > v2:
>> >   - Rebased after addition of prep patch "drm/i915/wm: Reorder
>> >     adjust_wm_latency() for Xe3_LPD".
>> > 
>> > Bspec: 68986, 69126
>> > Cc: Matt Atwood <matthew.s.atwood@intel.com>
>> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> > ---
>> >  drivers/gpu/drm/i915/display/skl_watermark.c | 25 +++++++++++++++++--------
>> >  1 file changed, 17 insertions(+), 8 deletions(-)
>> > 
>> > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
>> > index 57260a2a765a..5bb6cdc4ad2c 100644
>> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
>> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
>> > @@ -3220,15 +3220,24 @@ adjust_wm_latency(struct intel_display *display)
>> >  
>> >          sanitize_wm_latency(display);
>> >  
>> > -        /*
>> > -         * WaWmMemoryReadLatency
>> > -         *
>> > -         * punit doesn't take into account the read latency so we need
>> > -         * to add proper adjustment to each valid level we retrieve
>> > -         * from the punit when level 0 response data is 0us.
>> > -         */
>> > -        if (wm[0] == 0)
>> > +        if (DISPLAY_VER(display) >= 35) {
>> > +                /*
>> > +                 * Xe3p asks to ignore wm[0] read from the register and always
>> > +                 * use the adjustment that adds the read latency to all valid
>> > +                 * latency values.
>> > +                 */
>> > +                wm[0] = 0;
>> >                  inc += wm_read_latency(display);
>> > +        } else if (wm[0] == 0) {
>> > +                /*
>> > +                 * WaWmMemoryReadLatency
>> > +                 *
>> > +                 * punit doesn't take into account the read latency so we need
>> > +                 * to add proper adjustment to each valid level we retrieve
>> > +                 * from the punit when level 0 response data is 0us.
>> > +                 */
>> > +                inc += wm_read_latency(display);
>> > +        }
>> 
>> Wouldn't it be simpler to just have a separate
>> 
>>         /*
>>          * Xe3p and beyond should ignore level 0's reported latency and
>>          * always apply WaWmMemoryReadLatency logic.
>>          */
>>         if (DISPLAY_VER(display) >= 35)
>>                 wm[0] = 0;
>> 
>> and leave the rest of the code unchanged?
>
>That, and I think just stuff it into sanitize_wm_latency() so that
>the bogus value gets nuked before we use it for anything.

Alright.  Let me do that then.

FWIW, I wanted to keep the code clearly differentiating a WA path from
what is now part of the regular spec for Xe3p (or is it still a WA?
:-P), hence trying avoiding the split (doing wm[0] = 0 elsewhere).

--
Gustavo Sousa

>
>> 
>> Either way, matches the spec so
>> 
>> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
>> 
>> 
>> Matt
>> 
>> >  
>> >          /*
>> >           * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
>> > 
>> > -- 
>> > 2.51.0
>> > 
>> 
>> -- 
>> Matt Roper
>> Graphics Software Engineer
>> Linux GPU Platform Enablement
>> Intel Corporation
>
>-- 
>Ville Syrjälä
>Intel

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

* Re: [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD
  2025-10-30 13:45       ` Gustavo Sousa
@ 2025-10-30 15:38         ` Ville Syrjälä
  0 siblings, 0 replies; 65+ messages in thread
From: Ville Syrjälä @ 2025-10-30 15:38 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Matt Roper, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai

On Thu, Oct 30, 2025 at 10:45:56AM -0300, Gustavo Sousa wrote:
> Quoting Ville Syrjälä (2025-10-29 19:36:14-03:00)
> >On Thu, Oct 30, 2025 at 12:22:01AM +0200, Ville Syrjälä wrote:
> >> On Tue, Oct 21, 2025 at 09:28:39PM -0300, Gustavo Sousa wrote:
> >> > In an upcoming change related to Xe3p_LPD, we will need to (i) update
> >> > wm[0] in adjust_wm_latency() and (ii) do the same increase_wm_latency()
> >> > that is currently done when (wm[0] == 0).
> >> > 
> >> > Because make_wm_latency_monotonic() depends on wm[0], part (i) needs to
> >> > be done before it gets called.  In order to keep (i) and (ii) as a
> >> > contiguous logical sequence, let's reorder adjust_wm_latency(), making
> >> > make_wm_latency_monotonic() the last thing to be done.
> >> > 
> >> > Also take this opportunity to simplify the code by doing the call to
> >> > increase_wm_latency() only once.
> >> > 
> >> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> > Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> >> > ---
> >> >  drivers/gpu/drm/i915/display/skl_watermark.c | 12 ++++++++----
> >> >  1 file changed, 8 insertions(+), 4 deletions(-)
> >> > 
> >> > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> >> > index c141d575009f..57260a2a765a 100644
> >> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> >> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> >> > @@ -3213,14 +3213,13 @@ static void
> >> >  adjust_wm_latency(struct intel_display *display)
> >> >  {
> >> >          u16 *wm = display->wm.skl_latency;
> >> > +        int inc = 0;
> >> >  
> >> >          if (display->platform.dg2)
> >> >                  multiply_wm_latency(display, 2);
> >> >  
> >> >          sanitize_wm_latency(display);
> >> >  
> >> > -        make_wm_latency_monotonic(display);
> >> > -
> >> 
> >> I was thinking that by doing this early we avoid potentially papering
> >> over our own bugs in the later adjustments. But Windows does appear to
> >> do this after the read latency adjustment.
> >
> >Hmm, I suppose it doesn't really matter whether it's before or after
> >since the read latency adjustment applies to all wm levels. So I think
> >I still prefer to keep it early to avoid papering over our own bugs.
> 
> Okay.  In this case, I guess I can drop this patch then and go back to
> the original approach + moving the assignment of "wm[0] = 0" to be done
> earlier.
> 
> >
> >> 
> >> And it looks like Windows actually stopped doing this for xe3 and now
> >> it rejects non-monotonic values. And it also does that after the read
> >> latency adjustment.
> >> 
> >> So I guess what we want to do is move this later, only call it for 
> >> pre-xe3, and add another step after it to validate that the latencies
> >> are indeed monotonic.
> 
> I guess in our case, we would reject them in sanitize_wm_latency(),
> making everything after the invalid level (i.e. wm[level] < wm[level -
> 1]) be forced to zero, right?
> 
> In summary, with keeping make_wm_latency_monotonic() early, something
> like this?
> 
>     |diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
>     |index c141d575009f..6cf1565dcefd 100644
>     |--- a/drivers/gpu/drm/i915/display/skl_watermark.c
>     |+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
>     |@@ -3183,11 +3183,16 @@ static void sanitize_wm_latency(struct intel_display *display)
>     | 	int level, num_levels = display->wm.num_levels;
>     | 
>     | 	/*
>     |-	 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
>     |-	 * need to be disabled. We make sure to sanitize the values out
>     |-	 * of the punit to satisfy this requirement.
>     |+	 * Two types of sanitization are done here:
>     |+	 * 1) If a level n (n > 1) has a 0us latency, all levels m (m >= n)
>     |+	 *    need to be disabled. We make sure to sanitize the values out of
>     |+	 *    the punit to satisfy this requirement.
>     |+	 * 2) For Xe3 onward, only accept monotonic ranges.
>     | 	 */
>     | 	for (level = 1; level < num_levels; level++) {
>     |+		if (DISPLAY_VER(display) >= 30 && wm[level] < wm[level - 1])
>     |+			wm[level] = 0;

I don't think we want to sweep these under the rug.

IMO we should simply not call make_wm_latency_monotonic() on xe3+,
and do some kind of drm_WARN(!is_wm_latency_monotonic()) once
we're done with all the adjustments.

>     |+
>     | 		if (wm[level] == 0)
>     | 			break;
>     | 	}
>     |@@ -3201,6 +3206,9 @@ static void make_wm_latency_monotonic(struct intel_display *display)
>     | 	u16 *wm = display->wm.skl_latency;
>     | 	int level, num_levels = display->wm.num_levels;
>     | 
>     |+	if (DISPLAY_VER(display) < 30)
>     |+		return;
>     |+
>     | 	for (level = 1; level < num_levels; level++) {
>     | 		if (wm[level] == 0)
>     | 			break;
> 
> If so, I could include this patch as part of this series to avoid
> conflicts or keep it as a separate patch...
> 
> --
> Gustavo Sousa
> 
> >> 
> >> >          /*
> >> >           * WaWmMemoryReadLatency
> >> >           *
> >> > @@ -3229,7 +3228,7 @@ adjust_wm_latency(struct intel_display *display)
> >> >           * from the punit when level 0 response data is 0us.
> >> >           */
> >> >          if (wm[0] == 0)
> >> > -                increase_wm_latency(display, wm_read_latency(display));
> >> > +                inc += wm_read_latency(display);
> >> >  
> >> >          /*
> >> >           * WA Level-0 adjustment for 16Gb+ DIMMs: SKL+
> >> > @@ -3238,7 +3237,12 @@ adjust_wm_latency(struct intel_display *display)
> >> >           * to avoid any underrun.
> >> >           */
> >> >          if (need_16gb_dimm_wa(display))
> >> > -                increase_wm_latency(display, 1);
> >> > +                inc += 1;
> >> > +
> >> > +        if (inc)
> >> > +                increase_wm_latency(display, inc);
> >> 
> >> I don't see that variable being helpful in any real way.
> >> Just makes the function more complicated for no good reason.
> >> It also has nothing to do with the rest of this patch.
> >> 
> >> > +
> >> > +        make_wm_latency_monotonic(display);
> >> >  }
> >> >  
> >> >  static void mtl_read_wm_latency(struct intel_display *display)
> >> > 
> >> > -- 
> >> > 2.51.0
> >> 
> >> -- 
> >> Ville Syrjälä
> >> Intel
> >
> >-- 
> >Ville Syrjälä
> >Intel

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
  2025-10-29 20:54   ` Matt Roper
@ 2025-10-30 21:56     ` Gustavo Sousa
  2025-10-31 22:17       ` Matt Roper
  0 siblings, 1 reply; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-30 21:56 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula,
	Ville Syrjälä

Quoting Matt Roper (2025-10-29 17:54:39-03:00)
>On Tue, Oct 21, 2025 at 09:28:36PM -0300, Gustavo Sousa wrote:
>> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> 
>> Starting with Xe3p_LPD, we get two new registers and some bits in
>> existing registers that expose hardware state information at the time of
>> underrun notification that can be relevant to debugging.
>> 
>> Add the necessary logic in the driver to print the available debug
>> information when an underrun happens.
>> 
>> v2:
>>   - Use seq_buf to generate planes string. (Jani)
>>   - Move definition of FBC_DEBUG_STATUS to intel_fbc_regs.h. (Ville)
>>   - Change logic for processing UNDERRUN_DBG1 to use loops and move it
>>     to a separate function. (Gustavo)
>>   - Always print underrun error message, even if there wouldn't be any
>>     debug info associated to the underrun. (Gustavo)
>> 
>> Bspec: 69111, 69561, 74411, 74412
>> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> Co-developed-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_display_regs.h  | 20 +++++
>>  drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
>>  drivers/gpu/drm/i915/display/intel_fifo_underrun.c | 87 ++++++++++++++++++++++
>>  3 files changed, 109 insertions(+)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> index 9d71e26a4fa2..c9f8b90faa42 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> @@ -882,6 +882,25 @@
>>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK                REG_GENMASK(2, 0) /* tgl+ */
>>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id)        REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
>>  
>> +#define _UNDERRUN_DBG1_A                                0x70064
>> +#define _UNDERRUN_DBG1_B                                0x71064
>> +#define UNDERRUN_DBG1(pipe)                                _MMIO_PIPE(pipe, \
>> +                                                                   _UNDERRUN_DBG1_A, \
>> +                                                                   _UNDERRUN_DBG1_B)
>> +#define   UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK                REG_GENMASK(29, 24)
>> +#define   UNDERRUN_DDB_EMPTY_MASK                        REG_GENMASK(21, 16)
>> +#define   UNDERRUN_DBUF_NOT_FILLED_MASK                        REG_GENMASK(13, 8)
>> +#define   UNDERRUN_BELOW_WM0_MASK                        REG_GENMASK(5, 0)
>> +
>> +#define _UNDERRUN_DBG2_A                                0x70068
>> +#define _UNDERRUN_DBG2_B                                0x71068
>> +#define UNDERRUN_DBG2(pipe)                                _MMIO_PIPE(pipe, \
>> +                                                                   _UNDERRUN_DBG2_A, \
>> +                                                                   _UNDERRUN_DBG2_B)
>> +#define   UNDERRUN_FRAME_LINE_COUNTERS_FROZEN                REG_BIT(31)
>> +#define   UNDERRUN_PIPE_FRAME_COUNT_MASK                REG_GENMASK(30, 20)
>> +#define   UNDERRUN_LINE_COUNT_MASK                        REG_GENMASK(19, 0)
>> +
>>  #define DPINVGTT                                _MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
>>  #define   DPINVGTT_EN_MASK_CHV                                REG_GENMASK(27, 16)
>>  #define   DPINVGTT_EN_MASK_VLV                                REG_GENMASK(23, 16)
>> @@ -1416,6 +1435,7 @@
>>  
>>  #define GEN12_DCPR_STATUS_1                                _MMIO(0x46440)
>>  #define  XELPDP_PMDEMAND_INFLIGHT_STATUS                REG_BIT(26)
>> +#define  XE3P_UNDERRUN_PKGC                                REG_BIT(21)
>>  
>>  #define FUSE_STRAP                _MMIO(0x42014)
>>  #define   ILK_INTERNAL_GRAPHICS_DISABLE        REG_BIT(31)
>> diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> index b1d0161a3196..272dba7f9695 100644
>> --- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> +++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> @@ -88,6 +88,8 @@
>>  #define DPFC_FENCE_YOFF                        _MMIO(0x3218)
>>  #define ILK_DPFC_FENCE_YOFF(fbc_id)        _MMIO_PIPE((fbc_id), 0x43218, 0x43258)
>>  #define DPFC_CHICKEN                        _MMIO(0x3224)
>> +#define FBC_DEBUG_STATUS(pipe)                _MMIO_PIPE(pipe, 0x43220, 0x43260)
>
>Is 'pipe' correct here?  Most of the other FBC registers are
>parameterized by FBC instance rather than pipe.

Yeah, I just blindly copy/pasted the definition without realizing that
the rest of the file uses fbc_id. I'll change it to use fbc_id as well.

>
>> +#define   FBC_UNDERRUN_DECOMPRESSION                REG_BIT(27)
>>  #define ILK_DPFC_CHICKEN(fbc_id)        _MMIO_PIPE((fbc_id), 0x43224, 0x43264)
>>  #define   DPFC_HT_MODIFY                        REG_BIT(31) /* pre-ivb */
>>  #define   DPFC_NUKE_ON_ANY_MODIFICATION                REG_BIT(23) /* bdw+ */
>> diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> index c2ce8461ac9e..43cf141a59ae 100644
>> --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> @@ -25,6 +25,8 @@
>>   *
>>   */
>>  
>> +#include <linux/seq_buf.h>
>> +
>>  #include <drm/drm_print.h>
>>  
>>  #include "i915_reg.h"
>> @@ -34,6 +36,7 @@
>>  #include "intel_display_trace.h"
>>  #include "intel_display_types.h"
>>  #include "intel_fbc.h"
>> +#include "intel_fbc_regs.h"
>>  #include "intel_fifo_underrun.h"
>>  #include "intel_pch_display.h"
>>  
>> @@ -352,6 +355,87 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>>          return old;
>>  }
>>  
>> +#define UNDERRUN_DBG1_NUM_PLANES 6
>> +
>> +static void process_underrun_dbg1(struct intel_display *display,
>> +                                  enum pipe pipe)
>> +{
>> +        struct {
>> +                u32 mask;
>> +                const char *info;
>> +        } info_masks[] = {
>> +                { UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
>> +                { UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
>> +                { UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
>> +                { UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
>> +        };
>> +        DECLARE_SEQ_BUF(planes_desc, 32);
>> +        u32 val;
>> +
>> +        val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>> +        intel_de_write(display, UNDERRUN_DBG1(pipe), val);
>> +
>> +        for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
>> +                u32 plane_bits;
>> +
>> +                plane_bits = val & info_masks[i].mask;
>> +
>> +                if (!plane_bits)
>> +                        continue;
>> +
>> +                plane_bits >>= ffs(info_masks[i].mask) - 1;
>
>Nitpick:  It seems like we're just open-coding REG_FIELD_GET here.  Any
>reason not to simplify down to something like this?
>
>        u32 plane_bits = REG_FIELD_GET(info_masks[i].mask, val);
>
>        if (!plane_bits)
>                continue;

We can't use REG_FIELD_GET() because the mask parameter must be a
constant expression. That's why I went with open-coded version.

We could change the current patch to use REG_FIELD_GET() with something
like below. What do you think?

    |diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
    |index 43cf141a59ae..34faedb9799c 100644
    |--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
    |+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
    |@@ -360,35 +360,28 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
    | static void process_underrun_dbg1(struct intel_display *display,
    | 				  enum pipe pipe)
    | {
    |+	u32 val = intel_de_read(display, UNDERRUN_DBG1(pipe));
    | 	struct {
    |-		u32 mask;
    |+		u32 plane_mask;
    | 		const char *info;
    |-	} info_masks[] = {
    |-		{ UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
    |-		{ UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
    |-		{ UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
    |-		{ UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
    |+	} masks[] = {
    |+		{ REG_FIELD_GET(UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, val), "DBUF block not valid" },
    |+		{ REG_FIELD_GET(UNDERRUN_DDB_EMPTY_MASK, val), "DDB empty" },
    |+		{ REG_FIELD_GET(UNDERRUN_DBUF_NOT_FILLED_MASK, val), "DBUF not completely filled" },
    |+		{ REG_FIELD_GET(UNDERRUN_BELOW_WM0_MASK, val), "DBUF below WM0" },
    | 	};
    | 	DECLARE_SEQ_BUF(planes_desc, 32);
    |-	u32 val;
    | 
    |-	val = intel_de_read(display, UNDERRUN_DBG1(pipe));
    | 	intel_de_write(display, UNDERRUN_DBG1(pipe), val);
    | 
    |-	for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
    |-		u32 plane_bits;
    |-
    |-		plane_bits = val & info_masks[i].mask;
    |-
    |-		if (!plane_bits)
    |+	for (int i = 0; i < ARRAY_SIZE(masks); i++) {
    |+		if (!masks[i].plane_mask)
    | 			continue;
    | 
    |-		plane_bits >>= ffs(info_masks[i].mask) - 1;
    |-
    | 		seq_buf_clear(&planes_desc);
    | 
    | 		for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
    |-			if (!(plane_bits & REG_BIT(j)))
    |+			if (!(masks[i].plane_mask & REG_BIT(j)))
    | 				continue;
    | 
    | 			if (j == 0)
    |@@ -399,7 +392,7 @@ static void process_underrun_dbg1(struct intel_display *display,
    | 
    | 		drm_err(display->drm,
    | 			"Pipe %c FIFO underrun info: %s on planes: %s\n",
    |-			pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
    |+			pipe_name(pipe), masks[i].info, seq_buf_str(&planes_desc));
    | 
    | 		drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
    | 	}

>
>> +
>> +                seq_buf_clear(&planes_desc);
>> +
>> +                for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
>> +                        if (!(plane_bits & REG_BIT(j)))
>> +                                continue;
>> +
>> +                        if (j == 0)
>> +                                seq_buf_puts(&planes_desc, "[C]");
>> +                        else
>> +                                seq_buf_printf(&planes_desc, "[%d]", j);
>> +                }
>> +
>> +                drm_err(display->drm,
>> +                        "Pipe %c FIFO underrun info: %s on planes: %s\n",
>> +                        pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
>> +
>> +                drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
>> +        }
>> +}
>> +
>> +static void xe3p_lpd_log_underrun(struct intel_display *display,
>> +                                  enum pipe pipe)
>> +{
>> +        u32 val;
>> +
>> +        process_underrun_dbg1(display, pipe);
>> +
>> +        val = intel_de_read(display, UNDERRUN_DBG2(pipe));
>> +        if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {
>> +                intel_de_write(display, UNDERRUN_DBG2(pipe), UNDERRUN_FRAME_LINE_COUNTERS_FROZEN);
>> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Frame count: %u, Line count: %u\n",
>> +                        pipe_name(pipe),
>> +                        REG_FIELD_GET(UNDERRUN_PIPE_FRAME_COUNT_MASK, val),
>> +                        REG_FIELD_GET(UNDERRUN_LINE_COUNT_MASK, val));
>> +        }
>> +
>> +        val = intel_de_read(display, FBC_DEBUG_STATUS(pipe));
>> +        if (val & FBC_UNDERRUN_DECOMPRESSION) {
>> +                intel_de_write(display, FBC_DEBUG_STATUS(pipe), FBC_UNDERRUN_DECOMPRESSION);
>> +                drm_err(display->drm, "Pipe %c FIFO underrun info: FBC decompression\n",
>> +                        pipe_name(pipe));
>> +        }
>
>As noted above, I'm not sure if 'pipe' is technically correct for this
>register.  I think it always winds up with a 1:1 relationship on current
>platforms, but would it make more sense to just move this check and
>print into intel_fbc_handle_fifo_underrun_irq() where we're already
>handling the FBC stuff on a per-FBC unit basis?

Yeah.  We probably want to check if there is a valid FBC instance
respective to this pipe and then read the register.

I see complications with moving this to
intel_fbc_handle_fifo_underrun_irq():

  1) The function intel_fbc_handle_fifo_underrun_irq() is more about
     disabling the FBC on an underrun.  I think reporting that the FBC
     was decompressing when the there was an underrun makes more sense
     to be grouped together with the other info related to FIFO
     underruns.  It could even be useful if, due to some hw/sw bug, FBC
     is still doing something after we disabled it (or so we thought)
     due to a previous underrun.

  2) Logging underrun debug info is currently guarded by
     intel_set_cpu_fifo_underrun_reporting().  So, we would need to
     complicate the implementation a bit to ensure that
     intel_fbc_handle_fifo_underrun_irq() would only report when
     reporting was enabled.


So, I was thinking about defining a new function
intel_fbc_fifo_underrun_log_info() and calling it from
xe3p_lpd_log_underrun().  What do you think?

--
Gustavo Sousa
>
>
>Matt
>
>> +
>> +        val = intel_de_read(display, GEN12_DCPR_STATUS_1);
>> +        if (val & XE3P_UNDERRUN_PKGC) {
>> +                intel_de_write(display, GEN12_DCPR_STATUS_1, XE3P_UNDERRUN_PKGC);
>> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Pkgc blocking memory\n",
>> +                        pipe_name(pipe));
>> +        }
>> +}
>> +
>>  /**
>>   * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
>>   * @display: display device instance
>> @@ -379,6 +463,9 @@ void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
>>                  trace_intel_cpu_fifo_underrun(display, pipe);
>>  
>>                  drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
>> +
>> +                if (DISPLAY_VER(display) >= 35)
>> +                        xe3p_lpd_log_underrun(display, pipe);
>>          }
>>  
>>          intel_fbc_handle_fifo_underrun_irq(display);
>> 
>> -- 
>> 2.51.0
>> 
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers
  2025-10-29 21:22   ` Matt Roper
@ 2025-10-31  2:48     ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-31  2:48 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

Quoting Matt Roper (2025-10-29 18:22:15-03:00)
>On Tue, Oct 21, 2025 at 09:28:38PM -0300, Gustavo Sousa wrote:
>> From: Ravi Kumar Vodapalli <ravi.kumar.vodapalli@intel.com>
>> 
>> Some of the register fields of MBUS_CTL and DBUF_CTL register are
>> changed for Xe3p_LPD platforms. Update the changed fields in the driver.
>> Below are the changes:
>> 
>> MBUS_CTL:
>>         Translation Throttle Min
>>                 It changed from BIT[15:13] to BIT[16:13]
>> 
>> DBUF_CTL:
>>         Min Tracker State Service
>>                 It changed from BIT[18:16] to BIT[20:16]
>>         Max Tracker State Service
>>                 It changed to from BIT[23:19] to BIT[14:10]
>>                 but using default value, so no need to define
>>                 in code.
>
>In a lot of cases when a register field picks up extra high bit(s), the
>extra bits were previously reserved, so it's fine to just adjust the
>existing definition (since reserved bits are required to always read out
>of hardware as zeroes).  However in these cases, the new bits these
>fields are extending into were actively used by the hardware for other
>purposes on previous platforms, which is why it's necessary to keep the
>existing pre-Xe3p definitions unchanged and create separate Xe3p ones
>that can be used only on the newer Xe3p platforms.  You should make some
>mention of that in the commit message so it's clear why we're handling
>these a bit differently than a lot of other registers.

Agreed.  Just updated the local v3 to make that clear.

>
>> 
>> v2:
>>   - Keep definitions in the same line (i.e. without line continuation
>>     breaks) for better readability. (Jani)
>> 
>> Bspec: 68868, 68872
>> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> Signed-off-by: Ravi Kumar Vodapalli <ravi.kumar.vodapalli@intel.com>
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/skl_watermark.c      | 16 +++++--
>>  drivers/gpu/drm/i915/display/skl_watermark_regs.h | 52 ++++++++++++-----------
>>  2 files changed, 40 insertions(+), 28 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
>> index 256162da9afc..c141d575009f 100644
>> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
>> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
>> @@ -3477,7 +3477,10 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
>>          if (!HAS_MBUS_JOINING(display))
>>                  return;
>>  
>> -        if (DISPLAY_VER(display) >= 20)
>> +        if (DISPLAY_VER(display) >= 35)
>> +                intel_de_rmw(display, MBUS_CTL, XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK,
>> +                             XE3P_MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
>> +        else if (DISPLAY_VER(display) >= 20)
>>                  intel_de_rmw(display, MBUS_CTL, MBUS_TRANSLATION_THROTTLE_MIN_MASK,
>>                               MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
>>  
>> @@ -3488,9 +3491,14 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
>>                      ratio, str_yes_no(joined_mbus));
>>  
>>          for_each_dbuf_slice(display, slice)
>> -                intel_de_rmw(display, DBUF_CTL_S(slice),
>> -                             DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
>> -                             DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
>> +                if (DISPLAY_VER(display) >= 35)
>> +                        intel_de_rmw(display, DBUF_CTL_S(slice),
>> +                                     XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
>> +                                     XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
>> +                else
>> +                        intel_de_rmw(display, DBUF_CTL_S(slice),
>> +                                     DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
>> +                                     DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
>>  }
>>  
>>  static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state)
>> diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
>> index c5572fc0e847..94915afc6b0b 100644
>> --- a/drivers/gpu/drm/i915/display/skl_watermark_regs.h
>> +++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
>> @@ -32,16 +32,18 @@
>>  #define MBUS_BBOX_CTL_S1                _MMIO(0x45040)
>>  #define MBUS_BBOX_CTL_S2                _MMIO(0x45044)
>>  
>> -#define MBUS_CTL                                _MMIO(0x4438C)
>> -#define   MBUS_JOIN                                REG_BIT(31)
>> -#define   MBUS_HASHING_MODE_MASK                REG_BIT(30)
>> -#define   MBUS_HASHING_MODE_2x2                        REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
>> -#define   MBUS_HASHING_MODE_1x4                        REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
>> -#define   MBUS_JOIN_PIPE_SELECT_MASK                REG_GENMASK(28, 26)
>> -#define   MBUS_JOIN_PIPE_SELECT(pipe)                REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
>> -#define   MBUS_JOIN_PIPE_SELECT_NONE                MBUS_JOIN_PIPE_SELECT(7)
>> -#define   MBUS_TRANSLATION_THROTTLE_MIN_MASK        REG_GENMASK(15, 13)
>> -#define   MBUS_TRANSLATION_THROTTLE_MIN(val)        REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
>> +#define MBUS_CTL                                        _MMIO(0x4438C)
>> +#define   MBUS_JOIN                                        REG_BIT(31)
>> +#define   MBUS_HASHING_MODE_MASK                        REG_BIT(30)
>> +#define   MBUS_HASHING_MODE_2x2                                REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
>> +#define   MBUS_HASHING_MODE_1x4                                REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
>> +#define   MBUS_JOIN_PIPE_SELECT_MASK                        REG_GENMASK(28, 26)
>> +#define   MBUS_JOIN_PIPE_SELECT(pipe)                        REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
>> +#define   MBUS_JOIN_PIPE_SELECT_NONE                        MBUS_JOIN_PIPE_SELECT(7)
>> +#define   MBUS_TRANSLATION_THROTTLE_MIN_MASK                REG_GENMASK(15, 13)
>> +#define   MBUS_TRANSLATION_THROTTLE_MIN(val)                REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
>> +#define   XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK        REG_GENMASK(16, 13)
>> +#define   XE3P_MBUS_TRANSLATION_THROTTLE_MIN(val)        REG_FIELD_PREP(XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
>
>Nitpick:  I'm not sure if we're 100% consistent, but I feel like we
>usually sort bitfields based on their upper bound rather than their
>lower bound.  So even though xe3p and pre-xe3p start at the same bit 13,
>the xe3p should probably be sorted first since it ends at a higher bit
>(16 vs 15).

Ack.

Thanks!

--
Gustavo Sousa

>
>>  
>>  /*
>>   * The below are numbered starting from "S1" on gen11/gen12, but starting
>> @@ -51,21 +53,23 @@
>>   * way things will be named by the hardware team going forward, plus it's more
>>   * consistent with how most of the rest of our registers are named.
>>   */
>> -#define _DBUF_CTL_S0                                0x45008
>> -#define _DBUF_CTL_S1                                0x44FE8
>> -#define _DBUF_CTL_S2                                0x44300
>> -#define _DBUF_CTL_S3                                0x44304
>> -#define DBUF_CTL_S(slice)                        _MMIO(_PICK(slice, \
>> -                                                            _DBUF_CTL_S0, \
>> -                                                            _DBUF_CTL_S1, \
>> -                                                            _DBUF_CTL_S2, \
>> -                                                            _DBUF_CTL_S3))
>> -#define  DBUF_POWER_REQUEST                        REG_BIT(31)
>> -#define  DBUF_POWER_STATE                        REG_BIT(30)
>> -#define  DBUF_TRACKER_STATE_SERVICE_MASK        REG_GENMASK(23, 19)
>> -#define  DBUF_TRACKER_STATE_SERVICE(x)                REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
>> -#define  DBUF_MIN_TRACKER_STATE_SERVICE_MASK        REG_GENMASK(18, 16) /* ADL-P+ */
>> +#define _DBUF_CTL_S0                                        0x45008
>> +#define _DBUF_CTL_S1                                        0x44FE8
>> +#define _DBUF_CTL_S2                                        0x44300
>> +#define _DBUF_CTL_S3                                        0x44304
>> +#define DBUF_CTL_S(slice)                                _MMIO(_PICK(slice, \
>> +                                                                    _DBUF_CTL_S0, \
>> +                                                                    _DBUF_CTL_S1, \
>> +                                                                    _DBUF_CTL_S2, \
>> +                                                                    _DBUF_CTL_S3))
>> +#define  DBUF_POWER_REQUEST                                REG_BIT(31)
>> +#define  DBUF_POWER_STATE                                REG_BIT(30)
>> +#define  DBUF_TRACKER_STATE_SERVICE_MASK                REG_GENMASK(23, 19)
>> +#define  DBUF_TRACKER_STATE_SERVICE(x)                        REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
>> +#define  DBUF_MIN_TRACKER_STATE_SERVICE_MASK                REG_GENMASK(18, 16) /* ADL-P+ */
>>  #define  DBUF_MIN_TRACKER_STATE_SERVICE(x)                REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */
>> +#define  XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK        REG_GENMASK(20, 16)
>> +#define  XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(x)                REG_FIELD_PREP(XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x)
>
>Same here.
>
>
>Matt
>
>>  
>>  #define MTL_LATENCY_LP0_LP1                _MMIO(0x45780)
>>  #define MTL_LATENCY_LP2_LP3                _MMIO(0x45784)
>> 
>> -- 
>> 2.51.0
>> 
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4
  2025-10-29 22:14   ` Matt Roper
@ 2025-10-31 17:36     ` Gustavo Sousa
  0 siblings, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-31 17:36 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula

Quoting Matt Roper (2025-10-29 19:14:23-03:00)
>On Tue, Oct 21, 2025 at 09:28:44PM -0300, Gustavo Sousa wrote:
>> From: Jouni Högander <jouni.hogander@intel.com>
>> 
>> Ensure the minimum selective update line count is 4 in case of display
>> version 35 and onwards.
>
>I don't think this is true for Xe3p (at least based on what's shown
>at the bottom of bspec 69887).

Agreed.  I think we can drop this patch.

--
Gustavo Sousa

>
>
>Matt
>
>> 
>> v2:
>>   - Fix style by dropping extra spaces after assignment operator.
>>     (Jani).
>> 
>> Bspec: 69887
>> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_psr.c | 25 +++++++++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
>> index cfc8b04f98fa..a23519b9b388 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -2804,6 +2804,29 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
>>                  intel_psr_apply_pr_link_on_su_wa(crtc_state);
>>  }
>>  
>> +static void intel_psr_su_area_min_lines(struct intel_crtc_state *crtc_state)
>> +{
>> +        struct intel_display *display = to_intel_display(crtc_state);
>> +        struct drm_rect damaged_area;
>> +
>> +        /*
>> +         * Bspec mentions 4 being minimum lines in SU for display version
>> +         * 35 and onwards.
>> +         */
>> +        if (DISPLAY_VER(display) < 35 || drm_rect_height(&crtc_state->psr2_su_area) >= 4)
>> +                return;
>> +
>> +        damaged_area.x1 = crtc_state->psr2_su_area.x1;
>> +        damaged_area.y1 = crtc_state->psr2_su_area.y1;
>> +        damaged_area.x2 = crtc_state->psr2_su_area.x2;
>> +        damaged_area.y2 = crtc_state->psr2_su_area.y2;
>> +
>> +        damaged_area.y2 += 4 - drm_rect_height(&damaged_area);
>> +        drm_rect_intersect(&damaged_area, &crtc_state->pipe_src);
>> +        damaged_area.y1 -= 4 - drm_rect_height(&damaged_area);
>> +        clip_area_update(&crtc_state->psr2_su_area, &damaged_area, &crtc_state->pipe_src);
>> +}
>> +
>>  int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
>>                                  struct intel_crtc *crtc)
>>  {
>> @@ -2912,6 +2935,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
>>          if (full_update)
>>                  goto skip_sel_fetch_set_loop;
>>  
>> +        intel_psr_su_area_min_lines(crtc_state);
>> +
>>          intel_psr_apply_su_area_workarounds(crtc_state);
>>  
>>          ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
>> 
>> -- 
>> 2.51.0
>> 
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
  2025-10-30 21:56     ` Gustavo Sousa
@ 2025-10-31 22:17       ` Matt Roper
  2025-10-31 22:41         ` Gustavo Sousa
  2025-11-11  0:44         ` Gustavo Sousa
  0 siblings, 2 replies; 65+ messages in thread
From: Matt Roper @ 2025-10-31 22:17 UTC (permalink / raw)
  To: Gustavo Sousa
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula,
	Ville Syrjälä

On Thu, Oct 30, 2025 at 06:56:07PM -0300, Gustavo Sousa wrote:
> Quoting Matt Roper (2025-10-29 17:54:39-03:00)
> >On Tue, Oct 21, 2025 at 09:28:36PM -0300, Gustavo Sousa wrote:
> >> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> >> 
> >> Starting with Xe3p_LPD, we get two new registers and some bits in
> >> existing registers that expose hardware state information at the time of
> >> underrun notification that can be relevant to debugging.
> >> 
> >> Add the necessary logic in the driver to print the available debug
> >> information when an underrun happens.
> >> 
> >> v2:
> >>   - Use seq_buf to generate planes string. (Jani)
> >>   - Move definition of FBC_DEBUG_STATUS to intel_fbc_regs.h. (Ville)
> >>   - Change logic for processing UNDERRUN_DBG1 to use loops and move it
> >>     to a separate function. (Gustavo)
> >>   - Always print underrun error message, even if there wouldn't be any
> >>     debug info associated to the underrun. (Gustavo)
> >> 
> >> Bspec: 69111, 69561, 74411, 74412
> >> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
> >> Co-developed-by: Gustavo Sousa <gustavo.sousa@intel.com>
> >> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/display/intel_display_regs.h  | 20 +++++
> >>  drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
> >>  drivers/gpu/drm/i915/display/intel_fifo_underrun.c | 87 ++++++++++++++++++++++
> >>  3 files changed, 109 insertions(+)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
> >> index 9d71e26a4fa2..c9f8b90faa42 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
> >> @@ -882,6 +882,25 @@
> >>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK                REG_GENMASK(2, 0) /* tgl+ */
> >>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id)        REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
> >>  
> >> +#define _UNDERRUN_DBG1_A                                0x70064
> >> +#define _UNDERRUN_DBG1_B                                0x71064
> >> +#define UNDERRUN_DBG1(pipe)                                _MMIO_PIPE(pipe, \
> >> +                                                                   _UNDERRUN_DBG1_A, \
> >> +                                                                   _UNDERRUN_DBG1_B)
> >> +#define   UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK                REG_GENMASK(29, 24)
> >> +#define   UNDERRUN_DDB_EMPTY_MASK                        REG_GENMASK(21, 16)
> >> +#define   UNDERRUN_DBUF_NOT_FILLED_MASK                        REG_GENMASK(13, 8)
> >> +#define   UNDERRUN_BELOW_WM0_MASK                        REG_GENMASK(5, 0)
> >> +
> >> +#define _UNDERRUN_DBG2_A                                0x70068
> >> +#define _UNDERRUN_DBG2_B                                0x71068
> >> +#define UNDERRUN_DBG2(pipe)                                _MMIO_PIPE(pipe, \
> >> +                                                                   _UNDERRUN_DBG2_A, \
> >> +                                                                   _UNDERRUN_DBG2_B)
> >> +#define   UNDERRUN_FRAME_LINE_COUNTERS_FROZEN                REG_BIT(31)
> >> +#define   UNDERRUN_PIPE_FRAME_COUNT_MASK                REG_GENMASK(30, 20)
> >> +#define   UNDERRUN_LINE_COUNT_MASK                        REG_GENMASK(19, 0)
> >> +
> >>  #define DPINVGTT                                _MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
> >>  #define   DPINVGTT_EN_MASK_CHV                                REG_GENMASK(27, 16)
> >>  #define   DPINVGTT_EN_MASK_VLV                                REG_GENMASK(23, 16)
> >> @@ -1416,6 +1435,7 @@
> >>  
> >>  #define GEN12_DCPR_STATUS_1                                _MMIO(0x46440)
> >>  #define  XELPDP_PMDEMAND_INFLIGHT_STATUS                REG_BIT(26)
> >> +#define  XE3P_UNDERRUN_PKGC                                REG_BIT(21)
> >>  
> >>  #define FUSE_STRAP                _MMIO(0x42014)
> >>  #define   ILK_INTERNAL_GRAPHICS_DISABLE        REG_BIT(31)
> >> diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
> >> index b1d0161a3196..272dba7f9695 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
> >> @@ -88,6 +88,8 @@
> >>  #define DPFC_FENCE_YOFF                        _MMIO(0x3218)
> >>  #define ILK_DPFC_FENCE_YOFF(fbc_id)        _MMIO_PIPE((fbc_id), 0x43218, 0x43258)
> >>  #define DPFC_CHICKEN                        _MMIO(0x3224)
> >> +#define FBC_DEBUG_STATUS(pipe)                _MMIO_PIPE(pipe, 0x43220, 0x43260)
> >
> >Is 'pipe' correct here?  Most of the other FBC registers are
> >parameterized by FBC instance rather than pipe.
> 
> Yeah, I just blindly copy/pasted the definition without realizing that
> the rest of the file uses fbc_id. I'll change it to use fbc_id as well.
> 
> >
> >> +#define   FBC_UNDERRUN_DECOMPRESSION                REG_BIT(27)
> >>  #define ILK_DPFC_CHICKEN(fbc_id)        _MMIO_PIPE((fbc_id), 0x43224, 0x43264)
> >>  #define   DPFC_HT_MODIFY                        REG_BIT(31) /* pre-ivb */
> >>  #define   DPFC_NUKE_ON_ANY_MODIFICATION                REG_BIT(23) /* bdw+ */
> >> diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
> >> index c2ce8461ac9e..43cf141a59ae 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
> >> @@ -25,6 +25,8 @@
> >>   *
> >>   */
> >>  
> >> +#include <linux/seq_buf.h>
> >> +
> >>  #include <drm/drm_print.h>
> >>  
> >>  #include "i915_reg.h"
> >> @@ -34,6 +36,7 @@
> >>  #include "intel_display_trace.h"
> >>  #include "intel_display_types.h"
> >>  #include "intel_fbc.h"
> >> +#include "intel_fbc_regs.h"
> >>  #include "intel_fifo_underrun.h"
> >>  #include "intel_pch_display.h"
> >>  
> >> @@ -352,6 +355,87 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
> >>          return old;
> >>  }
> >>  
> >> +#define UNDERRUN_DBG1_NUM_PLANES 6
> >> +
> >> +static void process_underrun_dbg1(struct intel_display *display,
> >> +                                  enum pipe pipe)
> >> +{
> >> +        struct {
> >> +                u32 mask;
> >> +                const char *info;
> >> +        } info_masks[] = {
> >> +                { UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
> >> +                { UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
> >> +                { UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
> >> +                { UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
> >> +        };
> >> +        DECLARE_SEQ_BUF(planes_desc, 32);
> >> +        u32 val;
> >> +
> >> +        val = intel_de_read(display, UNDERRUN_DBG1(pipe));
> >> +        intel_de_write(display, UNDERRUN_DBG1(pipe), val);
> >> +
> >> +        for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
> >> +                u32 plane_bits;
> >> +
> >> +                plane_bits = val & info_masks[i].mask;
> >> +
> >> +                if (!plane_bits)
> >> +                        continue;
> >> +
> >> +                plane_bits >>= ffs(info_masks[i].mask) - 1;
> >
> >Nitpick:  It seems like we're just open-coding REG_FIELD_GET here.  Any
> >reason not to simplify down to something like this?
> >
> >        u32 plane_bits = REG_FIELD_GET(info_masks[i].mask, val);
> >
> >        if (!plane_bits)
> >                continue;
> 
> We can't use REG_FIELD_GET() because the mask parameter must be a
> constant expression. That's why I went with open-coded version.

Oh yeah, I always forget about that restriction.  I'm fine with keeping
the open-coded version in that case, although you may want to move the
plane_bits assignment up onto the declaration line.  And maybe use
__ffs() instead of ffs() to avoid the need to substract 1.

> 
> We could change the current patch to use REG_FIELD_GET() with something
> like below. What do you think?
> 
>     |diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>     |index 43cf141a59ae..34faedb9799c 100644
>     |--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>     |+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>     |@@ -360,35 +360,28 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>     | static void process_underrun_dbg1(struct intel_display *display,
>     | 				  enum pipe pipe)
>     | {
>     |+	u32 val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>     | 	struct {
>     |-		u32 mask;
>     |+		u32 plane_mask;
>     | 		const char *info;
>     |-	} info_masks[] = {
>     |-		{ UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
>     |-		{ UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
>     |-		{ UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
>     |-		{ UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
>     |+	} masks[] = {
>     |+		{ REG_FIELD_GET(UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, val), "DBUF block not valid" },
>     |+		{ REG_FIELD_GET(UNDERRUN_DDB_EMPTY_MASK, val), "DDB empty" },
>     |+		{ REG_FIELD_GET(UNDERRUN_DBUF_NOT_FILLED_MASK, val), "DBUF not completely filled" },
>     |+		{ REG_FIELD_GET(UNDERRUN_BELOW_WM0_MASK, val), "DBUF below WM0" },
>     | 	};
>     | 	DECLARE_SEQ_BUF(planes_desc, 32);
>     |-	u32 val;
>     | 
>     |-	val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>     | 	intel_de_write(display, UNDERRUN_DBG1(pipe), val);
>     | 
>     |-	for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
>     |-		u32 plane_bits;
>     |-
>     |-		plane_bits = val & info_masks[i].mask;
>     |-
>     |-		if (!plane_bits)
>     |+	for (int i = 0; i < ARRAY_SIZE(masks); i++) {
>     |+		if (!masks[i].plane_mask)
>     | 			continue;
>     | 
>     |-		plane_bits >>= ffs(info_masks[i].mask) - 1;
>     |-
>     | 		seq_buf_clear(&planes_desc);
>     | 
>     | 		for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
>     |-			if (!(plane_bits & REG_BIT(j)))
>     |+			if (!(masks[i].plane_mask & REG_BIT(j)))
>     | 				continue;
>     | 
>     | 			if (j == 0)
>     |@@ -399,7 +392,7 @@ static void process_underrun_dbg1(struct intel_display *display,
>     | 
>     | 		drm_err(display->drm,
>     | 			"Pipe %c FIFO underrun info: %s on planes: %s\n",
>     |-			pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
>     |+			pipe_name(pipe), masks[i].info, seq_buf_str(&planes_desc));
>     | 
>     | 		drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
>     | 	}
> 
> >
> >> +
> >> +                seq_buf_clear(&planes_desc);
> >> +
> >> +                for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
> >> +                        if (!(plane_bits & REG_BIT(j)))
> >> +                                continue;
> >> +
> >> +                        if (j == 0)
> >> +                                seq_buf_puts(&planes_desc, "[C]");
> >> +                        else
> >> +                                seq_buf_printf(&planes_desc, "[%d]", j);
> >> +                }
> >> +
> >> +                drm_err(display->drm,
> >> +                        "Pipe %c FIFO underrun info: %s on planes: %s\n",
> >> +                        pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
> >> +
> >> +                drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
> >> +        }
> >> +}
> >> +
> >> +static void xe3p_lpd_log_underrun(struct intel_display *display,
> >> +                                  enum pipe pipe)
> >> +{
> >> +        u32 val;
> >> +
> >> +        process_underrun_dbg1(display, pipe);
> >> +
> >> +        val = intel_de_read(display, UNDERRUN_DBG2(pipe));
> >> +        if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {
> >> +                intel_de_write(display, UNDERRUN_DBG2(pipe), UNDERRUN_FRAME_LINE_COUNTERS_FROZEN);
> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Frame count: %u, Line count: %u\n",
> >> +                        pipe_name(pipe),
> >> +                        REG_FIELD_GET(UNDERRUN_PIPE_FRAME_COUNT_MASK, val),
> >> +                        REG_FIELD_GET(UNDERRUN_LINE_COUNT_MASK, val));
> >> +        }
> >> +
> >> +        val = intel_de_read(display, FBC_DEBUG_STATUS(pipe));
> >> +        if (val & FBC_UNDERRUN_DECOMPRESSION) {
> >> +                intel_de_write(display, FBC_DEBUG_STATUS(pipe), FBC_UNDERRUN_DECOMPRESSION);
> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: FBC decompression\n",
> >> +                        pipe_name(pipe));
> >> +        }
> >
> >As noted above, I'm not sure if 'pipe' is technically correct for this
> >register.  I think it always winds up with a 1:1 relationship on current
> >platforms, but would it make more sense to just move this check and
> >print into intel_fbc_handle_fifo_underrun_irq() where we're already
> >handling the FBC stuff on a per-FBC unit basis?
> 
> Yeah.  We probably want to check if there is a valid FBC instance
> respective to this pipe and then read the register.
> 
> I see complications with moving this to
> intel_fbc_handle_fifo_underrun_irq():
> 
>   1) The function intel_fbc_handle_fifo_underrun_irq() is more about
>      disabling the FBC on an underrun.  I think reporting that the FBC
>      was decompressing when the there was an underrun makes more sense
>      to be grouped together with the other info related to FIFO
>      underruns.  It could even be useful if, due to some hw/sw bug, FBC
>      is still doing something after we disabled it (or so we thought)
>      due to a previous underrun.
> 
>   2) Logging underrun debug info is currently guarded by
>      intel_set_cpu_fifo_underrun_reporting().  So, we would need to
>      complicate the implementation a bit to ensure that
>      intel_fbc_handle_fifo_underrun_irq() would only report when
>      reporting was enabled.
> 
> 
> So, I was thinking about defining a new function
> intel_fbc_fifo_underrun_log_info() and calling it from
> xe3p_lpd_log_underrun().  What do you think?

Yeah, that sounds fine to me.


Matt

> 
> --
> Gustavo Sousa
> >
> >
> >Matt
> >
> >> +
> >> +        val = intel_de_read(display, GEN12_DCPR_STATUS_1);
> >> +        if (val & XE3P_UNDERRUN_PKGC) {
> >> +                intel_de_write(display, GEN12_DCPR_STATUS_1, XE3P_UNDERRUN_PKGC);
> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Pkgc blocking memory\n",
> >> +                        pipe_name(pipe));
> >> +        }
> >> +}
> >> +
> >>  /**
> >>   * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
> >>   * @display: display device instance
> >> @@ -379,6 +463,9 @@ void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
> >>                  trace_intel_cpu_fifo_underrun(display, pipe);
> >>  
> >>                  drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
> >> +
> >> +                if (DISPLAY_VER(display) >= 35)
> >> +                        xe3p_lpd_log_underrun(display, pipe);
> >>          }
> >>  
> >>          intel_fbc_handle_fifo_underrun_irq(display);
> >> 
> >> -- 
> >> 2.51.0
> >> 
> >
> >-- 
> >Matt Roper
> >Graphics Software Engineer
> >Linux GPU Platform Enablement
> >Intel Corporation

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation

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

* Re: [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
  2025-10-31 22:17       ` Matt Roper
@ 2025-10-31 22:41         ` Gustavo Sousa
  2025-11-11  0:44         ` Gustavo Sousa
  1 sibling, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-10-31 22:41 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula,
	Ville Syrjälä

Quoting Matt Roper (2025-10-31 19:17:23-03:00)
>On Thu, Oct 30, 2025 at 06:56:07PM -0300, Gustavo Sousa wrote:
>> Quoting Matt Roper (2025-10-29 17:54:39-03:00)
>> >On Tue, Oct 21, 2025 at 09:28:36PM -0300, Gustavo Sousa wrote:
>> >> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> >> 
>> >> Starting with Xe3p_LPD, we get two new registers and some bits in
>> >> existing registers that expose hardware state information at the time of
>> >> underrun notification that can be relevant to debugging.
>> >> 
>> >> Add the necessary logic in the driver to print the available debug
>> >> information when an underrun happens.
>> >> 
>> >> v2:
>> >>   - Use seq_buf to generate planes string. (Jani)
>> >>   - Move definition of FBC_DEBUG_STATUS to intel_fbc_regs.h. (Ville)
>> >>   - Change logic for processing UNDERRUN_DBG1 to use loops and move it
>> >>     to a separate function. (Gustavo)
>> >>   - Always print underrun error message, even if there wouldn't be any
>> >>     debug info associated to the underrun. (Gustavo)
>> >> 
>> >> Bspec: 69111, 69561, 74411, 74412
>> >> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> >> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> >> Co-developed-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> >> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/i915/display/intel_display_regs.h  | 20 +++++
>> >>  drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
>> >>  drivers/gpu/drm/i915/display/intel_fifo_underrun.c | 87 ++++++++++++++++++++++
>> >>  3 files changed, 109 insertions(+)
>> >> 
>> >> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> >> index 9d71e26a4fa2..c9f8b90faa42 100644
>> >> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
>> >> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> >> @@ -882,6 +882,25 @@
>> >>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK                REG_GENMASK(2, 0) /* tgl+ */
>> >>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id)        REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
>> >>  
>> >> +#define _UNDERRUN_DBG1_A                                0x70064
>> >> +#define _UNDERRUN_DBG1_B                                0x71064
>> >> +#define UNDERRUN_DBG1(pipe)                                _MMIO_PIPE(pipe, \
>> >> +                                                                   _UNDERRUN_DBG1_A, \
>> >> +                                                                   _UNDERRUN_DBG1_B)
>> >> +#define   UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK                REG_GENMASK(29, 24)
>> >> +#define   UNDERRUN_DDB_EMPTY_MASK                        REG_GENMASK(21, 16)
>> >> +#define   UNDERRUN_DBUF_NOT_FILLED_MASK                        REG_GENMASK(13, 8)
>> >> +#define   UNDERRUN_BELOW_WM0_MASK                        REG_GENMASK(5, 0)
>> >> +
>> >> +#define _UNDERRUN_DBG2_A                                0x70068
>> >> +#define _UNDERRUN_DBG2_B                                0x71068
>> >> +#define UNDERRUN_DBG2(pipe)                                _MMIO_PIPE(pipe, \
>> >> +                                                                   _UNDERRUN_DBG2_A, \
>> >> +                                                                   _UNDERRUN_DBG2_B)
>> >> +#define   UNDERRUN_FRAME_LINE_COUNTERS_FROZEN                REG_BIT(31)
>> >> +#define   UNDERRUN_PIPE_FRAME_COUNT_MASK                REG_GENMASK(30, 20)
>> >> +#define   UNDERRUN_LINE_COUNT_MASK                        REG_GENMASK(19, 0)
>> >> +
>> >>  #define DPINVGTT                                _MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
>> >>  #define   DPINVGTT_EN_MASK_CHV                                REG_GENMASK(27, 16)
>> >>  #define   DPINVGTT_EN_MASK_VLV                                REG_GENMASK(23, 16)
>> >> @@ -1416,6 +1435,7 @@
>> >>  
>> >>  #define GEN12_DCPR_STATUS_1                                _MMIO(0x46440)
>> >>  #define  XELPDP_PMDEMAND_INFLIGHT_STATUS                REG_BIT(26)
>> >> +#define  XE3P_UNDERRUN_PKGC                                REG_BIT(21)
>> >>  
>> >>  #define FUSE_STRAP                _MMIO(0x42014)
>> >>  #define   ILK_INTERNAL_GRAPHICS_DISABLE        REG_BIT(31)
>> >> diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> >> index b1d0161a3196..272dba7f9695 100644
>> >> --- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> >> +++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> >> @@ -88,6 +88,8 @@
>> >>  #define DPFC_FENCE_YOFF                        _MMIO(0x3218)
>> >>  #define ILK_DPFC_FENCE_YOFF(fbc_id)        _MMIO_PIPE((fbc_id), 0x43218, 0x43258)
>> >>  #define DPFC_CHICKEN                        _MMIO(0x3224)
>> >> +#define FBC_DEBUG_STATUS(pipe)                _MMIO_PIPE(pipe, 0x43220, 0x43260)
>> >
>> >Is 'pipe' correct here?  Most of the other FBC registers are
>> >parameterized by FBC instance rather than pipe.
>> 
>> Yeah, I just blindly copy/pasted the definition without realizing that
>> the rest of the file uses fbc_id. I'll change it to use fbc_id as well.
>> 
>> >
>> >> +#define   FBC_UNDERRUN_DECOMPRESSION                REG_BIT(27)
>> >>  #define ILK_DPFC_CHICKEN(fbc_id)        _MMIO_PIPE((fbc_id), 0x43224, 0x43264)
>> >>  #define   DPFC_HT_MODIFY                        REG_BIT(31) /* pre-ivb */
>> >>  #define   DPFC_NUKE_ON_ANY_MODIFICATION                REG_BIT(23) /* bdw+ */
>> >> diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> >> index c2ce8461ac9e..43cf141a59ae 100644
>> >> --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> >> +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> >> @@ -25,6 +25,8 @@
>> >>   *
>> >>   */
>> >>  
>> >> +#include <linux/seq_buf.h>
>> >> +
>> >>  #include <drm/drm_print.h>
>> >>  
>> >>  #include "i915_reg.h"
>> >> @@ -34,6 +36,7 @@
>> >>  #include "intel_display_trace.h"
>> >>  #include "intel_display_types.h"
>> >>  #include "intel_fbc.h"
>> >> +#include "intel_fbc_regs.h"
>> >>  #include "intel_fifo_underrun.h"
>> >>  #include "intel_pch_display.h"
>> >>  
>> >> @@ -352,6 +355,87 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>> >>          return old;
>> >>  }
>> >>  
>> >> +#define UNDERRUN_DBG1_NUM_PLANES 6
>> >> +
>> >> +static void process_underrun_dbg1(struct intel_display *display,
>> >> +                                  enum pipe pipe)
>> >> +{
>> >> +        struct {
>> >> +                u32 mask;
>> >> +                const char *info;
>> >> +        } info_masks[] = {
>> >> +                { UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
>> >> +                { UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
>> >> +                { UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
>> >> +                { UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
>> >> +        };
>> >> +        DECLARE_SEQ_BUF(planes_desc, 32);
>> >> +        u32 val;
>> >> +
>> >> +        val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>> >> +        intel_de_write(display, UNDERRUN_DBG1(pipe), val);
>> >> +
>> >> +        for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
>> >> +                u32 plane_bits;
>> >> +
>> >> +                plane_bits = val & info_masks[i].mask;
>> >> +
>> >> +                if (!plane_bits)
>> >> +                        continue;
>> >> +
>> >> +                plane_bits >>= ffs(info_masks[i].mask) - 1;
>> >
>> >Nitpick:  It seems like we're just open-coding REG_FIELD_GET here.  Any
>> >reason not to simplify down to something like this?
>> >
>> >        u32 plane_bits = REG_FIELD_GET(info_masks[i].mask, val);
>> >
>> >        if (!plane_bits)
>> >                continue;
>> 
>> We can't use REG_FIELD_GET() because the mask parameter must be a
>> constant expression. That's why I went with open-coded version.
>
>Oh yeah, I always forget about that restriction.  I'm fine with keeping
>the open-coded version in that case, although you may want to move the
>plane_bits assignment up onto the declaration line.  And maybe use
>__ffs() instead of ffs() to avoid the need to substract 1.

Hehe.  I ended up applying the diff from below to my local v3; it is not
too late to go back to the open-coded version though.  I could go with
either versions, so let me know what you prefer.  :-)

--
Gustavo Sousa

>
>> 
>> We could change the current patch to use REG_FIELD_GET() with something
>> like below. What do you think?
>> 
>>     |diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>>     |index 43cf141a59ae..34faedb9799c 100644
>>     |--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>>     |+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>>     |@@ -360,35 +360,28 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>>     | static void process_underrun_dbg1(struct intel_display *display,
>>     |                                   enum pipe pipe)
>>     | {
>>     |+        u32 val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>>     |         struct {
>>     |-                u32 mask;
>>     |+                u32 plane_mask;
>>     |                 const char *info;
>>     |-        } info_masks[] = {
>>     |-                { UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
>>     |-                { UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
>>     |-                { UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
>>     |-                { UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
>>     |+        } masks[] = {
>>     |+                { REG_FIELD_GET(UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, val), "DBUF block not valid" },
>>     |+                { REG_FIELD_GET(UNDERRUN_DDB_EMPTY_MASK, val), "DDB empty" },
>>     |+                { REG_FIELD_GET(UNDERRUN_DBUF_NOT_FILLED_MASK, val), "DBUF not completely filled" },
>>     |+                { REG_FIELD_GET(UNDERRUN_BELOW_WM0_MASK, val), "DBUF below WM0" },
>>     |         };
>>     |         DECLARE_SEQ_BUF(planes_desc, 32);
>>     |-        u32 val;
>>     | 
>>     |-        val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>>     |         intel_de_write(display, UNDERRUN_DBG1(pipe), val);
>>     | 
>>     |-        for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
>>     |-                u32 plane_bits;
>>     |-
>>     |-                plane_bits = val & info_masks[i].mask;
>>     |-
>>     |-                if (!plane_bits)
>>     |+        for (int i = 0; i < ARRAY_SIZE(masks); i++) {
>>     |+                if (!masks[i].plane_mask)
>>     |                         continue;
>>     | 
>>     |-                plane_bits >>= ffs(info_masks[i].mask) - 1;
>>     |-
>>     |                 seq_buf_clear(&planes_desc);
>>     | 
>>     |                 for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
>>     |-                        if (!(plane_bits & REG_BIT(j)))
>>     |+                        if (!(masks[i].plane_mask & REG_BIT(j)))
>>     |                                 continue;
>>     | 
>>     |                         if (j == 0)
>>     |@@ -399,7 +392,7 @@ static void process_underrun_dbg1(struct intel_display *display,
>>     | 
>>     |                 drm_err(display->drm,
>>     |                         "Pipe %c FIFO underrun info: %s on planes: %s\n",
>>     |-                        pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
>>     |+                        pipe_name(pipe), masks[i].info, seq_buf_str(&planes_desc));
>>     | 
>>     |                 drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
>>     |         }
>> 
>> >
>> >> +
>> >> +                seq_buf_clear(&planes_desc);
>> >> +
>> >> +                for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
>> >> +                        if (!(plane_bits & REG_BIT(j)))
>> >> +                                continue;
>> >> +
>> >> +                        if (j == 0)
>> >> +                                seq_buf_puts(&planes_desc, "[C]");
>> >> +                        else
>> >> +                                seq_buf_printf(&planes_desc, "[%d]", j);
>> >> +                }
>> >> +
>> >> +                drm_err(display->drm,
>> >> +                        "Pipe %c FIFO underrun info: %s on planes: %s\n",
>> >> +                        pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
>> >> +
>> >> +                drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
>> >> +        }
>> >> +}
>> >> +
>> >> +static void xe3p_lpd_log_underrun(struct intel_display *display,
>> >> +                                  enum pipe pipe)
>> >> +{
>> >> +        u32 val;
>> >> +
>> >> +        process_underrun_dbg1(display, pipe);
>> >> +
>> >> +        val = intel_de_read(display, UNDERRUN_DBG2(pipe));
>> >> +        if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {
>> >> +                intel_de_write(display, UNDERRUN_DBG2(pipe), UNDERRUN_FRAME_LINE_COUNTERS_FROZEN);
>> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Frame count: %u, Line count: %u\n",
>> >> +                        pipe_name(pipe),
>> >> +                        REG_FIELD_GET(UNDERRUN_PIPE_FRAME_COUNT_MASK, val),
>> >> +                        REG_FIELD_GET(UNDERRUN_LINE_COUNT_MASK, val));
>> >> +        }
>> >> +
>> >> +        val = intel_de_read(display, FBC_DEBUG_STATUS(pipe));
>> >> +        if (val & FBC_UNDERRUN_DECOMPRESSION) {
>> >> +                intel_de_write(display, FBC_DEBUG_STATUS(pipe), FBC_UNDERRUN_DECOMPRESSION);
>> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: FBC decompression\n",
>> >> +                        pipe_name(pipe));
>> >> +        }
>> >
>> >As noted above, I'm not sure if 'pipe' is technically correct for this
>> >register.  I think it always winds up with a 1:1 relationship on current
>> >platforms, but would it make more sense to just move this check and
>> >print into intel_fbc_handle_fifo_underrun_irq() where we're already
>> >handling the FBC stuff on a per-FBC unit basis?
>> 
>> Yeah.  We probably want to check if there is a valid FBC instance
>> respective to this pipe and then read the register.
>> 
>> I see complications with moving this to
>> intel_fbc_handle_fifo_underrun_irq():
>> 
>>   1) The function intel_fbc_handle_fifo_underrun_irq() is more about
>>      disabling the FBC on an underrun.  I think reporting that the FBC
>>      was decompressing when the there was an underrun makes more sense
>>      to be grouped together with the other info related to FIFO
>>      underruns.  It could even be useful if, due to some hw/sw bug, FBC
>>      is still doing something after we disabled it (or so we thought)
>>      due to a previous underrun.
>> 
>>   2) Logging underrun debug info is currently guarded by
>>      intel_set_cpu_fifo_underrun_reporting().  So, we would need to
>>      complicate the implementation a bit to ensure that
>>      intel_fbc_handle_fifo_underrun_irq() would only report when
>>      reporting was enabled.
>> 
>> 
>> So, I was thinking about defining a new function
>> intel_fbc_fifo_underrun_log_info() and calling it from
>> xe3p_lpd_log_underrun().  What do you think?
>
>Yeah, that sounds fine to me.
>
>
>Matt
>
>> 
>> --
>> Gustavo Sousa
>> >
>> >
>> >Matt
>> >
>> >> +
>> >> +        val = intel_de_read(display, GEN12_DCPR_STATUS_1);
>> >> +        if (val & XE3P_UNDERRUN_PKGC) {
>> >> +                intel_de_write(display, GEN12_DCPR_STATUS_1, XE3P_UNDERRUN_PKGC);
>> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Pkgc blocking memory\n",
>> >> +                        pipe_name(pipe));
>> >> +        }
>> >> +}
>> >> +
>> >>  /**
>> >>   * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
>> >>   * @display: display device instance
>> >> @@ -379,6 +463,9 @@ void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
>> >>                  trace_intel_cpu_fifo_underrun(display, pipe);
>> >>  
>> >>                  drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
>> >> +
>> >> +                if (DISPLAY_VER(display) >= 35)
>> >> +                        xe3p_lpd_log_underrun(display, pipe);
>> >>          }
>> >>  
>> >>          intel_fbc_handle_fifo_underrun_irq(display);
>> >> 
>> >> -- 
>> >> 2.51.0
>> >> 
>> >
>> >-- 
>> >Matt Roper
>> >Graphics Software Engineer
>> >Linux GPU Platform Enablement
>> >Intel Corporation
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

* Re: [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints
  2025-10-31 22:17       ` Matt Roper
  2025-10-31 22:41         ` Gustavo Sousa
@ 2025-11-11  0:44         ` Gustavo Sousa
  1 sibling, 0 replies; 65+ messages in thread
From: Gustavo Sousa @ 2025-11-11  0:44 UTC (permalink / raw)
  To: Matt Roper
  Cc: intel-xe, intel-gfx, Ankit Nautiyal, Dnyaneshwar Bhadane,
	Jouni Högander, Juha-pekka Heikkila, Luca Coelho,
	Lucas De Marchi, Matt Atwood, Ravi Kumar Vodapalli,
	Shekhar Chauhan, Vinod Govindapillai, Jani Nikula,
	Ville Syrjälä, Rodrigo Vivi

Quoting Matt Roper (2025-10-31 19:17:23-03:00)
>On Thu, Oct 30, 2025 at 06:56:07PM -0300, Gustavo Sousa wrote:
>> Quoting Matt Roper (2025-10-29 17:54:39-03:00)
>> >On Tue, Oct 21, 2025 at 09:28:36PM -0300, Gustavo Sousa wrote:
>> >> From: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> >> 
>> >> Starting with Xe3p_LPD, we get two new registers and some bits in
>> >> existing registers that expose hardware state information at the time of
>> >> underrun notification that can be relevant to debugging.
>> >> 
>> >> Add the necessary logic in the driver to print the available debug
>> >> information when an underrun happens.
>> >> 
>> >> v2:
>> >>   - Use seq_buf to generate planes string. (Jani)
>> >>   - Move definition of FBC_DEBUG_STATUS to intel_fbc_regs.h. (Ville)
>> >>   - Change logic for processing UNDERRUN_DBG1 to use loops and move it
>> >>     to a separate function. (Gustavo)
>> >>   - Always print underrun error message, even if there wouldn't be any
>> >>     debug info associated to the underrun. (Gustavo)
>> >> 
>> >> Bspec: 69111, 69561, 74411, 74412
>> >> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> >> Signed-off-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com>
>> >> Co-developed-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> >> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/i915/display/intel_display_regs.h  | 20 +++++
>> >>  drivers/gpu/drm/i915/display/intel_fbc_regs.h      |  2 +
>> >>  drivers/gpu/drm/i915/display/intel_fifo_underrun.c | 87 ++++++++++++++++++++++
>> >>  3 files changed, 109 insertions(+)
>> >> 
>> >> diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> >> index 9d71e26a4fa2..c9f8b90faa42 100644
>> >> --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
>> >> +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
>> >> @@ -882,6 +882,25 @@
>> >>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK                REG_GENMASK(2, 0) /* tgl+ */
>> >>  #define   PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id)        REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
>> >>  
>> >> +#define _UNDERRUN_DBG1_A                                0x70064
>> >> +#define _UNDERRUN_DBG1_B                                0x71064
>> >> +#define UNDERRUN_DBG1(pipe)                                _MMIO_PIPE(pipe, \
>> >> +                                                                   _UNDERRUN_DBG1_A, \
>> >> +                                                                   _UNDERRUN_DBG1_B)
>> >> +#define   UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK                REG_GENMASK(29, 24)
>> >> +#define   UNDERRUN_DDB_EMPTY_MASK                        REG_GENMASK(21, 16)
>> >> +#define   UNDERRUN_DBUF_NOT_FILLED_MASK                        REG_GENMASK(13, 8)
>> >> +#define   UNDERRUN_BELOW_WM0_MASK                        REG_GENMASK(5, 0)
>> >> +
>> >> +#define _UNDERRUN_DBG2_A                                0x70068
>> >> +#define _UNDERRUN_DBG2_B                                0x71068
>> >> +#define UNDERRUN_DBG2(pipe)                                _MMIO_PIPE(pipe, \
>> >> +                                                                   _UNDERRUN_DBG2_A, \
>> >> +                                                                   _UNDERRUN_DBG2_B)
>> >> +#define   UNDERRUN_FRAME_LINE_COUNTERS_FROZEN                REG_BIT(31)
>> >> +#define   UNDERRUN_PIPE_FRAME_COUNT_MASK                REG_GENMASK(30, 20)
>> >> +#define   UNDERRUN_LINE_COUNT_MASK                        REG_GENMASK(19, 0)
>> >> +
>> >>  #define DPINVGTT                                _MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
>> >>  #define   DPINVGTT_EN_MASK_CHV                                REG_GENMASK(27, 16)
>> >>  #define   DPINVGTT_EN_MASK_VLV                                REG_GENMASK(23, 16)
>> >> @@ -1416,6 +1435,7 @@
>> >>  
>> >>  #define GEN12_DCPR_STATUS_1                                _MMIO(0x46440)
>> >>  #define  XELPDP_PMDEMAND_INFLIGHT_STATUS                REG_BIT(26)
>> >> +#define  XE3P_UNDERRUN_PKGC                                REG_BIT(21)
>> >>  
>> >>  #define FUSE_STRAP                _MMIO(0x42014)
>> >>  #define   ILK_INTERNAL_GRAPHICS_DISABLE        REG_BIT(31)
>> >> diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> >> index b1d0161a3196..272dba7f9695 100644
>> >> --- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> >> +++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
>> >> @@ -88,6 +88,8 @@
>> >>  #define DPFC_FENCE_YOFF                        _MMIO(0x3218)
>> >>  #define ILK_DPFC_FENCE_YOFF(fbc_id)        _MMIO_PIPE((fbc_id), 0x43218, 0x43258)
>> >>  #define DPFC_CHICKEN                        _MMIO(0x3224)
>> >> +#define FBC_DEBUG_STATUS(pipe)                _MMIO_PIPE(pipe, 0x43220, 0x43260)
>> >
>> >Is 'pipe' correct here?  Most of the other FBC registers are
>> >parameterized by FBC instance rather than pipe.
>> 
>> Yeah, I just blindly copy/pasted the definition without realizing that
>> the rest of the file uses fbc_id. I'll change it to use fbc_id as well.
>> 
>> >
>> >> +#define   FBC_UNDERRUN_DECOMPRESSION                REG_BIT(27)
>> >>  #define ILK_DPFC_CHICKEN(fbc_id)        _MMIO_PIPE((fbc_id), 0x43224, 0x43264)
>> >>  #define   DPFC_HT_MODIFY                        REG_BIT(31) /* pre-ivb */
>> >>  #define   DPFC_NUKE_ON_ANY_MODIFICATION                REG_BIT(23) /* bdw+ */
>> >> diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> >> index c2ce8461ac9e..43cf141a59ae 100644
>> >> --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> >> +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>> >> @@ -25,6 +25,8 @@
>> >>   *
>> >>   */
>> >>  
>> >> +#include <linux/seq_buf.h>
>> >> +
>> >>  #include <drm/drm_print.h>
>> >>  
>> >>  #include "i915_reg.h"
>> >> @@ -34,6 +36,7 @@
>> >>  #include "intel_display_trace.h"
>> >>  #include "intel_display_types.h"
>> >>  #include "intel_fbc.h"
>> >> +#include "intel_fbc_regs.h"
>> >>  #include "intel_fifo_underrun.h"
>> >>  #include "intel_pch_display.h"
>> >>  
>> >> @@ -352,6 +355,87 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>> >>          return old;
>> >>  }
>> >>  
>> >> +#define UNDERRUN_DBG1_NUM_PLANES 6
>> >> +
>> >> +static void process_underrun_dbg1(struct intel_display *display,
>> >> +                                  enum pipe pipe)
>> >> +{
>> >> +        struct {
>> >> +                u32 mask;
>> >> +                const char *info;
>> >> +        } info_masks[] = {
>> >> +                { UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
>> >> +                { UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
>> >> +                { UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
>> >> +                { UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
>> >> +        };
>> >> +        DECLARE_SEQ_BUF(planes_desc, 32);
>> >> +        u32 val;
>> >> +
>> >> +        val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>> >> +        intel_de_write(display, UNDERRUN_DBG1(pipe), val);
>> >> +
>> >> +        for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
>> >> +                u32 plane_bits;
>> >> +
>> >> +                plane_bits = val & info_masks[i].mask;
>> >> +
>> >> +                if (!plane_bits)
>> >> +                        continue;
>> >> +
>> >> +                plane_bits >>= ffs(info_masks[i].mask) - 1;
>> >
>> >Nitpick:  It seems like we're just open-coding REG_FIELD_GET here.  Any
>> >reason not to simplify down to something like this?
>> >
>> >        u32 plane_bits = REG_FIELD_GET(info_masks[i].mask, val);
>> >
>> >        if (!plane_bits)
>> >                continue;
>> 
>> We can't use REG_FIELD_GET() because the mask parameter must be a
>> constant expression. That's why I went with open-coded version.
>
>Oh yeah, I always forget about that restriction.  I'm fine with keeping
>the open-coded version in that case, although you may want to move the
>plane_bits assignment up onto the declaration line.  And maybe use
>__ffs() instead of ffs() to avoid the need to substract 1.

I'm going back to the open-coded version after feedback[1] on v4.  With
that, I'll move the assignment up onto the declaration.

Now, for the suggestion of using __ffs(), while i915 (non-display part)
and xe do use it, it appears display code has the preference of using
"ffs(...) - 1", so I'm a bit hesitant on introducing its usage to
display code.

Maybe display maintainers could give their view on this.

[1] https://lore.kernel.org/all/cd8a88c0e6f02aa1209abd3f1188e1bacf1ec1c1@intel.com/

>
>> 
>> We could change the current patch to use REG_FIELD_GET() with something
>> like below. What do you think?
>> 
>>     |diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>>     |index 43cf141a59ae..34faedb9799c 100644
>>     |--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>>     |+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
>>     |@@ -360,35 +360,28 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
>>     | static void process_underrun_dbg1(struct intel_display *display,
>>     |                                   enum pipe pipe)
>>     | {
>>     |+        u32 val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>>     |         struct {
>>     |-                u32 mask;
>>     |+                u32 plane_mask;
>>     |                 const char *info;
>>     |-        } info_masks[] = {
>>     |-                { UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, "DBUF block not valid" },
>>     |-                { UNDERRUN_DDB_EMPTY_MASK, "DDB empty" },
>>     |-                { UNDERRUN_DBUF_NOT_FILLED_MASK, "DBUF not completely filled" },
>>     |-                { UNDERRUN_BELOW_WM0_MASK, "DBUF below WM0" },
>>     |+        } masks[] = {
>>     |+                { REG_FIELD_GET(UNDERRUN_DBUF_BLOCK_NOT_VALID_MASK, val), "DBUF block not valid" },
>>     |+                { REG_FIELD_GET(UNDERRUN_DDB_EMPTY_MASK, val), "DDB empty" },
>>     |+                { REG_FIELD_GET(UNDERRUN_DBUF_NOT_FILLED_MASK, val), "DBUF not completely filled" },
>>     |+                { REG_FIELD_GET(UNDERRUN_BELOW_WM0_MASK, val), "DBUF below WM0" },
>>     |         };
>>     |         DECLARE_SEQ_BUF(planes_desc, 32);
>>     |-        u32 val;
>>     | 
>>     |-        val = intel_de_read(display, UNDERRUN_DBG1(pipe));
>>     |         intel_de_write(display, UNDERRUN_DBG1(pipe), val);
>>     | 
>>     |-        for (int i = 0; i < ARRAY_SIZE(info_masks); i++) {
>>     |-                u32 plane_bits;
>>     |-
>>     |-                plane_bits = val & info_masks[i].mask;
>>     |-
>>     |-                if (!plane_bits)
>>     |+        for (int i = 0; i < ARRAY_SIZE(masks); i++) {
>>     |+                if (!masks[i].plane_mask)
>>     |                         continue;
>>     | 
>>     |-                plane_bits >>= ffs(info_masks[i].mask) - 1;
>>     |-
>>     |                 seq_buf_clear(&planes_desc);
>>     | 
>>     |                 for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
>>     |-                        if (!(plane_bits & REG_BIT(j)))
>>     |+                        if (!(masks[i].plane_mask & REG_BIT(j)))
>>     |                                 continue;
>>     | 
>>     |                         if (j == 0)
>>     |@@ -399,7 +392,7 @@ static void process_underrun_dbg1(struct intel_display *display,
>>     | 
>>     |                 drm_err(display->drm,
>>     |                         "Pipe %c FIFO underrun info: %s on planes: %s\n",
>>     |-                        pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
>>     |+                        pipe_name(pipe), masks[i].info, seq_buf_str(&planes_desc));
>>     | 
>>     |                 drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
>>     |         }
>> 
>> >
>> >> +
>> >> +                seq_buf_clear(&planes_desc);
>> >> +
>> >> +                for (int j = 0; j < UNDERRUN_DBG1_NUM_PLANES; j++) {
>> >> +                        if (!(plane_bits & REG_BIT(j)))
>> >> +                                continue;
>> >> +
>> >> +                        if (j == 0)
>> >> +                                seq_buf_puts(&planes_desc, "[C]");
>> >> +                        else
>> >> +                                seq_buf_printf(&planes_desc, "[%d]", j);
>> >> +                }
>> >> +
>> >> +                drm_err(display->drm,
>> >> +                        "Pipe %c FIFO underrun info: %s on planes: %s\n",
>> >> +                        pipe_name(pipe), info_masks[i].info, seq_buf_str(&planes_desc));
>> >> +
>> >> +                drm_WARN_ON(display->drm, seq_buf_has_overflowed(&planes_desc));
>> >> +        }
>> >> +}
>> >> +
>> >> +static void xe3p_lpd_log_underrun(struct intel_display *display,
>> >> +                                  enum pipe pipe)
>> >> +{
>> >> +        u32 val;
>> >> +
>> >> +        process_underrun_dbg1(display, pipe);
>> >> +
>> >> +        val = intel_de_read(display, UNDERRUN_DBG2(pipe));
>> >> +        if (val & UNDERRUN_FRAME_LINE_COUNTERS_FROZEN) {
>> >> +                intel_de_write(display, UNDERRUN_DBG2(pipe), UNDERRUN_FRAME_LINE_COUNTERS_FROZEN);
>> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Frame count: %u, Line count: %u\n",
>> >> +                        pipe_name(pipe),
>> >> +                        REG_FIELD_GET(UNDERRUN_PIPE_FRAME_COUNT_MASK, val),
>> >> +                        REG_FIELD_GET(UNDERRUN_LINE_COUNT_MASK, val));
>> >> +        }
>> >> +
>> >> +        val = intel_de_read(display, FBC_DEBUG_STATUS(pipe));
>> >> +        if (val & FBC_UNDERRUN_DECOMPRESSION) {
>> >> +                intel_de_write(display, FBC_DEBUG_STATUS(pipe), FBC_UNDERRUN_DECOMPRESSION);
>> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: FBC decompression\n",
>> >> +                        pipe_name(pipe));
>> >> +        }
>> >
>> >As noted above, I'm not sure if 'pipe' is technically correct for this
>> >register.  I think it always winds up with a 1:1 relationship on current
>> >platforms, but would it make more sense to just move this check and
>> >print into intel_fbc_handle_fifo_underrun_irq() where we're already
>> >handling the FBC stuff on a per-FBC unit basis?
>> 
>> Yeah.  We probably want to check if there is a valid FBC instance
>> respective to this pipe and then read the register.
>> 
>> I see complications with moving this to
>> intel_fbc_handle_fifo_underrun_irq():
>> 
>>   1) The function intel_fbc_handle_fifo_underrun_irq() is more about
>>      disabling the FBC on an underrun.  I think reporting that the FBC
>>      was decompressing when the there was an underrun makes more sense
>>      to be grouped together with the other info related to FIFO
>>      underruns.  It could even be useful if, due to some hw/sw bug, FBC
>>      is still doing something after we disabled it (or so we thought)
>>      due to a previous underrun.
>> 
>>   2) Logging underrun debug info is currently guarded by
>>      intel_set_cpu_fifo_underrun_reporting().  So, we would need to
>>      complicate the implementation a bit to ensure that
>>      intel_fbc_handle_fifo_underrun_irq() would only report when
>>      reporting was enabled.
>> 
>> 
>> So, I was thinking about defining a new function
>> intel_fbc_fifo_underrun_log_info() and calling it from
>> xe3p_lpd_log_underrun().  What do you think?
>
>Yeah, that sounds fine to me.
>
>
>Matt
>
>> 
>> --
>> Gustavo Sousa
>> >
>> >
>> >Matt
>> >
>> >> +
>> >> +        val = intel_de_read(display, GEN12_DCPR_STATUS_1);
>> >> +        if (val & XE3P_UNDERRUN_PKGC) {
>> >> +                intel_de_write(display, GEN12_DCPR_STATUS_1, XE3P_UNDERRUN_PKGC);
>> >> +                drm_err(display->drm, "Pipe %c FIFO underrun info: Pkgc blocking memory\n",
>> >> +                        pipe_name(pipe));
>> >> +        }
>> >> +}
>> >> +
>> >>  /**
>> >>   * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
>> >>   * @display: display device instance
>> >> @@ -379,6 +463,9 @@ void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
>> >>                  trace_intel_cpu_fifo_underrun(display, pipe);
>> >>  
>> >>                  drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
>> >> +
>> >> +                if (DISPLAY_VER(display) >= 35)
>> >> +                        xe3p_lpd_log_underrun(display, pipe);
>> >>          }
>> >>  
>> >>          intel_fbc_handle_fifo_underrun_irq(display);
>> >> 
>> >> -- 
>> >> 2.51.0
>> >> 
>> >
>> >-- 
>> >Matt Roper
>> >Graphics Software Engineer
>> >Linux GPU Platform Enablement
>> >Intel Corporation
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation

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

end of thread, other threads:[~2025-11-11  0:44 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-22  0:28 [PATCH v2 00/32] drm/i915/display: Add initial support for Xe3p_LPD Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 01/32] drm/i915/xe3p_lpd: Add Xe3p_LPD display IP features Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 02/32] drm/i915/xe3p_lpd: Drop north display reset option programming Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 03/32] drm/i915/display: Use braces for if-ladder in intel_bw_init_hw() Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 04/32] drm/i915/dram: Add field ecc_impacting_de_bw Gustavo Sousa
2025-10-22 11:37   ` Gustavo Sousa
2025-10-22 11:53     ` Jani Nikula
2025-10-22 12:12       ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 05/32] drm/i915/xe3p_lpd: Update bandwidth parameters Gustavo Sousa
2025-10-22 14:56   ` Matt Roper
2025-10-27 22:26     ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 06/32] drm/i915/xe3p_lpd: Expand bifield masks dbuf blocks fields Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 07/32] drm/i915/xe3p_lpd: Support UINT16 formats Gustavo Sousa
2025-10-22 12:28   ` Ville Syrjälä
2025-10-22 17:58     ` Matt Roper
2025-10-27 19:41       ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 08/32] drm/i915/xe3p_lpd: Extend FBC support to " Gustavo Sousa
2025-10-22 12:39   ` Ville Syrjälä
2025-10-22  0:28 ` [PATCH v2 09/32] drm/i915/xe3p_lpd: Horizontal flip support for linear surfaces Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 10/32] drm/i915/xe3p_lpd: Wait for AUX channel power status Gustavo Sousa
2025-10-29 20:06   ` Matt Roper
2025-10-29 20:50     ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 11/32] drm/i915/xe3p_lpd: Underrun debuggability and error codes/hints Gustavo Sousa
2025-10-29 20:54   ` Matt Roper
2025-10-30 21:56     ` Gustavo Sousa
2025-10-31 22:17       ` Matt Roper
2025-10-31 22:41         ` Gustavo Sousa
2025-11-11  0:44         ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 12/32] drm/i915/xe3p_lpd: Remove gamma,csc bottom color checks Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 13/32] drm/i915/xe3p_lpd: Adapt to updates on MBUS_CTL/DBUF_CTL registers Gustavo Sousa
2025-10-29 21:22   ` Matt Roper
2025-10-31  2:48     ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 14/32] drm/i915/wm: Reorder adjust_wm_latency() for Xe3_LPD Gustavo Sousa
2025-10-29 21:53   ` Matt Roper
2025-10-29 22:22   ` Ville Syrjälä
2025-10-29 22:36     ` Ville Syrjälä
2025-10-30 13:45       ` Gustavo Sousa
2025-10-30 15:38         ` Ville Syrjälä
2025-10-30 13:48     ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 15/32] drm/i915/xe3p_lpd: Always apply level-0 watermark adjustment Gustavo Sousa
2025-10-29 22:08   ` Matt Roper
2025-10-29 22:39     ` Ville Syrjälä
2025-10-30 13:53       ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 16/32] drm/i915/xe3p_lpd: Add CDCLK table Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 17/32] drm/i915/xe3p_lpd: Load DMC firmware Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 18/32] drm/i915/xe3p_lpd: Drop support for interlace mode Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 19/32] drm/i915/xe3p_lpd: PSR SU minimum lines is 4 Gustavo Sousa
2025-10-29 22:14   ` Matt Roper
2025-10-31 17:36     ` Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 20/32] drm/i915/xe3p_lpd: Enable system caching for FBC Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 21/32] drm/i915/xe3p_lpd: Extend Wa_16025573575 Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 22/32] drm/i915/xe3p_lpd: Don't allow odd ypan or ysize with semiplanar format Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 23/32] drm/i915/xe3p_lpd: Reload DMC MMIO for pipes C and D Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 24/32] drm/i915/xe3p_lpd: Introduce pixel normalizer config support Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 25/32] drm/i915/xe3p_lpd: Add FBC support for FP16 formats Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 26/32] drm/i915/xe3p_lpd: Enable pixel normalizer for fp16 formats for FBC Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 27/32] drm/i915/vbt: Add fields dedicated_external and dyn_port_over_tc Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 28/32] drm/i915/power: Use intel_encoder_is_tc() Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 29/32] drm/i915/display: Handle dedicated external ports in intel_encoder_is_tc() Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 30/32] drm/i915/wm: don't use method1 in Xe3p_LPD onwards Gustavo Sousa
2025-10-22 15:08   ` Shekhar Chauhan
2025-10-22  0:28 ` [PATCH v2 31/32] drm/i915/xe3p_lpd: Extend Type-C flow for static DDI allocation Gustavo Sousa
2025-10-22  0:28 ` [PATCH v2 32/32] drm/i915/nvls: Add NVL-S display support Gustavo Sousa
2025-10-22 15:12   ` Shekhar Chauhan
2025-10-22  1:46 ` ✗ i915.CI.BAT: failure for drm/i915/display: Add initial support for Xe3p_LPD (rev2) 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).