All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support
@ 2024-02-20 21:18 Imre Deak
  2024-02-20 21:18 ` [PATCH v2 01/21] drm/dp: Add drm_dp_max_dprx_data_rate() Imre Deak
                   ` (32 more replies)
  0 siblings, 33 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Mika Westerberg, Ville Syrjälä,
	Uma Shankar, Jouni Högander, Saranya Gopal,
	Rajaram Regupathy, Gil Fine, Naama Shachar, Pengfei Xu

This is v2 of [1], with the following changes:

- Several functional/typo/formatting fixes, detailed in the patches.
- Move the BW allocation from encoder hooks to
  intel_atomic_commit_tail() fixing the allocation for MST streams
  enabled/disabled w/o a full modeset (i.e. w/o re-enabling the master
  stream).
- Fix an MST mode restore issue during system resume, which also lead
  to a tunnel BW allocation failure. (Patch 3)
- Ensure a DPCD DPRX cap read as required by the TBT CM any time a long
  HPD pulse is detected. (Patch 20)
- Explicitly disable the BW allocation mode during system suspend.

The patchset is also available at:
https://github.com/ideak/linux/commits/dp_tun_bw_alloc

Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Saranya Gopal <saranya.gopal@intel.com>
Cc: Rajaram Regupathy <rajaram.regupathy@intel.com>
Cc: Gil Fine <gil.fine@intel.com>
Cc: Naama Shachar <naamax.shachar@intel.com>
Cc: Pengfei Xu <pengfei.xu@intel.com>

[1] https://lore.kernel.org/all/20240123102850.390126-1-imre.deak@intel.com

Imre Deak (21):
  drm/dp: Add drm_dp_max_dprx_data_rate()
  drm/dp: Add support for DP tunneling
  drm/i915: Fix display bpp limit computation during system resume
  drm/i915/dp: Add support to notify MST connectors to retry modesets
  drm/i915/dp: Use drm_dp_max_dprx_data_rate()
  drm/i915/dp: Factor out intel_dp_config_required_rate()
  drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
  drm/i915/dp: Factor out intel_dp_update_sink_caps()
  drm/i915/dp: Factor out intel_dp_read_dprx_caps()
  drm/i915/dp: Add intel_dp_max_link_data_rate()
  drm/i915/dp: Add way to get active pipes with syncing commits
  drm/i915/dp: Add support for DP tunnel BW allocation
  drm/i915/dp: Add DP tunnel atomic state and check BW limit
  drm/i915/dp: Account for tunnel BW limit in
    intel_dp_max_link_data_rate()
  drm/i915/dp: Compute DP tunnel BW during encoder state computation
  drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable
    hooks
  drm/i915/dp: Handle DP tunnel IRQs
  drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
  drm/i915/dp: Suspend/resume DP tunnels
  drm/i915/dp: Read DPRX for all long HPD pulses
  drm/i915/dp: Enable DP tunnel BW allocation mode

 drivers/gpu/drm/display/Kconfig               |   21 +
 drivers/gpu/drm/display/Makefile              |    2 +
 drivers/gpu/drm/display/drm_dp_helper.c       |   30 +
 drivers/gpu/drm/display/drm_dp_tunnel.c       | 1929 +++++++++++++++++
 drivers/gpu/drm/i915/Kconfig                  |   14 +
 drivers/gpu/drm/i915/Kconfig.debug            |    1 +
 drivers/gpu/drm/i915/Makefile                 |    3 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |   10 +
 drivers/gpu/drm/i915/display/intel_crtc.c     |   52 +
 drivers/gpu/drm/i915/display/intel_crtc.h     |    2 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |    3 +-
 drivers/gpu/drm/i915/display/intel_display.c  |   26 +-
 .../gpu/drm/i915/display/intel_display_core.h |    1 +
 .../drm/i915/display/intel_display_driver.c   |   20 +-
 .../drm/i915/display/intel_display_types.h    |    9 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  292 ++-
 drivers/gpu/drm/i915/display/intel_dp.h       |   13 +-
 .../drm/i915/display/intel_dp_link_training.c |   33 +-
 .../drm/i915/display/intel_dp_link_training.h |    1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   18 +-
 .../gpu/drm/i915/display/intel_dp_tunnel.c    |  815 +++++++
 .../gpu/drm/i915/display/intel_dp_tunnel.h    |  133 ++
 drivers/gpu/drm/i915/display/intel_link_bw.c  |   27 +-
 drivers/gpu/drm/i915/display/intel_link_bw.h  |    2 +-
 drivers/gpu/drm/i915/display/intel_tc.c       |    7 +
 include/drm/display/drm_dp.h                  |   61 +
 include/drm/display/drm_dp_helper.h           |    2 +
 include/drm/display/drm_dp_tunnel.h           |  248 +++
 28 files changed, 3650 insertions(+), 125 deletions(-)
 create mode 100644 drivers/gpu/drm/display/drm_dp_tunnel.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h
 create mode 100644 include/drm/display/drm_dp_tunnel.h

-- 
2.39.2


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

* [PATCH v2 01/21] drm/dp: Add drm_dp_max_dprx_data_rate()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-26 18:52   ` [PATCH v3 " Imre Deak
  2024-02-20 21:18 ` [PATCH v2 02/21] drm/dp: Add support for DP tunneling Imre Deak
                   ` (31 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Ville Syrjälä, Uma Shankar

Copy intel_dp_max_data_rate() to DRM core. It will be needed by a
follow-up DP tunnel patch, checking the maximum rate the DPRX (sink)
supports. Accordingly use the drm_dp_max_dprx_data_rate() name for
clarity. This patchset will also switch calling the new DRM function
in i915 instead of intel_dp_max_data_rate().

While at it simplify the function documentation/comments, removing
parts described already by drm_dp_bw_channel_coding_efficiency().

v2: (Ville)
- Remove max_link_rate_kbps.
- Simplify the function documentation.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/display/drm_dp_helper.c | 30 +++++++++++++++++++++++++
 include/drm/display/drm_dp_helper.h     |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 8d6ce46471ae6..d046dfa79504f 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -4055,3 +4055,33 @@ int drm_dp_bw_channel_coding_efficiency(bool is_uhbr)
 		return 800000;
 }
 EXPORT_SYMBOL(drm_dp_bw_channel_coding_efficiency);
+
+/**
+ * drm_dp_max_dprx_data_rate - Get the max data bandwidth of a DPRX sink
+ * @max_link_rate: max DPRX link rate in 10kbps units
+ * @max_lanes: max DPRX lane count
+ *
+ * Given a link rate and lanes, get the data bandwidth.
+ *
+ * Data bandwidth is the actual payload rate, which depends on the data
+ * bandwidth efficiency and the link rate.
+ *
+ * Note that protocol layers above the DPRX link level considered here can
+ * further limit the maximum data rate. Such layers are the MST topology (with
+ * limits on the link between the source and first branch device as well as on
+ * the whole MST path until the DPRX link) and (Thunderbolt) DP tunnels -
+ * which in turn can encapsulate an MST link with its own limit - with each
+ * SST or MST encapsulated tunnel sharing the BW of a tunnel group.
+ *
+ * Returns the maximum data rate in kBps units.
+ */
+int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes)
+{
+	int ch_coding_efficiency =
+		drm_dp_bw_channel_coding_efficiency(drm_dp_is_uhbr_rate(max_link_rate));
+
+	return DIV_ROUND_DOWN_ULL(mul_u32_u32(max_link_rate * 10 * max_lanes,
+					      ch_coding_efficiency),
+				  1000000 * 8);
+}
+EXPORT_SYMBOL(drm_dp_max_dprx_data_rate);
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index d02014a87f127..65dae9a9f2fb6 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -812,4 +812,6 @@ int drm_dp_bw_overhead(int lane_count, int hactive,
 		       int bpp_x16, unsigned long flags);
 int drm_dp_bw_channel_coding_efficiency(bool is_uhbr);
 
+int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes);
+
 #endif /* _DRM_DP_HELPER_H_ */
-- 
2.39.2


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

* [PATCH v2 02/21] drm/dp: Add support for DP tunneling
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
  2024-02-20 21:18 ` [PATCH v2 01/21] drm/dp: Add drm_dp_max_dprx_data_rate() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23  6:25   ` Shankar, Uma
                     ` (2 more replies)
  2024-02-20 21:18 ` [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during system resume Imre Deak
                   ` (30 subsequent siblings)
  32 siblings, 3 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Ville Syrjälä

Add support for Display Port tunneling. For now this includes the
support for Bandwidth Allocation Mode (BWA), leaving adding Panel Replay
support for later.

BWA allows using displays that share the same (Thunderbolt) link with
their maximum resolution. Atm, this may not be possible due to the
coarse granularity of partitioning the link BW among the displays on the
link: the BW allocation policy is in a SW/FW/HW component on the link
(on Thunderbolt it's the SW or FW Connection Manager), independent of
the driver. This policy will set the DPRX maximum rate and lane count
DPCD registers the GFX driver will see (0x00000, 0x00001, 0x02200,
0x02201) based on the available link BW.

The granularity of the current BW allocation policy is coarse, based on
the required link rate in the 1.62Gbs..8.1Gbps range and it may prevent
using higher resolutions all together: the display connected first will
get a share of the link BW which corresponds to its full DPRX capability
(regardless of the actual mode it uses). A subsequent display connected
will only get the remaining BW, which could be well below its full
capability.

BWA solves the above coarse granularity (reducing it to a 250Mbs..1Gps
range) and first-come/first-served issues by letting the driver request
the BW for each display on a link which reflects the actual modes the
displays use.

This patch adds the DRM core helper functions, while a follow-up change
in the patchset takes them into use in the i915 driver.

v2:
- Fix prepare_to_wait vs. wake-up cond check order in
  allocate_tunnel_bw(). (Ville)
- Move tunnel==NULL checks from callers in drivers to here. (Ville)
- Avoid var inits in declaration blocks that can fail or have
  side-effects. (Ville)
- Use u8 for driver and group IDs. (Ville)
- Simplify API removing drm_dp_tunnel_get/put_untracked(). (Ville)
- Reuse str_yes_no() instead of a local yes_no_chr(). (Ville)
- s/drm_dp_tunnel_atomic_clear_state()/free_tunnel_state() and unexport
  the function. (Ville)
- s/clear_tunnel_group_state()/free_group_state() and move kfree() to
  this function. (Ville)
- Add separate group_free_bw() helper and describe what the tunnel
  estimated BW includes. (Ville)
- Improve help text for CONFIG_DRM_DISPLAY_DP_TUNNEL. (Ville)
- Add code comment explaining the purpose of DPCD reg read helpers.
  (Ville)
- Add code comment describing the tunnel group name prefix format.
  (Ville)
- Report the allocated BW as undetermined until the first allocation
  request.
- Skip allocation requests matching the previous request.
- Clear any stale BW request status flags before a new request.
- Add missing error return check of drm_dp_tunnel_atomic_get_group_state()
  in drm_dp_tunnel_atomic_set_stream_bw().
- Add drm_dp_tunnel_get_allocated_bw().
- s/drm_dp_tunnel_atomic_get_tunnel_bw/drm_dp_tunnel_atomic_get_required_bw
- Fix return value description in function doc of drm_dp_tunnel_detect().
- Add function documentation to all exported functions.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/display/Kconfig         |   21 +
 drivers/gpu/drm/display/Makefile        |    2 +
 drivers/gpu/drm/display/drm_dp_tunnel.c | 1929 +++++++++++++++++++++++
 include/drm/display/drm_dp.h            |   60 +
 include/drm/display/drm_dp_tunnel.h     |  248 +++
 5 files changed, 2260 insertions(+)
 create mode 100644 drivers/gpu/drm/display/drm_dp_tunnel.c
 create mode 100644 include/drm/display/drm_dp_tunnel.h

diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 09712b88a5b83..c0f56888c3280 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -17,6 +17,27 @@ config DRM_DISPLAY_DP_HELPER
 	help
 	  DRM display helpers for DisplayPort.
 
+config DRM_DISPLAY_DP_TUNNEL
+	bool
+	select DRM_DISPLAY_DP_HELPER
+	help
+	  Enable support for DisplayPort tunnels. This allows drivers to use
+	  DP tunnel features like the Bandwidth Allocation mode to maximize the
+	  BW utilization for display streams on Thunderbolt links.
+
+config DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	bool "Enable debugging the DP tunnel state"
+	depends on REF_TRACKER
+	depends on DRM_DISPLAY_DP_TUNNEL
+	depends on DEBUG_KERNEL
+	depends on EXPERT
+	help
+	  Enables debugging the DP tunnel manager's state, including the
+	  consistency of all managed tunnels' reference counting and the state of
+	  streams contained in tunnels.
+
+	  If in doubt, say "N".
+
 config DRM_DISPLAY_HDCP_HELPER
 	bool
 	depends on DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 17ac4a1006a80..7ca61333c6696 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -8,6 +8,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \
 	drm_dp_helper.o \
 	drm_dp_mst_topology.o \
 	drm_dsc_helper.o
+drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \
+	drm_dp_tunnel.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
 	drm_hdmi_helper.o \
diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c
new file mode 100644
index 0000000000000..919337eabb313
--- /dev/null
+++ b/drivers/gpu/drm/display/drm_dp_tunnel.c
@@ -0,0 +1,1929 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <linux/ref_tracker.h>
+#include <linux/types.h>
+
+#include <drm/drm_atomic_state_helper.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_print.h>
+#include <drm/display/drm_dp.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
+
+#define to_group(__private_obj) \
+	container_of(__private_obj, struct drm_dp_tunnel_group, base)
+
+#define to_group_state(__private_state) \
+	container_of(__private_state, struct drm_dp_tunnel_group_state, base)
+
+#define is_dp_tunnel_private_obj(__obj) \
+	((__obj)->funcs == &tunnel_group_funcs)
+
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))
+
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))
+
+#define for_each_tunnel_in_group(__group, __tunnel) \
+	list_for_each_entry(__tunnel, &(__group)->tunnels, node)
+
+#define for_each_tunnel_state(__group_state, __tunnel_state) \
+	list_for_each_entry(__tunnel_state, &(__group_state)->tunnel_states, node)
+
+#define for_each_tunnel_state_safe(__group_state, __tunnel_state, __tunnel_state_tmp) \
+	list_for_each_entry_safe(__tunnel_state, __tunnel_state_tmp, \
+				 &(__group_state)->tunnel_states, node)
+
+#define kbytes_to_mbits(__kbytes) \
+	DIV_ROUND_UP((__kbytes) * 8, 1000)
+
+#define DPTUN_BW_ARG(__bw) ((__bw) < 0 ? (__bw) : kbytes_to_mbits(__bw))
+
+#define __tun_prn(__tunnel, __level, __type, __fmt, ...) \
+	drm_##__level##__type((__tunnel)->group->mgr->dev, \
+			      "[DPTUN %s][%s] " __fmt, \
+			      drm_dp_tunnel_name(__tunnel), \
+			      (__tunnel)->aux->name, ## \
+			      __VA_ARGS__)
+
+#define tun_dbg(__tunnel, __fmt, ...) \
+	__tun_prn(__tunnel, dbg, _kms, __fmt, ## __VA_ARGS__)
+
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)
+
+#define tun_dbg_atomic(__tunnel, __fmt, ...) \
+	__tun_prn(__tunnel, dbg, _atomic, __fmt, ## __VA_ARGS__)
+
+#define tun_grp_dbg(__group, __fmt, ...) \
+	drm_dbg_kms((__group)->mgr->dev, \
+		    "[DPTUN %s] " __fmt, \
+		    drm_dp_tunnel_group_name(__group), ## \
+		    __VA_ARGS__)
+
+#define DP_TUNNELING_BASE DP_TUNNELING_OUI
+
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)
+
+#define DPTUN_REG_RANGE(addr, size) \
+	__DPTUN_REG_RANGE((addr) - DP_TUNNELING_BASE, size)
+
+#define DPTUN_REG(addr) DPTUN_REG_RANGE(addr, 1)
+
+#define DPTUN_INFO_REG_MASK ( \
+	DPTUN_REG_RANGE(DP_TUNNELING_OUI, DP_TUNNELING_OUI_BYTES) | \
+	DPTUN_REG_RANGE(DP_TUNNELING_DEV_ID, DP_TUNNELING_DEV_ID_BYTES) | \
+	DPTUN_REG(DP_TUNNELING_HW_REV) | \
+	DPTUN_REG(DP_TUNNELING_SW_REV_MAJOR) | \
+	DPTUN_REG(DP_TUNNELING_SW_REV_MINOR) | \
+	DPTUN_REG(DP_TUNNELING_CAPABILITIES) | \
+	DPTUN_REG(DP_IN_ADAPTER_INFO) | \
+	DPTUN_REG(DP_USB4_DRIVER_ID) | \
+	DPTUN_REG(DP_USB4_DRIVER_BW_CAPABILITY) | \
+	DPTUN_REG(DP_IN_ADAPTER_TUNNEL_INFORMATION) | \
+	DPTUN_REG(DP_BW_GRANULARITY) | \
+	DPTUN_REG(DP_ESTIMATED_BW) | \
+	DPTUN_REG(DP_ALLOCATED_BW) | \
+	DPTUN_REG(DP_TUNNELING_MAX_LINK_RATE) | \
+	DPTUN_REG(DP_TUNNELING_MAX_LANE_COUNT) | \
+	DPTUN_REG(DP_DPTX_BW_ALLOCATION_MODE_CONTROL))
+
+static const DECLARE_BITMAP(dptun_info_regs, 64) = {
+	DPTUN_INFO_REG_MASK & -1UL,
+#if BITS_PER_LONG == 32
+	DPTUN_INFO_REG_MASK >> 32,
+#endif
+};
+
+struct drm_dp_tunnel_regs {
+	u8 buf[HWEIGHT64(DPTUN_INFO_REG_MASK)];
+};
+
+struct drm_dp_tunnel_group;
+
+struct drm_dp_tunnel {
+	struct drm_dp_tunnel_group *group;
+
+	struct list_head node;
+
+	struct kref kref;
+	struct ref_tracker *tracker;
+	struct drm_dp_aux *aux;
+	char name[8];
+
+	int bw_granularity;
+	int estimated_bw;
+	int allocated_bw;
+
+	int max_dprx_rate;
+	u8 max_dprx_lane_count;
+
+	u8 adapter_id;
+
+	bool bw_alloc_supported:1;
+	bool bw_alloc_enabled:1;
+	bool has_io_error:1;
+	bool destroyed:1;
+};
+
+struct drm_dp_tunnel_group_state;
+
+struct drm_dp_tunnel_state {
+	struct drm_dp_tunnel_group_state *group_state;
+
+	struct drm_dp_tunnel_ref tunnel_ref;
+
+	struct list_head node;
+
+	u32 stream_mask;
+	int *stream_bw;
+};
+
+struct drm_dp_tunnel_group_state {
+	struct drm_private_state base;
+
+	struct list_head tunnel_states;
+};
+
+struct drm_dp_tunnel_group {
+	struct drm_private_obj base;
+	struct drm_dp_tunnel_mgr *mgr;
+
+	struct list_head tunnels;
+
+	/* available BW including the allocated_bw of all tunnels in the group */
+	int available_bw;
+	u8 drv_group_id;
+
+	char name[8];
+
+	bool active:1;
+};
+
+struct drm_dp_tunnel_mgr {
+	struct drm_device *dev;
+
+	int group_count;
+	struct drm_dp_tunnel_group *groups;
+	wait_queue_head_t bw_req_queue;
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	struct ref_tracker_dir ref_tracker;
+#endif
+};
+
+/*
+ * The following helpers provide a way to read out the tunneling DPCD
+ * registers with a minimal amount of AUX transfers (1 transfer per contiguous
+ * range, as permitted by the 16 byte per transfer AUX limit), not accessing
+ * other registers to avoid any read side-effects.
+ */
+static int next_reg_area(int *offset)
+{
+	*offset = find_next_bit(dptun_info_regs, 64, *offset);
+
+	return find_next_zero_bit(dptun_info_regs, 64, *offset + 1) - *offset;
+}
+
+#define tunnel_reg_ptr(__regs, __address) ({ \
+	WARN_ON(!test_bit((__address) - DP_TUNNELING_BASE, dptun_info_regs)); \
+	&(__regs)->buf[bitmap_weight(dptun_info_regs, (__address) - DP_TUNNELING_BASE)]; \
+})
+
+static int read_tunnel_regs(struct drm_dp_aux *aux, struct drm_dp_tunnel_regs *regs)
+{
+	int offset = 0;
+	int len;
+
+	while ((len = next_reg_area(&offset))) {
+		int address = DP_TUNNELING_BASE + offset;
+
+		if (drm_dp_dpcd_read(aux, address, tunnel_reg_ptr(regs, address), len) < 0)
+			return -EIO;
+
+		offset += len;
+	}
+
+	return 0;
+}
+
+static u8 tunnel_reg(const struct drm_dp_tunnel_regs *regs, int address)
+{
+	return *tunnel_reg_ptr(regs, address);
+}
+
+static u8 tunnel_reg_drv_group_id(const struct drm_dp_tunnel_regs *regs)
+{
+	u8 drv_id = tunnel_reg(regs, DP_USB4_DRIVER_ID) & DP_USB4_DRIVER_ID_MASK;
+	u8 group_id = tunnel_reg(regs, DP_IN_ADAPTER_TUNNEL_INFORMATION) & DP_GROUP_ID_MASK;
+
+	if (!group_id)
+		return 0;
+
+	return (drv_id << DP_GROUP_ID_BITS) | group_id;
+}
+
+/* Return granularity in kB/s units */
+static int tunnel_reg_bw_granularity(const struct drm_dp_tunnel_regs *regs)
+{
+	int gr = tunnel_reg(regs, DP_BW_GRANULARITY) & DP_BW_GRANULARITY_MASK;
+
+	WARN_ON(gr > 2);
+
+	return (250000 << gr) / 8;
+}
+
+static int tunnel_reg_max_dprx_rate(const struct drm_dp_tunnel_regs *regs)
+{
+	u8 bw_code = tunnel_reg(regs, DP_TUNNELING_MAX_LINK_RATE);
+
+	return drm_dp_bw_code_to_link_rate(bw_code);
+}
+
+static int tunnel_reg_max_dprx_lane_count(const struct drm_dp_tunnel_regs *regs)
+{
+	return tunnel_reg(regs, DP_TUNNELING_MAX_LANE_COUNT) &
+	       DP_TUNNELING_MAX_LANE_COUNT_MASK;
+}
+
+static bool tunnel_reg_bw_alloc_supported(const struct drm_dp_tunnel_regs *regs)
+{
+	u8 cap_mask = DP_TUNNELING_SUPPORT | DP_IN_BW_ALLOCATION_MODE_SUPPORT;
+
+	if ((tunnel_reg(regs, DP_TUNNELING_CAPABILITIES) & cap_mask) != cap_mask)
+		return false;
+
+	return tunnel_reg(regs, DP_USB4_DRIVER_BW_CAPABILITY) &
+	       DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT;
+}
+
+static bool tunnel_reg_bw_alloc_enabled(const struct drm_dp_tunnel_regs *regs)
+{
+	return tunnel_reg(regs, DP_DPTX_BW_ALLOCATION_MODE_CONTROL) &
+	       DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE;
+}
+
+static u8 tunnel_group_drv_id(u8 drv_group_id)
+{
+	return drv_group_id >> DP_GROUP_ID_BITS;
+}
+
+static u8 tunnel_group_id(u8 drv_group_id)
+{
+	return drv_group_id & DP_GROUP_ID_MASK;
+}
+
+const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->name;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_name);
+
+static const char *drm_dp_tunnel_group_name(const struct drm_dp_tunnel_group *group)
+{
+	return group->name;
+}
+
+static struct drm_dp_tunnel_group *
+lookup_or_alloc_group(struct drm_dp_tunnel_mgr *mgr, u8 drv_group_id)
+{
+	struct drm_dp_tunnel_group *group = NULL;
+	int i;
+
+	for (i = 0; i < mgr->group_count; i++) {
+		/*
+		 * A tunnel group with 0 group ID shouldn't have more than one
+		 * tunnels.
+		 */
+		if (tunnel_group_id(drv_group_id) &&
+		    mgr->groups[i].drv_group_id == drv_group_id)
+			return &mgr->groups[i];
+
+		if (!group && !mgr->groups[i].active)
+			group = &mgr->groups[i];
+	}
+
+	if (!group) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Can't allocate more tunnel groups\n");
+		return NULL;
+	}
+
+	group->drv_group_id = drv_group_id;
+	group->active = true;
+
+	/*
+	 * The group name format here and elsewhere: Driver-ID:Group-ID:*
+	 * (* standing for all DP-Adapters/tunnels in the group).
+	 */
+	snprintf(group->name, sizeof(group->name), "%d:%d:*",
+		 tunnel_group_drv_id(drv_group_id) & ((1 << DP_GROUP_ID_BITS) - 1),
+		 tunnel_group_id(drv_group_id) & ((1 << DP_USB4_DRIVER_ID_BITS) - 1));
+
+	return group;
+}
+
+static void free_group(struct drm_dp_tunnel_group *group)
+{
+	struct drm_dp_tunnel_mgr *mgr = group->mgr;
+
+	if (drm_WARN_ON(mgr->dev, !list_empty(&group->tunnels)))
+		return;
+
+	group->drv_group_id = 0;
+	group->available_bw = -1;
+	group->active = false;
+}
+
+static struct drm_dp_tunnel *
+tunnel_get(struct drm_dp_tunnel *tunnel)
+{
+	kref_get(&tunnel->kref);
+
+	return tunnel;
+}
+
+static void free_tunnel(struct kref *kref)
+{
+	struct drm_dp_tunnel *tunnel = container_of(kref, typeof(*tunnel), kref);
+	struct drm_dp_tunnel_group *group = tunnel->group;
+
+	list_del(&tunnel->node);
+	if (list_empty(&group->tunnels))
+		free_group(group);
+
+	kfree(tunnel);
+}
+
+static void tunnel_put(struct drm_dp_tunnel *tunnel)
+{
+	kref_put(&tunnel->kref, free_tunnel);
+}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+static void track_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			     struct ref_tracker **tracker)
+{
+	ref_tracker_alloc(&tunnel->group->mgr->ref_tracker,
+			  tracker, GFP_KERNEL);
+}
+
+static void untrack_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			       struct ref_tracker **tracker)
+{
+	ref_tracker_free(&tunnel->group->mgr->ref_tracker,
+			 tracker);
+}
+#else
+static void track_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			     struct ref_tracker **tracker)
+{
+}
+
+static void untrack_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			       struct ref_tracker **tracker)
+{
+}
+#endif
+
+/**
+ * drm_dp_tunnel_get - Get a reference for a DP tunnel
+ * @tunnel: Tunnel object
+ * @tracker: Debug tracker for the reference
+ *
+ * Get a reference for @tunnel, along with a debug tracker to help locating
+ * the source of a reference leak/double reference put etc. issue.
+ *
+ * The reference must be dropped after use calling drm_dp_tunnel_put()
+ * passing @tunnel and *@tracker returned from here.
+ *
+ * Returns @tunnel - as a convenience - along with *@tracker.
+ */
+struct drm_dp_tunnel *
+drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel,
+		  struct ref_tracker **tracker)
+{
+	track_tunnel_ref(tunnel, tracker);
+
+	return tunnel_get(tunnel);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_get);
+
+/**
+ * drm_dp_tunnel_put - Put a reference for a DP tunnel
+ * @tunnel - Tunnel object
+ * @tracker - Debug tracker for the reference
+ *
+ * Put a reference for @tunnel along with its debug *@tracker, which
+ * was obtained with drm_dp_tunnel_get().
+ */
+void drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel,
+			 struct ref_tracker **tracker)
+{
+	untrack_tunnel_ref(tunnel, tracker);
+
+	tunnel_put(tunnel);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_put);
+
+static bool add_tunnel_to_group(struct drm_dp_tunnel_mgr *mgr,
+				u8 drv_group_id,
+				struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group *group;
+
+	group = lookup_or_alloc_group(mgr, drv_group_id);
+	if (!group)
+		return false;
+
+	tunnel->group = group;
+	list_add(&tunnel->node, &group->tunnels);
+
+	return true;
+}
+
+static struct drm_dp_tunnel *
+create_tunnel(struct drm_dp_tunnel_mgr *mgr,
+	      struct drm_dp_aux *aux,
+	      const struct drm_dp_tunnel_regs *regs)
+{
+	u8 drv_group_id = tunnel_reg_drv_group_id(regs);
+	struct drm_dp_tunnel *tunnel;
+
+	tunnel = kzalloc(sizeof(*tunnel), GFP_KERNEL);
+	if (!tunnel)
+		return NULL;
+
+	INIT_LIST_HEAD(&tunnel->node);
+
+	kref_init(&tunnel->kref);
+
+	tunnel->aux = aux;
+
+	tunnel->adapter_id = tunnel_reg(regs, DP_IN_ADAPTER_INFO) & DP_IN_ADAPTER_NUMBER_MASK;
+
+	snprintf(tunnel->name, sizeof(tunnel->name), "%d:%d:%d",
+		 tunnel_group_drv_id(drv_group_id) & ((1 << DP_GROUP_ID_BITS) - 1),
+		 tunnel_group_id(drv_group_id) & ((1 << DP_USB4_DRIVER_ID_BITS) - 1),
+		 tunnel->adapter_id & ((1 << DP_IN_ADAPTER_NUMBER_BITS) - 1));
+
+	tunnel->bw_granularity = tunnel_reg_bw_granularity(regs);
+	tunnel->allocated_bw = tunnel_reg(regs, DP_ALLOCATED_BW) *
+			       tunnel->bw_granularity;
+	/*
+	 * An initial allocated BW of 0 indicates an undefined state: the
+	 * actual allocation is determined by the TBT CM, usually following a
+	 * legacy allocation policy (based on the max DPRX caps). From the
+	 * driver's POV the state becomes defined only after the first
+	 * allocation request.
+	 */
+	if (!tunnel->allocated_bw)
+		tunnel->allocated_bw = -1;
+
+	tunnel->bw_alloc_supported = tunnel_reg_bw_alloc_supported(regs);
+	tunnel->bw_alloc_enabled = tunnel_reg_bw_alloc_enabled(regs);
+
+	if (!add_tunnel_to_group(mgr, drv_group_id, tunnel)) {
+		kfree(tunnel);
+
+		return NULL;
+	}
+
+	track_tunnel_ref(tunnel, &tunnel->tracker);
+
+	return tunnel;
+}
+
+static void destroy_tunnel(struct drm_dp_tunnel *tunnel)
+{
+	untrack_tunnel_ref(tunnel, &tunnel->tracker);
+	tunnel_put(tunnel);
+}
+
+/**
+ * drm_dp_tunnel_set_io_error - Set the IO error flag for a DP tunnel
+ * @tunnel: Tunnel object
+ *
+ * Set the IO error flag for @tunnel. Drivers can call this function upon
+ * detecting a failure that affects the tunnel functionality, for instance
+ * after a DP AUX transfer failure on the port @tunnel is connected to.
+ *
+ * This disables further management of @tunnel, including any related
+ * AUX accesses for tunneling DPCD registers, returning error to the
+ * initiators of these. The driver is supposed to drop this tunnel and -
+ * optionally - recreate it.
+ */
+void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel)
+{
+	tunnel->has_io_error = true;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_set_io_error);
+
+#define SKIP_DPRX_CAPS_CHECK		BIT(0)
+#define ALLOW_ALLOCATED_BW_CHANGE	BIT(1)
+static bool tunnel_regs_are_valid(struct drm_dp_tunnel_mgr *mgr,
+				  const struct drm_dp_tunnel_regs *regs,
+				  unsigned int flags)
+{
+	u8 drv_group_id = tunnel_reg_drv_group_id(regs);
+	bool check_dprx = !(flags & SKIP_DPRX_CAPS_CHECK);
+	bool ret = true;
+
+	if (!tunnel_reg_bw_alloc_supported(regs)) {
+		if (tunnel_group_id(drv_group_id)) {
+			drm_dbg_kms(mgr->dev,
+				    "DPTUN: A non-zero group ID is only allowed with BWA support\n");
+			ret = false;
+		}
+
+		if (tunnel_reg(regs, DP_ALLOCATED_BW)) {
+			drm_dbg_kms(mgr->dev,
+				    "DPTUN: BW is allocated without BWA support\n");
+			ret = false;
+		}
+
+		return ret;
+	}
+
+	if (!tunnel_group_id(drv_group_id)) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: BWA support requires a non-zero group ID\n");
+		ret = false;
+	}
+
+	if (check_dprx && hweight8(tunnel_reg_max_dprx_lane_count(regs)) != 1) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Invalid DPRX lane count: %d\n",
+			    tunnel_reg_max_dprx_lane_count(regs));
+
+		ret = false;
+	}
+
+	if (check_dprx && !tunnel_reg_max_dprx_rate(regs)) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: DPRX rate is 0\n");
+
+		ret = false;
+	}
+
+	if (tunnel_reg(regs, DP_ALLOCATED_BW) > tunnel_reg(regs, DP_ESTIMATED_BW)) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Allocated BW %d > estimated BW %d Mb/s\n",
+			    DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) *
+					 tunnel_reg_bw_granularity(regs)),
+			    DPTUN_BW_ARG(tunnel_reg(regs, DP_ESTIMATED_BW) *
+					 tunnel_reg_bw_granularity(regs)));
+
+		ret = false;
+	}
+
+	return ret;
+}
+
+static int tunnel_allocated_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return max(tunnel->allocated_bw, 0);
+}
+
+static bool tunnel_info_changes_are_valid(struct drm_dp_tunnel *tunnel,
+					  const struct drm_dp_tunnel_regs *regs,
+					  unsigned int flags)
+{
+	u8 new_drv_group_id = tunnel_reg_drv_group_id(regs);
+	bool ret = true;
+
+	if (tunnel->bw_alloc_supported != tunnel_reg_bw_alloc_supported(regs)) {
+		tun_dbg(tunnel,
+			"BW alloc support has changed %s -> %s\n",
+			str_yes_no(tunnel->bw_alloc_supported),
+			str_yes_no(tunnel_reg_bw_alloc_supported(regs)));
+
+		ret = false;
+	}
+
+	if (tunnel->group->drv_group_id != new_drv_group_id) {
+		tun_dbg(tunnel,
+			"Driver/group ID has changed %d:%d:* -> %d:%d:*\n",
+			tunnel_group_drv_id(tunnel->group->drv_group_id),
+			tunnel_group_id(tunnel->group->drv_group_id),
+			tunnel_group_drv_id(new_drv_group_id),
+			tunnel_group_id(new_drv_group_id));
+
+		ret = false;
+	}
+
+	if (!tunnel->bw_alloc_supported)
+		return ret;
+
+	if (tunnel->bw_granularity != tunnel_reg_bw_granularity(regs)) {
+		tun_dbg(tunnel,
+			"BW granularity has changed: %d -> %d Mb/s\n",
+			DPTUN_BW_ARG(tunnel->bw_granularity),
+			DPTUN_BW_ARG(tunnel_reg_bw_granularity(regs)));
+
+		ret = false;
+	}
+
+	/*
+	 * On some devices at least the BW alloc mode enabled status is always
+	 * reported as 0, so skip checking that here.
+	 */
+
+	if (!(flags & ALLOW_ALLOCATED_BW_CHANGE) &&
+	    tunnel_allocated_bw(tunnel) !=
+	    tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity) {
+		tun_dbg(tunnel,
+			"Allocated BW has changed: %d -> %d Mb/s\n",
+			DPTUN_BW_ARG(tunnel->allocated_bw),
+			DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity));
+
+		ret = false;
+	}
+
+	return ret;
+}
+
+static int
+read_and_verify_tunnel_regs(struct drm_dp_tunnel *tunnel,
+			    struct drm_dp_tunnel_regs *regs,
+			    unsigned int flags)
+{
+	int err;
+
+	err = read_tunnel_regs(tunnel->aux, regs);
+	if (err < 0) {
+		drm_dp_tunnel_set_io_error(tunnel);
+
+		return err;
+	}
+
+	if (!tunnel_regs_are_valid(tunnel->group->mgr, regs, flags))
+		return -EINVAL;
+
+	if (!tunnel_info_changes_are_valid(tunnel, regs, flags))
+		return -EINVAL;
+
+	return 0;
+}
+
+static bool update_dprx_caps(struct drm_dp_tunnel *tunnel, const struct drm_dp_tunnel_regs *regs)
+{
+	bool changed = false;
+
+	if (tunnel_reg_max_dprx_rate(regs) != tunnel->max_dprx_rate) {
+		tunnel->max_dprx_rate = tunnel_reg_max_dprx_rate(regs);
+		changed = true;
+	}
+
+	if (tunnel_reg_max_dprx_lane_count(regs) != tunnel->max_dprx_lane_count) {
+		tunnel->max_dprx_lane_count = tunnel_reg_max_dprx_lane_count(regs);
+		changed = true;
+	}
+
+	return changed;
+}
+
+static int dev_id_len(const u8 *dev_id, int max_len)
+{
+	while (max_len && dev_id[max_len - 1] == '\0')
+		max_len--;
+
+	return max_len;
+}
+
+static int get_max_dprx_bw(const struct drm_dp_tunnel *tunnel)
+{
+	int max_dprx_bw = drm_dp_max_dprx_data_rate(tunnel->max_dprx_rate,
+						    tunnel->max_dprx_lane_count);
+
+	/*
+	 * A BW request of roundup(max_dprx_bw, tunnel->bw_granularity) results in
+	 * an allocation of max_dprx_bw. A BW request above this rounded-up
+	 * value will fail.
+	 */
+	return min(roundup(max_dprx_bw, tunnel->bw_granularity),
+		   MAX_DP_REQUEST_BW * tunnel->bw_granularity);
+}
+
+static int get_max_tunnel_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return min(get_max_dprx_bw(tunnel), tunnel->group->available_bw);
+}
+
+/**
+ * drm_dp_tunnel_detect - Detect DP tunnel on the link
+ * @mgr: Tunnel manager
+ * @aux: DP AUX on which the tunnel will be detected
+ *
+ * Detect if there is any DP tunnel on the link and add it to the tunnel
+ * group's tunnel list.
+ *
+ * Returns a pointer to a tunnel on success, or an ERR_PTR() error on
+ * failure.
+ */
+struct drm_dp_tunnel *
+drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
+		     struct drm_dp_aux *aux)
+{
+	struct drm_dp_tunnel_regs regs;
+	struct drm_dp_tunnel *tunnel;
+	int err;
+
+	err = read_tunnel_regs(aux, &regs);
+	if (err)
+		return ERR_PTR(err);
+
+	if (!(tunnel_reg(&regs, DP_TUNNELING_CAPABILITIES) &
+	      DP_TUNNELING_SUPPORT))
+		return ERR_PTR(-ENODEV);
+
+	/* The DPRX caps are valid only after enabling BW alloc mode. */
+	if (!tunnel_regs_are_valid(mgr, &regs, SKIP_DPRX_CAPS_CHECK))
+		return ERR_PTR(-EINVAL);
+
+	tunnel = create_tunnel(mgr, aux, &regs);
+	if (!tunnel)
+		return ERR_PTR(-ENOMEM);
+
+	tun_dbg(tunnel,
+		"OUI:%*phD DevID:%*pE Rev-HW:%d.%d SW:%d.%d PR-Sup:%s BWA-Sup:%s BWA-En:%s\n",
+		DP_TUNNELING_OUI_BYTES,
+			tunnel_reg_ptr(&regs, DP_TUNNELING_OUI),
+		dev_id_len(tunnel_reg_ptr(&regs, DP_TUNNELING_DEV_ID), DP_TUNNELING_DEV_ID_BYTES),
+			tunnel_reg_ptr(&regs, DP_TUNNELING_DEV_ID),
+		(tunnel_reg(&regs, DP_TUNNELING_HW_REV) & DP_TUNNELING_HW_REV_MAJOR_MASK) >>
+			DP_TUNNELING_HW_REV_MAJOR_SHIFT,
+		(tunnel_reg(&regs, DP_TUNNELING_HW_REV) & DP_TUNNELING_HW_REV_MINOR_MASK) >>
+			DP_TUNNELING_HW_REV_MINOR_SHIFT,
+		tunnel_reg(&regs, DP_TUNNELING_SW_REV_MAJOR),
+		tunnel_reg(&regs, DP_TUNNELING_SW_REV_MINOR),
+		str_yes_no(tunnel_reg(&regs, DP_TUNNELING_CAPABILITIES) &
+			   DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT),
+		str_yes_no(tunnel->bw_alloc_supported),
+		str_yes_no(tunnel->bw_alloc_enabled));
+
+	return tunnel;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_detect);
+
+/**
+ * drm_dp_tunnel_destroy - Destroy tunnel object
+ * @tunnel: Tunnel object
+ *
+ * Remove the tunnel from the tunnel topology and destroy it.
+ *
+ * Returns 0 on success, -ENODEV if the tunnel has been destroyed already.
+ */
+int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
+{
+	if (!tunnel)
+		return 0;
+
+	if (drm_WARN_ON(tunnel->group->mgr->dev, tunnel->destroyed))
+		return -ENODEV;
+
+	tun_dbg(tunnel, "destroying\n");
+
+	tunnel->destroyed = true;
+	destroy_tunnel(tunnel);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_destroy);
+
+static int check_tunnel(const struct drm_dp_tunnel *tunnel)
+{
+	if (tunnel->destroyed)
+		return -ENODEV;
+
+	if (tunnel->has_io_error)
+		return -EIO;
+
+	return 0;
+}
+
+static int group_allocated_bw(struct drm_dp_tunnel_group *group)
+{
+	struct drm_dp_tunnel *tunnel;
+	int group_allocated_bw = 0;
+
+	for_each_tunnel_in_group(group, tunnel) {
+		if (check_tunnel(tunnel) == 0 &&
+		    tunnel->bw_alloc_enabled)
+			group_allocated_bw += tunnel_allocated_bw(tunnel);
+	}
+
+	return group_allocated_bw;
+}
+
+/*
+ * The estimated BW reported by the TBT Connection Manager for each tunnel in
+ * a group includes the BW already allocated for the given tunnel and the
+ * unallocated BW which is free to be used by any tunnel in the group.
+ */
+static int group_free_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->estimated_bw - tunnel_allocated_bw(tunnel);
+}
+
+static int calc_group_available_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return group_allocated_bw(tunnel->group) +
+	       group_free_bw(tunnel);
+}
+
+static int update_group_available_bw(struct drm_dp_tunnel *tunnel,
+				     const struct drm_dp_tunnel_regs *regs)
+{
+	struct drm_dp_tunnel *tunnel_iter;
+	int group_available_bw;
+	bool changed;
+
+	tunnel->estimated_bw = tunnel_reg(regs, DP_ESTIMATED_BW) * tunnel->bw_granularity;
+
+	if (calc_group_available_bw(tunnel) == tunnel->group->available_bw)
+		return 0;
+
+	for_each_tunnel_in_group(tunnel->group, tunnel_iter) {
+		int err;
+
+		if (tunnel_iter == tunnel)
+			continue;
+
+		if (check_tunnel(tunnel_iter) != 0 ||
+		    !tunnel_iter->bw_alloc_enabled)
+			continue;
+
+		err = drm_dp_dpcd_probe(tunnel_iter->aux, DP_DPCD_REV);
+		if (err) {
+			tun_dbg(tunnel_iter,
+				"Probe failed, assume disconnected (err %pe)\n",
+				ERR_PTR(err));
+			drm_dp_tunnel_set_io_error(tunnel_iter);
+		}
+	}
+
+	group_available_bw = calc_group_available_bw(tunnel);
+
+	tun_dbg(tunnel, "Updated group available BW: %d->%d\n",
+		DPTUN_BW_ARG(tunnel->group->available_bw),
+		DPTUN_BW_ARG(group_available_bw));
+
+	changed = tunnel->group->available_bw != group_available_bw;
+
+	tunnel->group->available_bw = group_available_bw;
+
+	return changed ? 1 : 0;
+}
+
+static int set_bw_alloc_mode(struct drm_dp_tunnel *tunnel, bool enable)
+{
+	u8 mask = DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE | DP_UNMASK_BW_ALLOCATION_IRQ;
+	u8 val;
+
+	if (drm_dp_dpcd_readb(tunnel->aux, DP_DPTX_BW_ALLOCATION_MODE_CONTROL, &val) < 0)
+		goto out_err;
+
+	if (enable)
+		val |= mask;
+	else
+		val &= ~mask;
+
+	if (drm_dp_dpcd_writeb(tunnel->aux, DP_DPTX_BW_ALLOCATION_MODE_CONTROL, val) < 0)
+		goto out_err;
+
+	tunnel->bw_alloc_enabled = enable;
+
+	return 0;
+
+out_err:
+	drm_dp_tunnel_set_io_error(tunnel);
+
+	return -EIO;
+}
+
+/**
+ * drm_dp_tunnel_enable_bw_alloc - Enable DP tunnel BW allocation mode
+ * @tunnel: Tunnel object
+ *
+ * Enable the DP tunnel BW allocation mode on @tunnel if it supports it.
+ *
+ * Returns 0 in case of success, negative error code otherwise.
+ */
+int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_regs regs;
+	int err;
+
+	err = check_tunnel(tunnel);
+	if (err)
+		return err;
+
+	if (!tunnel->bw_alloc_supported)
+		return -EOPNOTSUPP;
+
+	if (!tunnel_group_id(tunnel->group->drv_group_id))
+		return -EINVAL;
+
+	err = set_bw_alloc_mode(tunnel, true);
+	if (err)
+		goto out;
+
+	err = read_and_verify_tunnel_regs(tunnel, &regs, 0);
+	if (err) {
+		set_bw_alloc_mode(tunnel, false);
+
+		goto out;
+	}
+
+	if (!tunnel->max_dprx_rate)
+		update_dprx_caps(tunnel, &regs);
+
+	if (tunnel->group->available_bw == -1) {
+		err = update_group_available_bw(tunnel, &regs);
+		if (err > 0)
+			err = 0;
+	}
+out:
+	tun_dbg_stat(tunnel, err,
+		     "Enabling BW alloc mode: DPRX:%dx%d Group alloc:%d/%d Mb/s",
+		     tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
+		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
+		     DPTUN_BW_ARG(tunnel->group->available_bw));
+
+	return err;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_enable_bw_alloc);
+
+/**
+ * drm_dp_tunnel_disable_bw_alloc - Disable DP tunnel BW allocation mode
+ * @tunnel: Tunnel object
+ *
+ * Disable the DP tunnel BW allocation mode on @tunnel.
+ *
+ * Returns 0 in case of success, negative error code otherwise.
+ */
+int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	int err;
+
+	err = check_tunnel(tunnel);
+	if (err)
+		return err;
+
+	tunnel->allocated_bw = -1;
+
+	err = set_bw_alloc_mode(tunnel, false);
+
+	tun_dbg_stat(tunnel, err, "Disabling BW alloc mode");
+
+	return err;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_disable_bw_alloc);
+
+/**
+ * drm_dp_tunnel_bw_alloc_is_enabled - Query the BW allocation mode enabled state
+ * @tunnel: Tunnel object
+ *
+ * Query if the BW allocation mode is enabled for @tunnel.
+ *
+ * Returns %true if the BW allocation mode is enabled for @tunnel.
+ */
+bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel && tunnel->bw_alloc_enabled;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_bw_alloc_is_enabled);
+
+static int clear_bw_req_state(struct drm_dp_aux *aux)
+{
+	u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED;
+
+	if (drm_dp_dpcd_writeb(aux, DP_TUNNELING_STATUS, bw_req_mask) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int bw_req_complete(struct drm_dp_aux *aux, bool *status_changed)
+{
+	u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED;
+	u8 status_change_mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED;
+	u8 val;
+	int err;
+
+	if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
+		return -EIO;
+
+	*status_changed = val & status_change_mask;
+
+	val &= bw_req_mask;
+
+	if (!val)
+		return -EAGAIN;
+
+	err = clear_bw_req_state(aux);
+	if (err < 0)
+		return err;
+
+	return val == DP_BW_REQUEST_SUCCEEDED ? 0 : -ENOSPC;
+}
+
+static int allocate_tunnel_bw(struct drm_dp_tunnel *tunnel, int bw)
+{
+	struct drm_dp_tunnel_mgr *mgr = tunnel->group->mgr;
+	int request_bw = DIV_ROUND_UP(bw, tunnel->bw_granularity);
+	DEFINE_WAIT_FUNC(wait, woken_wake_function);
+	long timeout;
+	int err;
+
+	if (bw < 0) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (request_bw * tunnel->bw_granularity == tunnel->allocated_bw)
+		return 0;
+
+	/* Atomic check should prevent the following. */
+	if (drm_WARN_ON(mgr->dev, request_bw > MAX_DP_REQUEST_BW)) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	err = clear_bw_req_state(tunnel->aux);
+	if (err)
+		goto out;
+
+	if (drm_dp_dpcd_writeb(tunnel->aux, DP_REQUEST_BW, request_bw) < 0) {
+		err = -EIO;
+		goto out;
+	}
+
+	timeout = msecs_to_jiffies(3000);
+	add_wait_queue(&mgr->bw_req_queue, &wait);
+
+	for (;;) {
+		bool status_changed;
+
+		err = bw_req_complete(tunnel->aux, &status_changed);
+		if (err != -EAGAIN)
+			break;
+
+		if (status_changed) {
+			struct drm_dp_tunnel_regs regs;
+
+			err = read_and_verify_tunnel_regs(tunnel, &regs,
+							  ALLOW_ALLOCATED_BW_CHANGE);
+			if (err)
+				break;
+		}
+
+		if (!timeout) {
+			err = -ETIMEDOUT;
+			break;
+		}
+
+		timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE, timeout);
+	};
+
+	remove_wait_queue(&mgr->bw_req_queue, &wait);
+
+	if (err)
+		goto out;
+
+	tunnel->allocated_bw = request_bw * tunnel->bw_granularity;
+
+out:
+	tun_dbg_stat(tunnel, err, "Allocating %d/%d Mb/s for tunnel: Group alloc:%d/%d Mb/s",
+		     DPTUN_BW_ARG(request_bw * tunnel->bw_granularity),
+		     DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
+		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
+		     DPTUN_BW_ARG(tunnel->group->available_bw));
+
+	if (err == -EIO)
+		drm_dp_tunnel_set_io_error(tunnel);
+
+	return err;
+}
+
+/**
+ * drm_dp_tunnel_alloc_bw - Allocate BW for a DP tunnel
+ * @tunnel: Tunnel object
+ * @bw: BW in kB/s units
+ *
+ * Allocate @bw kB/s for @tunnel. The allocated BW must be freed after use by
+ * calling this function for the same tunnel setting @bw to 0.
+ *
+ * Returns 0 in case of success, a negative error code otherwise.
+ */
+int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
+{
+	int err;
+
+	err = check_tunnel(tunnel);
+	if (err)
+		return err;
+
+	return allocate_tunnel_bw(tunnel, bw);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_alloc_bw);
+
+/**
+ * drm_dp_tunnel_atomic_get_allocated_bw - Get the BW allocated for a DP tunnel
+ * @tunnel: Tunnel object
+ *
+ * Get the current BW allocated for @tunnel. After the tunnel is created /
+ * resumed and the BW allocation mode is enabled for it, the allocation
+ * becomes determined only after the first allocation request by the driver
+ * calling drm_dp_tunnel_alloc_bw().
+ *
+ * Return the BW allocated for the tunnel, or -1 if the allocation is
+ * undetermined.
+ */
+int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->allocated_bw;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_get_allocated_bw);
+
+static int check_and_clear_status_change(struct drm_dp_tunnel *tunnel)
+{
+	u8 mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED;
+	u8 val;
+
+	if (drm_dp_dpcd_readb(tunnel->aux, DP_TUNNELING_STATUS, &val) < 0)
+		goto out_err;
+
+	val &= mask;
+
+	if (val) {
+		if (drm_dp_dpcd_writeb(tunnel->aux, DP_TUNNELING_STATUS, val) < 0)
+			goto out_err;
+
+		return 1;
+	}
+
+	if (!drm_dp_tunnel_bw_alloc_is_enabled(tunnel))
+		return 0;
+
+	/*
+	 * Check for estimated BW changes explicitly to account for lost
+	 * BW change notifications.
+	 */
+	if (drm_dp_dpcd_readb(tunnel->aux, DP_ESTIMATED_BW, &val) < 0)
+		goto out_err;
+
+	if (val * tunnel->bw_granularity != tunnel->estimated_bw)
+		return 1;
+
+	return 0;
+
+out_err:
+	drm_dp_tunnel_set_io_error(tunnel);
+
+	return -EIO;
+}
+
+/**
+ * drm_dp_tunnel_update_state - Update DP tunnel SW state with the HW state
+ * @tunnel: Tunnel object
+ *
+ * Update the SW state of @tunnel with the HW state.
+ *
+ * Returns 0 if the state has not changed, 1 if it has changed and got updated
+ * successfully and a negative error code otherwise.
+ */
+int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_regs regs;
+	bool changed = false;
+	int ret;
+
+	ret = check_tunnel(tunnel);
+	if (ret < 0)
+		return ret;
+
+	ret = check_and_clear_status_change(tunnel);
+	if (ret < 0)
+		goto out;
+
+	if (!ret)
+		return 0;
+
+	ret = read_and_verify_tunnel_regs(tunnel, &regs, 0);
+	if (ret)
+		goto out;
+
+	if (update_dprx_caps(tunnel, &regs))
+		changed = true;
+
+	ret = update_group_available_bw(tunnel, &regs);
+	if (ret == 1)
+		changed = true;
+
+out:
+	tun_dbg_stat(tunnel, ret < 0 ? ret : 0,
+		     "State update: Changed:%s DPRX:%dx%d Tunnel alloc:%d/%d Group alloc:%d/%d Mb/s",
+		     str_yes_no(changed),
+		     tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
+		     DPTUN_BW_ARG(tunnel->allocated_bw),
+		     DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
+		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
+		     DPTUN_BW_ARG(tunnel->group->available_bw));
+
+	if (ret < 0)
+		return ret;
+
+	if (changed)
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_update_state);
+
+/*
+ * drm_dp_tunnel_handle_irq - Handle DP tunnel IRQs
+ *
+ * Handle any pending DP tunnel IRQs, waking up waiters for a completion
+ * event.
+ *
+ * Returns 1 if the state of the tunnel has changed which requires calling
+ * drm_dp_tunnel_update_state(), a negative error code in case of a failure,
+ * 0 otherwise.
+ */
+int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_aux *aux)
+{
+	u8 val;
+
+	if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
+		return -EIO;
+
+	if (val & (DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED))
+		wake_up_all(&mgr->bw_req_queue);
+
+	if (val & (DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED))
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_handle_irq);
+
+/**
+ * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's DPRX
+ * @tunnel: Tunnel object
+ *
+ * The function is used to query the maximum link rate of the DPRX connected
+ * to @tunnel. Note that this rate will not be limited by the BW limit of the
+ * tunnel, as opposed to the standard and extended DP_MAX_LINK_RATE DPCD
+ * registers.
+ *
+ * Returns the maximum link rate in 10 kbit/s units.
+ */
+int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->max_dprx_rate;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_rate);
+
+/**
+ * drm_dp_tunnel_max_dprx_lane_count - Query the maximum lane count of the tunnel's DPRX
+ * @tunnel: Tunnel object
+ *
+ * The function is used to query the maximum lane count of the DPRX connected
+ * to @tunnel. Note that this lane count will not be limited by the BW limit of
+ * the tunnel, as opposed to the standard and extended DP_MAX_LANE_COUNT DPCD
+ * registers.
+ *
+ * Returns the maximum lane count.
+ */
+int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->max_dprx_lane_count;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_lane_count);
+
+/**
+ * drm_dp_tunnel_available_bw - Query the estimated total available BW of the tunnel
+ * @tunnel: Tunnel object
+ *
+ * This function is used to query the estimated total available BW of the
+ * tunnel. This includes the currently allocated and free BW for all the
+ * tunnels in @tunnel's group. The available BW is valid only after the BW
+ * allocation mode has been enabled for the tunnel and its state got updated
+ * calling drm_dp_tunnel_update_state().
+ *
+ * Returns the @tunnel group's estimated total available bandwidth in kB/s
+ * units, or -1 if the available BW isn't valid (the BW allocation mode is
+ * not enabled or the tunnel's state hasn't been updated).
+ */
+int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->group->available_bw;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_available_bw);
+
+static struct drm_dp_tunnel_group_state *
+drm_dp_tunnel_atomic_get_group_state(struct drm_atomic_state *state,
+				     const struct drm_dp_tunnel *tunnel)
+{
+	return (struct drm_dp_tunnel_group_state *)
+		drm_atomic_get_private_obj_state(state,
+						 &tunnel->group->base);
+}
+
+static struct drm_dp_tunnel_state *
+add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
+		 struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	tun_dbg_atomic(tunnel,
+		       "Adding state for tunnel %p to group state %p\n",
+		       tunnel, group_state);
+
+	tunnel_state = kzalloc(sizeof(*tunnel_state), GFP_KERNEL);
+	if (!tunnel_state)
+		return NULL;
+
+	tunnel_state->group_state = group_state;
+
+	drm_dp_tunnel_ref_get(tunnel, &tunnel_state->tunnel_ref);
+
+	INIT_LIST_HEAD(&tunnel_state->node);
+	list_add(&tunnel_state->node, &group_state->tunnel_states);
+
+	return tunnel_state;
+}
+
+static void free_tunnel_state(struct drm_dp_tunnel_state *tunnel_state)
+{
+	tun_dbg_atomic(tunnel_state->tunnel_ref.tunnel,
+		       "Freeing state for tunnel %p\n",
+		       tunnel_state->tunnel_ref.tunnel);
+
+	list_del(&tunnel_state->node);
+
+	kfree(tunnel_state->stream_bw);
+	drm_dp_tunnel_ref_put(&tunnel_state->tunnel_ref);
+
+	kfree(tunnel_state);
+}
+
+static void free_group_state(struct drm_dp_tunnel_group_state *group_state)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+	struct drm_dp_tunnel_state *tunnel_state_tmp;
+
+	for_each_tunnel_state_safe(group_state, tunnel_state, tunnel_state_tmp)
+		free_tunnel_state(tunnel_state);
+
+	kfree(group_state);
+}
+
+static struct drm_dp_tunnel_state *
+get_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
+		 const struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	for_each_tunnel_state(group_state, tunnel_state)
+		if (tunnel_state->tunnel_ref.tunnel == tunnel)
+			return tunnel_state;
+
+	return NULL;
+}
+
+static struct drm_dp_tunnel_state *
+get_or_add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
+			struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	tunnel_state = get_tunnel_state(group_state, tunnel);
+	if (tunnel_state)
+		return tunnel_state;
+
+	return add_tunnel_state(group_state, tunnel);
+}
+
+static struct drm_private_state *
+tunnel_group_duplicate_state(struct drm_private_obj *obj)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
+	if (!group_state)
+		return NULL;
+
+	INIT_LIST_HEAD(&group_state->tunnel_states);
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &group_state->base);
+
+	for_each_tunnel_state(to_group_state(obj->state), tunnel_state) {
+		struct drm_dp_tunnel_state *new_tunnel_state;
+
+		new_tunnel_state = get_or_add_tunnel_state(group_state,
+							   tunnel_state->tunnel_ref.tunnel);
+		if (!new_tunnel_state)
+			goto out_free_state;
+
+		new_tunnel_state->stream_mask = tunnel_state->stream_mask;
+		new_tunnel_state->stream_bw = kmemdup(tunnel_state->stream_bw,
+						      sizeof(*tunnel_state->stream_bw) *
+							hweight32(tunnel_state->stream_mask),
+						      GFP_KERNEL);
+
+		if (!new_tunnel_state->stream_bw)
+			goto out_free_state;
+	}
+
+	return &group_state->base;
+
+out_free_state:
+	free_group_state(group_state);
+
+	return NULL;
+}
+
+static void tunnel_group_destroy_state(struct drm_private_obj *obj, struct drm_private_state *state)
+{
+	free_group_state(to_group_state(state));
+}
+
+static const struct drm_private_state_funcs tunnel_group_funcs = {
+	.atomic_duplicate_state = tunnel_group_duplicate_state,
+	.atomic_destroy_state = tunnel_group_destroy_state,
+};
+
+/**
+ * drm_dp_tunnel_atomic_get_state - get/allocate the new atomic state for a tunnel
+ * @state: Atomic state
+ * @tunnel: Tunnel to get the state for
+ *
+ * Get the new atomic state for @tunnel, duplicating it from the old tunnel
+ * state if not yet allocated.
+ *
+ * Return the state or an ERR_PTR() error on failure.
+ */
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
+			       struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
+	if (IS_ERR(group_state))
+		return ERR_CAST(group_state);
+
+	tunnel_state = get_or_add_tunnel_state(group_state, tunnel);
+	if (!tunnel_state)
+		return ERR_PTR(-ENOMEM);
+
+	return tunnel_state;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_state);
+
+/**
+ * drm_dp_tunnel_atomic_get_old_state - get the old atomic state for a tunnel
+ * @state: Atomic state
+ * @tunnel: Tunnel to get the state for
+ *
+ * Get the old atomic state for @tunnel.
+ *
+ * Return the old state or NULL if the tunnel's atomic state is not in @state.
+ */
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group_state *old_group_state;
+	int i;
+
+	for_each_old_group_in_state(state, old_group_state, i)
+		if (to_group(old_group_state->base.obj) == tunnel->group)
+			return get_tunnel_state(old_group_state, tunnel);
+
+	return NULL;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_old_state);
+
+/**
+ * drm_dp_tunnel_atomic_get_new_state - get the new atomic state for a tunnel
+ * @state: Atomic state
+ * @tunnel: Tunnel to get the state for
+ *
+ * Get the new atomic state for @tunnel.
+ *
+ * Return the new state or NULL if the tunnel's atomic state is not in @state.
+ */
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group_state *new_group_state;
+	int i;
+
+	for_each_new_group_in_state(state, new_group_state, i)
+		if (to_group(new_group_state->base.obj) == tunnel->group)
+			return get_tunnel_state(new_group_state, tunnel);
+
+	return NULL;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_new_state);
+
+static bool init_group(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_tunnel_group *group)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+
+	group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
+	if (!group_state)
+		return false;
+
+	INIT_LIST_HEAD(&group_state->tunnel_states);
+
+	group->mgr = mgr;
+	group->available_bw = -1;
+	INIT_LIST_HEAD(&group->tunnels);
+
+	drm_atomic_private_obj_init(mgr->dev, &group->base, &group_state->base,
+				    &tunnel_group_funcs);
+
+	return true;
+}
+
+static void cleanup_group(struct drm_dp_tunnel_group *group)
+{
+	drm_atomic_private_obj_fini(&group->base);
+}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state *group_state)
+{
+	const struct drm_dp_tunnel_state *tunnel_state;
+	u32 stream_mask = 0;
+
+	for_each_tunnel_state(group_state, tunnel_state) {
+		drm_WARN(to_group(group_state->base.obj)->mgr->dev,
+			 tunnel_state->stream_mask & stream_mask,
+			 "[DPTUN %s]: conflicting stream IDs %x (IDs in other tunnels %x)\n",
+			 tunnel_state->tunnel_ref.tunnel->name,
+			 tunnel_state->stream_mask,
+			 stream_mask);
+
+		stream_mask |= tunnel_state->stream_mask;
+	}
+}
+#else
+static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state *group_state)
+{
+}
+#endif
+
+static int stream_id_to_idx(u32 stream_mask, u8 stream_id)
+{
+	return hweight32(stream_mask & (BIT(stream_id) - 1));
+}
+
+static int resize_bw_array(struct drm_dp_tunnel_state *tunnel_state,
+			   unsigned long old_mask, unsigned long new_mask)
+{
+	unsigned long move_mask = old_mask & new_mask;
+	int *new_bws = NULL;
+	int id;
+
+	WARN_ON(!new_mask);
+
+	if (old_mask == new_mask)
+		return 0;
+
+	new_bws = kcalloc(hweight32(new_mask), sizeof(*new_bws), GFP_KERNEL);
+	if (!new_bws)
+		return -ENOMEM;
+
+	for_each_set_bit(id, &move_mask, BITS_PER_TYPE(move_mask))
+		new_bws[stream_id_to_idx(new_mask, id)] =
+			tunnel_state->stream_bw[stream_id_to_idx(old_mask, id)];
+
+	kfree(tunnel_state->stream_bw);
+	tunnel_state->stream_bw = new_bws;
+	tunnel_state->stream_mask = new_mask;
+
+	return 0;
+}
+
+static int set_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
+			 u8 stream_id, int bw)
+{
+	int err;
+
+	err = resize_bw_array(tunnel_state,
+			      tunnel_state->stream_mask,
+			      tunnel_state->stream_mask | BIT(stream_id));
+	if (err)
+		return err;
+
+	tunnel_state->stream_bw[stream_id_to_idx(tunnel_state->stream_mask, stream_id)] = bw;
+
+	return 0;
+}
+
+static int clear_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
+			   u8 stream_id)
+{
+	if (!(tunnel_state->stream_mask & ~BIT(stream_id))) {
+		free_tunnel_state(tunnel_state);
+		return 0;
+	}
+
+	return resize_bw_array(tunnel_state,
+			       tunnel_state->stream_mask,
+			       tunnel_state->stream_mask & ~BIT(stream_id));
+}
+
+/**
+ * drm_dp_tunnel_atomic_set_stream_bw - Set the BW for a DP tunnel stream
+ * @state: Atomic state
+ * @tunnel: DP tunnel containing the stream
+ * @stream_id: Stream ID
+ * @bw: BW of the stream
+ *
+ * Set a DP tunnel stream's required BW in the atomic state.
+ *
+ * Returns 0 in case of success, a negative error code otherwise.
+ */
+int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
+				       struct drm_dp_tunnel *tunnel,
+				       u8 stream_id, int bw)
+{
+	struct drm_dp_tunnel_group_state *new_group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+	int err;
+
+	if (drm_WARN_ON(tunnel->group->mgr->dev,
+			stream_id > BITS_PER_TYPE(tunnel_state->stream_mask)))
+		return -EINVAL;
+
+	tun_dbg(tunnel,
+		"Setting %d Mb/s for stream %d\n",
+		DPTUN_BW_ARG(bw), stream_id);
+
+	new_group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
+	if (IS_ERR(new_group_state))
+		return PTR_ERR(new_group_state);
+
+	if (bw == 0) {
+		tunnel_state = get_tunnel_state(new_group_state, tunnel);
+		if (!tunnel_state)
+			return 0;
+
+		return clear_stream_bw(tunnel_state, stream_id);
+	}
+
+	tunnel_state = get_or_add_tunnel_state(new_group_state, tunnel);
+	if (drm_WARN_ON(state->dev, !tunnel_state))
+		return -EINVAL;
+
+	err = set_stream_bw(tunnel_state, stream_id, bw);
+	if (err)
+		return err;
+
+	check_unique_stream_ids(new_group_state);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_set_stream_bw);
+
+/**
+ * drm_dp_tunnel_atomic_get_required_bw - Get the BW required by a DP tunnel
+ * @tunnel_state: Atomic state of the queried tunnel
+ *
+ * Calculate the BW required by a tunnel adding up the required BW of all
+ * the streams in the tunnel.
+ *
+ * Return the total BW required by the tunnel.
+ */
+int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state *tunnel_state)
+{
+	int tunnel_bw = 0;
+	int i;
+
+	if (!tunnel_state || !tunnel_state->stream_mask)
+		return 0;
+
+	for (i = 0; i < hweight32(tunnel_state->stream_mask); i++)
+		tunnel_bw += tunnel_state->stream_bw[i];
+
+	return tunnel_bw;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_required_bw);
+
+/**
+ * drm_dp_tunnel_atomic_get_group_streams_in_state - Get mask of stream IDs in a group
+ * @state: Atomic state
+ * @tunnel: Tunnel object
+ * @stream_mask: Mask of streams in @tunnel's group
+ *
+ * Get the mask of all the stream IDs in the tunnel group of @tunnel.
+ *
+ * Return 0 in case of success - with the stream IDs in @stream_mask - or a
+ * negative error code in case of failure.
+ */
+int drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state *state,
+						    const struct drm_dp_tunnel *tunnel,
+						    u32 *stream_mask)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
+	if (IS_ERR(group_state))
+		return PTR_ERR(group_state);
+
+	*stream_mask = 0;
+	for_each_tunnel_state(group_state, tunnel_state)
+		*stream_mask |= tunnel_state->stream_mask;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_group_streams_in_state);
+
+static int
+drm_dp_tunnel_atomic_check_group_bw(struct drm_dp_tunnel_group_state *new_group_state,
+				    u32 *failed_stream_mask)
+{
+	struct drm_dp_tunnel_group *group = to_group(new_group_state->base.obj);
+	struct drm_dp_tunnel_state *new_tunnel_state;
+	u32 group_stream_mask = 0;
+	int group_bw = 0;
+
+	for_each_tunnel_state(new_group_state, new_tunnel_state) {
+		struct drm_dp_tunnel *tunnel = new_tunnel_state->tunnel_ref.tunnel;
+		int max_dprx_bw = get_max_dprx_bw(tunnel);
+		int tunnel_bw = drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
+
+		tun_dbg(tunnel,
+			"%sRequired %d/%d Mb/s total for tunnel.\n",
+			tunnel_bw > max_dprx_bw ? "Not enough BW: " : "",
+			DPTUN_BW_ARG(tunnel_bw),
+			DPTUN_BW_ARG(max_dprx_bw));
+
+		if (tunnel_bw > max_dprx_bw) {
+			*failed_stream_mask = new_tunnel_state->stream_mask;
+			return -ENOSPC;
+		}
+
+		group_bw += min(roundup(tunnel_bw, tunnel->bw_granularity),
+				max_dprx_bw);
+		group_stream_mask |= new_tunnel_state->stream_mask;
+	}
+
+	tun_grp_dbg(group,
+		    "%sRequired %d/%d Mb/s total for tunnel group.\n",
+		    group_bw > group->available_bw ? "Not enough BW: " : "",
+		    DPTUN_BW_ARG(group_bw),
+		    DPTUN_BW_ARG(group->available_bw));
+
+	if (group_bw > group->available_bw) {
+		*failed_stream_mask = group_stream_mask;
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+
+/**
+ * drm_dp_tunnel_atomic_check_stream_bws - Check BW limit for all streams in state
+ * @state: Atomic state
+ * @failed_stream_mask: Mask of stream IDs with a BW limit failure
+ *
+ * Check the required BW of each DP tunnel in @state against both the DPRX BW
+ * limit of the tunnel and the BW limit of the tunnel group. Return a mask of
+ * stream IDs in @failed_stream_mask once a check fails. The mask will contain
+ * either all the streams in a tunnel (in case a DPRX BW limit check failed) or
+ * all the streams in a tunnel group (in case a group BW limit check failed).
+ *
+ * Return 0 if all the BW limit checks passed, -ENOSPC in case a BW limit
+ * check failed - with @failed_stream_mask containing the streams failing the
+ * check - or a negative error code otherwise.
+ */
+int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
+					  u32 *failed_stream_mask)
+{
+	struct drm_dp_tunnel_group_state *new_group_state;
+	int i;
+
+	for_each_new_group_in_state(state, new_group_state, i) {
+		int ret;
+
+		ret = drm_dp_tunnel_atomic_check_group_bw(new_group_state,
+							  failed_stream_mask);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_check_stream_bws);
+
+static void destroy_mgr(struct drm_dp_tunnel_mgr *mgr)
+{
+	int i;
+
+	for (i = 0; i < mgr->group_count; i++) {
+		cleanup_group(&mgr->groups[i]);
+		drm_WARN_ON(mgr->dev, !list_empty(&mgr->groups[i].tunnels));
+	}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	ref_tracker_dir_exit(&mgr->ref_tracker);
+#endif
+
+	kfree(mgr->groups);
+	kfree(mgr);
+}
+
+/**
+ * drm_dp_tunnel_mgr_create - Create a DP tunnel manager
+ * @dev: DRM device object
+ *
+ * Creates a DP tunnel manager for @dev.
+ *
+ * Returns a pointer to the tunnel manager if created successfully or NULL in
+ * case of an error.
+ */
+struct drm_dp_tunnel_mgr *
+drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
+{
+	struct drm_dp_tunnel_mgr *mgr;
+	int i;
+
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+	if (!mgr)
+		return NULL;
+
+	mgr->dev = dev;
+	init_waitqueue_head(&mgr->bw_req_queue);
+
+	mgr->groups = kcalloc(max_group_count, sizeof(*mgr->groups), GFP_KERNEL);
+	if (!mgr->groups) {
+		kfree(mgr);
+
+		return NULL;
+	}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	ref_tracker_dir_init(&mgr->ref_tracker, 16, "dptun");
+#endif
+
+	for (i = 0; i < max_group_count; i++) {
+		if (!init_group(mgr, &mgr->groups[i])) {
+			destroy_mgr(mgr);
+
+			return NULL;
+		}
+
+		mgr->group_count++;
+	}
+
+	return mgr;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_mgr_create);
+
+/**
+ * drm_dp_tunnel_mgr_destroy - Destroy DP tunnel manager
+ * @mgr: Tunnel manager object
+ *
+ * Destroy the tunnel manager.
+ */
+void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr)
+{
+	destroy_mgr(mgr);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_mgr_destroy);
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 281afff6ee4e5..8bfd5d007be8d 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1382,6 +1382,66 @@
 #define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET	0x69494
 #define DP_HDCP_2_2_REG_DBG_OFFSET		0x69518
 
+/* DP-tunneling */
+#define DP_TUNNELING_OUI				0xe0000
+#define  DP_TUNNELING_OUI_BYTES				3
+
+#define DP_TUNNELING_DEV_ID				0xe0003
+#define  DP_TUNNELING_DEV_ID_BYTES			6
+
+#define DP_TUNNELING_HW_REV				0xe0009
+#define  DP_TUNNELING_HW_REV_MAJOR_SHIFT		4
+#define  DP_TUNNELING_HW_REV_MAJOR_MASK			(0xf << DP_TUNNELING_HW_REV_MAJOR_SHIFT)
+#define  DP_TUNNELING_HW_REV_MINOR_SHIFT		0
+#define  DP_TUNNELING_HW_REV_MINOR_MASK			(0xf << DP_TUNNELING_HW_REV_MINOR_SHIFT)
+
+#define DP_TUNNELING_SW_REV_MAJOR			0xe000a
+#define DP_TUNNELING_SW_REV_MINOR			0xe000b
+
+#define DP_TUNNELING_CAPABILITIES			0xe000d
+#define  DP_IN_BW_ALLOCATION_MODE_SUPPORT		(1 << 7)
+#define  DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT		(1 << 6)
+#define  DP_TUNNELING_SUPPORT				(1 << 0)
+
+#define DP_IN_ADAPTER_INFO				0xe000e
+#define  DP_IN_ADAPTER_NUMBER_BITS			7
+#define  DP_IN_ADAPTER_NUMBER_MASK			((1 << DP_IN_ADAPTER_NUMBER_BITS) - 1)
+
+#define DP_USB4_DRIVER_ID				0xe000f
+#define  DP_USB4_DRIVER_ID_BITS				4
+#define  DP_USB4_DRIVER_ID_MASK				((1 << DP_USB4_DRIVER_ID_BITS) - 1)
+
+#define DP_USB4_DRIVER_BW_CAPABILITY			0xe0020
+#define  DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT	(1 << 7)
+
+#define DP_IN_ADAPTER_TUNNEL_INFORMATION		0xe0021
+#define  DP_GROUP_ID_BITS				3
+#define  DP_GROUP_ID_MASK				((1 << DP_GROUP_ID_BITS) - 1)
+
+#define DP_BW_GRANULARITY				0xe0022
+#define  DP_BW_GRANULARITY_MASK				0x3
+
+#define DP_ESTIMATED_BW					0xe0023
+#define DP_ALLOCATED_BW					0xe0024
+
+#define DP_TUNNELING_STATUS				0xe0025
+#define  DP_BW_ALLOCATION_CAPABILITY_CHANGED		(1 << 3)
+#define  DP_ESTIMATED_BW_CHANGED			(1 << 2)
+#define  DP_BW_REQUEST_SUCCEEDED			(1 << 1)
+#define  DP_BW_REQUEST_FAILED				(1 << 0)
+
+#define DP_TUNNELING_MAX_LINK_RATE			0xe0028
+
+#define DP_TUNNELING_MAX_LANE_COUNT			0xe0029
+#define  DP_TUNNELING_MAX_LANE_COUNT_MASK		0x1f
+
+#define DP_DPTX_BW_ALLOCATION_MODE_CONTROL		0xe0030
+#define  DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE	(1 << 7)
+#define  DP_UNMASK_BW_ALLOCATION_IRQ			(1 << 6)
+
+#define DP_REQUEST_BW					0xe0031
+#define  MAX_DP_REQUEST_BW				255
+
 /* LTTPR: Link Training (LT)-tunable PHY Repeaters */
 #define DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV 0xf0000 /* 1.3 */
 #define DP_MAX_LINK_RATE_PHY_REPEATER			    0xf0001 /* 1.4a */
diff --git a/include/drm/display/drm_dp_tunnel.h b/include/drm/display/drm_dp_tunnel.h
new file mode 100644
index 0000000000000..476252021f15c
--- /dev/null
+++ b/include/drm/display/drm_dp_tunnel.h
@@ -0,0 +1,248 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __DRM_DP_TUNNEL_H__
+#define __DRM_DP_TUNNEL_H__
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct drm_dp_aux;
+
+struct drm_device;
+
+struct drm_atomic_state;
+struct drm_dp_tunnel_mgr;
+struct drm_dp_tunnel_state;
+
+struct ref_tracker;
+
+struct drm_dp_tunnel_ref {
+	struct drm_dp_tunnel *tunnel;
+	struct ref_tracker *tracker;
+};
+
+#ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL
+
+struct drm_dp_tunnel *
+drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker);
+
+void
+drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker);
+
+static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
+					 struct drm_dp_tunnel_ref *tunnel_ref)
+{
+	tunnel_ref->tunnel = drm_dp_tunnel_get(tunnel, &tunnel_ref->tracker);
+}
+
+static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
+{
+	drm_dp_tunnel_put(tunnel_ref->tunnel, &tunnel_ref->tracker);
+}
+
+struct drm_dp_tunnel *
+drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
+		     struct drm_dp_aux *aux);
+int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel);
+
+int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel);
+bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw);
+int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel);
+
+void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel);
+
+int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
+			     struct drm_dp_aux *aux);
+
+int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel);
+
+const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel);
+
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
+			       struct drm_dp_tunnel *tunnel);
+
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel);
+
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel);
+
+int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
+				       struct drm_dp_tunnel *tunnel,
+				       u8 stream_id, int bw);
+int drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state *state,
+						    const struct drm_dp_tunnel *tunnel,
+						    u32 *stream_mask);
+
+int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
+					  u32 *failed_stream_mask);
+
+int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state *tunnel_state);
+
+struct drm_dp_tunnel_mgr *
+drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count);
+void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr);
+
+#else
+
+static inline struct drm_dp_tunnel *
+drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker)
+{
+	return NULL;
+}
+
+static inline void
+drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker) {}
+
+static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
+					 struct drm_dp_tunnel_ref *tunnel_ref) {}
+
+static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref) {}
+
+static inline struct drm_dp_tunnel *
+drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
+		     struct drm_dp_aux *aux)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int
+drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
+{
+	return 0;
+}
+
+static inline int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel)
+{
+	return false;
+}
+
+static inline int
+drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
+{
+	return -1;
+}
+
+static inline int
+drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel) {}
+
+static inline int
+drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
+			 struct drm_dp_aux *aux)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
+{
+	return 0;
+}
+
+static inline int
+drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
+{
+	return 0;
+}
+
+static inline int
+drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return -1;
+}
+
+static inline const char *
+drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
+{
+	return NULL;
+}
+
+static inline struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
+			       struct drm_dp_tunnel *tunnel)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int
+drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
+				   struct drm_dp_tunnel *tunnel,
+				   u8 stream_id, int bw)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state *state,
+						const struct drm_dp_tunnel *tunnel,
+						u32 *stream_mask)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
+				      u32 *failed_stream_mask)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state *tunnel_state)
+{
+	return 0;
+}
+
+static inline struct drm_dp_tunnel_mgr *
+drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline
+void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr) {}
+
+
+#endif /* CONFIG_DRM_DISPLAY_DP_TUNNEL */
+
+#endif /* __DRM_DP_TUNNEL_H__ */
-- 
2.39.2


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

* [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during system resume
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
  2024-02-20 21:18 ` [PATCH v2 01/21] drm/dp: Add drm_dp_max_dprx_data_rate() Imre Deak
  2024-02-20 21:18 ` [PATCH v2 02/21] drm/dp: Add support for DP tunneling Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23  6:38   ` Shankar, Uma
  2024-02-20 21:18 ` [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to retry modesets Imre Deak
                   ` (29 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel

The system resume display mode restoration should happen with an output
configuration matching that of the suspend time saved mode. Since the
restored mode configuration is subject to the bpp fallback logic,
starting out with an unlimited bpp and reducing the bpp as required by
any (MST) link BW limit, the resulting bpp will match the one during
suspend only if the BW limit checks during suspend and resume are
applied in an identical way. The latter is not guaranteed at the moment,
since the pre-suspend MST topology may not be in place during resume
(for instance if the MST sink was disconnected while being suspended),
which makes the MST link BW check accept the unlimited bpp mode
configuration unconditionally without ensuring that the required BW fits
into the available MST link BW.

To fix the above, initialize the bpp fallback logic with the max link
bpp / force-FEC limits left behind by the suspend time mode save.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c |  3 +--
 drivers/gpu/drm/i915/display/intel_link_bw.c | 22 ++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_link_bw.h |  2 +-
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 00ac65a140298..485c38d71f106 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6252,12 +6252,11 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
 
 static int intel_atomic_check_config_and_link(struct intel_atomic_state *state)
 {
-	struct drm_i915_private *i915 = to_i915(state->base.dev);
 	struct intel_link_bw_limits new_limits;
 	struct intel_link_bw_limits old_limits;
 	int ret;
 
-	intel_link_bw_init_limits(i915, &new_limits);
+	intel_link_bw_init_limits(state, &new_limits);
 	old_limits = new_limits;
 
 	while (true) {
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c
index 9c6d35a405a18..27ea858897c9f 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
@@ -6,6 +6,7 @@
 #include "i915_drv.h"
 
 #include "intel_atomic.h"
+#include "intel_crtc.h"
 #include "intel_display_types.h"
 #include "intel_dp_mst.h"
 #include "intel_fdi.h"
@@ -13,19 +14,32 @@
 
 /**
  * intel_link_bw_init_limits - initialize BW limits
- * @i915: device instance
+ * @state: Atomic state
  * @limits: link BW limits
  *
  * Initialize @limits.
  */
-void intel_link_bw_init_limits(struct drm_i915_private *i915, struct intel_link_bw_limits *limits)
+void intel_link_bw_init_limits(struct intel_atomic_state *state,
+			       struct intel_link_bw_limits *limits)
 {
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
 	enum pipe pipe;
 
 	limits->force_fec_pipes = 0;
 	limits->bpp_limit_reached_pipes = 0;
-	for_each_pipe(i915, pipe)
-		limits->max_bpp_x16[pipe] = INT_MAX;
+	for_each_pipe(i915, pipe) {
+		const struct intel_crtc_state *crtc_state =
+			intel_atomic_get_new_crtc_state(state,
+							intel_crtc_for_pipe(i915, pipe));
+
+		if (state->base.duplicated && crtc_state) {
+			limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
+			if (crtc_state->fec_enable)
+				limits->force_fec_pipes |= BIT(pipe);
+		} else {
+			limits->max_bpp_x16[pipe] = INT_MAX;
+		}
+	}
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.h b/drivers/gpu/drm/i915/display/intel_link_bw.h
index 2cf57307cc249..6b0ccfff59dab 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.h
@@ -22,7 +22,7 @@ struct intel_link_bw_limits {
 	int max_bpp_x16[I915_MAX_PIPES];
 };
 
-void intel_link_bw_init_limits(struct drm_i915_private *i915,
+void intel_link_bw_init_limits(struct intel_atomic_state *state,
 			       struct intel_link_bw_limits *limits);
 int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
 			     struct intel_link_bw_limits *limits,
-- 
2.39.2


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

* [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to retry modesets
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (2 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during system resume Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23  7:59   ` Shankar, Uma
  2024-02-20 21:18 ` [PATCH v2 05/21] drm/i915/dp: Use drm_dp_max_dprx_data_rate() Imre Deak
                   ` (28 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Jouni Högander

On shared (Thunderbolt) links with DP tunnels, the modeset may need to
be retried on all connectors on the link due to a link BW limitation
arising only after the atomic check phase. To support this add a helper
function queuing a work to retry the modeset on a given port's connector
and at the same time any MST connector with streams through the same
port. A follow-up change enabling the DP tunnel Bandwidth Allocation
Mode will take this into use.

v2:
- Send the uevent only to enabled MST connectors. (Jouni)

Cc: Jouni Högander <jouni.hogander@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  |  5 ++-
 drivers/gpu/drm/i915/display/intel_dp.c       | 45 ++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp.h       |  6 +++
 .../drm/i915/display/intel_dp_link_training.c |  3 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  2 +
 5 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 485c38d71f106..2ee26d19c200b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8085,8 +8085,9 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915)
 	/* Kill all the work that may have been queued by hpd. */
 	drm_connector_list_iter_begin(&i915->drm, &conn_iter);
 	for_each_intel_connector_iter(connector, &conn_iter) {
-		if (connector->modeset_retry_work.func)
-			cancel_work_sync(&connector->modeset_retry_work);
+		if (connector->modeset_retry_work.func &&
+		    cancel_work_sync(&connector->modeset_retry_work))
+			drm_connector_put(&connector->base);
 		if (connector->hdcp.shim) {
 			cancel_delayed_work_sync(&connector->hdcp.check_work);
 			cancel_work_sync(&connector->hdcp.prop_work);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 217196196e50a..88606e336a920 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2842,6 +2842,40 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
 					intel_dp_is_uhbr(pipe_config);
 }
 
+void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
+{
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
+
+	drm_connector_get(&connector->base);
+	if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work))
+		drm_connector_put(&connector->base);
+}
+
+void
+intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
+				      struct intel_encoder *encoder,
+				      const struct intel_crtc_state *crtc_state)
+{
+	struct intel_connector *connector;
+	struct intel_digital_connector_state *conn_state;
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	int i;
+
+	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
+		intel_dp_queue_modeset_retry_work(intel_dp->attached_connector);
+
+		return;
+	}
+
+	for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
+		if (!conn_state->base.crtc)
+			continue;
+
+		if (connector->mst_port == intel_dp)
+			intel_dp_queue_modeset_retry_work(connector);
+	}
+}
+
 int
 intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_state *pipe_config,
@@ -6441,6 +6475,14 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
 	mutex_unlock(&connector->dev->mode_config.mutex);
 	/* Send Hotplug uevent so userspace can reprobe */
 	drm_kms_helper_connector_hotplug_event(connector);
+
+	drm_connector_put(connector);
+}
+
+void intel_dp_init_modeset_retry_work(struct intel_connector *connector)
+{
+	INIT_WORK(&connector->modeset_retry_work,
+		  intel_dp_modeset_retry_work_fn);
 }
 
 bool
@@ -6457,8 +6499,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
 	int type;
 
 	/* Initialize the work for modeset in case of link train failure */
-	INIT_WORK(&intel_connector->modeset_retry_work,
-		  intel_dp_modeset_retry_work_fn);
+	intel_dp_init_modeset_retry_work(intel_connector);
 
 	if (drm_WARN(dev, dig_port->max_lanes < 1,
 		     "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 530cc97bc42f4..e2875e03afba0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -43,6 +43,12 @@ void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
 bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state);
 int intel_dp_min_bpp(enum intel_output_format output_format);
+void intel_dp_init_modeset_retry_work(struct intel_connector *connector);
+void intel_dp_queue_modeset_retry_work(struct intel_connector *connector);
+void
+intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
+				      struct intel_encoder *encoder,
+				      const struct intel_crtc_state *crtc_state);
 bool intel_dp_init_connector(struct intel_digital_port *dig_port,
 			     struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 1abfafbbfa757..7b140cbf8dd31 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1075,7 +1075,6 @@ static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
 						     const struct intel_crtc_state *crtc_state)
 {
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
 	if (!intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) {
 		lt_dbg(intel_dp, DP_PHY_DPRX, "Link Training failed on disconnected sink.\n");
@@ -1093,7 +1092,7 @@ static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
 	}
 
 	/* Schedule a Hotplug Uevent to userspace to start modeset */
-	queue_work(i915->unordered_wq, &intel_connector->modeset_retry_work);
+	intel_dp_queue_modeset_retry_work(intel_connector);
 }
 
 /* Perform the link training on all LTTPRs and the DPRX on a link. */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 5307ddd4edcf5..c685b64bb7810 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1546,6 +1546,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
 	intel_connector->port = port;
 	drm_dp_mst_get_port_malloc(port);
 
+	intel_dp_init_modeset_retry_work(intel_connector);
+
 	intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port);
 	intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector);
 	intel_connector->dp.dsc_hblank_expansion_quirk =
-- 
2.39.2


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

* [PATCH v2 05/21] drm/i915/dp: Use drm_dp_max_dprx_data_rate()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (3 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to retry modesets Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 06/21] drm/i915/dp: Factor out intel_dp_config_required_rate() Imre Deak
                   ` (27 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Instead of intel_dp_max_data_rate() use the equivalent
drm_dp_max_dprx_data_rate() which was copied from the former one in a
previous patch.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c |  2 +-
 drivers/gpu/drm/i915/display/intel_dp.c      | 62 +++-----------------
 drivers/gpu/drm/i915/display/intel_dp.h      |  1 -
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  2 +-
 4 files changed, 10 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 2ee26d19c200b..e1a4200f67a7e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2478,7 +2478,7 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes,
 	u32 link_symbol_clock = intel_dp_link_symbol_clock(link_clock);
 	u32 data_m = intel_dp_effective_data_rate(pixel_clock, bits_per_pixel_x16,
 						  bw_overhead);
-	u32 data_n = intel_dp_max_data_rate(link_clock, nlanes);
+	u32 data_n = drm_dp_max_dprx_data_rate(link_clock, nlanes);
 
 	/*
 	 * Windows/BIOS uses fixed M/N values always. Follow suit.
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 88606e336a920..0a2ee43392142 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -383,52 +383,6 @@ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
 				1000000 * 16 * 8);
 }
 
-/*
- * Given a link rate and lanes, get the data bandwidth.
- *
- * Data bandwidth is the actual payload rate, which depends on the data
- * bandwidth efficiency and the link rate.
- *
- * For 8b/10b channel encoding, SST and non-FEC, the data bandwidth efficiency
- * is 80%. For example, for a 1.62 Gbps link, 1.62*10^9 bps * 0.80 * (1/8) =
- * 162000 kBps. With 8-bit symbols, we have 162000 kHz symbol clock. Just by
- * coincidence, the port clock in kHz matches the data bandwidth in kBps, and
- * they equal the link bit rate in Gbps multiplied by 100000. (Note that this no
- * longer holds for data bandwidth as soon as FEC or MST is taken into account!)
- *
- * For 128b/132b channel encoding, the data bandwidth efficiency is 96.71%. For
- * example, for a 10 Gbps link, 10*10^9 bps * 0.9671 * (1/8) = 1208875
- * kBps. With 32-bit symbols, we have 312500 kHz symbol clock. The value 1000000
- * does not match the symbol clock, the port clock (not even if you think in
- * terms of a byte clock), nor the data bandwidth. It only matches the link bit
- * rate in units of 10000 bps.
- */
-int
-intel_dp_max_data_rate(int max_link_rate, int max_lanes)
-{
-	int ch_coding_efficiency =
-		drm_dp_bw_channel_coding_efficiency(drm_dp_is_uhbr_rate(max_link_rate));
-	int max_link_rate_kbps = max_link_rate * 10;
-
-	/*
-	 * UHBR rates always use 128b/132b channel encoding, and have
-	 * 97.71% data bandwidth efficiency. Consider max_link_rate the
-	 * link bit rate in units of 10000 bps.
-	 */
-	/*
-	 * Lower than UHBR rates always use 8b/10b channel encoding, and have
-	 * 80% data bandwidth efficiency for SST non-FEC. However, this turns
-	 * out to be a nop by coincidence:
-	 *
-	 *	int max_link_rate_kbps = max_link_rate * 10;
-	 *	max_link_rate_kbps = DIV_ROUND_DOWN_ULL(max_link_rate_kbps * 8, 10);
-	 *	max_link_rate = max_link_rate_kbps / 8;
-	 */
-	return DIV_ROUND_DOWN_ULL(mul_u32_u32(max_link_rate_kbps * max_lanes,
-					      ch_coding_efficiency),
-				  1000000 * 8);
-}
-
 bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -658,7 +612,7 @@ static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
 	int mode_rate, max_rate;
 
 	mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
-	max_rate = intel_dp_max_data_rate(link_rate, lane_count);
+	max_rate = drm_dp_max_dprx_data_rate(link_rate, lane_count);
 	if (mode_rate > max_rate)
 		return false;
 
@@ -1262,7 +1216,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
-	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+	max_rate = drm_dp_max_dprx_data_rate(max_link_clock, max_lanes);
 	mode_rate = intel_dp_link_required(target_clock,
 					   intel_dp_mode_min_output_bpp(connector, mode));
 
@@ -1612,8 +1566,8 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
 			for (lane_count = limits->min_lane_count;
 			     lane_count <= limits->max_lane_count;
 			     lane_count <<= 1) {
-				link_avail = intel_dp_max_data_rate(link_rate,
-								    lane_count);
+				link_avail = drm_dp_max_dprx_data_rate(link_rate,
+								       lane_count);
 
 				if (mode_rate <= link_avail) {
 					pipe_config->lane_count = lane_count;
@@ -2467,8 +2421,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			    "DP link rate required %i available %i\n",
 			    intel_dp_link_required(adjusted_mode->crtc_clock,
 						   to_bpp_int_roundup(pipe_config->dsc.compressed_bpp_x16)),
-			    intel_dp_max_data_rate(pipe_config->port_clock,
-						   pipe_config->lane_count));
+			    drm_dp_max_dprx_data_rate(pipe_config->port_clock,
+						      pipe_config->lane_count));
 	} else {
 		drm_dbg_kms(&i915->drm, "DP lane count %d clock %d bpp %d\n",
 			    pipe_config->lane_count, pipe_config->port_clock,
@@ -2478,8 +2432,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			    "DP link rate required %i available %i\n",
 			    intel_dp_link_required(adjusted_mode->crtc_clock,
 						   pipe_config->pipe_bpp),
-			    intel_dp_max_data_rate(pipe_config->port_clock,
-						   pipe_config->lane_count));
+			    drm_dp_max_dprx_data_rate(pipe_config->port_clock,
+						      pipe_config->lane_count));
 	}
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e2875e03afba0..20252984b3b04 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -111,7 +111,6 @@ bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
 int intel_dp_link_required(int pixel_clock, int bpp);
 int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
 				 int bw_overhead);
-int intel_dp_max_data_rate(int max_link_rate, int max_lanes);
 bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp);
 bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index c685b64bb7810..b4d4bb90126e9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1299,7 +1299,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
-	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+	max_rate = drm_dp_max_dprx_data_rate(max_link_clock, max_lanes);
 	mode_rate = intel_dp_link_required(mode->clock, min_bpp);
 
 	ret = drm_modeset_lock(&mgr->base.lock, ctx);
-- 
2.39.2


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

* [PATCH v2 06/21] drm/i915/dp: Factor out intel_dp_config_required_rate()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (4 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 05/21] drm/i915/dp: Use drm_dp_max_dprx_data_rate() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 07/21] drm/i915/dp: Export intel_dp_max_common_rate/lane_count() Imre Deak
                   ` (26 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Factor out intel_dp_config_required_rate() used by a follow-up patch
enabling the DP tunnel BW allocation mode.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 43 +++++++++++--------------
 drivers/gpu/drm/i915/display/intel_dp.h |  1 +
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 0a2ee43392142..c7e3e4efc324e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2343,6 +2343,17 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
 						       limits);
 }
 
+int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state)
+{
+	const struct drm_display_mode *adjusted_mode =
+		&crtc_state->hw.adjusted_mode;
+	int bpp = crtc_state->dsc.compression_enable ?
+		to_bpp_int_roundup(crtc_state->dsc.compressed_bpp_x16) :
+		crtc_state->pipe_bpp;
+
+	return intel_dp_link_required(adjusted_mode->crtc_clock, bpp);
+}
+
 static int
 intel_dp_compute_link_config(struct intel_encoder *encoder,
 			     struct intel_crtc_state *pipe_config,
@@ -2410,31 +2421,15 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			return ret;
 	}
 
-	if (pipe_config->dsc.compression_enable) {
-		drm_dbg_kms(&i915->drm,
-			    "DP lane count %d clock %d Input bpp %d Compressed bpp " BPP_X16_FMT "\n",
-			    pipe_config->lane_count, pipe_config->port_clock,
-			    pipe_config->pipe_bpp,
-			    BPP_X16_ARGS(pipe_config->dsc.compressed_bpp_x16));
+	drm_dbg_kms(&i915->drm,
+		    "DP lane count %d clock %d bpp input %d compressed " BPP_X16_FMT " link rate required %d available %d\n",
+		    pipe_config->lane_count, pipe_config->port_clock,
+		    pipe_config->pipe_bpp,
+		    BPP_X16_ARGS(pipe_config->dsc.compressed_bpp_x16),
+		    intel_dp_config_required_rate(pipe_config),
+		    drm_dp_max_dprx_data_rate(pipe_config->port_clock,
+					      pipe_config->lane_count));
 
-		drm_dbg_kms(&i915->drm,
-			    "DP link rate required %i available %i\n",
-			    intel_dp_link_required(adjusted_mode->crtc_clock,
-						   to_bpp_int_roundup(pipe_config->dsc.compressed_bpp_x16)),
-			    drm_dp_max_dprx_data_rate(pipe_config->port_clock,
-						      pipe_config->lane_count));
-	} else {
-		drm_dbg_kms(&i915->drm, "DP lane count %d clock %d bpp %d\n",
-			    pipe_config->lane_count, pipe_config->port_clock,
-			    pipe_config->pipe_bpp);
-
-		drm_dbg_kms(&i915->drm,
-			    "DP link rate required %i available %i\n",
-			    intel_dp_link_required(adjusted_mode->crtc_clock,
-						   pipe_config->pipe_bpp),
-			    drm_dp_max_dprx_data_rate(pipe_config->port_clock,
-						      pipe_config->lane_count));
-	}
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 20252984b3b04..4667870fed31a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -100,6 +100,7 @@ void intel_dp_mst_suspend(struct drm_i915_private *dev_priv);
 void intel_dp_mst_resume(struct drm_i915_private *dev_priv);
 int intel_dp_max_link_rate(struct intel_dp *intel_dp);
 int intel_dp_max_lane_count(struct intel_dp *intel_dp);
+int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state);
 int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
 
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
-- 
2.39.2


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

* [PATCH v2 07/21] drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (5 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 06/21] drm/i915/dp: Factor out intel_dp_config_required_rate() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 08/21] drm/i915/dp: Factor out intel_dp_update_sink_caps() Imre Deak
                   ` (25 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Export intel_dp_max_common_rate() and intel_dp_max_lane_count() used by
a follow-up patch enabling the DP tunnel BW allocation mode.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 4 ++--
 drivers/gpu/drm/i915/display/intel_dp.h | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index c7e3e4efc324e..20e04cbdffcae 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -309,7 +309,7 @@ static int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
 }
 
 /* Theoretical max between source and sink */
-static int intel_dp_max_common_rate(struct intel_dp *intel_dp)
+int intel_dp_max_common_rate(struct intel_dp *intel_dp)
 {
 	return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1);
 }
@@ -326,7 +326,7 @@ static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
 }
 
 /* Theoretical max between source and sink */
-static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
+int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	int source_max = intel_dp_max_source_lane_count(dig_port);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 4667870fed31a..ee0600b4425e1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -102,6 +102,8 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp);
 int intel_dp_max_lane_count(struct intel_dp *intel_dp);
 int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state);
 int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
+int intel_dp_max_common_rate(struct intel_dp *intel_dp);
+int intel_dp_max_common_lane_count(struct intel_dp *intel_dp);
 
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   u8 *link_bw, u8 *rate_select);
-- 
2.39.2


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

* [PATCH v2 08/21] drm/i915/dp: Factor out intel_dp_update_sink_caps()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (6 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 07/21] drm/i915/dp: Export intel_dp_max_common_rate/lane_count() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 09/21] drm/i915/dp: Factor out intel_dp_read_dprx_caps() Imre Deak
                   ` (24 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Factor out a function updating the sink's link rate and lane count
capabilities, used by a follow-up patch enabling the DP tunnel BW
allocation mode.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 11 ++++++++---
 drivers/gpu/drm/i915/display/intel_dp.h |  1 +
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 20e04cbdffcae..520c04245c2df 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3944,6 +3944,13 @@ intel_dp_has_sink_count(struct intel_dp *intel_dp)
 					  &intel_dp->desc);
 }
 
+void intel_dp_update_sink_caps(struct intel_dp *intel_dp)
+{
+	intel_dp_set_sink_rates(intel_dp);
+	intel_dp_set_max_sink_lane_count(intel_dp);
+	intel_dp_set_common_rates(intel_dp);
+}
+
 static bool
 intel_dp_get_dpcd(struct intel_dp *intel_dp)
 {
@@ -3960,9 +3967,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
 		drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
 				 drm_dp_is_branch(intel_dp->dpcd));
 
-		intel_dp_set_sink_rates(intel_dp);
-		intel_dp_set_max_sink_lane_count(intel_dp);
-		intel_dp_set_common_rates(intel_dp);
+		intel_dp_update_sink_caps(intel_dp);
 	}
 
 	if (intel_dp_has_sink_count(intel_dp)) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index ee0600b4425e1..10e859b62bbe9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -104,6 +104,7 @@ int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state);
 int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
 int intel_dp_max_common_rate(struct intel_dp *intel_dp);
 int intel_dp_max_common_lane_count(struct intel_dp *intel_dp);
+void intel_dp_update_sink_caps(struct intel_dp *intel_dp);
 
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   u8 *link_bw, u8 *rate_select);
-- 
2.39.2


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

* [PATCH v2 09/21] drm/i915/dp: Factor out intel_dp_read_dprx_caps()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (7 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 08/21] drm/i915/dp: Factor out intel_dp_update_sink_caps() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 10/21] drm/i915/dp: Add intel_dp_max_link_data_rate() Imre Deak
                   ` (23 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Factor out a function to read the sink's DPRX capabilities used by a
follow-up patch enabling the DP tunnel BW allocation mode.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 .../drm/i915/display/intel_dp_link_training.c | 30 +++++++++++++++----
 .../drm/i915/display/intel_dp_link_training.h |  1 +
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 7b140cbf8dd31..fb84ca98bb7ab 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -162,6 +162,28 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
 	return lttpr_count;
 }
 
+int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+	if (intel_dp_is_edp(intel_dp))
+		return 0;
+
+	/*
+	 * Detecting LTTPRs must be avoided on platforms with an AUX timeout
+	 * period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1).
+	 */
+	if (DISPLAY_VER(i915) >= 10 && !IS_GEMINILAKE(i915))
+		if (drm_dp_dpcd_probe(&intel_dp->aux,
+				      DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV))
+			return -EIO;
+
+	if (drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd))
+		return -EIO;
+
+	return 0;
+}
+
 /**
  * intel_dp_init_lttpr_and_dprx_caps - detect LTTPR and DPRX caps, init the LTTPR link training mode
  * @intel_dp: Intel DP struct
@@ -192,12 +214,10 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
 	if (!intel_dp_is_edp(intel_dp) &&
 	    (DISPLAY_VER(i915) >= 10 && !IS_GEMINILAKE(i915))) {
 		u8 dpcd[DP_RECEIVER_CAP_SIZE];
+		int err = intel_dp_read_dprx_caps(intel_dp, dpcd);
 
-		if (drm_dp_dpcd_probe(&intel_dp->aux, DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV))
-			return -EIO;
-
-		if (drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd))
-			return -EIO;
+		if (err != 0)
+			return err;
 
 		lttpr_count = intel_dp_init_lttpr(intel_dp, dpcd);
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 2c8f2775891b0..19836a8a4f904 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -11,6 +11,7 @@
 struct intel_crtc_state;
 struct intel_dp;
 
+int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE]);
 int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
 
 void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
-- 
2.39.2


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

* [PATCH v2 10/21] drm/i915/dp: Add intel_dp_max_link_data_rate()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (8 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 09/21] drm/i915/dp: Factor out intel_dp_read_dprx_caps() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits Imre Deak
                   ` (22 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Add intel_dp_max_link_data_rate() to get the link BW vs. the sink DPRX
BW used by a follow-up patch enabling the DP tunnel BW allocation mode.
The link BW can be below the DPRX BW due to a BW limitation on a link
shared by multiple sinks.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c     | 32 +++++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp.h     |  2 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  3 +-
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 520c04245c2df..d9e75922ff8f5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -383,6 +383,22 @@ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
 				1000000 * 16 * 8);
 }
 
+/**
+ * intel_dp_max_link_data_rate: Calculate the maximum rate for the given link params
+ * @intel_dp: Intel DP object
+ * @max_dprx_rate: Maximum data rate of the DPRX
+ * @max_dprx_lanes: Maximum lane count of the DPRX
+ *
+ * Calculate the maximum data rate for the provided link parameters.
+ *
+ * Returns the maximum data rate in kBps units.
+ */
+int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
+				int max_dprx_rate, int max_dprx_lanes)
+{
+	return drm_dp_max_dprx_data_rate(max_dprx_rate, max_dprx_lanes);
+}
+
 bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -612,7 +628,7 @@ static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
 	int mode_rate, max_rate;
 
 	mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
-	max_rate = drm_dp_max_dprx_data_rate(link_rate, lane_count);
+	max_rate = intel_dp_max_link_data_rate(intel_dp, link_rate, lane_count);
 	if (mode_rate > max_rate)
 		return false;
 
@@ -1216,7 +1232,8 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
-	max_rate = drm_dp_max_dprx_data_rate(max_link_clock, max_lanes);
+	max_rate = intel_dp_max_link_data_rate(intel_dp, max_link_clock, max_lanes);
+
 	mode_rate = intel_dp_link_required(target_clock,
 					   intel_dp_mode_min_output_bpp(connector, mode));
 
@@ -1566,8 +1583,10 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
 			for (lane_count = limits->min_lane_count;
 			     lane_count <= limits->max_lane_count;
 			     lane_count <<= 1) {
-				link_avail = drm_dp_max_dprx_data_rate(link_rate,
-								       lane_count);
+				link_avail = intel_dp_max_link_data_rate(intel_dp,
+									 link_rate,
+									 lane_count);
+
 
 				if (mode_rate <= link_avail) {
 					pipe_config->lane_count = lane_count;
@@ -2427,8 +2446,9 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 		    pipe_config->pipe_bpp,
 		    BPP_X16_ARGS(pipe_config->dsc.compressed_bpp_x16),
 		    intel_dp_config_required_rate(pipe_config),
-		    drm_dp_max_dprx_data_rate(pipe_config->port_clock,
-					      pipe_config->lane_count));
+		    intel_dp_max_link_data_rate(intel_dp,
+						pipe_config->port_clock,
+						pipe_config->lane_count));
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 10e859b62bbe9..564a587e2d018 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -115,6 +115,8 @@ bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
 int intel_dp_link_required(int pixel_clock, int bpp);
 int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
 				 int bw_overhead);
+int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
+				int max_dprx_rate, int max_dprx_lanes);
 bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp);
 bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b4d4bb90126e9..4b6c8ff974297 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1299,7 +1299,8 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
-	max_rate = drm_dp_max_dprx_data_rate(max_link_clock, max_lanes);
+	max_rate = intel_dp_max_link_data_rate(intel_dp,
+					       max_link_clock, max_lanes);
 	mode_rate = intel_dp_link_required(mode->clock, min_bpp);
 
 	ret = drm_modeset_lock(&mgr->base.lock, ctx);
-- 
2.39.2


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

* [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (9 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 10/21] drm/i915/dp: Add intel_dp_max_link_data_rate() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23  8:10   ` Shankar, Uma
                     ` (2 more replies)
  2024-02-20 21:18 ` [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation Imre Deak
                   ` (21 subsequent siblings)
  32 siblings, 3 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Ville Syrjälä

Add a way to get the active pipes through a given DP port by syncing
against a related pending non-blocking commit. Atm
intel_dp_get_active_pipes() will only try to sync a given pipe and if
that would block ignore the pipe. A follow-up change enabling the DP
tunnel BW allocation mode will need to ensure that all active pipes are
returned.

This change will use intel_crtc_state::uapi.commit instead of the
corresponding commit in the connector state. This shouldn't make a
difference, since the two commit objects match for an active pipe.

A follow-up patchset will remove syncing during TC port reset, which
should reset a port/pipe even if syncing against a commit would block.
Syncing OTOH is not needed there, since the commit used for the reset
implies a sync already. For now add a TODO comment for this.

v2:
- Add a separate function to try-sync the pipes. (Ville)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_crtc.c | 27 +++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_crtc.h |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   |  6 ++---
 drivers/gpu/drm/i915/display/intel_tc.c   |  7 ++++++
 4 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 25593f6aae7de..17ed2e62cc66a 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -654,3 +654,30 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
 out:
 	intel_psr_unlock(new_crtc_state);
 }
+
+/**
+ * intel_crtc_try_sync_pipes - Try syncing pending commits on a set of pipes
+ * @i915: i915 device object
+ * @pipe_mask: Mask of pipes to sync
+ *
+ * Try to sync a pending non-blocking commit for the provided pipes in
+ * @pipe_mask. The commit won't be synced if this would block.
+ *
+ * Return a mask of the pipes that got synced or didn't need syncing.
+ */
+u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask)
+{
+	struct intel_crtc *crtc;
+	u32 synced = 0;
+
+	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
+		const struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+
+		if (!crtc_state->uapi.commit ||
+		    try_wait_for_completion(&crtc_state->uapi.commit->hw_done))
+			synced |= BIT(crtc->pipe);
+	}
+
+	return synced;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
index 22d7993d1f0ba..71a5b93166da7 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.h
+++ b/drivers/gpu/drm/i915/display/intel_crtc.h
@@ -47,5 +47,6 @@ struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
 void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
 				     enum pipe pipe);
 void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
+u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
 
 #endif
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d9e75922ff8f5..d0452d3e534a7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5048,10 +5048,6 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
 		if (!crtc_state->hw.active)
 			continue;
 
-		if (conn_state->commit &&
-		    !try_wait_for_completion(&conn_state->commit->hw_done))
-			continue;
-
 		*pipe_mask |= BIT(crtc->pipe);
 	}
 	drm_connector_list_iter_end(&conn_iter);
@@ -5091,6 +5087,8 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
 	if (ret)
 		return ret;
 
+	pipe_mask &= intel_crtc_try_sync_pipes(dev_priv, pipe_mask);
+
 	if (pipe_mask == 0)
 		return 0;
 
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 6b374d481cd9e..14d17903a81f5 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -7,6 +7,7 @@
 #include "i915_reg.h"
 #include "intel_atomic.h"
 #include "intel_cx0_phy_regs.h"
+#include "intel_crtc.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
 #include "intel_display.h"
@@ -1663,6 +1664,12 @@ static int reset_link_commit(struct intel_tc_port *tc,
 	if (ret)
 		return ret;
 
+	/*
+	 * TODO: remove the following, since an output must be reset
+	 * even if we had to wait for a non-blocking commit on a pipe.
+	 */
+	pipe_mask &= intel_crtc_try_sync_pipes(i915, pipe_mask);
+
 	if (!pipe_mask)
 		return 0;
 
-- 
2.39.2


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

* [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (10 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 21:37   ` Ville Syrjälä
                     ` (2 more replies)
  2024-02-20 21:18 ` [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check BW limit Imre Deak
                   ` (20 subsequent siblings)
  32 siblings, 3 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Ville Syrjälä

Add support to enable the DP tunnel BW allocation mode. Follow-up
patches will call the required helpers added here to prepare for a
modeset on a link with DP tunnels, the last change in the patchset
actually enabling BWA.

With BWA enabled, the driver will expose the full mode list a display
supports, regardless of any BW limitation on a shared (Thunderbolt)
link. Such BW limits will be checked against only during a modeset, when
the driver has the full knowledge of each display's BW requirement.

If the link BW changes in a way that a connector's modelist may also
change, userspace will get a hotplug notification for all the connectors
sharing the same link (so it can adjust the mode used for a display).

The BW limitation can change at any point, asynchronously to modesets
on a given connector, so a modeset can fail even though the atomic check
for it passed. In such scenarios userspace will get a bad link
notification and in response is supposed to retry the modeset.

v2:
- Fix old vs. new connector state in intel_dp_tunnel_atomic_check_state().
  (Ville)
- Fix propagating the error from
  intel_dp_tunnel_atomic_compute_stream_bw(). (Ville)
- Move tunnel==NULL checks from driver to DRM core helpers. (Ville)
- Simplify return flow from intel_dp_tunnel_detect(). (Ville)
- s/dp_tunnel_state/inherited_dp_tunnels (Ville)
- Simplify struct intel_dp_tunnel_inherited_state. (Ville)
- Unconstify object pointers (vs. states) where possible. (Ville)
- Init crtc_state while declaring it in check_group_state(). (Ville)
- Join obj->base.id, obj->name arg lines in debug prints to reduce LOC.
  (Ville)
- Add/rework intel_dp_tunnel_atomic_alloc_bw() to prepare for moving the
  BW allocation from encoder hooks up to intel_atomic_commit_tail()
  later in the patchset.
- Disable BW alloc mode during system suspend.
- Allocate the required BW for all tunnels during system resume.
- Add intel_dp_tunnel_atomic_clear_stream_bw() instead of the open-coded
  sequence in a follow-up patch.
- Add function documentation to all exported functions.
- Add CONFIG_USB4 dependency to CONFIG_DRM_I915_DP_TUNNEL.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/Kconfig                  |  14 +
 drivers/gpu/drm/i915/Kconfig.debug            |   1 +
 drivers/gpu/drm/i915/Makefile                 |   3 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |   2 +
 drivers/gpu/drm/i915/display/intel_crtc.c     |  25 +
 drivers/gpu/drm/i915/display/intel_crtc.h     |   1 +
 .../gpu/drm/i915/display/intel_display_core.h |   1 +
 .../drm/i915/display/intel_display_types.h    |   9 +
 .../gpu/drm/i915/display/intel_dp_tunnel.c    | 815 ++++++++++++++++++
 .../gpu/drm/i915/display/intel_dp_tunnel.h    | 133 +++
 10 files changed, 1004 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 3089029abba48..5932024f8f954 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -155,6 +155,20 @@ config DRM_I915_PXP
 	  protected session and manage the status of the alive software session,
 	  as well as its life cycle.
 
+config DRM_I915_DP_TUNNEL
+	bool "Enable DP tunnel support"
+	depends on DRM_I915
+	depends on USB4
+	select DRM_DISPLAY_DP_TUNNEL
+	default y
+	help
+	  Choose this option to detect DP tunnels and enable the Bandwidth
+	  Allocation mode for such tunnels. This allows using the maximum
+	  resolution allowed by the link BW on all displays sharing the
+	  link BW, for instance on a Thunderbolt link.
+
+	  If in doubt, say "Y".
+
 menu "drm/i915 Debugging"
 depends on DRM_I915
 depends on EXPERT
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 5b7162076850c..bc18e2d9ea05d 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -28,6 +28,7 @@ config DRM_I915_DEBUG
 	select STACKDEPOT
 	select STACKTRACE
 	select DRM_DP_AUX_CHARDEV
+	select DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE if DRM_I915_DP_TUNNEL
 	select X86_MSR # used by igt/pm_rpm
 	select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
 	select DRM_DEBUG_MM if DRM=y
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c13f14edb5088..3ef6ed41e62b4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -369,6 +369,9 @@ i915-y += \
 	display/vlv_dsi.o \
 	display/vlv_dsi_pll.o
 
+i915-$(CONFIG_DRM_I915_DP_TUNNEL) += \
+	display/intel_dp_tunnel.o
+
 i915-y += \
 	i915_perf.o
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index ec0d5168b5035..96ab37e158995 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -29,6 +29,7 @@
  * See intel_atomic_plane.c for the plane-specific atomic functionality.
  */
 
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_fourcc.h>
@@ -38,6 +39,7 @@
 #include "intel_atomic.h"
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
+#include "intel_dp_tunnel.h"
 #include "intel_global_state.h"
 #include "intel_hdcp.h"
 #include "intel_psr.h"
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 17ed2e62cc66a..8224400b5b72c 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -681,3 +681,28 @@ u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask)
 
 	return synced;
 }
+
+/**
+ * intel_crtc_sync_pipes - Sync pending commits on a set of pipes
+ * @i915: i915 device object
+ * @pipe_mask: Mask of pipes to sync
+ *
+ * Sync a pending non-blocking commit for the provided pipes in
+ * @pipe_mask.
+ */
+void intel_crtc_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask)
+{
+	struct intel_crtc *crtc;
+
+	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
+		const struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+		bool synced = true;
+
+		if (crtc_state->uapi.commit)
+			synced = wait_for_completion_timeout(&crtc_state->uapi.commit->hw_done,
+							     msecs_to_jiffies(5000));
+
+		drm_WARN_ON(&i915->drm, !synced);
+	}
+}
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
index 71a5b93166da7..ffee73b8df74e 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.h
+++ b/drivers/gpu/drm/i915/display/intel_crtc.h
@@ -48,5 +48,6 @@ void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
 				     enum pipe pipe);
 void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
 u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
+void intel_crtc_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
 
 #endif
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index fdeaac994e17b..2167dbee5eea7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -524,6 +524,7 @@ struct intel_display {
 	} wq;
 
 	/* Grouping using named structs. Keep sorted. */
+	struct drm_dp_tunnel_mgr *dp_tunnel_mgr;
 	struct intel_audio audio;
 	struct intel_dpll dpll;
 	struct intel_fbc *fbc[I915_MAX_FBCS];
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 578763e202c01..601e7f88e6c61 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -33,6 +33,7 @@
 
 #include <drm/display/drm_dp_dual_mode_helper.h>
 #include <drm/display/drm_dp_mst_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/display/drm_dsc.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_crtc.h>
@@ -678,6 +679,8 @@ struct intel_atomic_state {
 
 	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
 
+	struct intel_dp_tunnel_inherited_state *inherited_dp_tunnels;
+
 	/*
 	 * Current watermarks can't be trusted during hardware readout, so
 	 * don't bother calculating intermediate watermarks.
@@ -1375,6 +1378,9 @@ struct intel_crtc_state {
 		struct drm_dsc_config config;
 	} dsc;
 
+	/* DP tunnel used for BW allocation. */
+	struct drm_dp_tunnel_ref dp_tunnel_ref;
+
 	/* HSW+ linetime watermarks */
 	u16 linetime;
 	u16 ips_linetime;
@@ -1785,6 +1791,9 @@ struct intel_dp {
 	/* connector directly attached - won't be use for modeset in mst world */
 	struct intel_connector *attached_connector;
 
+	struct drm_dp_tunnel *tunnel;
+	bool tunnel_suspended:1;
+
 	/* mst connector list */
 	struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
 	struct drm_dp_mst_topology_mgr mst_mgr;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
new file mode 100644
index 0000000000000..fd639ded853ae
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
@@ -0,0 +1,815 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include "i915_drv.h"
+
+#include <drm/display/drm_dp_tunnel.h>
+
+#include "intel_atomic.h"
+#include "intel_crtc.h"
+#include "intel_display_limits.h"
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_dp_link_training.h"
+#include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
+#include "intel_link_bw.h"
+
+struct intel_dp_tunnel_inherited_state {
+	struct drm_dp_tunnel_ref ref[I915_MAX_PIPES];
+};
+
+/**
+ * intel_dp_tunnel_disconnect - Disconnect a DP tunnel from a port
+ * @intel_dp: DP port object the tunnel is connected to
+ *
+ * Disconnect a DP tunnel from @intel_dp, destroying any related state. This
+ * should be called after detecting a sink-disconnect event from the port.
+ */
+void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp)
+{
+	drm_dp_tunnel_destroy(intel_dp->tunnel);
+	intel_dp->tunnel = NULL;
+}
+
+/**
+ * intel_dp_tunnel_destroy - Destroy a DP tunnel
+ * @intel_dp: DP port object the tunnel is connected to
+ *
+ * Destroy a DP tunnel connected to @intel_dp, after disabling the BW
+ * allocation mode on the tunnel. This should be called while destroying the
+ * port.
+ */
+void intel_dp_tunnel_destroy(struct intel_dp *intel_dp)
+{
+	if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		drm_dp_tunnel_disable_bw_alloc(intel_dp->tunnel);
+
+	intel_dp_tunnel_disconnect(intel_dp);
+}
+
+static int kbytes_to_mbits(int kbytes)
+{
+	return DIV_ROUND_UP(kbytes * 8, 1000);
+}
+
+static int get_current_link_bw(struct intel_dp *intel_dp,
+			       bool *below_dprx_bw)
+{
+	int rate = intel_dp_max_common_rate(intel_dp);
+	int lane_count = intel_dp_max_common_lane_count(intel_dp);
+	int bw;
+
+	bw = intel_dp_max_link_data_rate(intel_dp, rate, lane_count);
+	*below_dprx_bw = bw < drm_dp_max_dprx_data_rate(rate, lane_count);
+
+	return bw;
+}
+
+static int update_tunnel_state(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	bool old_bw_below_dprx;
+	bool new_bw_below_dprx;
+	int old_bw;
+	int new_bw;
+	int ret;
+
+	old_bw = get_current_link_bw(intel_dp, &old_bw_below_dprx);
+
+	ret = drm_dp_tunnel_update_state(intel_dp->tunnel);
+	if (ret < 0) {
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s] State update failed (err %pe)\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    ERR_PTR(ret));
+
+		return ret;
+	}
+
+	if (ret == 0 ||
+	    !drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel))
+		return 0;
+
+	intel_dp_update_sink_caps(intel_dp);
+
+	new_bw = get_current_link_bw(intel_dp, &new_bw_below_dprx);
+
+	/* Suppress the notification if the mode list can't change due to bw. */
+	if (old_bw_below_dprx == new_bw_below_dprx &&
+	    !new_bw_below_dprx)
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][ENCODER:%d:%s] Notify users about BW change: %d -> %d\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    encoder->base.base.id, encoder->base.name,
+		    kbytes_to_mbits(old_bw), kbytes_to_mbits(new_bw));
+
+	return 1;
+}
+
+/*
+ * Allocate the BW for a tunnel on a DP connector/port if the connector/port
+ * was already active when detecting the tunnel. The allocated BW must be
+ * freed by the next atomic modeset, storing the BW in the
+ * intel_atomic_state::inherited_dp_tunnels, and calling
+ * intel_dp_tunnel_atomic_free_bw().
+ */
+static int allocate_initial_tunnel_bw_for_pipes(struct intel_dp *intel_dp, u8 pipe_mask)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct intel_crtc *crtc;
+	int tunnel_bw = 0;
+	int err;
+
+	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
+		const struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+		int stream_bw = intel_dp_config_required_rate(crtc_state);
+
+		tunnel_bw += stream_bw;
+
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s][CRTC:%d:%s] Initial BW for stream %d: %d/%d Mb/s\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    crtc->base.base.id, crtc->base.name,
+			    crtc->pipe,
+			    kbytes_to_mbits(stream_bw), kbytes_to_mbits(tunnel_bw));
+	}
+
+	err = drm_dp_tunnel_alloc_bw(intel_dp->tunnel, tunnel_bw);
+	if (err) {
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s] Initial BW allocation failed (err %pe)\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    ERR_PTR(err));
+
+		return err;
+	}
+
+	return update_tunnel_state(intel_dp);
+}
+
+static int allocate_initial_tunnel_bw(struct intel_dp *intel_dp,
+				      struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	u8 pipe_mask;
+	int err;
+
+	err = intel_dp_get_active_pipes(intel_dp, ctx, &pipe_mask);
+	if (err)
+		return err;
+
+	intel_crtc_sync_pipes(i915, pipe_mask);
+
+	return allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask);
+}
+
+static int detect_new_tunnel(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct drm_dp_tunnel *tunnel;
+	int ret;
+
+	tunnel = drm_dp_tunnel_detect(i915->display.dp_tunnel_mgr,
+					&intel_dp->aux);
+	if (IS_ERR(tunnel))
+		return PTR_ERR(tunnel);
+
+	intel_dp->tunnel = tunnel;
+
+	ret = drm_dp_tunnel_enable_bw_alloc(intel_dp->tunnel);
+	if (ret) {
+		if (ret == -EOPNOTSUPP)
+			return 0;
+
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s] Failed to enable BW allocation mode (ret %pe)\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    ERR_PTR(ret));
+
+		/* Keep the tunnel with BWA disabled */
+		return 0;
+	}
+
+	ret = allocate_initial_tunnel_bw(intel_dp, ctx);
+	if (ret < 0)
+		intel_dp_tunnel_destroy(intel_dp);
+
+	return ret;
+}
+
+/**
+ * intel_dp_tunnel_detect - Detect a DP tunnel on a port
+ * @intel_dp: DP port object
+ * @ctx: lock context acquired by the connector detection handler
+ *
+ * Detect a DP tunnel on the @intel_dp port, enabling the BW allocation mode
+ * on it if supported and allocating the BW required on an already active port.
+ * The BW allocated this way must be freed by the next atomic modeset calling
+ * intel_dp_tunnel_atomic_free_bw().
+ *
+ * If @intel_dp has already a tunnel detected on it, update the tunnel's state
+ * wrt. its support for BW allocation mode and the available BW via the
+ * tunnel. If the tunnel's state change requires this - for instance the
+ * tunnel's group ID has changed - the tunnel will be dropped and recreated.
+ *
+ * Return 0 in case of success - after any tunnel detected and added to
+ * @intel_dp - 1 in case the BW on an already existing tunnel has changed in a
+ * way that requires notifying user space.
+ */
+int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
+{
+	int ret;
+
+	if (intel_dp_is_edp(intel_dp))
+		return 0;
+
+	if (intel_dp->tunnel) {
+		ret = update_tunnel_state(intel_dp);
+		if (ret >= 0)
+			return ret;
+
+		/* Try to recreate the tunnel after an update error. */
+		intel_dp_tunnel_destroy(intel_dp);
+	}
+
+	return detect_new_tunnel(intel_dp, ctx);
+}
+
+/**
+ * intel_dp_tunnel_bw_alloc_is_enabled - Query the BW allocation support on a tunnel
+ * @intel_dp: DP port object
+ *
+ * Query whether a DP tunnel is connected on @intel_dp and the tunnel supports
+ * the BW allocation mode.
+ *
+ * Returns %true if the BW allocation mode is supported on @intel_dp.
+ */
+bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp)
+{
+	return drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel);
+}
+
+/**
+ * intel_dp_tunnel_suspend - Suspend a DP tunnel connected on a port
+ * @intel_dp: DP port object
+ *
+ * Suspend a DP tunnel on @intel_dp with BW allocation mode enabled on it.
+ */
+void intel_dp_tunnel_suspend(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+
+	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return;
+
+	drm_dbg_kms(&i915->drm, "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Suspend\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name);
+
+	drm_dp_tunnel_disable_bw_alloc(intel_dp->tunnel);
+
+	intel_dp->tunnel_suspended = true;
+}
+
+/**
+ * intel_dp_tunnel_resume - Resume a DP tunnel connected on a port
+ * @intel_dp: DP port object
+ * @crtc_state: CRTC state
+ * @dpcd_updated: the DPCD DPRX capabilities got updated during resume
+ *
+ * Resume a DP tunnel on @intel_dp with BW allocation mode enabled on it.
+ */
+void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state,
+			    bool dpcd_updated)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	u8 dpcd[DP_RECEIVER_CAP_SIZE];
+	u8 pipe_mask;
+	int err = 0;
+
+	if (!intel_dp->tunnel_suspended)
+		return;
+
+	intel_dp->tunnel_suspended = false;
+
+	drm_dbg_kms(&i915->drm, "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Resume\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name);
+
+	/*
+	 * The TBT Connection Manager requires the GFX driver to read out
+	 * the sink's DPRX caps to be able to service any BW requests later.
+	 * During resume overriding the caps in @intel_dp cached before
+	 * suspend must be avoided, so do here only a dummy read, unless the
+	 * capabilities were updated already during resume.
+	 */
+	if (!dpcd_updated) {
+		err = intel_dp_read_dprx_caps(intel_dp, dpcd);
+
+		if (err) {
+			drm_dp_tunnel_set_io_error(intel_dp->tunnel);
+			goto out_err;
+		}
+	}
+
+	err = drm_dp_tunnel_enable_bw_alloc(intel_dp->tunnel);
+	if (err)
+		goto out_err;
+
+	pipe_mask = 0;
+	if (crtc_state) {
+		struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+		/* TODO: Add support for MST */
+		pipe_mask |= BIT(crtc->pipe);
+	}
+
+	err = allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask);
+	if (err)
+		goto out_err;
+
+	return;
+
+out_err:
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Tunnel can't be resumed, will drop and redect it (err %pe)\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    ERR_PTR(err));
+}
+
+static struct drm_dp_tunnel *
+get_inherited_tunnel(struct intel_atomic_state *state, struct intel_crtc *crtc)
+{
+	if (!state->inherited_dp_tunnels)
+		return NULL;
+
+	return state->inherited_dp_tunnels->ref[crtc->pipe].tunnel;
+}
+
+static int
+add_inherited_tunnel(struct intel_atomic_state *state,
+		     struct drm_dp_tunnel *tunnel,
+		     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct drm_dp_tunnel *old_tunnel;
+
+	old_tunnel = get_inherited_tunnel(state, crtc);
+	if (old_tunnel) {
+		drm_WARN_ON(&i915->drm, old_tunnel != tunnel);
+		return 0;
+	}
+
+	if (!state->inherited_dp_tunnels) {
+		state->inherited_dp_tunnels = kzalloc(sizeof(*state->inherited_dp_tunnels),
+						      GFP_KERNEL);
+		if (!state->inherited_dp_tunnels)
+			return -ENOMEM;
+	}
+
+	drm_dp_tunnel_ref_get(tunnel, &state->inherited_dp_tunnels->ref[crtc->pipe]);
+
+	return 0;
+}
+
+static int check_inherited_tunnel_state(struct intel_atomic_state *state,
+					struct intel_dp *intel_dp,
+					const struct intel_digital_connector_state *old_conn_state)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct intel_connector *connector =
+		to_intel_connector(old_conn_state->base.connector);
+	struct intel_crtc *old_crtc;
+	const struct intel_crtc_state *old_crtc_state;
+
+	/*
+	 * If a BWA tunnel gets detected only after the corresponding
+	 * connector got enabled already without a BWA tunnel, or a different
+	 * BWA tunnel (which was removed meanwhile) the old CRTC state won't
+	 * contain the state of the current tunnel. This tunnel still has a
+	 * reserved BW, which needs to be released, add the state for such
+	 * inherited tunnels separately only to this atomic state.
+	 */
+	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return 0;
+
+	if (!old_conn_state->base.crtc)
+		return 0;
+
+	old_crtc = to_intel_crtc(old_conn_state->base.crtc);
+	old_crtc_state = intel_atomic_get_old_crtc_state(state, old_crtc);
+
+	if (!old_crtc_state->hw.active ||
+	    old_crtc_state->dp_tunnel_ref.tunnel == intel_dp->tunnel)
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Adding state for inherited tunnel %p\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    old_crtc->base.base.id, old_crtc->base.name,
+		    intel_dp->tunnel);
+
+	return add_inherited_tunnel(state, intel_dp->tunnel, old_crtc);
+}
+
+/**
+ * intel_dp_tunnel_atomic_cleanup_inherited_state - Free any inherited DP tunnel state
+ * @state: Atomic state
+ *
+ * Free the inherited DP tunnel state in @state.
+ */
+void intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state)
+{
+	enum pipe pipe;
+
+	if (!state->inherited_dp_tunnels)
+		return;
+
+	for_each_pipe(to_i915(state->base.dev), pipe)
+		if (state->inherited_dp_tunnels->ref[pipe].tunnel)
+			drm_dp_tunnel_ref_put(&state->inherited_dp_tunnels->ref[pipe]);
+
+	kfree(state->inherited_dp_tunnels);
+	state->inherited_dp_tunnels = NULL;
+}
+
+static int intel_dp_tunnel_atomic_add_group_state(struct intel_atomic_state *state,
+						  struct drm_dp_tunnel *tunnel)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	u32 pipe_mask;
+	int err;
+
+	err = drm_dp_tunnel_atomic_get_group_streams_in_state(&state->base,
+							      tunnel, &pipe_mask);
+	if (err)
+		return err;
+
+	drm_WARN_ON(&i915->drm, pipe_mask & ~((1 << I915_MAX_PIPES) - 1));
+
+	return intel_modeset_pipes_in_mask_early(state, "DPTUN", pipe_mask);
+}
+
+/**
+ * intel_dp_tunnel_atomic_add_state_for_crtc - Add CRTC specific DP tunnel state
+ * @state: Atomic state
+ * @crtc: CRTC to add the tunnel state for
+ *
+ * Add the DP tunnel state for @crtc if the CRTC (aka DP tunnel stream) is enabled
+ * via a DP tunnel.
+ *
+ * Return 0 in case of success, a negative error code otherwise.
+ */
+int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
+					      struct intel_crtc *crtc)
+{
+	const struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct drm_dp_tunnel_state *tunnel_state;
+	struct drm_dp_tunnel *tunnel = new_crtc_state->dp_tunnel_ref.tunnel;
+
+	if (!tunnel)
+		return 0;
+
+	tunnel_state = drm_dp_tunnel_atomic_get_state(&state->base, tunnel);
+	if (IS_ERR(tunnel_state))
+		return PTR_ERR(tunnel_state);
+
+	return 0;
+}
+
+static int check_group_state(struct intel_atomic_state *state,
+			     struct intel_dp *intel_dp,
+			     struct intel_connector *connector,
+			     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	const struct intel_crtc_state *crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+
+	if (!crtc_state->dp_tunnel_ref.tunnel)
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Adding group state for tunnel %p\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    crtc->base.base.id, crtc->base.name,
+		    crtc_state->dp_tunnel_ref.tunnel);
+
+	return intel_dp_tunnel_atomic_add_group_state(state, crtc_state->dp_tunnel_ref.tunnel);
+}
+
+/**
+ * intel_dp_tunnel_atomic_check_state - Check a connector's DP tunnel specific state
+ * @state: Atomic state
+ * @intel_dp: DP port object
+ * @connector: connector using @intel_dp
+ *
+ * Check and add the DP tunnel atomic state for @intel_dp/@connector to
+ * @state, if there is a DP tunnel detected on @intel_dp with BW allocation
+ * mode enabled on it, or if @intel_dp/@connector was previously enabled via a
+ * DP tunnel.
+ *
+ * Returns 0 in case of success, or a negative error code otherwise.
+ */
+int intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
+				       struct intel_dp *intel_dp,
+				       struct intel_connector *connector)
+{
+	const struct intel_digital_connector_state *old_conn_state =
+		intel_atomic_get_old_connector_state(state, connector);
+	const struct intel_digital_connector_state *new_conn_state =
+		intel_atomic_get_new_connector_state(state, connector);
+	int err;
+
+	if (old_conn_state->base.crtc) {
+		err = check_group_state(state, intel_dp, connector,
+					to_intel_crtc(old_conn_state->base.crtc));
+		if (err)
+			return err;
+	}
+
+	if (new_conn_state->base.crtc &&
+	    new_conn_state->base.crtc != old_conn_state->base.crtc) {
+		err = check_group_state(state, intel_dp, connector,
+					to_intel_crtc(new_conn_state->base.crtc));
+		if (err)
+			return err;
+	}
+
+	return check_inherited_tunnel_state(state, intel_dp, old_conn_state);
+}
+
+/**
+ * intel_dp_tunnel_atomic_compute_stream_bw - Compute the BW required by a DP tunnel stream
+ * @state: Atomic state
+ * @intel_dp: DP object
+ * @connector: connector using @intel_dp
+ * @crtc_state: state of CRTC of the given DP tunnel stream
+ *
+ * Compute the required BW of CRTC (aka DP tunnel stream), storing this BW to
+ * the DP tunnel state containing the stream in @state. Before re-calculating a
+ * BW requirement in the crtc_state state the old BW requirement computed by this
+ * function must be cleared by calling intel_dp_tunnel_atomic_clear_stream_bw().
+ *
+ * Returns 0 in case of success, a negative error code otherwise.
+ */
+int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
+					     struct intel_dp *intel_dp,
+					     const struct intel_connector *connector,
+					     struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	int required_rate = intel_dp_config_required_rate(crtc_state);
+	int ret;
+
+	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Stream %d required BW %d Mb/s\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    crtc->base.base.id, crtc->base.name,
+		    crtc->pipe,
+		    kbytes_to_mbits(required_rate));
+
+	ret = drm_dp_tunnel_atomic_set_stream_bw(&state->base, intel_dp->tunnel,
+						 crtc->pipe, required_rate);
+	if (ret < 0)
+		return ret;
+
+	drm_dp_tunnel_ref_get(intel_dp->tunnel,
+			      &crtc_state->dp_tunnel_ref);
+
+	return 0;
+}
+
+/**
+ * intel_dp_tunnel_atomic_clear_stream_bw - Clear any DP tunnel stream BW requirement
+ * @state: Atomic state
+ * @crtc_state: state of CRTC of the given DP tunnel stream
+ *
+ * Clear any DP tunnel stream BW requirement set by
+ * intel_dp_tunnel_atomic_compute_stream_bw().
+ */
+void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
+					    struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+	if (!crtc_state->dp_tunnel_ref.tunnel)
+		return;
+
+	drm_dp_tunnel_atomic_set_stream_bw(&state->base,
+					   crtc_state->dp_tunnel_ref.tunnel,
+					   crtc->pipe, 0);
+	drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref);
+}
+
+/**
+ * intel_dp_tunnel_atomic_check_link - Check the DP tunnel atomic state
+ * @state: intel atomic state
+ * @limits: link BW limits
+ *
+ * Check the link configuration for all DP tunnels in @state. If the
+ * configuration is invalid @limits will be updated if possible to
+ * reduce the total BW, after which the configuration for all CRTCs in
+ * @state must be recomputed with the updated @limits.
+ *
+ * Returns:
+ *   - 0 if the confugration is valid
+ *   - %-EAGAIN, if the configuration is invalid and @limits got updated
+ *     with fallback values with which the configuration of all CRTCs in
+ *     @state must be recomputed
+ *   - Other negative error, if the configuration is invalid without a
+ *     fallback possibility, or the check failed for another reason
+ */
+int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
+				      struct intel_link_bw_limits *limits)
+{
+	u32 failed_stream_mask;
+	int err;
+
+	err = drm_dp_tunnel_atomic_check_stream_bws(&state->base,
+						    &failed_stream_mask);
+	if (err != -ENOSPC)
+		return err;
+
+	err = intel_link_bw_reduce_bpp(state, limits,
+				       failed_stream_mask, "DP tunnel link BW");
+
+	return err ? : -EAGAIN;
+}
+
+static void atomic_decrease_bw(struct intel_atomic_state *state)
+{
+	struct intel_crtc *crtc;
+	const struct intel_crtc_state *old_crtc_state;
+	const struct intel_crtc_state *new_crtc_state;
+	int i;
+
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+		const struct drm_dp_tunnel_state *new_tunnel_state;
+		struct drm_dp_tunnel *tunnel;
+		int old_bw;
+		int new_bw;
+
+		if (!intel_crtc_needs_modeset(new_crtc_state))
+			continue;
+
+		tunnel = get_inherited_tunnel(state, crtc);
+		if (!tunnel)
+			tunnel = old_crtc_state->dp_tunnel_ref.tunnel;
+
+		if (!tunnel)
+			continue;
+
+		old_bw = drm_dp_tunnel_get_allocated_bw(tunnel);
+
+		new_tunnel_state = drm_dp_tunnel_atomic_get_new_state(&state->base, tunnel);
+		new_bw = drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
+
+		if (new_bw >= old_bw)
+			continue;
+
+		drm_dp_tunnel_alloc_bw(tunnel, new_bw);
+	}
+}
+
+static void queue_retry_work(struct intel_atomic_state *state,
+			     struct drm_dp_tunnel *tunnel,
+			     const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct intel_encoder *encoder;
+
+	encoder = intel_get_crtc_new_encoder(state, crtc_state);
+
+	if (!intel_digital_port_connected(encoder))
+		return;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][ENCODER:%d:%s] BW allocation failed on a connected sink\n",
+		    drm_dp_tunnel_name(tunnel),
+		    encoder->base.base.id,
+		    encoder->base.name);
+
+	intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
+}
+
+static void atomic_increase_bw(struct intel_atomic_state *state)
+{
+	struct intel_crtc *crtc;
+	const struct intel_crtc_state *crtc_state;
+	int i;
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+		struct drm_dp_tunnel_state *tunnel_state;
+		struct drm_dp_tunnel *tunnel = crtc_state->dp_tunnel_ref.tunnel;
+		int bw;
+
+		if (!intel_crtc_needs_modeset(crtc_state))
+			continue;
+
+		if (!tunnel)
+			continue;
+
+		tunnel_state = drm_dp_tunnel_atomic_get_new_state(&state->base, tunnel);
+
+		bw = drm_dp_tunnel_atomic_get_required_bw(tunnel_state);
+
+		if (drm_dp_tunnel_alloc_bw(tunnel, bw) != 0)
+			queue_retry_work(state, tunnel, crtc_state);
+	}
+}
+
+/**
+ * intel_dp_tunnel_atomic_alloc_bw - Allocate the BW for all modeset tunnels
+ * @state: Atomic state
+ *
+ * Allocate the required BW for all tunnels in @state.
+ */
+void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state)
+{
+	atomic_decrease_bw(state);
+	atomic_increase_bw(state);
+}
+
+/**
+ * intel_dp_tunnel_mgr_init - Initialize the DP tunnel manager
+ * @i915: i915 device object
+ *
+ * Initialize the DP tunnel manager. The tunnel manager will support the
+ * detection/management of DP tunnels on all DP connectors, so the function
+ * must be called after all these connectors have been registered already.
+ *
+ * Return 0 in case of success, a negative error code otherwise.
+ */
+int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915)
+{
+	struct drm_dp_tunnel_mgr *tunnel_mgr;
+	struct drm_connector_list_iter connector_list_iter;
+	struct intel_connector *connector;
+	int dp_connectors = 0;
+
+	drm_connector_list_iter_begin(&i915->drm, &connector_list_iter);
+	for_each_intel_connector_iter(connector, &connector_list_iter) {
+		if (connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		dp_connectors++;
+	}
+	drm_connector_list_iter_end(&connector_list_iter);
+
+	tunnel_mgr = drm_dp_tunnel_mgr_create(&i915->drm, dp_connectors);
+	if (IS_ERR(tunnel_mgr))
+		return PTR_ERR(tunnel_mgr);
+
+	i915->display.dp_tunnel_mgr = tunnel_mgr;
+
+	return 0;
+}
+
+/**
+ * intel_dp_tunnel_mgr_cleanup - Clean up the DP tunnel manager state
+ * @i915: i915 device object
+ *
+ * Clean up the DP tunnel manager state.
+ */
+void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915)
+{
+	drm_dp_tunnel_mgr_destroy(i915->display.dp_tunnel_mgr);
+	i915->display.dp_tunnel_mgr = NULL;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
new file mode 100644
index 0000000000000..08b2cba84af2b
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __INTEL_DP_TUNNEL_H__
+#define __INTEL_DP_TUNNEL_H__
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct drm_connector_state;
+struct drm_modeset_acquire_ctx;
+
+struct intel_atomic_state;
+struct intel_connector;
+struct intel_crtc;
+struct intel_crtc_state;
+struct intel_dp;
+struct intel_encoder;
+struct intel_link_bw_limits;
+
+#if defined(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
+
+int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx);
+void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp);
+void intel_dp_tunnel_destroy(struct intel_dp *intel_dp);
+void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state,
+			    bool dpcd_updated);
+void intel_dp_tunnel_suspend(struct intel_dp *intel_dp);
+
+bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp);
+
+void
+intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state);
+
+int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
+					     struct intel_dp *intel_dp,
+					     const struct intel_connector *connector,
+					     struct intel_crtc_state *crtc_state);
+void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
+					    struct intel_crtc_state *crtc_state);
+
+int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
+					      struct intel_crtc *crtc);
+int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
+				      struct intel_link_bw_limits *limits);
+int intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
+				       struct intel_dp *intel_dp,
+				       struct intel_connector *connector);
+
+void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state);
+
+int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915);
+void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915);
+
+#else
+
+static inline int
+intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp) {}
+static inline void intel_dp_tunnel_destroy(struct intel_dp *intel_dp) {}
+static inline void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
+					  const struct intel_crtc_state *crtc_state,
+					  bool dpcd_updated) {}
+static inline void intel_dp_tunnel_suspend(struct intel_dp *intel_dp) {}
+
+static inline bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp)
+{
+	return false;
+}
+
+static inline void
+intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state) {}
+
+static inline int
+intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
+					 struct intel_dp *intel_dp,
+					 const struct intel_connector *connector,
+					 struct intel_crtc_state *crtc_state)
+{
+	return 0;
+}
+
+static inline void
+intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
+				       struct intel_crtc_state *crtc_state) {}
+
+static inline int
+intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
+					  struct intel_crtc *crtc)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
+				  struct intel_link_bw_limits *limits)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
+				   struct intel_dp *intel_dp,
+				   struct intel_connector *connector)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_mgr_init(struct drm_i915_private *i915)
+{
+	return 0;
+}
+
+static inline void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915) {}
+
+#endif /* CONFIG_DRM_I915_DP_TUNNEL */
+
+#endif /* __INTEL_DP_TUNNEL_H__ */
-- 
2.39.2


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

* [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check BW limit
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (11 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 10:13   ` Shankar, Uma
  2024-02-20 21:18 ` [PATCH v2 14/21] drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate() Imre Deak
                   ` (19 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Ville Syrjälä

Add the atomic state during a modeset required to enable the DP tunnel
BW allocation mode on links where such a tunnel was detected. This state
applies to an already enabled output, the state added for a newly
enabled output will be computed and added/cleared to/from the atomic
state in a follow-up patch.

v2:
- s/old_crtc_state/crtc_state in intel_crtc_duplicate_state().
- Move intel_dp_tunnel_atomic_cleanup_inherited_state() to a follow-up
  patch adding the corresponding state. (Ville)
- Move intel_dp_tunnel_atomic_clear_stream_bw() to a follow-up
  patch adding the corresponding state.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c  |  6 ++++++
 drivers/gpu/drm/i915/display/intel_display.c | 12 ++++++++++++
 drivers/gpu/drm/i915/display/intel_link_bw.c |  5 +++++
 3 files changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 96ab37e158995..798cb90361a83 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -260,6 +260,10 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	if (crtc_state->post_csc_lut)
 		drm_property_blob_get(crtc_state->post_csc_lut);
 
+	if (crtc_state->dp_tunnel_ref.tunnel)
+		drm_dp_tunnel_ref_get(crtc_state->dp_tunnel_ref.tunnel,
+				      &crtc_state->dp_tunnel_ref);
+
 	crtc_state->update_pipe = false;
 	crtc_state->update_m_n = false;
 	crtc_state->update_lrr = false;
@@ -311,6 +315,8 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
 
 	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
 	intel_crtc_free_hw_state(crtc_state);
+	if (crtc_state->dp_tunnel_ref.tunnel)
+		drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref);
 	kfree(crtc_state);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e1a4200f67a7e..16973ebb7865d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -33,6 +33,7 @@
 #include <linux/string_helpers.h>
 
 #include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic_uapi.h>
@@ -73,6 +74,7 @@
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
 #include "intel_dpll.h"
 #include "intel_dpll_mgr.h"
 #include "intel_dpt.h"
@@ -4490,6 +4492,8 @@ copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
 	saved_state->crc_enabled = slave_crtc_state->crc_enabled;
 
 	intel_crtc_free_hw_state(slave_crtc_state);
+	if (slave_crtc_state->dp_tunnel_ref.tunnel)
+		drm_dp_tunnel_ref_put(&slave_crtc_state->dp_tunnel_ref);
 	memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
 	kfree(saved_state);
 
@@ -4505,6 +4509,10 @@ copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
 		      &master_crtc_state->hw.adjusted_mode);
 	slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter;
 
+	if (master_crtc_state->dp_tunnel_ref.tunnel)
+		drm_dp_tunnel_ref_get(master_crtc_state->dp_tunnel_ref.tunnel,
+					&slave_crtc_state->dp_tunnel_ref);
+
 	copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
 
 	slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
@@ -5365,6 +5373,10 @@ static int intel_modeset_pipe(struct intel_atomic_state *state,
 	if (ret)
 		return ret;
 
+	ret = intel_dp_tunnel_atomic_add_state_for_crtc(state, crtc);
+	if (ret)
+		return ret;
+
 	ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c
index 27ea858897c9f..dfd7d5e23f3fa 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
@@ -9,6 +9,7 @@
 #include "intel_crtc.h"
 #include "intel_display_types.h"
 #include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
 #include "intel_fdi.h"
 #include "intel_link_bw.h"
 
@@ -163,6 +164,10 @@ static int check_all_link_config(struct intel_atomic_state *state,
 	if (ret)
 		return ret;
 
+	ret = intel_dp_tunnel_atomic_check_link(state, limits);
+	if (ret)
+		return ret;
+
 	ret = intel_fdi_atomic_check_link(state, limits);
 	if (ret)
 		return ret;
-- 
2.39.2


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

* [PATCH v2 14/21] drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (12 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check BW limit Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 15/21] drm/i915/dp: Compute DP tunnel BW during encoder state computation Imre Deak
                   ` (18 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Take any link BW limitation into account in
intel_dp_max_link_data_rate(). Such a limitation can be due to multiple
displays on (Thunderbolt) links with DP tunnels sharing the link BW.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 32 +++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d0452d3e534a7..f4f748d95ad17 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -63,6 +63,7 @@
 #include "intel_dp_hdcp.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
 #include "intel_dpio_phy.h"
 #include "intel_dpll.h"
 #include "intel_fifo_underrun.h"
@@ -152,6 +153,22 @@ int intel_dp_link_symbol_clock(int rate)
 	return DIV_ROUND_CLOSEST(rate * 10, intel_dp_link_symbol_size(rate));
 }
 
+static int max_dprx_rate(struct intel_dp *intel_dp)
+{
+	if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
+
+	return drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
+}
+
+static int max_dprx_lane_count(struct intel_dp *intel_dp)
+{
+	if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return drm_dp_tunnel_max_dprx_lane_count(intel_dp->tunnel);
+
+	return drm_dp_max_lane_count(intel_dp->dpcd);
+}
+
 static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp)
 {
 	intel_dp->sink_rates[0] = 162000;
@@ -180,7 +197,7 @@ static void intel_dp_set_dpcd_sink_rates(struct intel_dp *intel_dp)
 	/*
 	 * Sink rates for 8b/10b.
 	 */
-	max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
+	max_rate = max_dprx_rate(intel_dp);
 	max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps);
 	if (max_lttpr_rate)
 		max_rate = min(max_rate, max_lttpr_rate);
@@ -259,7 +276,7 @@ static void intel_dp_set_max_sink_lane_count(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct intel_encoder *encoder = &intel_dig_port->base;
 
-	intel_dp->max_sink_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
+	intel_dp->max_sink_lane_count = max_dprx_lane_count(intel_dp);
 
 	switch (intel_dp->max_sink_lane_count) {
 	case 1:
@@ -389,14 +406,21 @@ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
  * @max_dprx_rate: Maximum data rate of the DPRX
  * @max_dprx_lanes: Maximum lane count of the DPRX
  *
- * Calculate the maximum data rate for the provided link parameters.
+ * Calculate the maximum data rate for the provided link parameters taking into
+ * account any BW limitations by a DP tunnel attached to @intel_dp.
  *
  * Returns the maximum data rate in kBps units.
  */
 int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
 				int max_dprx_rate, int max_dprx_lanes)
 {
-	return drm_dp_max_dprx_data_rate(max_dprx_rate, max_dprx_lanes);
+	int max_rate = drm_dp_max_dprx_data_rate(max_dprx_rate, max_dprx_lanes);
+
+	if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		max_rate = min(max_rate,
+			       drm_dp_tunnel_available_bw(intel_dp->tunnel));
+
+	return max_rate;
 }
 
 bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
-- 
2.39.2


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

* [PATCH v2 15/21] drm/i915/dp: Compute DP tunnel BW during encoder state computation
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (13 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 14/21] drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate() Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 16/21] drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks Imre Deak
                   ` (17 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Compute the BW required through a DP tunnel on links with such tunnels
detected and add the corresponding atomic state during a modeset.

v2:
- Fix error check of intel_dp_tunnel_compute_stream_bw(). (Ville)
- Move intel_dp_tunnel_atomic_cleanup_inherited_state() to this patch.
  (Ville)
- Move intel_dp_tunnel_atomic_clear_stream_bw() to this patch.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com> (v1)
---
 drivers/gpu/drm/i915/display/intel_atomic.c  |  2 ++
 drivers/gpu/drm/i915/display/intel_display.c |  2 ++
 drivers/gpu/drm/i915/display/intel_dp.c      | 16 ++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 13 ++++++++++++-
 4 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 798cb90361a83..2bb270f82932e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -352,6 +352,8 @@ void intel_atomic_state_clear(struct drm_atomic_state *s)
 	/* state->internal not reset on purpose */
 
 	state->dpll_set = state->modeset = false;
+
+	intel_dp_tunnel_atomic_cleanup_inherited_state(state);
 }
 
 struct intel_crtc_state *
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 16973ebb7865d..20647c97e86fa 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4541,6 +4541,8 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
 	/* free the old crtc_state->hw members */
 	intel_crtc_free_hw_state(crtc_state);
 
+	intel_dp_tunnel_atomic_clear_stream_bw(state, crtc_state);
+
 	/* FIXME: before the switch to atomic started, a new pipe_config was
 	 * kzalloc'd. Code that depends on any field being zero should be
 	 * fixed, so that the crtc_state can be safely duplicated. For now,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f4f748d95ad17..5ad7808788745 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2875,6 +2875,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 			struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state);
 	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	const struct drm_display_mode *fixed_mode;
@@ -2975,7 +2976,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
 	intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
 
-	return 0;
+	return intel_dp_tunnel_atomic_compute_stream_bw(state, intel_dp, connector,
+							pipe_config);
 }
 
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
@@ -6063,6 +6065,15 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,
 			return ret;
 	}
 
+	if (!intel_connector_needs_modeset(state, conn))
+		return 0;
+
+	ret = intel_dp_tunnel_atomic_check_state(state,
+						 intel_dp,
+						 intel_conn);
+	if (ret)
+		return ret;
+
 	/*
 	 * We don't enable port sync on BDW due to missing w/as and
 	 * due to not having adjusted the modeset sequence appropriately.
@@ -6070,9 +6081,6 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,
 	if (DISPLAY_VER(dev_priv) < 9)
 		return 0;
 
-	if (!intel_connector_needs_modeset(state, conn))
-		return 0;
-
 	if (conn->has_tile) {
 		ret = intel_modeset_tile_group(state, conn->tile_group->id);
 		if (ret)
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4b6c8ff974297..db1254b036f18 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -42,6 +42,7 @@
 #include "intel_dp.h"
 #include "intel_dp_hdcp.h"
 #include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
 #include "intel_dpio_phy.h"
 #include "intel_hdcp.h"
 #include "intel_hotplug.h"
@@ -523,6 +524,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 				       struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state);
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
 	struct intel_dp *intel_dp = &intel_mst->primary->dp;
 	const struct intel_connector *connector =
@@ -619,7 +621,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	intel_psr_compute_config(intel_dp, pipe_config, conn_state);
 
-	return 0;
+	return intel_dp_tunnel_atomic_compute_stream_bw(state, intel_dp, connector,
+							pipe_config);
 }
 
 /*
@@ -876,6 +879,14 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
 	if (ret)
 		return ret;
 
+	if (intel_connector_needs_modeset(state, connector)) {
+		ret = intel_dp_tunnel_atomic_check_state(state,
+							 intel_connector->mst_port,
+							 intel_connector);
+		if (ret)
+			return ret;
+	}
+
 	return drm_dp_atomic_release_time_slots(&state->base,
 						&intel_connector->mst_port->mst_mgr,
 						intel_connector->port);
-- 
2.39.2


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

* [PATCH v2 16/21] drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (14 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 15/21] drm/i915/dp: Compute DP tunnel BW during encoder state computation Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 21:25   ` Ville Syrjälä
  2024-02-20 21:18 ` [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs Imre Deak
                   ` (16 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

Allocate and free the DP tunnel BW required by a stream while
enabling/disabling the stream during a modeset.

v2:
- Move the allocation up from encoder hooks to
  intel_atomic_commit_tail().

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com> (v1)
---
 drivers/gpu/drm/i915/display/intel_ddi.c     | 1 +
 drivers/gpu/drm/i915/display/intel_display.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index bea4415902044..ed7301808604d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -54,6 +54,7 @@
 #include "intel_dp_aux.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
 #include "intel_dpio_phy.h"
 #include "intel_dsi.h"
 #include "intel_fdi.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 20647c97e86fa..445efe0087cde 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7123,6 +7123,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 
 	intel_commit_modeset_disables(state);
 
+	intel_dp_tunnel_atomic_alloc_bw(state);
+
 	/* FIXME: Eventually get rid of our crtc->config pointer */
 	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
 		crtc->config = new_crtc_state;
-- 
2.39.2


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

* [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (15 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 16/21] drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 10:19   ` Shankar, Uma
  2024-02-20 21:18 ` [PATCH v2 18/21] drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders Imre Deak
                   ` (15 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel

Handle DP tunnel IRQs a sink (or rather a BW management component like
the Thunderbolt Connection Manager) raises to signal the completion of a
BW request by the driver, or to signal any state change related to the
link BW.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 37 +++++++++++++++++++------
 include/drm/display/drm_dp.h            |  1 +
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5ad7808788745..a3dfcbb710027 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4904,13 +4904,15 @@ static bool intel_dp_mst_link_status(struct intel_dp *intel_dp)
  * - %true if pending interrupts were serviced (or no interrupts were
  *   pending) w/o detecting an error condition.
  * - %false if an error condition - like AUX failure or a loss of link - is
- *   detected, which needs servicing from the hotplug work.
+ *   detected, or another condition - like a DP tunnel BW state change - needs
+ *   servicing from the hotplug work.
  */
 static bool
 intel_dp_check_mst_status(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	bool link_ok = true;
+	bool reprobe_needed = false;
 
 	drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
 
@@ -4937,6 +4939,13 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
 
 		intel_dp_mst_hpd_irq(intel_dp, esi, ack);
 
+		if (esi[3] & DP_TUNNELING_IRQ) {
+			if (drm_dp_tunnel_handle_irq(i915->display.dp_tunnel_mgr,
+						     &intel_dp->aux))
+				reprobe_needed = true;
+			ack[3] |= DP_TUNNELING_IRQ;
+		}
+
 		if (!memchr_inv(ack, 0, sizeof(ack)))
 			break;
 
@@ -4947,7 +4956,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
 			drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr);
 	}
 
-	return link_ok;
+	return link_ok && !reprobe_needed;
 }
 
 static void
@@ -5304,23 +5313,32 @@ static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
 		drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n");
 }
 
-static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
+static bool intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	bool reprobe_needed = false;
 	u8 val;
 
 	if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
-		return;
+		return false;
 
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
 			      DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 || !val)
-		return;
+		return false;
+
+	if ((val & DP_TUNNELING_IRQ) &&
+	    drm_dp_tunnel_handle_irq(i915->display.dp_tunnel_mgr,
+				     &intel_dp->aux))
+		reprobe_needed = true;
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux,
 			       DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1)
-		return;
+		return reprobe_needed;
 
 	if (val & HDMI_LINK_STATUS_CHANGED)
 		intel_dp_handle_hdmi_link_status_change(intel_dp);
+
+	return reprobe_needed;
 }
 
 /*
@@ -5341,6 +5359,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 old_sink_count = intel_dp->sink_count;
+	bool reprobe_needed = false;
 	bool ret;
 
 	/*
@@ -5363,7 +5382,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 	}
 
 	intel_dp_check_device_service_irq(intel_dp);
-	intel_dp_check_link_service_irq(intel_dp);
+	reprobe_needed = intel_dp_check_link_service_irq(intel_dp);
 
 	/* Handle CEC interrupts, if any */
 	drm_dp_cec_irq(&intel_dp->aux);
@@ -5390,10 +5409,10 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 		 * FIXME get rid of the ad-hoc phy test modeset code
 		 * and properly incorporate it into the normal modeset.
 		 */
-		return false;
+		reprobe_needed = true;
 	}
 
-	return true;
+	return !reprobe_needed;
 }
 
 /* XXX this is probably wrong for multiple downstream ports */
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 8bfd5d007be8d..4891bd916d26a 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1081,6 +1081,7 @@
 # define STREAM_STATUS_CHANGED               (1 << 2)
 # define HDMI_LINK_STATUS_CHANGED            (1 << 3)
 # define CONNECTED_OFF_ENTRY_REQUESTED       (1 << 4)
+# define DP_TUNNELING_IRQ                    (1 << 5)
 
 #define DP_PSR_ERROR_STATUS                 0x2006  /* XXX 1.2? */
 # define DP_PSR_LINK_CRC_ERROR              (1 << 0)
-- 
2.39.2


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

* [PATCH v2 18/21] drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (16 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-20 21:18 ` [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels Imre Deak
                   ` (14 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Uma Shankar

A follow-up change will need to resume DP tunnels during system resume,
so call intel_dp_sync_state() always for DDI encoders, so this function
can resume the tunnels for all DP connectors.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index ed7301808604d..c587a8efeafcf 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4151,7 +4151,7 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder,
 		intel_tc_port_sanitize_mode(enc_to_dig_port(encoder),
 					    crtc_state);
 
-	if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
+	if (intel_encoder_is_dp(encoder))
 		intel_dp_sync_state(encoder, crtc_state);
 }
 
-- 
2.39.2


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

* [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (17 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 18/21] drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 10:23   ` Shankar, Uma
  2024-02-20 21:18 ` [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses Imre Deak
                   ` (13 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel

Suspend and resume DP tunnels during system suspend/resume, disabling
the BW allocation mode during suspend, re-enabling it after resume. This
reflects the link's BW management component (Thunderbolt CM) disabling
BWA during suspend. Before any BW requests the driver must read the
sink's DPRX capabilities (since the BW manager requires this
information, so snoops for it on AUX), so ensure this read takes place.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index a3dfcbb710027..35ef17439038a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -36,6 +36,7 @@
 #include <asm/byteorder.h>
 
 #include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/display/drm_dsc_helper.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/drm_atomic_helper.h>
@@ -3313,18 +3314,21 @@ void intel_dp_sync_state(struct intel_encoder *encoder,
 			 const struct intel_crtc_state *crtc_state)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-	if (!crtc_state)
-		return;
+	bool dpcd_updated = false;
 
 	/*
 	 * Don't clobber DPCD if it's been already read out during output
 	 * setup (eDP) or detect.
 	 */
-	if (intel_dp->dpcd[DP_DPCD_REV] == 0)
+	if (crtc_state && intel_dp->dpcd[DP_DPCD_REV] == 0) {
 		intel_dp_get_dpcd(intel_dp);
+		dpcd_updated = true;
+	}
 
-	intel_dp_reset_max_link_params(intel_dp);
+	intel_dp_tunnel_resume(intel_dp, crtc_state, dpcd_updated);
+
+	if (crtc_state)
+		intel_dp_reset_max_link_params(intel_dp);
 }
 
 bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
@@ -5947,6 +5951,8 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
 
 	intel_pps_vdd_off_sync(intel_dp);
+
+	intel_dp_tunnel_suspend(intel_dp);
 }
 
 void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder)
-- 
2.39.2


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

* [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (18 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 10:33   ` Shankar, Uma
  2024-02-20 21:18 ` [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode Imre Deak
                   ` (12 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel

The TBT DP tunnel BW request logic in the Thunderbolt Connection Manager
depends on the GFX driver reading out the sink's DPRX capabilities in
response to a long HPD pulse. Since in i915 this read-out can be blocked
by another connector's/encoder's hotplug event handling (which is
serialized by drm_mode_config::connection_mutex), do a dummy DPRX read-out
in the encoder's HPD pulse handler (which is not blocked by other
encoders).

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 35ef17439038a..f7f8bd5742ad4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6162,6 +6162,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
 {
 	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
 	struct intel_dp *intel_dp = &dig_port->dp;
+	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 
 	if (dig_port->base.type == INTEL_OUTPUT_EDP &&
 	    (long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) {
@@ -6184,6 +6185,17 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
 		    dig_port->base.base.name,
 		    long_hpd ? "long" : "short");
 
+	/*
+	 * TBT DP tunnels require the GFX driver to read out the DPRX caps in
+	 * response to long HPD pulses. The DP hotplug handler does that,
+	 * however the hotplug handler may be blocked by another
+	 * connector's/encoder's hotplug handler. Since the TBT CM may not
+	 * complete the DP tunnel BW request for the latter connector/encoder
+	 * waiting for this encoder's DPRX read, perform a dummy read here.
+	 */
+	if (long_hpd)
+		intel_dp_read_dprx_caps(intel_dp, dpcd);
+
 	if (long_hpd) {
 		intel_dp->reset_link_params = true;
 		return IRQ_NONE;
-- 
2.39.2


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

* [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (19 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses Imre Deak
@ 2024-02-20 21:18 ` Imre Deak
  2024-02-23 10:36   ` Shankar, Uma
  2024-02-21  1:49 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev2) Patchwork
                   ` (11 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-20 21:18 UTC (permalink / raw)
  To: intel-gfx, dri-devel

Detect DP tunnels and enable the BW allocation mode on them. Send a
hotplug notification to userspace in response to a BW change.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 .../drm/i915/display/intel_display_driver.c   | 20 +++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp.c       | 14 +++++++++++--
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 4f7ba7eb03d27..87dd07e0d138d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -35,6 +35,7 @@
 #include "intel_dkl_phy.h"
 #include "intel_dmc.h"
 #include "intel_dp.h"
+#include "intel_dp_tunnel.h"
 #include "intel_dpll.h"
 #include "intel_dpll_mgr.h"
 #include "intel_fb.h"
@@ -434,10 +435,8 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
 
 	for_each_pipe(i915, pipe) {
 		ret = intel_crtc_init(i915, pipe);
-		if (ret) {
-			intel_mode_config_cleanup(i915);
-			return ret;
-		}
+		if (ret)
+			goto err_mode_config;
 	}
 
 	intel_plane_possible_crtcs_init(i915);
@@ -457,6 +456,10 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
 	intel_vga_disable(i915);
 	intel_setup_outputs(i915);
 
+	ret = intel_dp_tunnel_mgr_init(i915);
+	if (ret)
+		goto err_hdcp;
+
 	intel_display_driver_disable_user_access(i915);
 
 	drm_modeset_lock_all(dev);
@@ -475,6 +478,13 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
 		ilk_wm_sanitize(i915);
 
 	return 0;
+
+err_hdcp:
+	intel_hdcp_component_fini(i915);
+err_mode_config:
+	intel_mode_config_cleanup(i915);
+
+	return ret;
 }
 
 /* part #3: call after gem init */
@@ -599,6 +609,8 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
 
 	intel_mode_config_cleanup(i915);
 
+	intel_dp_tunnel_mgr_cleanup(i915);
+
 	intel_overlay_cleanup(i915);
 
 	intel_gmbus_teardown(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f7f8bd5742ad4..789b5fa074fd0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5726,6 +5726,7 @@ intel_dp_detect(struct drm_connector *connector,
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct intel_encoder *encoder = &dig_port->base;
 	enum drm_connector_status status;
+	int ret;
 
 	drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
 		    connector->base.id, connector->name);
@@ -5761,9 +5762,18 @@ intel_dp_detect(struct drm_connector *connector,
 							intel_dp->is_mst);
 		}
 
+		intel_dp_tunnel_disconnect(intel_dp);
+
 		goto out;
 	}
 
+	ret = intel_dp_tunnel_detect(intel_dp, ctx);
+	if (ret == -EDEADLK)
+		return ret;
+
+	if (ret == 1)
+		intel_connector->base.epoch_counter++;
+
 	intel_dp_detect_dsc_caps(intel_dp, intel_connector);
 
 	intel_dp_configure_mst(intel_dp);
@@ -5794,8 +5804,6 @@ intel_dp_detect(struct drm_connector *connector,
 	 * with an IRQ_HPD, so force a link status check.
 	 */
 	if (!intel_dp_is_edp(intel_dp)) {
-		int ret;
-
 		ret = intel_dp_retrain_link(encoder, ctx);
 		if (ret)
 			return ret;
@@ -5935,6 +5943,8 @@ void intel_dp_encoder_flush_work(struct drm_encoder *encoder)
 
 	intel_dp_mst_encoder_cleanup(dig_port);
 
+	intel_dp_tunnel_destroy(intel_dp);
+
 	intel_pps_vdd_off_sync(intel_dp);
 
 	/*
-- 
2.39.2


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

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev2)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (20 preceding siblings ...)
  2024-02-20 21:18 ` [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode Imre Deak
@ 2024-02-21  1:49 ` Patchwork
  2024-02-21  1:49 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (10 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-21  1:49 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev2)
URL   : https://patchwork.freedesktop.org/series/129082/
State : warning

== Summary ==

Error: dim checkpatch failed
501cc0798f87 drm/dp: Add drm_dp_max_dprx_data_rate()
14d74f578b99 drm/dp: Add support for DP tunneling
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:118: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#118: 
new file mode 100644

-:148: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#148: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:26:
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))

-:148: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__state' - possible side-effects?
#148: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:26:
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))

-:148: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__i' - possible side-effects?
#148: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:26:
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))

-:152: WARNING:SPACING: space prohibited between function name and open parenthesis '('
#152: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:30:
+		for_each_if ((__state)->private_objs[__i].ptr && \

-:157: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#157: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:35:
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))

-:157: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__state' - possible side-effects?
#157: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:35:
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))

-:157: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__i' - possible side-effects?
#157: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:35:
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))

-:161: WARNING:SPACING: space prohibited between function name and open parenthesis '('
#161: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:39:
+		for_each_if ((__state)->private_objs[__i].ptr && \

-:179: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__bw' - possible side-effects?
#179: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:57:
+#define DPTUN_BW_ARG(__bw) ((__bw) < 0 ? (__bw) : kbytes_to_mbits(__bw))

-:181: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__tunnel' - possible side-effects?
#181: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:59:
+#define __tun_prn(__tunnel, __level, __type, __fmt, ...) \
+	drm_##__level##__type((__tunnel)->group->mgr->dev, \
+			      "[DPTUN %s][%s] " __fmt, \
+			      drm_dp_tunnel_name(__tunnel), \
+			      (__tunnel)->aux->name, ## \
+			      __VA_ARGS__)

-:191: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__tunnel' - possible side-effects?
#191: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:69:
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)

-:191: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__err' - possible side-effects?
#191: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:69:
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)

-:191: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__fmt' - possible side-effects?
#191: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:69:
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)

-:203: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__group' - possible side-effects?
#203: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:81:
+#define tun_grp_dbg(__group, __fmt, ...) \
+	drm_dbg_kms((__group)->mgr->dev, \
+		    "[DPTUN %s] " __fmt, \
+		    drm_dp_tunnel_group_name(__group), ## \
+		    __VA_ARGS__)

-:211: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'start' - possible side-effects?
#211: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:89:
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)

-:211: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'start' may be better as '(start)' to avoid precedence issues
#211: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:89:
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)

-:211: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'size' may be better as '(size)' to avoid precedence issues
#211: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:89:
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)

-:334: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__address' - possible side-effects?
#334: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:212:
+#define tunnel_reg_ptr(__regs, __address) ({ \
+	WARN_ON(!test_bit((__address) - DP_TUNNELING_BASE, dptun_info_regs)); \
+	&(__regs)->buf[bitmap_weight(dptun_info_regs, (__address) - DP_TUNNELING_BASE)]; \
+})

-:567: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#567: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:445:
+void drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel,
+			 struct ref_tracker **tracker)

-:1893: CHECK:SPACING: spaces preferred around that '*' (ctx:ExV)
#1893: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:1771:
+		*stream_mask |= tunnel_state->stream_mask;
 		^

-:2373: CHECK:LINE_SPACING: Please don't use multiple blank lines
#2373: FILE: include/drm/display/drm_dp_tunnel.h:245:
+
+

total: 2 errors, 3 warnings, 17 checks, 2278 lines checked
82078361838f drm/i915: Fix display bpp limit computation during system resume
976b15a03a8c drm/i915/dp: Add support to notify MST connectors to retry modesets
9d6981886b45 drm/i915/dp: Use drm_dp_max_dprx_data_rate()
066e5527378f drm/i915/dp: Factor out intel_dp_config_required_rate()
b352f0a35faf drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
47eeb30effa9 drm/i915/dp: Factor out intel_dp_update_sink_caps()
7531c2fd6f83 drm/i915/dp: Factor out intel_dp_read_dprx_caps()
7149929cb442 drm/i915/dp: Add intel_dp_max_link_data_rate()
ef0a8dd54e5c drm/i915/dp: Add way to get active pipes with syncing commits
577cf7b2cf35 drm/i915/dp: Add support for DP tunnel BW allocation
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:223: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#223: 
new file mode 100644

-:412: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#412: FILE: drivers/gpu/drm/i915/display/intel_dp_tunnel.c:185:
+	tunnel = drm_dp_tunnel_detect(i915->display.dp_tunnel_mgr,
+					&intel_dp->aux);

total: 0 errors, 1 warnings, 1 checks, 1072 lines checked
ec34759d6f26 drm/i915/dp: Add DP tunnel atomic state and check BW limit
-:84: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#84: FILE: drivers/gpu/drm/i915/display/intel_display.c:4514:
+		drm_dp_tunnel_ref_get(master_crtc_state->dp_tunnel_ref.tunnel,
+					&slave_crtc_state->dp_tunnel_ref);

total: 0 errors, 0 warnings, 1 checks, 77 lines checked
4fdd1af8df9e drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
0cb4cb2cd6d4 drm/i915/dp: Compute DP tunnel BW during encoder state computation
e8408bdcd57d drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
0a4db8693254 drm/i915/dp: Handle DP tunnel IRQs
d5e99925dddc drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
807c117f13f2 drm/i915/dp: Suspend/resume DP tunnels
2ad0f8709182 drm/i915/dp: Read DPRX for all long HPD pulses
45d207ae4bbc drm/i915/dp: Enable DP tunnel BW allocation mode



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

* ✗ Fi.CI.SPARSE: warning for drm/i915: Add Display Port tunnel BW allocation support (rev2)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (21 preceding siblings ...)
  2024-02-21  1:49 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev2) Patchwork
@ 2024-02-21  1:49 ` Patchwork
  2024-02-21  2:08 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (9 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-21  1:49 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev2)
URL   : https://patchwork.freedesktop.org/series/129082/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.



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

* ✓ Fi.CI.BAT: success for drm/i915: Add Display Port tunnel BW allocation support (rev2)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (22 preceding siblings ...)
  2024-02-21  1:49 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2024-02-21  2:08 ` Patchwork
  2024-02-21  5:25 ` ✗ Fi.CI.IGT: failure " Patchwork
                   ` (8 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-21  2:08 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev2)
URL   : https://patchwork.freedesktop.org/series/129082/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_14305 -> Patchwork_129082v2
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

Participating hosts (40 -> 39)
------------------------------

  Missing    (1): fi-snb-2520m 

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

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

### IGT changes ###

#### Suppressed ####

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

  * igt@gem_softpin@safe-alignment:
    - {bat-arls-2}:       [PASS][1] -> [ABORT][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/bat-arls-2/igt@gem_softpin@safe-alignment.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/bat-arls-2/igt@gem_softpin@safe-alignment.html

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

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

### CI changes ###

#### Issues hit ####

  * boot:
    - fi-bsw-n3050:       [PASS][3] -> [FAIL][4] ([i915#8293])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/fi-bsw-n3050/boot.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/fi-bsw-n3050/boot.html

  

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@execlists:
    - fi-bsw-nick:        [PASS][5] -> [ABORT][6] ([i915#7911])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/fi-bsw-nick/igt@i915_selftest@live@execlists.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/fi-bsw-nick/igt@i915_selftest@live@execlists.html

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

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


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

  * Linux: CI_DRM_14305 -> Patchwork_129082v2

  CI-20190529: 20190529
  CI_DRM_14305: 4b8a238dee9c18201f3652695414587cd2ef6d8f @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7718: 40e8b9122853f455c84afcfa56469a6bc9a0d564 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_129082v2: 4b8a238dee9c18201f3652695414587cd2ef6d8f @ git://anongit.freedesktop.org/gfx-ci/linux


### Linux commits

ac3d933462e0 drm/i915/dp: Enable DP tunnel BW allocation mode
8a3130d98ca2 drm/i915/dp: Read DPRX for all long HPD pulses
9e26545ff64e drm/i915/dp: Suspend/resume DP tunnels
4a6ed7708e66 drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
633260352fcf drm/i915/dp: Handle DP tunnel IRQs
e655a8dad126 drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
861868fa5b1f drm/i915/dp: Compute DP tunnel BW during encoder state computation
e6e8be41fc8e drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
fdc02281f1ae drm/i915/dp: Add DP tunnel atomic state and check BW limit
f65489307c55 drm/i915/dp: Add support for DP tunnel BW allocation
389f06304a2f drm/i915/dp: Add way to get active pipes with syncing commits
2ca5a931db6d drm/i915/dp: Add intel_dp_max_link_data_rate()
348ef611b934 drm/i915/dp: Factor out intel_dp_read_dprx_caps()
0d0ce61a14da drm/i915/dp: Factor out intel_dp_update_sink_caps()
696cdaf32b54 drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
06addb22b256 drm/i915/dp: Factor out intel_dp_config_required_rate()
b6c0fee143a2 drm/i915/dp: Use drm_dp_max_dprx_data_rate()
6f16dda74ee5 drm/i915/dp: Add support to notify MST connectors to retry modesets
6461ebe4ef9e drm/i915: Fix display bpp limit computation during system resume
e34814cf0972 drm/dp: Add support for DP tunneling
4bf7a633951f drm/dp: Add drm_dp_max_dprx_data_rate()

== Logs ==

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

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

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

* ✗ Fi.CI.IGT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev2)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (23 preceding siblings ...)
  2024-02-21  2:08 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2024-02-21  5:25 ` Patchwork
  2024-02-23 22:14 ` [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Ville Syrjälä
                   ` (7 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-21  5:25 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev2)
URL   : https://patchwork.freedesktop.org/series/129082/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_14305_full -> Patchwork_129082v2_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_129082v2_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_129082v2_full, 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_129082v2/index.html

Participating hosts (8 -> 8)
------------------------------

  No changes in participating hosts

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

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

### IGT changes ###

#### Possible regressions ####

  * igt@gem_exec_gttfill@engines@bcs0:
    - shard-glk:          [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-glk6/igt@gem_exec_gttfill@engines@bcs0.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk1/igt@gem_exec_gttfill@engines@bcs0.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
    - shard-glk:          [PASS][3] -> [FAIL][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-glk8/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk9/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html

  * igt@kms_vblank@query-idle-hang@pipe-b-hdmi-a-1:
    - shard-snb:          [PASS][5] -> [ABORT][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb4/igt@kms_vblank@query-idle-hang@pipe-b-hdmi-a-1.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb5/igt@kms_vblank@query-idle-hang@pipe-b-hdmi-a-1.html

  * igt@prime_vgem@fence-wait@ccs0:
    - shard-mtlp:         [PASS][7] -> [DMESG-WARN][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-mtlp-5/igt@prime_vgem@fence-wait@ccs0.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@prime_vgem@fence-wait@ccs0.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@api_intel_bb@blit-reloc-purge-cache:
    - shard-rkl:          NOTRUN -> [SKIP][9] ([i915#8411])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-4/igt@api_intel_bb@blit-reloc-purge-cache.html

  * igt@api_intel_bb@object-reloc-keep-cache:
    - shard-dg2:          NOTRUN -> [SKIP][10] ([i915#8411])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@api_intel_bb@object-reloc-keep-cache.html

  * igt@device_reset@cold-reset-bound:
    - shard-dg2:          NOTRUN -> [SKIP][11] ([i915#7701])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@device_reset@cold-reset-bound.html

  * igt@drm_fdinfo@busy@rcs0:
    - shard-dg2:          NOTRUN -> [SKIP][12] ([i915#8414]) +21 other tests skip
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@drm_fdinfo@busy@rcs0.html

  * igt@drm_fdinfo@virtual-busy-idle:
    - shard-mtlp:         NOTRUN -> [SKIP][13] ([i915#8414])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@drm_fdinfo@virtual-busy-idle.html

  * igt@drm_fdinfo@virtual-idle:
    - shard-rkl:          [PASS][14] -> [FAIL][15] ([i915#7742]) +1 other test fail
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-5/igt@drm_fdinfo@virtual-idle.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@drm_fdinfo@virtual-idle.html

  * igt@gem_create@create-ext-cpu-access-sanity-check:
    - shard-mtlp:         NOTRUN -> [SKIP][16] ([i915#6335])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_create@create-ext-cpu-access-sanity-check.html

  * igt@gem_ctx_persistence@engines-cleanup:
    - shard-snb:          NOTRUN -> [SKIP][17] ([fdo#109271] / [i915#1099])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb2/igt@gem_ctx_persistence@engines-cleanup.html

  * igt@gem_ctx_persistence@heartbeat-hostile:
    - shard-dg2:          NOTRUN -> [SKIP][18] ([i915#8555]) +1 other test skip
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@gem_ctx_persistence@heartbeat-hostile.html

  * igt@gem_ctx_persistence@saturated-hostile-nopreempt@vcs0:
    - shard-mtlp:         NOTRUN -> [SKIP][19] ([i915#5882]) +5 other tests skip
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_ctx_persistence@saturated-hostile-nopreempt@vcs0.html

  * igt@gem_ctx_sseu@invalid-sseu:
    - shard-dg2:          NOTRUN -> [SKIP][20] ([i915#280]) +1 other test skip
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@gem_ctx_sseu@invalid-sseu.html

  * igt@gem_eio@reset-stress:
    - shard-dg1:          [PASS][21] -> [FAIL][22] ([i915#5784])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg1-18/igt@gem_eio@reset-stress.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-15/igt@gem_eio@reset-stress.html

  * igt@gem_exec_balancer@bonded-false-hang:
    - shard-dg2:          NOTRUN -> [SKIP][23] ([i915#4812]) +2 other tests skip
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@gem_exec_balancer@bonded-false-hang.html

  * igt@gem_exec_capture@many-4k-incremental:
    - shard-dg2:          NOTRUN -> [FAIL][24] ([i915#9606])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@gem_exec_capture@many-4k-incremental.html

  * igt@gem_exec_fair@basic-none:
    - shard-mtlp:         NOTRUN -> [SKIP][25] ([i915#4473] / [i915#4771])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_exec_fair@basic-none.html

  * igt@gem_exec_fair@basic-none-vip@rcs0:
    - shard-glk:          NOTRUN -> [FAIL][26] ([i915#2842]) +1 other test fail
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk3/igt@gem_exec_fair@basic-none-vip@rcs0.html

  * igt@gem_exec_fair@basic-pace@rcs0:
    - shard-rkl:          [PASS][27] -> [FAIL][28] ([i915#2842])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-1/igt@gem_exec_fair@basic-pace@rcs0.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-7/igt@gem_exec_fair@basic-pace@rcs0.html

  * igt@gem_exec_fair@basic-throttle:
    - shard-dg2:          NOTRUN -> [SKIP][29] ([i915#3539]) +2 other tests skip
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@gem_exec_fair@basic-throttle.html

  * igt@gem_exec_fence@submit:
    - shard-mtlp:         NOTRUN -> [SKIP][30] ([i915#4812])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_exec_fence@submit.html

  * igt@gem_exec_flush@basic-wb-ro-before-default:
    - shard-dg2:          NOTRUN -> [SKIP][31] ([i915#3539] / [i915#4852]) +4 other tests skip
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@gem_exec_flush@basic-wb-ro-before-default.html

  * igt@gem_exec_gttfill@multigpu-basic:
    - shard-dg2:          NOTRUN -> [SKIP][32] ([i915#7697]) +1 other test skip
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_exec_gttfill@multigpu-basic.html

  * igt@gem_exec_params@secure-non-master:
    - shard-dg2:          NOTRUN -> [SKIP][33] ([fdo#112283])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@gem_exec_params@secure-non-master.html

  * igt@gem_exec_reloc@basic-cpu-read:
    - shard-dg2:          NOTRUN -> [SKIP][34] ([i915#3281]) +13 other tests skip
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_exec_reloc@basic-cpu-read.html

  * igt@gem_exec_reloc@basic-write-cpu:
    - shard-mtlp:         NOTRUN -> [SKIP][35] ([i915#3281]) +1 other test skip
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_exec_reloc@basic-write-cpu.html

  * igt@gem_exec_schedule@reorder-wide:
    - shard-dg2:          NOTRUN -> [SKIP][36] ([i915#4537] / [i915#4812]) +2 other tests skip
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_exec_schedule@reorder-wide.html

  * igt@gem_exec_suspend@basic-s4-devices@smem:
    - shard-rkl:          NOTRUN -> [ABORT][37] ([i915#7975] / [i915#8213]) +1 other test abort
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-4/igt@gem_exec_suspend@basic-s4-devices@smem.html

  * igt@gem_fenced_exec_thrash@2-spare-fences:
    - shard-dg2:          NOTRUN -> [SKIP][38] ([i915#4860]) +1 other test skip
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_fenced_exec_thrash@2-spare-fences.html

  * igt@gem_lmem_evict@dontneed-evict-race:
    - shard-rkl:          NOTRUN -> [SKIP][39] ([i915#4613] / [i915#7582])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@gem_lmem_evict@dontneed-evict-race.html

  * igt@gem_lmem_swapping@heavy-random:
    - shard-glk:          NOTRUN -> [SKIP][40] ([fdo#109271] / [i915#4613]) +2 other tests skip
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk5/igt@gem_lmem_swapping@heavy-random.html

  * igt@gem_lmem_swapping@parallel-random:
    - shard-tglu:         NOTRUN -> [SKIP][41] ([i915#4613])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@gem_lmem_swapping@parallel-random.html

  * igt@gem_lmem_swapping@smem-oom:
    - shard-mtlp:         NOTRUN -> [SKIP][42] ([i915#4613])
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_lmem_swapping@smem-oom.html

  * igt@gem_media_fill@media-fill:
    - shard-dg2:          NOTRUN -> [SKIP][43] ([i915#8289])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@gem_media_fill@media-fill.html

  * igt@gem_media_vme:
    - shard-dg2:          NOTRUN -> [SKIP][44] ([i915#284])
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_media_vme.html

  * igt@gem_mmap_wc@bad-object:
    - shard-mtlp:         NOTRUN -> [SKIP][45] ([i915#4083])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_mmap_wc@bad-object.html

  * igt@gem_mmap_wc@write-prefaulted:
    - shard-dg2:          NOTRUN -> [SKIP][46] ([i915#4083]) +7 other tests skip
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@gem_mmap_wc@write-prefaulted.html

  * igt@gem_partial_pwrite_pread@write-uncached:
    - shard-dg2:          NOTRUN -> [SKIP][47] ([i915#3282]) +8 other tests skip
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_partial_pwrite_pread@write-uncached.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-tglu:         NOTRUN -> [WARN][48] ([i915#2658])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_pwrite_snooped:
    - shard-rkl:          NOTRUN -> [SKIP][49] ([i915#3282]) +1 other test skip
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-4/igt@gem_pwrite_snooped.html

  * igt@gem_pxp@protected-encrypted-src-copy-not-readible:
    - shard-mtlp:         NOTRUN -> [SKIP][50] ([i915#4270])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_pxp@protected-encrypted-src-copy-not-readible.html

  * igt@gem_pxp@verify-pxp-stale-buf-optout-execution:
    - shard-dg2:          NOTRUN -> [SKIP][51] ([i915#4270]) +3 other tests skip
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_pxp@verify-pxp-stale-buf-optout-execution.html

  * igt@gem_render_copy@y-tiled-mc-ccs-to-yf-tiled-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][52] ([i915#5190]) +8 other tests skip
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_render_copy@y-tiled-mc-ccs-to-yf-tiled-ccs.html

  * igt@gem_render_copy@yf-tiled-to-vebox-linear:
    - shard-mtlp:         NOTRUN -> [SKIP][53] ([i915#8428])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_render_copy@yf-tiled-to-vebox-linear.html

  * igt@gem_set_tiling_vs_gtt:
    - shard-dg2:          NOTRUN -> [SKIP][54] ([i915#4079]) +2 other tests skip
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_set_tiling_vs_gtt.html

  * igt@gem_softpin@evict-snoop:
    - shard-dg2:          NOTRUN -> [SKIP][55] ([i915#4885])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_softpin@evict-snoop.html

  * igt@gem_spin_batch@spin-all-new:
    - shard-dg2:          NOTRUN -> [FAIL][56] ([i915#5889])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@gem_spin_batch@spin-all-new.html

  * igt@gem_tiled_partial_pwrite_pread@writes:
    - shard-dg2:          NOTRUN -> [SKIP][57] ([i915#4077]) +16 other tests skip
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@gem_tiled_partial_pwrite_pread@writes.html

  * igt@gem_userptr_blits@dmabuf-unsync:
    - shard-dg2:          NOTRUN -> [SKIP][58] ([i915#3297]) +5 other tests skip
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@gem_userptr_blits@dmabuf-unsync.html

  * igt@gem_userptr_blits@map-fixed-invalidate:
    - shard-mtlp:         NOTRUN -> [SKIP][59] ([i915#3297])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gem_userptr_blits@map-fixed-invalidate.html

  * igt@gen7_exec_parse@load-register-reg:
    - shard-tglu:         NOTRUN -> [SKIP][60] ([fdo#109289]) +1 other test skip
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@gen7_exec_parse@load-register-reg.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          NOTRUN -> [INCOMPLETE][61] ([i915#10137] / [i915#5566])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk5/igt@gen9_exec_parse@allowed-all.html

  * igt@gen9_exec_parse@bb-start-out:
    - shard-rkl:          NOTRUN -> [SKIP][62] ([i915#2527])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@gen9_exec_parse@bb-start-out.html

  * igt@gen9_exec_parse@bb-start-param:
    - shard-mtlp:         NOTRUN -> [SKIP][63] ([i915#2856])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@gen9_exec_parse@bb-start-param.html

  * igt@gen9_exec_parse@shadow-peek:
    - shard-dg2:          NOTRUN -> [SKIP][64] ([i915#2856]) +5 other tests skip
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@gen9_exec_parse@shadow-peek.html

  * igt@i915_fb_tiling:
    - shard-dg2:          NOTRUN -> [SKIP][65] ([i915#4881])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@i915_fb_tiling.html

  * igt@i915_module_load@load:
    - shard-dg2:          NOTRUN -> [SKIP][66] ([i915#6227])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@i915_module_load@load.html

  * igt@i915_pm_rc6_residency@rc6-idle@gt0-vcs0:
    - shard-dg1:          [PASS][67] -> [FAIL][68] ([i915#3591])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg1-16/igt@i915_pm_rc6_residency@rc6-idle@gt0-vcs0.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-15/igt@i915_pm_rc6_residency@rc6-idle@gt0-vcs0.html

  * igt@i915_pm_rps@min-max-config-loaded:
    - shard-dg2:          NOTRUN -> [SKIP][69] ([i915#6621])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@i915_pm_rps@min-max-config-loaded.html

  * igt@i915_pm_sseu@full-enable:
    - shard-dg2:          NOTRUN -> [SKIP][70] ([i915#4387])
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@i915_pm_sseu@full-enable.html

  * igt@i915_query@query-topology-known-pci-ids:
    - shard-dg2:          NOTRUN -> [SKIP][71] ([fdo#109303])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@i915_query@query-topology-known-pci-ids.html

  * igt@i915_suspend@basic-s3-without-i915:
    - shard-rkl:          [PASS][72] -> [FAIL][73] ([i915#10031])
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-1/igt@i915_suspend@basic-s3-without-i915.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-7/igt@i915_suspend@basic-s3-without-i915.html

  * igt@kms_addfb_basic@addfb25-x-tiled-mismatch-legacy:
    - shard-dg2:          NOTRUN -> [SKIP][74] ([i915#4212])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_addfb_basic@addfb25-x-tiled-mismatch-legacy.html

  * igt@kms_addfb_basic@basic-y-tiled-legacy:
    - shard-dg2:          NOTRUN -> [SKIP][75] ([i915#4215] / [i915#5190])
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_addfb_basic@basic-y-tiled-legacy.html

  * igt@kms_addfb_basic@framebuffer-vs-set-tiling:
    - shard-mtlp:         NOTRUN -> [SKIP][76] ([i915#4212])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_addfb_basic@framebuffer-vs-set-tiling.html

  * igt@kms_addfb_basic@invalid-smem-bo-on-discrete:
    - shard-mtlp:         NOTRUN -> [SKIP][77] ([i915#3826])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_addfb_basic@invalid-smem-bo-on-discrete.html

  * igt@kms_async_flips@async-flip-with-page-flip-events@pipe-a-hdmi-a-1-y-rc-ccs-cc:
    - shard-rkl:          NOTRUN -> [SKIP][78] ([i915#8709]) +3 other tests skip
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-5/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-a-hdmi-a-1-y-rc-ccs-cc.html

  * igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-4-y-rc-ccs:
    - shard-dg1:          NOTRUN -> [SKIP][79] ([i915#8709]) +7 other tests skip
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-17/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-4-y-rc-ccs.html

  * igt@kms_async_flips@invalid-async-flip:
    - shard-dg2:          NOTRUN -> [SKIP][80] ([i915#6228])
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_async_flips@invalid-async-flip.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
    - shard-rkl:          NOTRUN -> [SKIP][81] ([i915#5286])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip:
    - shard-tglu:         NOTRUN -> [SKIP][82] ([fdo#111615] / [i915#5286])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip.html

  * igt@kms_big_fb@x-tiled-16bpp-rotate-270:
    - shard-rkl:          NOTRUN -> [SKIP][83] ([fdo#111614] / [i915#3638])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_big_fb@x-tiled-16bpp-rotate-270.html

  * igt@kms_big_fb@x-tiled-16bpp-rotate-90:
    - shard-dg2:          NOTRUN -> [SKIP][84] ([fdo#111614]) +6 other tests skip
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_big_fb@x-tiled-16bpp-rotate-90.html

  * igt@kms_big_fb@x-tiled-8bpp-rotate-90:
    - shard-mtlp:         NOTRUN -> [SKIP][85] ([fdo#111614]) +1 other test skip
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_big_fb@x-tiled-8bpp-rotate-90.html

  * igt@kms_big_fb@y-tiled-16bpp-rotate-180:
    - shard-mtlp:         NOTRUN -> [SKIP][86] ([fdo#111615]) +1 other test skip
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_big_fb@y-tiled-16bpp-rotate-180.html

  * igt@kms_big_fb@y-tiled-8bpp-rotate-90:
    - shard-tglu:         NOTRUN -> [SKIP][87] ([fdo#111614])
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_big_fb@y-tiled-8bpp-rotate-90.html

  * igt@kms_big_fb@y-tiled-addfb-size-overflow:
    - shard-mtlp:         NOTRUN -> [SKIP][88] ([i915#6187])
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_big_fb@y-tiled-addfb-size-overflow.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
    - shard-tglu:         [PASS][89] -> [FAIL][90] ([i915#3743]) +2 other tests fail
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-tglu-9/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-2/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip:
    - shard-dg2:          NOTRUN -> [SKIP][91] ([i915#4538] / [i915#5190]) +18 other tests skip
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip.html

  * igt@kms_big_fb@yf-tiled-64bpp-rotate-270:
    - shard-rkl:          NOTRUN -> [SKIP][92] ([fdo#110723])
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_big_fb@yf-tiled-64bpp-rotate-270.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0-hflip:
    - shard-tglu:         NOTRUN -> [SKIP][93] ([fdo#111615]) +1 other test skip
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0-hflip.html

  * igt@kms_big_joiner@basic:
    - shard-rkl:          NOTRUN -> [SKIP][94] ([i915#2705])
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_big_joiner@basic.html

  * igt@kms_big_joiner@invalid-modeset:
    - shard-dg2:          NOTRUN -> [SKIP][95] ([i915#2705])
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_big_joiner@invalid-modeset.html

  * igt@kms_ccs@pipe-a-missing-ccs-buffer-y-tiled-ccs:
    - shard-rkl:          NOTRUN -> [SKIP][96] ([i915#5354] / [i915#6095]) +2 other tests skip
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_ccs@pipe-a-missing-ccs-buffer-y-tiled-ccs.html

  * igt@kms_ccs@pipe-a-random-ccs-data-y-tiled-gen12-rc-ccs:
    - shard-mtlp:         NOTRUN -> [SKIP][97] ([i915#5354] / [i915#6095]) +11 other tests skip
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_ccs@pipe-a-random-ccs-data-y-tiled-gen12-rc-ccs.html

  * igt@kms_ccs@pipe-b-bad-pixel-format-4-tiled-mtl-rc-ccs-cc:
    - shard-tglu:         NOTRUN -> [SKIP][98] ([i915#5354] / [i915#6095]) +12 other tests skip
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_ccs@pipe-b-bad-pixel-format-4-tiled-mtl-rc-ccs-cc.html

  * igt@kms_ccs@pipe-b-bad-rotation-90-y-tiled-gen12-mc-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][99] ([i915#5354]) +129 other tests skip
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_ccs@pipe-b-bad-rotation-90-y-tiled-gen12-mc-ccs.html

  * igt@kms_ccs@pipe-c-crc-primary-rotation-180-4-tiled-mtl-mc-ccs:
    - shard-glk:          NOTRUN -> [SKIP][100] ([fdo#109271]) +176 other tests skip
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk3/igt@kms_ccs@pipe-c-crc-primary-rotation-180-4-tiled-mtl-mc-ccs.html

  * igt@kms_ccs@pipe-d-missing-ccs-buffer-y-tiled-ccs:
    - shard-rkl:          NOTRUN -> [SKIP][101] ([i915#5354]) +3 other tests skip
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_ccs@pipe-d-missing-ccs-buffer-y-tiled-ccs.html

  * igt@kms_cdclk@mode-transition@pipe-d-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][102] ([i915#7213]) +3 other tests skip
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_cdclk@mode-transition@pipe-d-hdmi-a-3.html

  * igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][103] ([i915#4087]) +3 other tests skip
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3.html

  * igt@kms_chamelium_color@ctm-blue-to-red:
    - shard-tglu:         NOTRUN -> [SKIP][104] ([fdo#111827])
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_chamelium_color@ctm-blue-to-red.html

  * igt@kms_chamelium_color@ctm-negative:
    - shard-rkl:          NOTRUN -> [SKIP][105] ([fdo#111827])
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_chamelium_color@ctm-negative.html

  * igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k:
    - shard-mtlp:         NOTRUN -> [SKIP][106] ([i915#7828]) +1 other test skip
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k.html

  * igt@kms_chamelium_hpd@dp-hpd-with-enabled-mode:
    - shard-dg2:          NOTRUN -> [SKIP][107] ([i915#7828]) +16 other tests skip
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_chamelium_hpd@dp-hpd-with-enabled-mode.html

  * igt@kms_chamelium_hpd@hdmi-hpd-storm:
    - shard-tglu:         NOTRUN -> [SKIP][108] ([i915#7828])
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_chamelium_hpd@hdmi-hpd-storm.html

  * igt@kms_chamelium_hpd@vga-hpd-after-suspend:
    - shard-rkl:          NOTRUN -> [SKIP][109] ([i915#7828])
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_chamelium_hpd@vga-hpd-after-suspend.html

  * igt@kms_content_protection@dp-mst-lic-type-0:
    - shard-tglu:         NOTRUN -> [SKIP][110] ([i915#3116] / [i915#3299])
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_content_protection@dp-mst-lic-type-0.html

  * igt@kms_content_protection@type1:
    - shard-dg2:          NOTRUN -> [SKIP][111] ([i915#7118] / [i915#9424])
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_content_protection@type1.html

  * igt@kms_cursor_crc@cursor-offscreen-256x85:
    - shard-mtlp:         NOTRUN -> [SKIP][112] ([i915#8814])
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_cursor_crc@cursor-offscreen-256x85.html

  * igt@kms_cursor_crc@cursor-onscreen-32x10:
    - shard-mtlp:         NOTRUN -> [SKIP][113] ([i915#3555] / [i915#8814])
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_cursor_crc@cursor-onscreen-32x10.html

  * igt@kms_cursor_crc@cursor-random-512x170:
    - shard-dg2:          NOTRUN -> [SKIP][114] ([i915#3359]) +4 other tests skip
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_cursor_crc@cursor-random-512x170.html

  * igt@kms_cursor_crc@cursor-sliding-32x10:
    - shard-dg2:          NOTRUN -> [SKIP][115] ([i915#3555]) +6 other tests skip
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_cursor_crc@cursor-sliding-32x10.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size:
    - shard-tglu:         NOTRUN -> [SKIP][116] ([fdo#109274]) +1 other test skip
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic:
    - shard-dg2:          NOTRUN -> [SKIP][117] ([fdo#109274] / [i915#5354]) +5 other tests skip
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions:
    - shard-dg2:          NOTRUN -> [SKIP][118] ([fdo#109274] / [fdo#111767] / [i915#5354])
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions.html
    - shard-snb:          NOTRUN -> [SKIP][119] ([fdo#109271] / [fdo#111767])
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb2/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions.html

  * igt@kms_cursor_legacy@modeset-atomic-cursor-hotspot:
    - shard-dg2:          NOTRUN -> [SKIP][120] ([i915#9067])
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@kms_cursor_legacy@modeset-atomic-cursor-hotspot.html

  * igt@kms_dirtyfb@drrs-dirtyfb-ioctl:
    - shard-dg2:          NOTRUN -> [SKIP][121] ([i915#9833]) +1 other test skip
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_dirtyfb@drrs-dirtyfb-ioctl.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-1:
    - shard-tglu:         NOTRUN -> [SKIP][122] ([fdo#110189] / [i915#9723])
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-1.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][123] ([fdo#110189] / [i915#9723])
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-19/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-4.html

  * igt@kms_dp_aux_dev:
    - shard-dg2:          NOTRUN -> [SKIP][124] ([i915#1257])
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_dp_aux_dev.html

  * igt@kms_dsc@dsc-fractional-bpp-with-bpc:
    - shard-dg2:          NOTRUN -> [SKIP][125] ([i915#3840])
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_dsc@dsc-fractional-bpp-with-bpc.html

  * igt@kms_dsc@dsc-with-bpc:
    - shard-tglu:         NOTRUN -> [SKIP][126] ([i915#3555] / [i915#3840])
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_dsc@dsc-with-bpc.html

  * igt@kms_dsc@dsc-with-bpc-formats:
    - shard-dg2:          NOTRUN -> [SKIP][127] ([i915#3555] / [i915#3840])
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_dsc@dsc-with-bpc-formats.html

  * igt@kms_feature_discovery@chamelium:
    - shard-rkl:          NOTRUN -> [SKIP][128] ([i915#4854])
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_feature_discovery@chamelium.html

  * igt@kms_feature_discovery@display-3x:
    - shard-dg2:          NOTRUN -> [SKIP][129] ([i915#1839]) +1 other test skip
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@kms_feature_discovery@display-3x.html

  * igt@kms_feature_discovery@psr2:
    - shard-dg2:          NOTRUN -> [SKIP][130] ([i915#658])
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@kms_feature_discovery@psr2.html

  * igt@kms_flip@2x-dpms-vs-vblank-race:
    - shard-mtlp:         NOTRUN -> [SKIP][131] ([i915#3637]) +2 other tests skip
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_flip@2x-dpms-vs-vblank-race.html

  * igt@kms_flip@2x-flip-vs-blocking-wf-vblank:
    - shard-dg2:          NOTRUN -> [SKIP][132] ([fdo#109274] / [fdo#111767])
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_flip@2x-flip-vs-blocking-wf-vblank.html

  * igt@kms_flip@2x-flip-vs-expired-vblank@bc-hdmi-a1-hdmi-a2:
    - shard-glk:          [PASS][133] -> [FAIL][134] ([i915#79])
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-glk2/igt@kms_flip@2x-flip-vs-expired-vblank@bc-hdmi-a1-hdmi-a2.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk4/igt@kms_flip@2x-flip-vs-expired-vblank@bc-hdmi-a1-hdmi-a2.html

  * igt@kms_flip@2x-flip-vs-modeset-vs-hang:
    - shard-dg2:          NOTRUN -> [SKIP][135] ([fdo#109274]) +11 other tests skip
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_flip@2x-flip-vs-modeset-vs-hang.html

  * igt@kms_flip@2x-flip-vs-panning-interruptible:
    - shard-tglu:         NOTRUN -> [SKIP][136] ([fdo#109274] / [i915#3637]) +1 other test skip
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_flip@2x-flip-vs-panning-interruptible.html

  * igt@kms_flip@2x-plain-flip-fb-recreate-interruptible:
    - shard-rkl:          NOTRUN -> [SKIP][137] ([fdo#111825])
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_flip@2x-plain-flip-fb-recreate-interruptible.html

  * igt@kms_flip@2x-plain-flip-ts-check:
    - shard-tglu:         NOTRUN -> [SKIP][138] ([fdo#109274] / [i915#3637] / [i915#3966])
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_flip@2x-plain-flip-ts-check.html

  * igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-downscaling@pipe-a-valid-mode:
    - shard-dg2:          NOTRUN -> [SKIP][139] ([i915#2672]) +4 other tests skip
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-downscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling@pipe-a-default-mode:
    - shard-mtlp:         NOTRUN -> [SKIP][140] ([i915#2672] / [i915#3555])
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling@pipe-a-default-mode.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling@pipe-a-valid-mode:
    - shard-rkl:          NOTRUN -> [SKIP][141] ([i915#2672])
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling@pipe-a-default-mode:
    - shard-mtlp:         NOTRUN -> [SKIP][142] ([i915#3555] / [i915#8810])
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling@pipe-a-default-mode.html

  * igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-cpu:
    - shard-dg2:          NOTRUN -> [FAIL][143] ([i915#6880])
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-cpu.html

  * igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw:
    - shard-dg2:          [PASS][144] -> [FAIL][145] ([i915#6880])
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg2-5/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-mmap-wc:
    - shard-snb:          [PASS][146] -> [SKIP][147] ([fdo#109271]) +10 other tests skip
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb7/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-mmap-wc.html
   [147]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-mmap-wc:
    - shard-dg2:          NOTRUN -> [SKIP][148] ([i915#8708]) +25 other tests skip
   [148]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-render:
    - shard-rkl:          NOTRUN -> [SKIP][149] ([fdo#111825] / [i915#1825]) +6 other tests skip
   [149]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-4/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt:
    - shard-mtlp:         NOTRUN -> [SKIP][150] ([i915#8708]) +1 other test skip
   [150]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-tiling-4:
    - shard-rkl:          NOTRUN -> [SKIP][151] ([i915#5439])
   [151]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_frontbuffer_tracking@fbcpsr-tiling-4.html

  * igt@kms_frontbuffer_tracking@fbcpsr-tiling-y:
    - shard-dg2:          NOTRUN -> [SKIP][152] ([i915#10055])
   [152]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_frontbuffer_tracking@fbcpsr-tiling-y.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-render:
    - shard-rkl:          NOTRUN -> [SKIP][153] ([i915#3023]) +2 other tests skip
   [153]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-onoff:
    - shard-dg2:          NOTRUN -> [SKIP][154] ([i915#3458]) +26 other tests skip
   [154]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-onoff.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-mmap-gtt:
    - shard-tglu:         NOTRUN -> [SKIP][155] ([fdo#109280]) +5 other tests skip
   [155]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render:
    - shard-dg2:          NOTRUN -> [SKIP][156] ([fdo#111767] / [i915#5354]) +2 other tests skip
   [156]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-onoff:
    - shard-mtlp:         NOTRUN -> [SKIP][157] ([i915#1825]) +6 other tests skip
   [157]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-onoff.html

  * igt@kms_frontbuffer_tracking@psr-rgb565-draw-mmap-gtt:
    - shard-tglu:         NOTRUN -> [SKIP][158] ([fdo#110189]) +5 other tests skip
   [158]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_frontbuffer_tracking@psr-rgb565-draw-mmap-gtt.html

  * igt@kms_getfb@getfb-reject-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][159] ([i915#6118])
   [159]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@kms_getfb@getfb-reject-ccs.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-tglu:         NOTRUN -> [SKIP][160] ([i915#3555] / [i915#8228])
   [160]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_hdr@static-toggle-suspend:
    - shard-dg2:          NOTRUN -> [SKIP][161] ([i915#3555] / [i915#8228]) +2 other tests skip
   [161]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_hdr@static-toggle-suspend.html

  * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
    - shard-mtlp:         NOTRUN -> [SKIP][162] ([i915#4816])
   [162]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html

  * igt@kms_pipe_b_c_ivb@from-pipe-c-to-b-with-3-lanes:
    - shard-dg2:          NOTRUN -> [SKIP][163] ([fdo#109289]) +5 other tests skip
   [163]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@kms_pipe_b_c_ivb@from-pipe-c-to-b-with-3-lanes.html

  * igt@kms_plane_lowres@tiling-yf:
    - shard-dg2:          NOTRUN -> [SKIP][164] ([i915#3555] / [i915#8821])
   [164]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_plane_lowres@tiling-yf.html

  * igt@kms_plane_multiple@tiling-yf:
    - shard-rkl:          NOTRUN -> [SKIP][165] ([i915#3555])
   [165]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-4/igt@kms_plane_multiple@tiling-yf.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-25-with-modifiers@pipe-a-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][166] ([i915#9423]) +7 other tests skip
   [166]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_plane_scaling@plane-downscale-factor-0-25-with-modifiers@pipe-a-hdmi-a-3.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-25-with-rotation@pipe-c-hdmi-a-3:
    - shard-dg1:          NOTRUN -> [SKIP][167] ([i915#9423]) +7 other tests skip
   [167]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-13/igt@kms_plane_scaling@plane-downscale-factor-0-25-with-rotation@pipe-c-hdmi-a-3.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-75-with-rotation@pipe-a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][168] ([i915#9423]) +13 other tests skip
   [168]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_plane_scaling@plane-downscale-factor-0-75-with-rotation@pipe-a-hdmi-a-2.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-b-hdmi-a-1:
    - shard-tglu:         NOTRUN -> [SKIP][169] ([i915#5176] / [i915#9423]) +3 other tests skip
   [169]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-b-hdmi-a-1.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][170] ([i915#5176] / [i915#9423]) +3 other tests skip
   [170]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-19/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-d-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][171] ([i915#5235] / [i915#9423]) +3 other tests skip
   [171]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-d-hdmi-a-3.html

  * igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][172] ([i915#5235]) +5 other tests skip
   [172]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-6/igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-a-hdmi-a-2.html

  * igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-d-hdmi-a-3:
    - shard-dg1:          NOTRUN -> [SKIP][173] ([i915#5235]) +15 other tests skip
   [173]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-13/igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-d-hdmi-a-3.html

  * igt@kms_pm_lpsp@screens-disabled:
    - shard-dg2:          NOTRUN -> [SKIP][174] ([i915#8430])
   [174]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_pm_lpsp@screens-disabled.html

  * igt@kms_pm_rpm@modeset-lpsp:
    - shard-dg2:          [PASS][175] -> [SKIP][176] ([i915#9519])
   [175]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg2-10/igt@kms_pm_rpm@modeset-lpsp.html
   [176]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@kms_pm_rpm@modeset-lpsp.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait:
    - shard-rkl:          [PASS][177] -> [SKIP][178] ([i915#9519]) +1 other test skip
   [177]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-1/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html
   [178]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html

  * igt@kms_pm_rpm@modeset-pc8-residency-stress:
    - shard-dg2:          NOTRUN -> [SKIP][179] ([fdo#109293] / [fdo#109506]) +1 other test skip
   [179]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_pm_rpm@modeset-pc8-residency-stress.html

  * igt@kms_prime@d3hot:
    - shard-dg2:          NOTRUN -> [SKIP][180] ([i915#6524] / [i915#6805])
   [180]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_prime@d3hot.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf:
    - shard-tglu:         NOTRUN -> [SKIP][181] ([i915#9683])
   [181]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area:
    - shard-rkl:          NOTRUN -> [SKIP][182] ([fdo#111068] / [i915#9683])
   [182]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area.html

  * igt@kms_psr2_su@page_flip-nv12:
    - shard-mtlp:         NOTRUN -> [SKIP][183] ([i915#4348])
   [183]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_psr2_su@page_flip-nv12.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-dg2:          NOTRUN -> [SKIP][184] ([i915#9683]) +3 other tests skip
   [184]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_rotation_crc@bad-pixel-format:
    - shard-snb:          NOTRUN -> [SKIP][185] ([fdo#109271]) +68 other tests skip
   [185]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb2/igt@kms_rotation_crc@bad-pixel-format.html

  * igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90:
    - shard-dg2:          NOTRUN -> [SKIP][186] ([i915#4235] / [i915#5190])
   [186]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90.html

  * igt@kms_rotation_crc@sprite-rotation-270:
    - shard-dg2:          NOTRUN -> [SKIP][187] ([i915#4235]) +1 other test skip
   [187]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@kms_rotation_crc@sprite-rotation-270.html

  * igt@kms_setmode@clone-exclusive-crtc:
    - shard-mtlp:         NOTRUN -> [SKIP][188] ([i915#3555] / [i915#8809])
   [188]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@kms_setmode@clone-exclusive-crtc.html

  * igt@kms_sysfs_edid_timing:
    - shard-dg2:          NOTRUN -> [FAIL][189] ([IGT#2])
   [189]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@kms_sysfs_edid_timing.html

  * igt@kms_tiled_display@basic-test-pattern:
    - shard-dg2:          NOTRUN -> [SKIP][190] ([i915#8623])
   [190]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_tiled_display@basic-test-pattern.html

  * igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1:
    - shard-rkl:          [PASS][191] -> [FAIL][192] ([i915#9196])
   [191]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-4/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
   [192]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-2/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
    - shard-snb:          [PASS][193] -> [FAIL][194] ([i915#9196])
   [193]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb6/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
   [194]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb4/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html

  * igt@kms_writeback@writeback-check-output-xrgb2101010:
    - shard-rkl:          NOTRUN -> [SKIP][195] ([i915#2437] / [i915#9412])
   [195]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_writeback@writeback-check-output-xrgb2101010.html

  * igt@kms_writeback@writeback-fb-id:
    - shard-dg2:          NOTRUN -> [SKIP][196] ([i915#2437]) +1 other test skip
   [196]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@kms_writeback@writeback-fb-id.html

  * igt@kms_writeback@writeback-invalid-parameters:
    - shard-glk:          NOTRUN -> [SKIP][197] ([fdo#109271] / [i915#2437])
   [197]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk9/igt@kms_writeback@writeback-invalid-parameters.html

  * igt@kms_writeback@writeback-pixel-formats:
    - shard-dg2:          NOTRUN -> [SKIP][198] ([i915#2437] / [i915#9412])
   [198]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@kms_writeback@writeback-pixel-formats.html

  * igt@perf@gen8-unprivileged-single-ctx-counters:
    - shard-dg2:          NOTRUN -> [SKIP][199] ([i915#2436] / [i915#7387])
   [199]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@perf@gen8-unprivileged-single-ctx-counters.html

  * igt@perf@non-zero-reason@0-rcs0:
    - shard-dg2:          [PASS][200] -> [FAIL][201] ([i915#7484])
   [200]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg2-1/igt@perf@non-zero-reason@0-rcs0.html
   [201]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-5/igt@perf@non-zero-reason@0-rcs0.html

  * igt@perf_pmu@frequency@gt0:
    - shard-dg2:          NOTRUN -> [FAIL][202] ([i915#6806])
   [202]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-7/igt@perf_pmu@frequency@gt0.html

  * igt@perf_pmu@module-unload:
    - shard-dg2:          NOTRUN -> [FAIL][203] ([i915#5793])
   [203]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@perf_pmu@module-unload.html

  * igt@prime_udl:
    - shard-dg2:          NOTRUN -> [SKIP][204] ([fdo#109291])
   [204]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@prime_udl.html

  * igt@prime_vgem@basic-fence-read:
    - shard-dg2:          NOTRUN -> [SKIP][205] ([i915#3291] / [i915#3708]) +1 other test skip
   [205]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-6/igt@prime_vgem@basic-fence-read.html

  * igt@prime_vgem@basic-gtt:
    - shard-dg2:          NOTRUN -> [SKIP][206] ([i915#3708] / [i915#4077])
   [206]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-2/igt@prime_vgem@basic-gtt.html

  * igt@prime_vgem@fence-flip-hang:
    - shard-mtlp:         NOTRUN -> [SKIP][207] ([i915#3708])
   [207]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@prime_vgem@fence-flip-hang.html

  * igt@prime_vgem@fence-wait@vecs0:
    - shard-mtlp:         [PASS][208] -> [ABORT][209] ([i915#8875])
   [208]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-mtlp-5/igt@prime_vgem@fence-wait@vecs0.html
   [209]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@prime_vgem@fence-wait@vecs0.html

  * igt@sriov_basic@enable-vfs-bind-unbind-each:
    - shard-dg2:          NOTRUN -> [SKIP][210] ([i915#9917])
   [210]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-10/igt@sriov_basic@enable-vfs-bind-unbind-each.html

  * igt@tools_test@sysfs_l3_parity:
    - shard-dg2:          NOTRUN -> [SKIP][211] ([i915#4818])
   [211]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@tools_test@sysfs_l3_parity.html

  * igt@v3d/v3d_get_param@base-params:
    - shard-mtlp:         NOTRUN -> [SKIP][212] ([i915#2575]) +2 other tests skip
   [212]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@v3d/v3d_get_param@base-params.html

  * igt@v3d/v3d_perfmon@get-values-invalid-pad:
    - shard-rkl:          NOTRUN -> [SKIP][213] ([fdo#109315])
   [213]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@v3d/v3d_perfmon@get-values-invalid-pad.html

  * igt@v3d/v3d_submit_cl@multisync-out-syncs:
    - shard-dg2:          NOTRUN -> [SKIP][214] ([i915#2575]) +20 other tests skip
   [214]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@v3d/v3d_submit_cl@multisync-out-syncs.html

  * igt@v3d/v3d_submit_cl@single-out-sync:
    - shard-tglu:         NOTRUN -> [SKIP][215] ([fdo#109315] / [i915#2575]) +2 other tests skip
   [215]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@v3d/v3d_submit_cl@single-out-sync.html

  * igt@vc4/vc4_create_bo@create-bo-zeroed:
    - shard-rkl:          NOTRUN -> [SKIP][216] ([i915#7711])
   [216]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@vc4/vc4_create_bo@create-bo-zeroed.html

  * igt@vc4/vc4_label_bo@set-bad-name:
    - shard-mtlp:         NOTRUN -> [SKIP][217] ([i915#7711]) +1 other test skip
   [217]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-mtlp-6/igt@vc4/vc4_label_bo@set-bad-name.html

  * igt@vc4/vc4_perfmon@create-single-perfmon:
    - shard-tglu:         NOTRUN -> [SKIP][218] ([i915#2575]) +1 other test skip
   [218]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-7/igt@vc4/vc4_perfmon@create-single-perfmon.html

  * igt@vc4/vc4_tiling@set-bad-modifier:
    - shard-dg2:          NOTRUN -> [SKIP][219] ([i915#7711]) +11 other tests skip
   [219]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg2-1/igt@vc4/vc4_tiling@set-bad-modifier.html

  
#### Possible fixes ####

  * igt@drm_fdinfo@idle@rcs0:
    - shard-rkl:          [FAIL][220] ([i915#7742]) -> [PASS][221]
   [220]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-1/igt@drm_fdinfo@idle@rcs0.html
   [221]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-5/igt@drm_fdinfo@idle@rcs0.html

  * igt@gem_ctx_exec@basic-nohangcheck:
    - shard-tglu:         [FAIL][222] ([i915#6268]) -> [PASS][223]
   [222]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-tglu-6/igt@gem_ctx_exec@basic-nohangcheck.html
   [223]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-2/igt@gem_ctx_exec@basic-nohangcheck.html

  * igt@gem_exec_capture@pi@vcs0:
    - shard-glk:          [INCOMPLETE][224] -> [PASS][225]
   [224]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-glk5/igt@gem_exec_capture@pi@vcs0.html
   [225]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-glk6/igt@gem_exec_capture@pi@vcs0.html

  * igt@gem_exec_fair@basic-none@vcs0:
    - shard-rkl:          [FAIL][226] ([i915#2842]) -> [PASS][227] +2 other tests pass
   [226]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-7/igt@gem_exec_fair@basic-none@vcs0.html
   [227]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-4/igt@gem_exec_fair@basic-none@vcs0.html

  * igt@i915_pm_rps@reset:
    - shard-snb:          [INCOMPLETE][228] ([i915#10137] / [i915#7790]) -> [PASS][229]
   [228]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb2/igt@i915_pm_rps@reset.html
   [229]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb2/igt@i915_pm_rps@reset.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
    - shard-tglu:         [FAIL][230] ([i915#3743]) -> [PASS][231] +1 other test pass
   [230]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-tglu-5/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html
   [231]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-4/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render:
    - shard-snb:          [SKIP][232] ([fdo#109271]) -> [PASS][233] +8 other tests pass
   [232]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb5/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render.html
   [233]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb7/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt:
    - shard-snb:          [SKIP][234] ([fdo#109271] / [fdo#111767]) -> [PASS][235] +1 other test pass
   [234]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb5/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt.html
   [235]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb6/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt.html

  * igt@kms_pm_rpm@modeset-lpsp-stress-no-wait:
    - shard-rkl:          [SKIP][236] ([i915#9519]) -> [PASS][237]
   [236]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-1/igt@kms_pm_rpm@modeset-lpsp-stress-no-wait.html
   [237]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-7/igt@kms_pm_rpm@modeset-lpsp-stress-no-wait.html

  
#### Warnings ####

  * igt@device_reset@unbind-reset-rebind:
    - shard-dg1:          [ABORT][238] ([i915#9618]) -> [INCOMPLETE][239] ([i915#10137] / [i915#9408] / [i915#9618])
   [238]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg1-13/igt@device_reset@unbind-reset-rebind.html
   [239]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-19/igt@device_reset@unbind-reset-rebind.html

  * igt@gem_lmem_swapping@heavy-verify-random-ccs@lmem0:
    - shard-dg1:          [SKIP][240] ([i915#4565]) -> [SKIP][241] ([i915#4423] / [i915#4565])
   [240]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg1-18/igt@gem_lmem_swapping@heavy-verify-random-ccs@lmem0.html
   [241]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-15/igt@gem_lmem_swapping@heavy-verify-random-ccs@lmem0.html

  * igt@i915_module_load@reload-with-fault-injection:
    - shard-dg1:          [ABORT][242] ([i915#9820]) -> [INCOMPLETE][243] ([i915#10137] / [i915#9849])
   [242]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg1-13/igt@i915_module_load@reload-with-fault-injection.html
   [243]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-17/igt@i915_module_load@reload-with-fault-injection.html

  * igt@i915_pm_rc6_residency@rc6-idle@gt0-rcs0:
    - shard-tglu:         [FAIL][244] ([i915#3591]) -> [WARN][245] ([i915#2681])
   [244]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-tglu-2/igt@i915_pm_rc6_residency@rc6-idle@gt0-rcs0.html
   [245]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-tglu-5/igt@i915_pm_rc6_residency@rc6-idle@gt0-rcs0.html

  * igt@kms_content_protection@type1:
    - shard-snb:          [INCOMPLETE][246] ([i915#8816]) -> [SKIP][247] ([fdo#109271]) +1 other test skip
   [246]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb7/igt@kms_content_protection@type1.html
   [247]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb1/igt@kms_content_protection@type1.html

  * igt@kms_fbcon_fbt@psr:
    - shard-dg1:          [SKIP][248] ([i915#3469]) -> [SKIP][249] ([i915#3469] / [i915#4423])
   [248]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-dg1-18/igt@kms_fbcon_fbt@psr.html
   [249]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-dg1-15/igt@kms_fbcon_fbt@psr.html

  * igt@kms_fbcon_fbt@psr-suspend:
    - shard-rkl:          [SKIP][250] ([i915#3955]) -> [SKIP][251] ([fdo#110189] / [i915#3955])
   [250]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-7/igt@kms_fbcon_fbt@psr-suspend.html
   [251]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-1/igt@kms_fbcon_fbt@psr-suspend.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render:
    - shard-snb:          [SKIP][252] ([fdo#109271]) -> [SKIP][253] ([fdo#109271] / [fdo#111767]) +1 other test skip
   [252]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-snb7/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html
   [253]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-snb1/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_pm_dc@dc6-dpms:
    - shard-rkl:          [SKIP][254] ([i915#3361]) -> [FAIL][255] ([i915#9295])
   [254]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-1/igt@kms_pm_dc@dc6-dpms.html
   [255]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-5/igt@kms_pm_dc@dc6-dpms.html

  * igt@kms_pm_dc@dc9-dpms:
    - shard-rkl:          [SKIP][256] ([i915#4281]) -> [SKIP][257] ([i915#3361])
   [256]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14305/shard-rkl-5/igt@kms_pm_dc@dc9-dpms.html
   [257]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v2/shard-rkl-2/igt@kms_pm_dc@dc9-dpms.html

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

  [IGT#2]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/2
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109293]: https://bugs.freedesktop.org/show_bug.cgi?id=109293
  [fdo#109303]: https://bugs.freedesktop.org/show_bug.cgi?id=109303
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#109506]: https://bugs.freedesktop.org/show_bug.cgi?id=109506
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111767]: https://bugs.freedesktop.org/show_bug.cgi?id=111767
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
  [i915#10031]: https://gitlab.freedesktop.org/drm/intel/issues/10031
  [i915#10055]: https://gitlab.freedesktop.org/drm/intel/issues/10055
  [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
  [i915#10278]: https://gitlab.freedesktop.org/drm/intel/issues/10278
  [i915#10282]: https://gitlab.freedesktop.org/drm/intel/issues/10282
  [i915#1099]: https://gitlab.freedesktop.org/drm/intel/issues/1099
  [i915#1257]: https://gitlab.freedesktop.org/drm/intel/issues/1257
  [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
  [i915#1839]: https://gitlab.freedesktop.org/drm/intel/issues/1839
  [i915#2436]: https://gitlab.freedesktop.org/drm/intel/issues/2436
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2527]: https://gitlab.freedesktop.org/drm/intel/issues/2527
  [i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
  [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#2681]: https://gitlab.freedesktop.org/drm/intel/issues/2681
  [i915#2705]: https://gitlab.freedesktop.org/drm/intel/issues/2705
  [i915#280]: https://gitlab.freedesktop.org/drm/intel/issues/280
  [i915#284]: https://gitlab.freedesktop.org/drm/intel/issues/284
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
  [i915#3023]: https://gitlab.freedesktop.org/drm/intel/issues/3023
  [i915#3116]: https://gitlab.freedesktop.org/drm/intel/issues/3116
  [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3299]: https://gitlab.freedesktop.org/drm/intel/issues/3299
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3361]: https://gitlab.freedesktop.org/drm/intel/issues/3361
  [i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
  [i915#3469]: https://gitlab.freedesktop.org/drm/intel/issues/3469
  [i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3591]: https://gitlab.freedesktop.org/drm/intel/issues/3591
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#3743]: https://gitlab.freedesktop.org/drm/intel/issues/3743
  [i915#3826]: https://gitlab.freedesktop.org/drm/intel/issues/3826
  [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
  [i915#3955]: https://gitlab.freedesktop.org/drm/intel/issues/3955
  [i915#3966]: https://gitlab.freedesktop.org/drm/intel/issues/3966
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4087]: https://gitlab.freedesktop.org/drm/intel/issues/4087
  [i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#4235]: https://gitlab.freedesktop.org/drm/intel/issues/4235
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4281]: https://gitlab.freedesktop.org/drm/intel/issues/4281
  [i915#4348]: https://gitlab.freedesktop.org/drm/intel/issues/4348
  [i915#4387]: https://gitlab.freedesktop.org/drm/intel/issues/4387
  [i915#4423]: https://gitlab.freedesktop.org/drm/intel/issues/4423
  [i915#4473]: https://gitlab.freedesktop.org/drm/intel/issues/4473
  [i915#4537]: https://gitlab.freedesktop.org/drm/intel/issues/4537
  [i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
  [i915#4565]: https://gitlab.freedesktop.org/drm/intel/issues/4565
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4771]: https://gitlab.freedesktop.org/drm/intel/issues/4771
  [i915#4812]: https://gitlab.freedesktop.org/drm/intel/issues/4812
  [i915#4816]: https://gitlab.freedesktop.org/drm/intel/issues/4816
  [i915#4818]: https://gitlab.freedesktop.org/drm/intel/issues/4818
  [i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
  [i915#4854]: https://gitlab.freedesktop.org/drm/intel/issues/4854
  [i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
  [i915#4881]: https://gitlab.freedesktop.org/drm/intel/issues/4881
  [i915#4885]: https://gitlab.freedesktop.org/drm/intel/issues/4885
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
  [i915#5439]: https://gitlab.freedesktop.org/drm/intel/issues/5439
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#5793]: https://gitlab.freedesktop.org/drm/intel/issues/5793
  [i915#5882]: https://gitlab.freedesktop.org/drm/intel/issues/5882
  [i915#5889]: https://gitlab.freedesktop.org/drm/intel/issues/5889
  [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
  [i915#6118]: https://gitlab.freedesktop.org/drm/intel/issues/6118
  [i915#6187]: https://gitlab.freedesktop.org/drm/intel/issues/6187
  [i915#6227]: https://gitlab.freedesktop.org/drm/intel/issues/6227
  [i915#6228]: https://gitlab.freedesktop.org/drm/intel/issues/6228
  [i915#6268]: https://gitlab.freedesktop.org/drm/intel/issues/6268
  [i915#6335]: https://gitlab.freedesktop.org/drm/intel/issues/6335
  [i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
  [i915#6805]: https://gitlab.freedesktop.org/drm/intel/issues/6805
  [i915#6806]: https://gitlab.freedesktop.org/drm/intel/issues/6806
  [i915#6880]: https://gitlab.freedesktop.org/drm/intel/issues/6880
  [i915#7118]: https://gitlab.freedesktop.org/drm/intel/issues/7118
  [i915#7213]: https://gitlab.freedesktop.org/drm/intel/issues/7213
  [i915#7387]: https://gitlab.freedesktop.org/drm/intel/issues/7387
  [i915#7484]: https://gitlab.freedesktop.org/drm/intel/issues/7484
  [i915#7582]: https://gitlab.freedesktop.org/drm/intel/issues/7582
  [i915#7697]: https://gitlab.freedesktop.org/drm/intel/issues/7697
  [i915#7701]: https://gitlab.freedesktop.org/drm/intel/issues/7701
  [i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
  [i915#7742]: https://gitlab.freedesktop.org/drm/intel/issues/7742
  [i915#7790]: https://gitlab.freedesktop.org/drm/intel/issues/7790
  [i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
  [i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
  [i915#8228]: https://gitlab.freedesktop.org/drm/intel/issues/8228
  [i915#8289]: https://gitlab.freedesktop.org/drm/intel/issues/8289
  [i915#8411]: https://gitlab.freedesktop.org/drm/intel/issues/8411
  [i915#8414]: https://gitlab.freedesktop.org/drm/intel/issues/8414
  [i915#8428]: https://gitlab.freedesktop.org/drm/intel/issues/8428
  [i915#8430]: https://gitlab.freedesktop.org/drm/intel/issues/8430
  [i915#8555]: https://gitlab.freedesktop.org/drm/intel/issues/8555
  [i915#8623]: https://gitlab.freedesktop.org/drm/intel/issues/8623
  [i915#8708]: https://gitlab.freedesktop.org/drm/intel/issues/8708
  [i915#8709]: https://gitlab.freedesktop.org/drm/intel/issues/8709
  [i915#8809]: https://gitlab.freedesktop.org/drm/intel/issues/8809
  [i915#8810]: https://gitlab.freedesktop.org/drm/intel/issues/8810
  [i915#8814]: https://gitlab.freedesktop.org/drm/intel/issues/8814
  [i915#8816]: https://gitlab.freedesktop.org/drm/intel/issues/8816
  [i915#8821]: https://gitlab.freedesktop.org/drm/intel/issues/8821
  [i915#8875]: https://gitlab.freedesktop.org/drm/intel/issues/8875
  [i915#9067]: https://gitlab.freedesktop.org/drm/intel/issues/9067
  [i915#9196]: https://gitlab.freedesktop.org/drm/intel/issues/9196
  [i915#9295]: https://gitlab.freedesktop.org/drm/intel/issues/9295
  [i915#9408]: https://gitlab.freedesktop.org/drm/intel/issues/9408
  [i915#9412]: https://gitlab.freedesktop.org/drm/intel/issues/9412
  [i915#9423]: https://gitlab.freedesktop.org/drm/intel/issues/9423
  [i915#9424]: https://gitlab.freedesktop.org/drm/intel/issues/9424
  [i915#9519]: https://gitlab.freedesktop.org/drm/intel/issues/9519
  [i915#9606]: https://gitlab.freedesktop.org/drm/intel/issues/9606
  [i915#9618]: https://gitlab.freedesktop.org/drm/intel/issues/9618
  [i915#9683]: https://gitlab.freedesktop.org/drm/intel/issues/9683
  [i915#9688]: https://gitlab.freedesktop.org/drm/intel/issues/9688
  [i915#9723]: https://gitlab.freedesktop.org/drm/intel/issues/9723
  [i915#9732]: https://gitlab.freedesktop.org/drm/intel/issues/9732
  [i915#9820]: https://gitlab.freedesktop.org/drm/intel/issues/9820
  [i915#9833]: https://gitlab.freedesktop.org/drm/intel/issues/9833
  [i915#9849]: https://gitlab.freedesktop.org/drm/intel/issues/9849
  [i915#9906]: https://gitlab.freedesktop.org/drm/intel/issues/9906
  [i915#9917]: https://gitlab.freedesktop.org/drm/intel/issues/9917


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

  * Linux: CI_DRM_14305 -> Patchwork_129082v2
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_14305: 4b8a238dee9c18201f3652695414587cd2ef6d8f @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7718: 40e8b9122853f455c84afcfa56469a6bc9a0d564 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_129082v2: 4b8a238dee9c18201f3652695414587cd2ef6d8f @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

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

* RE: [PATCH v2 02/21] drm/dp: Add support for DP tunneling
  2024-02-20 21:18 ` [PATCH v2 02/21] drm/dp: Add support for DP tunneling Imre Deak
@ 2024-02-23  6:25   ` Shankar, Uma
  2024-02-23 14:33     ` Imre Deak
  2024-02-23 21:32   ` Ville Syrjälä
  2024-02-26 18:52   ` [PATCH v3 " Imre Deak
  2 siblings, 1 reply; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23  6:25 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel; +Cc: Ville Syrjälä



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:48 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Subject: [PATCH v2 02/21] drm/dp: Add support for DP tunneling
> 
> Add support for Display Port tunneling. For now this includes the
> support for Bandwidth Allocation Mode (BWA), leaving adding Panel Replay
> support for later.
> 
> BWA allows using displays that share the same (Thunderbolt) link with
> their maximum resolution. Atm, this may not be possible due to the
> coarse granularity of partitioning the link BW among the displays on the
> link: the BW allocation policy is in a SW/FW/HW component on the link
> (on Thunderbolt it's the SW or FW Connection Manager), independent of
> the driver. This policy will set the DPRX maximum rate and lane count
> DPCD registers the GFX driver will see (0x00000, 0x00001, 0x02200,
> 0x02201) based on the available link BW.
> 
> The granularity of the current BW allocation policy is coarse, based on
> the required link rate in the 1.62Gbs..8.1Gbps range and it may prevent
> using higher resolutions all together: the display connected first will
> get a share of the link BW which corresponds to its full DPRX capability
> (regardless of the actual mode it uses). A subsequent display connected
> will only get the remaining BW, which could be well below its full
> capability.
> 
> BWA solves the above coarse granularity (reducing it to a 250Mbs..1Gps
> range) and first-come/first-served issues by letting the driver request
> the BW for each display on a link which reflects the actual modes the
> displays use.
> 
> This patch adds the DRM core helper functions, while a follow-up change
> in the patchset takes them into use in the i915 driver.
> 
> v2:
> - Fix prepare_to_wait vs. wake-up cond check order in
>   allocate_tunnel_bw(). (Ville)
> - Move tunnel==NULL checks from callers in drivers to here. (Ville)
> - Avoid var inits in declaration blocks that can fail or have
>   side-effects. (Ville)
> - Use u8 for driver and group IDs. (Ville)
> - Simplify API removing drm_dp_tunnel_get/put_untracked(). (Ville)
> - Reuse str_yes_no() instead of a local yes_no_chr(). (Ville)
> - s/drm_dp_tunnel_atomic_clear_state()/free_tunnel_state() and unexport
>   the function. (Ville)
> - s/clear_tunnel_group_state()/free_group_state() and move kfree() to
>   this function. (Ville)
> - Add separate group_free_bw() helper and describe what the tunnel
>   estimated BW includes. (Ville)
> - Improve help text for CONFIG_DRM_DISPLAY_DP_TUNNEL. (Ville)
> - Add code comment explaining the purpose of DPCD reg read helpers.
>   (Ville)
> - Add code comment describing the tunnel group name prefix format.
>   (Ville)
> - Report the allocated BW as undetermined until the first allocation
>   request.
> - Skip allocation requests matching the previous request.
> - Clear any stale BW request status flags before a new request.
> - Add missing error return check of drm_dp_tunnel_atomic_get_group_state()
>   in drm_dp_tunnel_atomic_set_stream_bw().
> - Add drm_dp_tunnel_get_allocated_bw().
> -
> s/drm_dp_tunnel_atomic_get_tunnel_bw/drm_dp_tunnel_atomic_get_required_
> bw
> - Fix return value description in function doc of drm_dp_tunnel_detect().
> - Add function documentation to all exported functions.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/display/Kconfig         |   21 +
>  drivers/gpu/drm/display/Makefile        |    2 +
>  drivers/gpu/drm/display/drm_dp_tunnel.c | 1929 +++++++++++++++++++++++
>  include/drm/display/drm_dp.h            |   60 +
>  include/drm/display/drm_dp_tunnel.h     |  248 +++
>  5 files changed, 2260 insertions(+)
>  create mode 100644 drivers/gpu/drm/display/drm_dp_tunnel.c
>  create mode 100644 include/drm/display/drm_dp_tunnel.h
> 
> diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
> index 09712b88a5b83..c0f56888c3280 100644
> --- a/drivers/gpu/drm/display/Kconfig
> +++ b/drivers/gpu/drm/display/Kconfig
> @@ -17,6 +17,27 @@ config DRM_DISPLAY_DP_HELPER
>  	help
>  	  DRM display helpers for DisplayPort.
> 
> +config DRM_DISPLAY_DP_TUNNEL
> +	bool
> +	select DRM_DISPLAY_DP_HELPER
> +	help
> +	  Enable support for DisplayPort tunnels. This allows drivers to use
> +	  DP tunnel features like the Bandwidth Allocation mode to maximize the
> +	  BW utilization for display streams on Thunderbolt links.
> +
> +config DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> +	bool "Enable debugging the DP tunnel state"
> +	depends on REF_TRACKER
> +	depends on DRM_DISPLAY_DP_TUNNEL
> +	depends on DEBUG_KERNEL
> +	depends on EXPERT
> +	help
> +	  Enables debugging the DP tunnel manager's state, including the
> +	  consistency of all managed tunnels' reference counting and the state of
> +	  streams contained in tunnels.
> +
> +	  If in doubt, say "N".
> +
>  config DRM_DISPLAY_HDCP_HELPER
>  	bool
>  	depends on DRM_DISPLAY_HELPER
> diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
> index 17ac4a1006a80..7ca61333c6696 100644
> --- a/drivers/gpu/drm/display/Makefile
> +++ b/drivers/gpu/drm/display/Makefile
> @@ -8,6 +8,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER)
> += \
>  	drm_dp_helper.o \
>  	drm_dp_mst_topology.o \
>  	drm_dsc_helper.o
> +drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \
> +	drm_dp_tunnel.o
>  drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) +=
> drm_hdcp_helper.o
>  drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
>  	drm_hdmi_helper.o \
> diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c
> b/drivers/gpu/drm/display/drm_dp_tunnel.c
> new file mode 100644
> index 0000000000000..919337eabb313
> --- /dev/null
> +++ b/drivers/gpu/drm/display/drm_dp_tunnel.c
> @@ -0,0 +1,1929 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#include <linux/ref_tracker.h>
> +#include <linux/types.h>
> +
> +#include <drm/drm_atomic_state_helper.h>
> +
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_print.h>
> +#include <drm/display/drm_dp.h>
> +#include <drm/display/drm_dp_helper.h>
> +#include <drm/display/drm_dp_tunnel.h>
> +
> +#define to_group(__private_obj) \
> +	container_of(__private_obj, struct drm_dp_tunnel_group, base)
> +
> +#define to_group_state(__private_state) \
> +	container_of(__private_state, struct drm_dp_tunnel_group_state, base)
> +
> +#define is_dp_tunnel_private_obj(__obj) \
> +	((__obj)->funcs == &tunnel_group_funcs)
> +
> +#define for_each_new_group_in_state(__state, __new_group_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->num_private_objs; \
> +	     (__i)++) \
> +		for_each_if ((__state)->private_objs[__i].ptr && \
> +			     is_dp_tunnel_private_obj((__state)-
> >private_objs[__i].ptr) && \
> +			     ((__new_group_state) = \
> +				to_group_state((__state)-
> >private_objs[__i].new_state), 1))
> +
> +#define for_each_old_group_in_state(__state, __old_group_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->num_private_objs; \
> +	     (__i)++) \
> +		for_each_if ((__state)->private_objs[__i].ptr && \
> +			     is_dp_tunnel_private_obj((__state)-
> >private_objs[__i].ptr) && \
> +			     ((__old_group_state) = \
> +				to_group_state((__state)-
> >private_objs[__i].old_state), 1))
> +
> +#define for_each_tunnel_in_group(__group, __tunnel) \
> +	list_for_each_entry(__tunnel, &(__group)->tunnels, node)
> +
> +#define for_each_tunnel_state(__group_state, __tunnel_state) \
> +	list_for_each_entry(__tunnel_state, &(__group_state)->tunnel_states,
> node)
> +
> +#define for_each_tunnel_state_safe(__group_state, __tunnel_state,
> __tunnel_state_tmp) \
> +	list_for_each_entry_safe(__tunnel_state, __tunnel_state_tmp, \
> +				 &(__group_state)->tunnel_states, node)
> +
> +#define kbytes_to_mbits(__kbytes) \
> +	DIV_ROUND_UP((__kbytes) * 8, 1000)
> +
> +#define DPTUN_BW_ARG(__bw) ((__bw) < 0 ? (__bw) : kbytes_to_mbits(__bw))
> +
> +#define __tun_prn(__tunnel, __level, __type, __fmt, ...) \
> +	drm_##__level##__type((__tunnel)->group->mgr->dev, \
> +			      "[DPTUN %s][%s] " __fmt, \
> +			      drm_dp_tunnel_name(__tunnel), \
> +			      (__tunnel)->aux->name, ## \
> +			      __VA_ARGS__)
> +
> +#define tun_dbg(__tunnel, __fmt, ...) \
> +	__tun_prn(__tunnel, dbg, _kms, __fmt, ## __VA_ARGS__)
> +
> +#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
> +	if (__err) \
> +		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
> +			  ## __VA_ARGS__, ERR_PTR(__err)); \
> +	else \
> +		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
> +			  ## __VA_ARGS__); \
> +} while (0)
> +
> +#define tun_dbg_atomic(__tunnel, __fmt, ...) \
> +	__tun_prn(__tunnel, dbg, _atomic, __fmt, ## __VA_ARGS__)
> +
> +#define tun_grp_dbg(__group, __fmt, ...) \
> +	drm_dbg_kms((__group)->mgr->dev, \
> +		    "[DPTUN %s] " __fmt, \
> +		    drm_dp_tunnel_group_name(__group), ## \
> +		    __VA_ARGS__)
> +
> +#define DP_TUNNELING_BASE DP_TUNNELING_OUI
> +
> +#define __DPTUN_REG_RANGE(start, size) \
> +	GENMASK_ULL(start + size - 1, start)
> +
> +#define DPTUN_REG_RANGE(addr, size) \
> +	__DPTUN_REG_RANGE((addr) - DP_TUNNELING_BASE, size)
> +
> +#define DPTUN_REG(addr) DPTUN_REG_RANGE(addr, 1)
> +
> +#define DPTUN_INFO_REG_MASK ( \
> +	DPTUN_REG_RANGE(DP_TUNNELING_OUI,
> DP_TUNNELING_OUI_BYTES) | \
> +	DPTUN_REG_RANGE(DP_TUNNELING_DEV_ID,
> DP_TUNNELING_DEV_ID_BYTES) | \
> +	DPTUN_REG(DP_TUNNELING_HW_REV) | \
> +	DPTUN_REG(DP_TUNNELING_SW_REV_MAJOR) | \
> +	DPTUN_REG(DP_TUNNELING_SW_REV_MINOR) | \
> +	DPTUN_REG(DP_TUNNELING_CAPABILITIES) | \
> +	DPTUN_REG(DP_IN_ADAPTER_INFO) | \
> +	DPTUN_REG(DP_USB4_DRIVER_ID) | \
> +	DPTUN_REG(DP_USB4_DRIVER_BW_CAPABILITY) | \
> +	DPTUN_REG(DP_IN_ADAPTER_TUNNEL_INFORMATION) | \
> +	DPTUN_REG(DP_BW_GRANULARITY) | \
> +	DPTUN_REG(DP_ESTIMATED_BW) | \
> +	DPTUN_REG(DP_ALLOCATED_BW) | \
> +	DPTUN_REG(DP_TUNNELING_MAX_LINK_RATE) | \
> +	DPTUN_REG(DP_TUNNELING_MAX_LANE_COUNT) | \
> +	DPTUN_REG(DP_DPTX_BW_ALLOCATION_MODE_CONTROL))
> +
> +static const DECLARE_BITMAP(dptun_info_regs, 64) = {
> +	DPTUN_INFO_REG_MASK & -1UL,
> +#if BITS_PER_LONG == 32
> +	DPTUN_INFO_REG_MASK >> 32,
> +#endif
> +};
> +
> +struct drm_dp_tunnel_regs {
> +	u8 buf[HWEIGHT64(DPTUN_INFO_REG_MASK)];
> +};
> +
> +struct drm_dp_tunnel_group;
> +
> +struct drm_dp_tunnel {
> +	struct drm_dp_tunnel_group *group;
> +
> +	struct list_head node;
> +
> +	struct kref kref;
> +	struct ref_tracker *tracker;
> +	struct drm_dp_aux *aux;
> +	char name[8];
> +
> +	int bw_granularity;
> +	int estimated_bw;
> +	int allocated_bw;
> +
> +	int max_dprx_rate;
> +	u8 max_dprx_lane_count;
> +
> +	u8 adapter_id;
> +
> +	bool bw_alloc_supported:1;
> +	bool bw_alloc_enabled:1;
> +	bool has_io_error:1;
> +	bool destroyed:1;
> +};
> +
> +struct drm_dp_tunnel_group_state;
> +
> +struct drm_dp_tunnel_state {
> +	struct drm_dp_tunnel_group_state *group_state;
> +
> +	struct drm_dp_tunnel_ref tunnel_ref;
> +
> +	struct list_head node;
> +
> +	u32 stream_mask;
> +	int *stream_bw;
> +};
> +
> +struct drm_dp_tunnel_group_state {
> +	struct drm_private_state base;
> +
> +	struct list_head tunnel_states;
> +};
> +
> +struct drm_dp_tunnel_group {
> +	struct drm_private_obj base;
> +	struct drm_dp_tunnel_mgr *mgr;
> +
> +	struct list_head tunnels;
> +
> +	/* available BW including the allocated_bw of all tunnels in the group */
> +	int available_bw;
> +	u8 drv_group_id;
> +
> +	char name[8];
> +

We can drop these line gaps.

> +	bool active:1;
> +};
> +
> +struct drm_dp_tunnel_mgr {
> +	struct drm_device *dev;
> +
> +	int group_count;
> +	struct drm_dp_tunnel_group *groups;
> +	wait_queue_head_t bw_req_queue;
> +
> +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> +	struct ref_tracker_dir ref_tracker;
> +#endif
> +};
> +
> +/*
> + * The following helpers provide a way to read out the tunneling DPCD
> + * registers with a minimal amount of AUX transfers (1 transfer per contiguous
> + * range, as permitted by the 16 byte per transfer AUX limit), not accessing
> + * other registers to avoid any read side-effects.
> + */
> +static int next_reg_area(int *offset)
> +{
> +	*offset = find_next_bit(dptun_info_regs, 64, *offset);
> +
> +	return find_next_zero_bit(dptun_info_regs, 64, *offset + 1) - *offset;
> +}
> +
> +#define tunnel_reg_ptr(__regs, __address) ({ \
> +	WARN_ON(!test_bit((__address) - DP_TUNNELING_BASE,
> dptun_info_regs)); \
> +	&(__regs)->buf[bitmap_weight(dptun_info_regs, (__address) -
> DP_TUNNELING_BASE)]; \
> +})
> +
> +static int read_tunnel_regs(struct drm_dp_aux *aux, struct drm_dp_tunnel_regs
> *regs)
> +{
> +	int offset = 0;
> +	int len;
> +
> +	while ((len = next_reg_area(&offset))) {
> +		int address = DP_TUNNELING_BASE + offset;
> +
> +		if (drm_dp_dpcd_read(aux, address, tunnel_reg_ptr(regs,
> address), len) < 0)
> +			return -EIO;
> +
> +		offset += len;
> +	}
> +
> +	return 0;
> +}
> +
> +static u8 tunnel_reg(const struct drm_dp_tunnel_regs *regs, int address)
> +{
> +	return *tunnel_reg_ptr(regs, address);
> +}
> +
> +static u8 tunnel_reg_drv_group_id(const struct drm_dp_tunnel_regs *regs)
> +{
> +	u8 drv_id = tunnel_reg(regs, DP_USB4_DRIVER_ID) &
> DP_USB4_DRIVER_ID_MASK;
> +	u8 group_id = tunnel_reg(regs,
> DP_IN_ADAPTER_TUNNEL_INFORMATION) & DP_GROUP_ID_MASK;
> +
> +	if (!group_id)
> +		return 0;
> +
> +	return (drv_id << DP_GROUP_ID_BITS) | group_id;
> +}
> +
> +/* Return granularity in kB/s units */
> +static int tunnel_reg_bw_granularity(const struct drm_dp_tunnel_regs *regs)
> +{
> +	int gr = tunnel_reg(regs, DP_BW_GRANULARITY) &
> DP_BW_GRANULARITY_MASK;
> +
> +	WARN_ON(gr > 2);
> +

I think it should fail as well along with WARN, > 2 is not supported.
However, this situation is highly unlikely though.

> +	return (250000 << gr) / 8;


> +}
> +
> +static int tunnel_reg_max_dprx_rate(const struct drm_dp_tunnel_regs *regs)
> +{
> +	u8 bw_code = tunnel_reg(regs, DP_TUNNELING_MAX_LINK_RATE);
> +
> +	return drm_dp_bw_code_to_link_rate(bw_code);
> +}
> +
> +static int tunnel_reg_max_dprx_lane_count(const struct drm_dp_tunnel_regs
> *regs)
> +{
> +	return tunnel_reg(regs, DP_TUNNELING_MAX_LANE_COUNT) &
> +	       DP_TUNNELING_MAX_LANE_COUNT_MASK;
> +}
> +
> +static bool tunnel_reg_bw_alloc_supported(const struct drm_dp_tunnel_regs
> *regs)
> +{
> +	u8 cap_mask = DP_TUNNELING_SUPPORT |
> DP_IN_BW_ALLOCATION_MODE_SUPPORT;
> +
> +	if ((tunnel_reg(regs, DP_TUNNELING_CAPABILITIES) & cap_mask) !=
> cap_mask)
> +		return false;
> +
> +	return tunnel_reg(regs, DP_USB4_DRIVER_BW_CAPABILITY) &
> +	       DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT;
> +}
> +
> +static bool tunnel_reg_bw_alloc_enabled(const struct drm_dp_tunnel_regs
> *regs)
> +{
> +	return tunnel_reg(regs, DP_DPTX_BW_ALLOCATION_MODE_CONTROL)
> &
> +	       DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE;
> +}
> +
> +static u8 tunnel_group_drv_id(u8 drv_group_id)
> +{
> +	return drv_group_id >> DP_GROUP_ID_BITS;
> +}
> +
> +static u8 tunnel_group_id(u8 drv_group_id)
> +{
> +	return drv_group_id & DP_GROUP_ID_MASK;
> +}
> +
> +const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel->name;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_name);
> +
> +static const char *drm_dp_tunnel_group_name(const struct
> drm_dp_tunnel_group *group)
> +{
> +	return group->name;
> +}
> +
> +static struct drm_dp_tunnel_group *
> +lookup_or_alloc_group(struct drm_dp_tunnel_mgr *mgr, u8 drv_group_id)
> +{
> +	struct drm_dp_tunnel_group *group = NULL;
> +	int i;
> +
> +	for (i = 0; i < mgr->group_count; i++) {
> +		/*
> +		 * A tunnel group with 0 group ID shouldn't have more than one
> +		 * tunnels.
> +		 */
> +		if (tunnel_group_id(drv_group_id) &&
> +		    mgr->groups[i].drv_group_id == drv_group_id)
> +			return &mgr->groups[i];
> +
> +		if (!group && !mgr->groups[i].active)
> +			group = &mgr->groups[i];
> +	}
> +
> +	if (!group) {
> +		drm_dbg_kms(mgr->dev,
> +			    "DPTUN: Can't allocate more tunnel groups\n");
> +		return NULL;
> +	}
> +
> +	group->drv_group_id = drv_group_id;
> +	group->active = true;
> +
> +	/*
> +	 * The group name format here and elsewhere: Driver-ID:Group-ID:*
> +	 * (* standing for all DP-Adapters/tunnels in the group).
> +	 */
> +	snprintf(group->name, sizeof(group->name), "%d:%d:*",
> +		 tunnel_group_drv_id(drv_group_id) & ((1 <<
> DP_GROUP_ID_BITS) - 1),
> +		 tunnel_group_id(drv_group_id) & ((1 <<
> DP_USB4_DRIVER_ID_BITS) - 1));
> +
> +	return group;
> +}
> +
> +static void free_group(struct drm_dp_tunnel_group *group)
> +{
> +	struct drm_dp_tunnel_mgr *mgr = group->mgr;
> +
> +	if (drm_WARN_ON(mgr->dev, !list_empty(&group->tunnels)))
> +		return;
> +
> +	group->drv_group_id = 0;
> +	group->available_bw = -1;
> +	group->active = false;
> +}
> +
> +static struct drm_dp_tunnel *
> +tunnel_get(struct drm_dp_tunnel *tunnel)
> +{
> +	kref_get(&tunnel->kref);
> +
> +	return tunnel;
> +}
> +
> +static void free_tunnel(struct kref *kref)
> +{
> +	struct drm_dp_tunnel *tunnel = container_of(kref, typeof(*tunnel), kref);
> +	struct drm_dp_tunnel_group *group = tunnel->group;
> +
> +	list_del(&tunnel->node);
> +	if (list_empty(&group->tunnels))
> +		free_group(group);
> +
> +	kfree(tunnel);
> +}
> +
> +static void tunnel_put(struct drm_dp_tunnel *tunnel)
> +{
> +	kref_put(&tunnel->kref, free_tunnel);
> +}
> +
> +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> +static void track_tunnel_ref(struct drm_dp_tunnel *tunnel,
> +			     struct ref_tracker **tracker)
> +{
> +	ref_tracker_alloc(&tunnel->group->mgr->ref_tracker,
> +			  tracker, GFP_KERNEL);
> +}
> +
> +static void untrack_tunnel_ref(struct drm_dp_tunnel *tunnel,
> +			       struct ref_tracker **tracker)
> +{
> +	ref_tracker_free(&tunnel->group->mgr->ref_tracker,
> +			 tracker);
> +}
> +#else
> +static void track_tunnel_ref(struct drm_dp_tunnel *tunnel,
> +			     struct ref_tracker **tracker)
> +{
> +}
> +
> +static void untrack_tunnel_ref(struct drm_dp_tunnel *tunnel,
> +			       struct ref_tracker **tracker)
> +{
> +}
> +#endif
> +
> +/**
> + * drm_dp_tunnel_get - Get a reference for a DP tunnel
> + * @tunnel: Tunnel object
> + * @tracker: Debug tracker for the reference
> + *
> + * Get a reference for @tunnel, along with a debug tracker to help locating
> + * the source of a reference leak/double reference put etc. issue.
> + *
> + * The reference must be dropped after use calling drm_dp_tunnel_put()
> + * passing @tunnel and *@tracker returned from here.
> + *
> + * Returns @tunnel - as a convenience - along with *@tracker.
> + */
> +struct drm_dp_tunnel *
> +drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel,
> +		  struct ref_tracker **tracker)
> +{
> +	track_tunnel_ref(tunnel, tracker);
> +
> +	return tunnel_get(tunnel);
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_get);
> +
> +/**
> + * drm_dp_tunnel_put - Put a reference for a DP tunnel
> + * @tunnel - Tunnel object
> + * @tracker - Debug tracker for the reference
> + *
> + * Put a reference for @tunnel along with its debug *@tracker, which
> + * was obtained with drm_dp_tunnel_get().
> + */
> +void drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel,
> +			 struct ref_tracker **tracker)
> +{
> +	untrack_tunnel_ref(tunnel, tracker);
> +
> +	tunnel_put(tunnel);
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_put);
> +
> +static bool add_tunnel_to_group(struct drm_dp_tunnel_mgr *mgr,
> +				u8 drv_group_id,
> +				struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_group *group;
> +
> +	group = lookup_or_alloc_group(mgr, drv_group_id);
> +	if (!group)
> +		return false;
> +
> +	tunnel->group = group;
> +	list_add(&tunnel->node, &group->tunnels);
> +
> +	return true;
> +}
> +
> +static struct drm_dp_tunnel *
> +create_tunnel(struct drm_dp_tunnel_mgr *mgr,
> +	      struct drm_dp_aux *aux,
> +	      const struct drm_dp_tunnel_regs *regs)
> +{
> +	u8 drv_group_id = tunnel_reg_drv_group_id(regs);
> +	struct drm_dp_tunnel *tunnel;
> +
> +	tunnel = kzalloc(sizeof(*tunnel), GFP_KERNEL);
> +	if (!tunnel)
> +		return NULL;
> +
> +	INIT_LIST_HEAD(&tunnel->node);
> +
> +	kref_init(&tunnel->kref);
> +
> +	tunnel->aux = aux;
> +
> +	tunnel->adapter_id = tunnel_reg(regs, DP_IN_ADAPTER_INFO) &
> DP_IN_ADAPTER_NUMBER_MASK;
> +
> +	snprintf(tunnel->name, sizeof(tunnel->name), "%d:%d:%d",
> +		 tunnel_group_drv_id(drv_group_id) & ((1 <<
> DP_GROUP_ID_BITS) - 1),
> +		 tunnel_group_id(drv_group_id) & ((1 <<
> DP_USB4_DRIVER_ID_BITS) - 1),
> +		 tunnel->adapter_id & ((1 << DP_IN_ADAPTER_NUMBER_BITS) -
> 1));
> +
> +	tunnel->bw_granularity = tunnel_reg_bw_granularity(regs);
> +	tunnel->allocated_bw = tunnel_reg(regs, DP_ALLOCATED_BW) *
> +			       tunnel->bw_granularity;
> +	/*
> +	 * An initial allocated BW of 0 indicates an undefined state: the
> +	 * actual allocation is determined by the TBT CM, usually following a
> +	 * legacy allocation policy (based on the max DPRX caps). From the
> +	 * driver's POV the state becomes defined only after the first
> +	 * allocation request.
> +	 */
> +	if (!tunnel->allocated_bw)
> +		tunnel->allocated_bw = -1;
> +
> +	tunnel->bw_alloc_supported = tunnel_reg_bw_alloc_supported(regs);
> +	tunnel->bw_alloc_enabled = tunnel_reg_bw_alloc_enabled(regs);
> +
> +	if (!add_tunnel_to_group(mgr, drv_group_id, tunnel)) {
> +		kfree(tunnel);
> +
> +		return NULL;
> +	}
> +
> +	track_tunnel_ref(tunnel, &tunnel->tracker);
> +
> +	return tunnel;
> +}
> +
> +static void destroy_tunnel(struct drm_dp_tunnel *tunnel)
> +{
> +	untrack_tunnel_ref(tunnel, &tunnel->tracker);
> +	tunnel_put(tunnel);
> +}
> +
> +/**
> + * drm_dp_tunnel_set_io_error - Set the IO error flag for a DP tunnel
> + * @tunnel: Tunnel object
> + *
> + * Set the IO error flag for @tunnel. Drivers can call this function upon
> + * detecting a failure that affects the tunnel functionality, for instance
> + * after a DP AUX transfer failure on the port @tunnel is connected to.
> + *
> + * This disables further management of @tunnel, including any related
> + * AUX accesses for tunneling DPCD registers, returning error to the
> + * initiators of these. The driver is supposed to drop this tunnel and -
> + * optionally - recreate it.
> + */
> +void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel)
> +{
> +	tunnel->has_io_error = true;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_set_io_error);
> +
> +#define SKIP_DPRX_CAPS_CHECK		BIT(0)
> +#define ALLOW_ALLOCATED_BW_CHANGE	BIT(1)
> +static bool tunnel_regs_are_valid(struct drm_dp_tunnel_mgr *mgr,
> +				  const struct drm_dp_tunnel_regs *regs,
> +				  unsigned int flags)
> +{
> +	u8 drv_group_id = tunnel_reg_drv_group_id(regs);
> +	bool check_dprx = !(flags & SKIP_DPRX_CAPS_CHECK);
> +	bool ret = true;
> +
> +	if (!tunnel_reg_bw_alloc_supported(regs)) {
> +		if (tunnel_group_id(drv_group_id)) {
> +			drm_dbg_kms(mgr->dev,
> +				    "DPTUN: A non-zero group ID is only allowed
> with BWA support\n");
> +			ret = false;
> +		}
> +
> +		if (tunnel_reg(regs, DP_ALLOCATED_BW)) {
> +			drm_dbg_kms(mgr->dev,
> +				    "DPTUN: BW is allocated without BWA
> support\n");
> +			ret = false;
> +		}
> +
> +		return ret;
> +	}
> +
> +	if (!tunnel_group_id(drv_group_id)) {
> +		drm_dbg_kms(mgr->dev,
> +			    "DPTUN: BWA support requires a non-zero group
> ID\n");
> +		ret = false;
> +	}
> +
> +	if (check_dprx && hweight8(tunnel_reg_max_dprx_lane_count(regs)) !=
> 1) {
> +		drm_dbg_kms(mgr->dev,
> +			    "DPTUN: Invalid DPRX lane count: %d\n",
> +			    tunnel_reg_max_dprx_lane_count(regs));
> +
> +		ret = false;
> +	}
> +
> +	if (check_dprx && !tunnel_reg_max_dprx_rate(regs)) {
> +		drm_dbg_kms(mgr->dev,
> +			    "DPTUN: DPRX rate is 0\n");
> +
> +		ret = false;
> +	}
> +
> +	if (tunnel_reg(regs, DP_ALLOCATED_BW) > tunnel_reg(regs,
> DP_ESTIMATED_BW)) {
> +		drm_dbg_kms(mgr->dev,
> +			    "DPTUN: Allocated BW %d > estimated BW %d
> Mb/s\n",
> +			    DPTUN_BW_ARG(tunnel_reg(regs,
> DP_ALLOCATED_BW) *
> +					 tunnel_reg_bw_granularity(regs)),
> +			    DPTUN_BW_ARG(tunnel_reg(regs,
> DP_ESTIMATED_BW) *
> +					 tunnel_reg_bw_granularity(regs)));
> +
> +		ret = false;
> +	}
> +
> +	return ret;
> +}
> +
> +static int tunnel_allocated_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	return max(tunnel->allocated_bw, 0);
> +}
> +
> +static bool tunnel_info_changes_are_valid(struct drm_dp_tunnel *tunnel,
> +					  const struct drm_dp_tunnel_regs
> *regs,
> +					  unsigned int flags)
> +{
> +	u8 new_drv_group_id = tunnel_reg_drv_group_id(regs);
> +	bool ret = true;
> +
> +	if (tunnel->bw_alloc_supported != tunnel_reg_bw_alloc_supported(regs))
> {
> +		tun_dbg(tunnel,
> +			"BW alloc support has changed %s -> %s\n",
> +			str_yes_no(tunnel->bw_alloc_supported),
> +			str_yes_no(tunnel_reg_bw_alloc_supported(regs)));
> +
> +		ret = false;
> +	}
> +
> +	if (tunnel->group->drv_group_id != new_drv_group_id) {
> +		tun_dbg(tunnel,
> +			"Driver/group ID has changed %d:%d:* -> %d:%d:*\n",
> +			tunnel_group_drv_id(tunnel->group->drv_group_id),
> +			tunnel_group_id(tunnel->group->drv_group_id),
> +			tunnel_group_drv_id(new_drv_group_id),
> +			tunnel_group_id(new_drv_group_id));
> +
> +		ret = false;
> +	}
> +
> +	if (!tunnel->bw_alloc_supported)
> +		return ret;
> +
> +	if (tunnel->bw_granularity != tunnel_reg_bw_granularity(regs)) {
> +		tun_dbg(tunnel,
> +			"BW granularity has changed: %d -> %d Mb/s\n",
> +			DPTUN_BW_ARG(tunnel->bw_granularity),
> +			DPTUN_BW_ARG(tunnel_reg_bw_granularity(regs)));
> +
> +		ret = false;
> +	}
> +
> +	/*
> +	 * On some devices at least the BW alloc mode enabled status is always
> +	 * reported as 0, so skip checking that here.
> +	 */
> +
> +	if (!(flags & ALLOW_ALLOCATED_BW_CHANGE) &&
> +	    tunnel_allocated_bw(tunnel) !=
> +	    tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity) {
> +		tun_dbg(tunnel,
> +			"Allocated BW has changed: %d -> %d Mb/s\n",
> +			DPTUN_BW_ARG(tunnel->allocated_bw),
> +			DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW)
> * tunnel->bw_granularity));
> +
> +		ret = false;
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +read_and_verify_tunnel_regs(struct drm_dp_tunnel *tunnel,
> +			    struct drm_dp_tunnel_regs *regs,
> +			    unsigned int flags)
> +{
> +	int err;
> +
> +	err = read_tunnel_regs(tunnel->aux, regs);
> +	if (err < 0) {
> +		drm_dp_tunnel_set_io_error(tunnel);
> +
> +		return err;
> +	}
> +
> +	if (!tunnel_regs_are_valid(tunnel->group->mgr, regs, flags))
> +		return -EINVAL;
> +
> +	if (!tunnel_info_changes_are_valid(tunnel, regs, flags))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static bool update_dprx_caps(struct drm_dp_tunnel *tunnel, const struct
> drm_dp_tunnel_regs *regs)
> +{
> +	bool changed = false;
> +
> +	if (tunnel_reg_max_dprx_rate(regs) != tunnel->max_dprx_rate) {
> +		tunnel->max_dprx_rate = tunnel_reg_max_dprx_rate(regs);
> +		changed = true;
> +	}
> +
> +	if (tunnel_reg_max_dprx_lane_count(regs) != tunnel-
> >max_dprx_lane_count) {
> +		tunnel->max_dprx_lane_count =
> tunnel_reg_max_dprx_lane_count(regs);
> +		changed = true;
> +	}
> +
> +	return changed;
> +}
> +
> +static int dev_id_len(const u8 *dev_id, int max_len)
> +{
> +	while (max_len && dev_id[max_len - 1] == '\0')
> +		max_len--;
> +
> +	return max_len;
> +}
> +
> +static int get_max_dprx_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	int max_dprx_bw = drm_dp_max_dprx_data_rate(tunnel-
> >max_dprx_rate,
> +						    tunnel-
> >max_dprx_lane_count);
> +
> +	/*
> +	 * A BW request of roundup(max_dprx_bw, tunnel->bw_granularity)
> results in
> +	 * an allocation of max_dprx_bw. A BW request above this rounded-up
> +	 * value will fail.
> +	 */
> +	return min(roundup(max_dprx_bw, tunnel->bw_granularity),
> +		   MAX_DP_REQUEST_BW * tunnel->bw_granularity);
> +}
> +
> +static int get_max_tunnel_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	return min(get_max_dprx_bw(tunnel), tunnel->group->available_bw);
> +}
> +
> +/**
> + * drm_dp_tunnel_detect - Detect DP tunnel on the link
> + * @mgr: Tunnel manager
> + * @aux: DP AUX on which the tunnel will be detected
> + *
> + * Detect if there is any DP tunnel on the link and add it to the tunnel
> + * group's tunnel list.
> + *
> + * Returns a pointer to a tunnel on success, or an ERR_PTR() error on
> + * failure.
> + */
> +struct drm_dp_tunnel *
> +drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
> +		     struct drm_dp_aux *aux)
> +{
> +	struct drm_dp_tunnel_regs regs;
> +	struct drm_dp_tunnel *tunnel;
> +	int err;
> +
> +	err = read_tunnel_regs(aux, &regs);
> +	if (err)
> +		return ERR_PTR(err);
> +
> +	if (!(tunnel_reg(&regs, DP_TUNNELING_CAPABILITIES) &
> +	      DP_TUNNELING_SUPPORT))
> +		return ERR_PTR(-ENODEV);
> +
> +	/* The DPRX caps are valid only after enabling BW alloc mode. */
> +	if (!tunnel_regs_are_valid(mgr, &regs, SKIP_DPRX_CAPS_CHECK))
> +		return ERR_PTR(-EINVAL);
> +
> +	tunnel = create_tunnel(mgr, aux, &regs);
> +	if (!tunnel)
> +		return ERR_PTR(-ENOMEM);
> +
> +	tun_dbg(tunnel,
> +		"OUI:%*phD DevID:%*pE Rev-HW:%d.%d SW:%d.%d PR-Sup:%s
> BWA-Sup:%s BWA-En:%s\n",
> +		DP_TUNNELING_OUI_BYTES,
> +			tunnel_reg_ptr(&regs, DP_TUNNELING_OUI),
> +		dev_id_len(tunnel_reg_ptr(&regs, DP_TUNNELING_DEV_ID),
> DP_TUNNELING_DEV_ID_BYTES),
> +			tunnel_reg_ptr(&regs, DP_TUNNELING_DEV_ID),
> +		(tunnel_reg(&regs, DP_TUNNELING_HW_REV) &
> DP_TUNNELING_HW_REV_MAJOR_MASK) >>
> +			DP_TUNNELING_HW_REV_MAJOR_SHIFT,
> +		(tunnel_reg(&regs, DP_TUNNELING_HW_REV) &
> DP_TUNNELING_HW_REV_MINOR_MASK) >>
> +			DP_TUNNELING_HW_REV_MINOR_SHIFT,
> +		tunnel_reg(&regs, DP_TUNNELING_SW_REV_MAJOR),
> +		tunnel_reg(&regs, DP_TUNNELING_SW_REV_MINOR),
> +		str_yes_no(tunnel_reg(&regs, DP_TUNNELING_CAPABILITIES) &
> +			   DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT),
> +		str_yes_no(tunnel->bw_alloc_supported),
> +		str_yes_no(tunnel->bw_alloc_enabled));
> +
> +	return tunnel;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_detect);
> +
> +/**
> + * drm_dp_tunnel_destroy - Destroy tunnel object
> + * @tunnel: Tunnel object
> + *
> + * Remove the tunnel from the tunnel topology and destroy it.
> + *
> + * Returns 0 on success, -ENODEV if the tunnel has been destroyed already.
> + */
> +int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
> +{
> +	if (!tunnel)
> +		return 0;
> +
> +	if (drm_WARN_ON(tunnel->group->mgr->dev, tunnel->destroyed))
> +		return -ENODEV;
> +
> +	tun_dbg(tunnel, "destroying\n");
> +
> +	tunnel->destroyed = true;
> +	destroy_tunnel(tunnel);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_destroy);
> +
> +static int check_tunnel(const struct drm_dp_tunnel *tunnel)
> +{
> +	if (tunnel->destroyed)
> +		return -ENODEV;
> +
> +	if (tunnel->has_io_error)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int group_allocated_bw(struct drm_dp_tunnel_group *group)
> +{
> +	struct drm_dp_tunnel *tunnel;
> +	int group_allocated_bw = 0;
> +
> +	for_each_tunnel_in_group(group, tunnel) {
> +		if (check_tunnel(tunnel) == 0 &&
> +		    tunnel->bw_alloc_enabled)
> +			group_allocated_bw += tunnel_allocated_bw(tunnel);
> +	}
> +
> +	return group_allocated_bw;
> +}
> +
> +/*
> + * The estimated BW reported by the TBT Connection Manager for each tunnel
> in
> + * a group includes the BW already allocated for the given tunnel and the
> + * unallocated BW which is free to be used by any tunnel in the group.
> + */
> +static int group_free_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel->estimated_bw - tunnel_allocated_bw(tunnel);
> +}
> +
> +static int calc_group_available_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	return group_allocated_bw(tunnel->group) +
> +	       group_free_bw(tunnel);
> +}
> +
> +static int update_group_available_bw(struct drm_dp_tunnel *tunnel,
> +				     const struct drm_dp_tunnel_regs *regs)
> +{
> +	struct drm_dp_tunnel *tunnel_iter;
> +	int group_available_bw;
> +	bool changed;
> +
> +	tunnel->estimated_bw = tunnel_reg(regs, DP_ESTIMATED_BW) * tunnel-
> >bw_granularity;
> +
> +	if (calc_group_available_bw(tunnel) == tunnel->group->available_bw)
> +		return 0;
> +
> +	for_each_tunnel_in_group(tunnel->group, tunnel_iter) {
> +		int err;
> +
> +		if (tunnel_iter == tunnel)
> +			continue;
> +
> +		if (check_tunnel(tunnel_iter) != 0 ||
> +		    !tunnel_iter->bw_alloc_enabled)
> +			continue;
> +
> +		err = drm_dp_dpcd_probe(tunnel_iter->aux, DP_DPCD_REV);
> +		if (err) {
> +			tun_dbg(tunnel_iter,
> +				"Probe failed, assume disconnected (err
> %pe)\n",
> +				ERR_PTR(err));
> +			drm_dp_tunnel_set_io_error(tunnel_iter);
> +		}
> +	}
> +
> +	group_available_bw = calc_group_available_bw(tunnel);
> +
> +	tun_dbg(tunnel, "Updated group available BW: %d->%d\n",
> +		DPTUN_BW_ARG(tunnel->group->available_bw),
> +		DPTUN_BW_ARG(group_available_bw));
> +
> +	changed = tunnel->group->available_bw != group_available_bw;
> +
> +	tunnel->group->available_bw = group_available_bw;
> +
> +	return changed ? 1 : 0;
> +}
> +
> +static int set_bw_alloc_mode(struct drm_dp_tunnel *tunnel, bool enable)
> +{
> +	u8 mask = DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE |
> DP_UNMASK_BW_ALLOCATION_IRQ;
> +	u8 val;
> +
> +	if (drm_dp_dpcd_readb(tunnel->aux,
> DP_DPTX_BW_ALLOCATION_MODE_CONTROL, &val) < 0)
> +		goto out_err;
> +
> +	if (enable)
> +		val |= mask;
> +	else
> +		val &= ~mask;
> +
> +	if (drm_dp_dpcd_writeb(tunnel->aux,
> DP_DPTX_BW_ALLOCATION_MODE_CONTROL, val) < 0)
> +		goto out_err;
> +
> +	tunnel->bw_alloc_enabled = enable;
> +
> +	return 0;
> +
> +out_err:
> +	drm_dp_tunnel_set_io_error(tunnel);
> +
> +	return -EIO;
> +}
> +
> +/**
> + * drm_dp_tunnel_enable_bw_alloc - Enable DP tunnel BW allocation mode
> + * @tunnel: Tunnel object
> + *
> + * Enable the DP tunnel BW allocation mode on @tunnel if it supports it.
> + *
> + * Returns 0 in case of success, negative error code otherwise.
> + */
> +int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_regs regs;
> +	int err;
> +
> +	err = check_tunnel(tunnel);
> +	if (err)
> +		return err;
> +
> +	if (!tunnel->bw_alloc_supported)
> +		return -EOPNOTSUPP;
> +
> +	if (!tunnel_group_id(tunnel->group->drv_group_id))
> +		return -EINVAL;
> +
> +	err = set_bw_alloc_mode(tunnel, true);
> +	if (err)
> +		goto out;
> +
> +	err = read_and_verify_tunnel_regs(tunnel, &regs, 0);
> +	if (err) {
> +		set_bw_alloc_mode(tunnel, false);
> +
> +		goto out;
> +	}
> +
> +	if (!tunnel->max_dprx_rate)
> +		update_dprx_caps(tunnel, &regs);
> +
> +	if (tunnel->group->available_bw == -1) {
> +		err = update_group_available_bw(tunnel, &regs);
> +		if (err > 0)
> +			err = 0;
> +	}
> +out:
> +	tun_dbg_stat(tunnel, err,
> +		     "Enabling BW alloc mode: DPRX:%dx%d Group alloc:%d/%d
> Mb/s",
> +		     tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
> +		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
> +		     DPTUN_BW_ARG(tunnel->group->available_bw));
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_enable_bw_alloc);
> +
> +/**
> + * drm_dp_tunnel_disable_bw_alloc - Disable DP tunnel BW allocation mode
> + * @tunnel: Tunnel object
> + *
> + * Disable the DP tunnel BW allocation mode on @tunnel.
> + *
> + * Returns 0 in case of success, negative error code otherwise.
> + */
> +int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel)
> +{
> +	int err;
> +
> +	err = check_tunnel(tunnel);
> +	if (err)
> +		return err;
> +
> +	tunnel->allocated_bw = -1;
> +
> +	err = set_bw_alloc_mode(tunnel, false);
> +
> +	tun_dbg_stat(tunnel, err, "Disabling BW alloc mode");
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_disable_bw_alloc);
> +
> +/**
> + * drm_dp_tunnel_bw_alloc_is_enabled - Query the BW allocation mode
> enabled state
> + * @tunnel: Tunnel object
> + *
> + * Query if the BW allocation mode is enabled for @tunnel.
> + *
> + * Returns %true if the BW allocation mode is enabled for @tunnel.
> + */
> +bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel && tunnel->bw_alloc_enabled;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_bw_alloc_is_enabled);
> +
> +static int clear_bw_req_state(struct drm_dp_aux *aux)
> +{
> +	u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED |
> DP_BW_REQUEST_FAILED;
> +
> +	if (drm_dp_dpcd_writeb(aux, DP_TUNNELING_STATUS, bw_req_mask) <
> 0)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int bw_req_complete(struct drm_dp_aux *aux, bool *status_changed)
> +{
> +	u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED |
> DP_BW_REQUEST_FAILED;
> +	u8 status_change_mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED
> | DP_ESTIMATED_BW_CHANGED;
> +	u8 val;
> +	int err;
> +
> +	if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
> +		return -EIO;
> +
> +	*status_changed = val & status_change_mask;
> +
> +	val &= bw_req_mask;
> +
> +	if (!val)
> +		return -EAGAIN;
> +
> +	err = clear_bw_req_state(aux);
> +	if (err < 0)
> +		return err;
> +
> +	return val == DP_BW_REQUEST_SUCCEEDED ? 0 : -ENOSPC;
> +}
> +
> +static int allocate_tunnel_bw(struct drm_dp_tunnel *tunnel, int bw)
> +{
> +	struct drm_dp_tunnel_mgr *mgr = tunnel->group->mgr;
> +	int request_bw = DIV_ROUND_UP(bw, tunnel->bw_granularity);
> +	DEFINE_WAIT_FUNC(wait, woken_wake_function);
> +	long timeout;
> +	int err;
> +
> +	if (bw < 0) {
> +		err = -EINVAL;
> +		goto out;
> +	}
> +
> +	if (request_bw * tunnel->bw_granularity == tunnel->allocated_bw)
> +		return 0;
> +
> +	/* Atomic check should prevent the following. */
> +	if (drm_WARN_ON(mgr->dev, request_bw > MAX_DP_REQUEST_BW)) {
> +		err = -EINVAL;
> +		goto out;
> +	}
> +
> +	err = clear_bw_req_state(tunnel->aux);
> +	if (err)
> +		goto out;
> +
> +	if (drm_dp_dpcd_writeb(tunnel->aux, DP_REQUEST_BW, request_bw) <
> 0) {
> +		err = -EIO;
> +		goto out;
> +	}
> +
> +	timeout = msecs_to_jiffies(3000);
> +	add_wait_queue(&mgr->bw_req_queue, &wait);
> +
> +	for (;;) {
> +		bool status_changed;
> +
> +		err = bw_req_complete(tunnel->aux, &status_changed);
> +		if (err != -EAGAIN)
> +			break;
> +
> +		if (status_changed) {
> +			struct drm_dp_tunnel_regs regs;
> +
> +			err = read_and_verify_tunnel_regs(tunnel, &regs,
> +
> ALLOW_ALLOCATED_BW_CHANGE);
> +			if (err)
> +				break;
> +		}
> +
> +		if (!timeout) {
> +			err = -ETIMEDOUT;
> +			break;
> +		}
> +
> +		timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE,
> timeout);
> +	};
> +
> +	remove_wait_queue(&mgr->bw_req_queue, &wait);
> +
> +	if (err)
> +		goto out;
> +
> +	tunnel->allocated_bw = request_bw * tunnel->bw_granularity;
> +
> +out:
> +	tun_dbg_stat(tunnel, err, "Allocating %d/%d Mb/s for tunnel: Group
> alloc:%d/%d Mb/s",
> +		     DPTUN_BW_ARG(request_bw * tunnel->bw_granularity),
> +		     DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
> +		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
> +		     DPTUN_BW_ARG(tunnel->group->available_bw));
> +
> +	if (err == -EIO)
> +		drm_dp_tunnel_set_io_error(tunnel);
> +
> +	return err;
> +}
> +
> +/**
> + * drm_dp_tunnel_alloc_bw - Allocate BW for a DP tunnel
> + * @tunnel: Tunnel object
> + * @bw: BW in kB/s units
> + *
> + * Allocate @bw kB/s for @tunnel. The allocated BW must be freed after use by
> + * calling this function for the same tunnel setting @bw to 0.
> + *
> + * Returns 0 in case of success, a negative error code otherwise.
> + */
> +int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
> +{
> +	int err;
> +
> +	err = check_tunnel(tunnel);
> +	if (err)
> +		return err;
> +
> +	return allocate_tunnel_bw(tunnel, bw);
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_alloc_bw);
> +
> +/**
> + * drm_dp_tunnel_atomic_get_allocated_bw - Get the BW allocated for a DP
> tunnel
> + * @tunnel: Tunnel object
> + *
> + * Get the current BW allocated for @tunnel. After the tunnel is created /
> + * resumed and the BW allocation mode is enabled for it, the allocation
> + * becomes determined only after the first allocation request by the driver
> + * calling drm_dp_tunnel_alloc_bw().
> + *
> + * Return the BW allocated for the tunnel, or -1 if the allocation is
> + * undetermined.
> + */
> +int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel->allocated_bw;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_get_allocated_bw);
> +
> +static int check_and_clear_status_change(struct drm_dp_tunnel *tunnel)
> +{
> +	u8 mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED |
> DP_ESTIMATED_BW_CHANGED;
> +	u8 val;
> +
> +	if (drm_dp_dpcd_readb(tunnel->aux, DP_TUNNELING_STATUS, &val) < 0)
> +		goto out_err;
> +
> +	val &= mask;
> +
> +	if (val) {
> +		if (drm_dp_dpcd_writeb(tunnel->aux, DP_TUNNELING_STATUS,
> val) < 0)
> +			goto out_err;
> +
> +		return 1;

Seems this return value is not considered by the caller. 

Hi Imre,
Overall changes look good to me.
It would be ideal if we can break this patch down, no major concern though.
Leaving to your judgment.

With some above minor nits addressed, this is
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

Note: Have checked the register definitions/addresses, offsets. Have Logically checked the code
in general, as well. It would be good if tunnel manager and tunnel groups related logic can be double
confirmed by someone. Having said that, no issue I could spot there.

Regards,
Uma Shankar

> +	}
> +
> +	if (!drm_dp_tunnel_bw_alloc_is_enabled(tunnel))
> +		return 0;
> +
> +	/*
> +	 * Check for estimated BW changes explicitly to account for lost
> +	 * BW change notifications.
> +	 */
> +	if (drm_dp_dpcd_readb(tunnel->aux, DP_ESTIMATED_BW, &val) < 0)
> +		goto out_err;
> +
> +	if (val * tunnel->bw_granularity != tunnel->estimated_bw)
> +		return 1;
> +
> +	return 0;
> +
> +out_err:
> +	drm_dp_tunnel_set_io_error(tunnel);
> +
> +	return -EIO;
> +}
> +
> +/**
> + * drm_dp_tunnel_update_state - Update DP tunnel SW state with the HW state
> + * @tunnel: Tunnel object
> + *
> + * Update the SW state of @tunnel with the HW state.
> + *
> + * Returns 0 if the state has not changed, 1 if it has changed and got updated
> + * successfully and a negative error code otherwise.
> + */
> +int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_regs regs;
> +	bool changed = false;
> +	int ret;
> +
> +	ret = check_tunnel(tunnel);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = check_and_clear_status_change(tunnel);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (!ret)
> +		return 0;
> +
> +	ret = read_and_verify_tunnel_regs(tunnel, &regs, 0);
> +	if (ret)
> +		goto out;
> +
> +	if (update_dprx_caps(tunnel, &regs))
> +		changed = true;
> +
> +	ret = update_group_available_bw(tunnel, &regs);
> +	if (ret == 1)
> +		changed = true;
> +
> +out:
> +	tun_dbg_stat(tunnel, ret < 0 ? ret : 0,
> +		     "State update: Changed:%s DPRX:%dx%d Tunnel alloc:%d/%d
> Group alloc:%d/%d Mb/s",
> +		     str_yes_no(changed),
> +		     tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
> +		     DPTUN_BW_ARG(tunnel->allocated_bw),
> +		     DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
> +		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
> +		     DPTUN_BW_ARG(tunnel->group->available_bw));
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	if (changed)
> +		return 1;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_update_state);
> +
> +/*
> + * drm_dp_tunnel_handle_irq - Handle DP tunnel IRQs
> + *
> + * Handle any pending DP tunnel IRQs, waking up waiters for a completion
> + * event.
> + *
> + * Returns 1 if the state of the tunnel has changed which requires calling
> + * drm_dp_tunnel_update_state(), a negative error code in case of a failure,
> + * 0 otherwise.
> + */
> +int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr, struct
> drm_dp_aux *aux)
> +{
> +	u8 val;
> +
> +	if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
> +		return -EIO;
> +
> +	if (val & (DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED))
> +		wake_up_all(&mgr->bw_req_queue);
> +
> +	if (val & (DP_BW_ALLOCATION_CAPABILITY_CHANGED |
> DP_ESTIMATED_BW_CHANGED))
> +		return 1;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_handle_irq);
> +
> +/**
> + * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's
> DPRX
> + * @tunnel: Tunnel object
> + *
> + * The function is used to query the maximum link rate of the DPRX connected
> + * to @tunnel. Note that this rate will not be limited by the BW limit of the
> + * tunnel, as opposed to the standard and extended DP_MAX_LINK_RATE DPCD
> + * registers.
> + *
> + * Returns the maximum link rate in 10 kbit/s units.
> + */
> +int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel->max_dprx_rate;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_rate);
> +
> +/**
> + * drm_dp_tunnel_max_dprx_lane_count - Query the maximum lane count of
> the tunnel's DPRX
> + * @tunnel: Tunnel object
> + *
> + * The function is used to query the maximum lane count of the DPRX connected
> + * to @tunnel. Note that this lane count will not be limited by the BW limit of
> + * the tunnel, as opposed to the standard and extended DP_MAX_LANE_COUNT
> DPCD
> + * registers.
> + *
> + * Returns the maximum lane count.
> + */
> +int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel->max_dprx_lane_count;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_lane_count);
> +
> +/**
> + * drm_dp_tunnel_available_bw - Query the estimated total available BW of the
> tunnel
> + * @tunnel: Tunnel object
> + *
> + * This function is used to query the estimated total available BW of the
> + * tunnel. This includes the currently allocated and free BW for all the
> + * tunnels in @tunnel's group. The available BW is valid only after the BW
> + * allocation mode has been enabled for the tunnel and its state got updated
> + * calling drm_dp_tunnel_update_state().
> + *
> + * Returns the @tunnel group's estimated total available bandwidth in kB/s
> + * units, or -1 if the available BW isn't valid (the BW allocation mode is
> + * not enabled or the tunnel's state hasn't been updated).
> + */
> +int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	return tunnel->group->available_bw;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_available_bw);
> +
> +static struct drm_dp_tunnel_group_state *
> +drm_dp_tunnel_atomic_get_group_state(struct drm_atomic_state *state,
> +				     const struct drm_dp_tunnel *tunnel)
> +{
> +	return (struct drm_dp_tunnel_group_state *)
> +		drm_atomic_get_private_obj_state(state,
> +						 &tunnel->group->base);
> +}
> +
> +static struct drm_dp_tunnel_state *
> +add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
> +		 struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_state *tunnel_state;
> +
> +	tun_dbg_atomic(tunnel,
> +		       "Adding state for tunnel %p to group state %p\n",
> +		       tunnel, group_state);
> +
> +	tunnel_state = kzalloc(sizeof(*tunnel_state), GFP_KERNEL);
> +	if (!tunnel_state)
> +		return NULL;
> +
> +	tunnel_state->group_state = group_state;
> +
> +	drm_dp_tunnel_ref_get(tunnel, &tunnel_state->tunnel_ref);
> +
> +	INIT_LIST_HEAD(&tunnel_state->node);
> +	list_add(&tunnel_state->node, &group_state->tunnel_states);
> +
> +	return tunnel_state;
> +}
> +
> +static void free_tunnel_state(struct drm_dp_tunnel_state *tunnel_state)
> +{
> +	tun_dbg_atomic(tunnel_state->tunnel_ref.tunnel,
> +		       "Freeing state for tunnel %p\n",
> +		       tunnel_state->tunnel_ref.tunnel);
> +
> +	list_del(&tunnel_state->node);
> +
> +	kfree(tunnel_state->stream_bw);
> +	drm_dp_tunnel_ref_put(&tunnel_state->tunnel_ref);
> +
> +	kfree(tunnel_state);
> +}
> +
> +static void free_group_state(struct drm_dp_tunnel_group_state *group_state)
> +{
> +	struct drm_dp_tunnel_state *tunnel_state;
> +	struct drm_dp_tunnel_state *tunnel_state_tmp;
> +
> +	for_each_tunnel_state_safe(group_state, tunnel_state,
> tunnel_state_tmp)
> +		free_tunnel_state(tunnel_state);
> +
> +	kfree(group_state);
> +}
> +
> +static struct drm_dp_tunnel_state *
> +get_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
> +		 const struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_state *tunnel_state;
> +
> +	for_each_tunnel_state(group_state, tunnel_state)
> +		if (tunnel_state->tunnel_ref.tunnel == tunnel)
> +			return tunnel_state;
> +
> +	return NULL;
> +}
> +
> +static struct drm_dp_tunnel_state *
> +get_or_add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
> +			struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_state *tunnel_state;
> +
> +	tunnel_state = get_tunnel_state(group_state, tunnel);
> +	if (tunnel_state)
> +		return tunnel_state;
> +
> +	return add_tunnel_state(group_state, tunnel);
> +}
> +
> +static struct drm_private_state *
> +tunnel_group_duplicate_state(struct drm_private_obj *obj)
> +{
> +	struct drm_dp_tunnel_group_state *group_state;
> +	struct drm_dp_tunnel_state *tunnel_state;
> +
> +	group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
> +	if (!group_state)
> +		return NULL;
> +
> +	INIT_LIST_HEAD(&group_state->tunnel_states);
> +
> +	__drm_atomic_helper_private_obj_duplicate_state(obj, &group_state-
> >base);
> +
> +	for_each_tunnel_state(to_group_state(obj->state), tunnel_state) {
> +		struct drm_dp_tunnel_state *new_tunnel_state;
> +
> +		new_tunnel_state = get_or_add_tunnel_state(group_state,
> +							   tunnel_state-
> >tunnel_ref.tunnel);
> +		if (!new_tunnel_state)
> +			goto out_free_state;
> +
> +		new_tunnel_state->stream_mask = tunnel_state-
> >stream_mask;
> +		new_tunnel_state->stream_bw = kmemdup(tunnel_state-
> >stream_bw,
> +						      sizeof(*tunnel_state-
> >stream_bw) *
> +
> 	hweight32(tunnel_state->stream_mask),
> +						      GFP_KERNEL);
> +
> +		if (!new_tunnel_state->stream_bw)
> +			goto out_free_state;
> +	}
> +
> +	return &group_state->base;
> +
> +out_free_state:
> +	free_group_state(group_state);
> +
> +	return NULL;
> +}
> +
> +static void tunnel_group_destroy_state(struct drm_private_obj *obj, struct
> drm_private_state *state)
> +{
> +	free_group_state(to_group_state(state));
> +}
> +
> +static const struct drm_private_state_funcs tunnel_group_funcs = {
> +	.atomic_duplicate_state = tunnel_group_duplicate_state,
> +	.atomic_destroy_state = tunnel_group_destroy_state,
> +};
> +
> +/**
> + * drm_dp_tunnel_atomic_get_state - get/allocate the new atomic state for a
> tunnel
> + * @state: Atomic state
> + * @tunnel: Tunnel to get the state for
> + *
> + * Get the new atomic state for @tunnel, duplicating it from the old tunnel
> + * state if not yet allocated.
> + *
> + * Return the state or an ERR_PTR() error on failure.
> + */
> +struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
> +			       struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_group_state *group_state;
> +	struct drm_dp_tunnel_state *tunnel_state;
> +
> +	group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
> +	if (IS_ERR(group_state))
> +		return ERR_CAST(group_state);
> +
> +	tunnel_state = get_or_add_tunnel_state(group_state, tunnel);
> +	if (!tunnel_state)
> +		return ERR_PTR(-ENOMEM);
> +
> +	return tunnel_state;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_state);
> +
> +/**
> + * drm_dp_tunnel_atomic_get_old_state - get the old atomic state for a tunnel
> + * @state: Atomic state
> + * @tunnel: Tunnel to get the state for
> + *
> + * Get the old atomic state for @tunnel.
> + *
> + * Return the old state or NULL if the tunnel's atomic state is not in @state.
> + */
> +struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
> +				   const struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_group_state *old_group_state;
> +	int i;
> +
> +	for_each_old_group_in_state(state, old_group_state, i)
> +		if (to_group(old_group_state->base.obj) == tunnel->group)
> +			return get_tunnel_state(old_group_state, tunnel);
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_old_state);
> +
> +/**
> + * drm_dp_tunnel_atomic_get_new_state - get the new atomic state for a
> tunnel
> + * @state: Atomic state
> + * @tunnel: Tunnel to get the state for
> + *
> + * Get the new atomic state for @tunnel.
> + *
> + * Return the new state or NULL if the tunnel's atomic state is not in @state.
> + */
> +struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
> +				   const struct drm_dp_tunnel *tunnel)
> +{
> +	struct drm_dp_tunnel_group_state *new_group_state;
> +	int i;
> +
> +	for_each_new_group_in_state(state, new_group_state, i)
> +		if (to_group(new_group_state->base.obj) == tunnel->group)
> +			return get_tunnel_state(new_group_state, tunnel);
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_new_state);
> +
> +static bool init_group(struct drm_dp_tunnel_mgr *mgr, struct
> drm_dp_tunnel_group *group)
> +{
> +	struct drm_dp_tunnel_group_state *group_state;
> +
> +	group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
> +	if (!group_state)
> +		return false;
> +
> +	INIT_LIST_HEAD(&group_state->tunnel_states);
> +
> +	group->mgr = mgr;
> +	group->available_bw = -1;
> +	INIT_LIST_HEAD(&group->tunnels);
> +
> +	drm_atomic_private_obj_init(mgr->dev, &group->base, &group_state-
> >base,
> +				    &tunnel_group_funcs);
> +
> +	return true;
> +}
> +
> +static void cleanup_group(struct drm_dp_tunnel_group *group)
> +{
> +	drm_atomic_private_obj_fini(&group->base);
> +}
> +
> +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> +static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state
> *group_state)
> +{
> +	const struct drm_dp_tunnel_state *tunnel_state;
> +	u32 stream_mask = 0;
> +
> +	for_each_tunnel_state(group_state, tunnel_state) {
> +		drm_WARN(to_group(group_state->base.obj)->mgr->dev,
> +			 tunnel_state->stream_mask & stream_mask,
> +			 "[DPTUN %s]: conflicting stream IDs %x (IDs in other
> tunnels %x)\n",
> +			 tunnel_state->tunnel_ref.tunnel->name,
> +			 tunnel_state->stream_mask,
> +			 stream_mask);
> +
> +		stream_mask |= tunnel_state->stream_mask;
> +	}
> +}
> +#else
> +static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state
> *group_state)
> +{
> +}
> +#endif
> +
> +static int stream_id_to_idx(u32 stream_mask, u8 stream_id)
> +{
> +	return hweight32(stream_mask & (BIT(stream_id) - 1));
> +}
> +
> +static int resize_bw_array(struct drm_dp_tunnel_state *tunnel_state,
> +			   unsigned long old_mask, unsigned long new_mask)
> +{
> +	unsigned long move_mask = old_mask & new_mask;
> +	int *new_bws = NULL;
> +	int id;
> +
> +	WARN_ON(!new_mask);
> +
> +	if (old_mask == new_mask)
> +		return 0;
> +
> +	new_bws = kcalloc(hweight32(new_mask), sizeof(*new_bws),
> GFP_KERNEL);
> +	if (!new_bws)
> +		return -ENOMEM;
> +
> +	for_each_set_bit(id, &move_mask, BITS_PER_TYPE(move_mask))
> +		new_bws[stream_id_to_idx(new_mask, id)] =
> +			tunnel_state->stream_bw[stream_id_to_idx(old_mask,
> id)];
> +
> +	kfree(tunnel_state->stream_bw);
> +	tunnel_state->stream_bw = new_bws;
> +	tunnel_state->stream_mask = new_mask;
> +
> +	return 0;
> +}
> +
> +static int set_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
> +			 u8 stream_id, int bw)
> +{
> +	int err;
> +
> +	err = resize_bw_array(tunnel_state,
> +			      tunnel_state->stream_mask,
> +			      tunnel_state->stream_mask | BIT(stream_id));
> +	if (err)
> +		return err;
> +
> +	tunnel_state->stream_bw[stream_id_to_idx(tunnel_state-
> >stream_mask, stream_id)] = bw;
> +
> +	return 0;
> +}
> +
> +static int clear_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
> +			   u8 stream_id)
> +{
> +	if (!(tunnel_state->stream_mask & ~BIT(stream_id))) {
> +		free_tunnel_state(tunnel_state);
> +		return 0;
> +	}
> +
> +	return resize_bw_array(tunnel_state,
> +			       tunnel_state->stream_mask,
> +			       tunnel_state->stream_mask & ~BIT(stream_id));
> +}
> +
> +/**
> + * drm_dp_tunnel_atomic_set_stream_bw - Set the BW for a DP tunnel stream
> + * @state: Atomic state
> + * @tunnel: DP tunnel containing the stream
> + * @stream_id: Stream ID
> + * @bw: BW of the stream
> + *
> + * Set a DP tunnel stream's required BW in the atomic state.
> + *
> + * Returns 0 in case of success, a negative error code otherwise.
> + */
> +int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
> +				       struct drm_dp_tunnel *tunnel,
> +				       u8 stream_id, int bw)
> +{
> +	struct drm_dp_tunnel_group_state *new_group_state;
> +	struct drm_dp_tunnel_state *tunnel_state;
> +	int err;
> +
> +	if (drm_WARN_ON(tunnel->group->mgr->dev,
> +			stream_id > BITS_PER_TYPE(tunnel_state-
> >stream_mask)))
> +		return -EINVAL;
> +
> +	tun_dbg(tunnel,
> +		"Setting %d Mb/s for stream %d\n",
> +		DPTUN_BW_ARG(bw), stream_id);
> +
> +	new_group_state = drm_dp_tunnel_atomic_get_group_state(state,
> tunnel);
> +	if (IS_ERR(new_group_state))
> +		return PTR_ERR(new_group_state);
> +
> +	if (bw == 0) {
> +		tunnel_state = get_tunnel_state(new_group_state, tunnel);
> +		if (!tunnel_state)
> +			return 0;
> +
> +		return clear_stream_bw(tunnel_state, stream_id);
> +	}
> +
> +	tunnel_state = get_or_add_tunnel_state(new_group_state, tunnel);
> +	if (drm_WARN_ON(state->dev, !tunnel_state))
> +		return -EINVAL;
> +
> +	err = set_stream_bw(tunnel_state, stream_id, bw);
> +	if (err)
> +		return err;
> +
> +	check_unique_stream_ids(new_group_state);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_set_stream_bw);
> +
> +/**
> + * drm_dp_tunnel_atomic_get_required_bw - Get the BW required by a DP
> tunnel
> + * @tunnel_state: Atomic state of the queried tunnel
> + *
> + * Calculate the BW required by a tunnel adding up the required BW of all
> + * the streams in the tunnel.
> + *
> + * Return the total BW required by the tunnel.
> + */
> +int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state
> *tunnel_state)
> +{
> +	int tunnel_bw = 0;
> +	int i;
> +
> +	if (!tunnel_state || !tunnel_state->stream_mask)
> +		return 0;
> +
> +	for (i = 0; i < hweight32(tunnel_state->stream_mask); i++)
> +		tunnel_bw += tunnel_state->stream_bw[i];
> +
> +	return tunnel_bw;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_required_bw);
> +
> +/**
> + * drm_dp_tunnel_atomic_get_group_streams_in_state - Get mask of stream
> IDs in a group
> + * @state: Atomic state
> + * @tunnel: Tunnel object
> + * @stream_mask: Mask of streams in @tunnel's group
> + *
> + * Get the mask of all the stream IDs in the tunnel group of @tunnel.
> + *
> + * Return 0 in case of success - with the stream IDs in @stream_mask - or a
> + * negative error code in case of failure.
> + */
> +int drm_dp_tunnel_atomic_get_group_streams_in_state(struct
> drm_atomic_state *state,
> +						    const struct drm_dp_tunnel
> *tunnel,
> +						    u32 *stream_mask)
> +{
> +	struct drm_dp_tunnel_group_state *group_state;
> +	struct drm_dp_tunnel_state *tunnel_state;
> +
> +	group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
> +	if (IS_ERR(group_state))
> +		return PTR_ERR(group_state);
> +
> +	*stream_mask = 0;
> +	for_each_tunnel_state(group_state, tunnel_state)
> +		*stream_mask |= tunnel_state->stream_mask;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_group_streams_in_state);
> +
> +static int
> +drm_dp_tunnel_atomic_check_group_bw(struct drm_dp_tunnel_group_state
> *new_group_state,
> +				    u32 *failed_stream_mask)
> +{
> +	struct drm_dp_tunnel_group *group = to_group(new_group_state-
> >base.obj);
> +	struct drm_dp_tunnel_state *new_tunnel_state;
> +	u32 group_stream_mask = 0;
> +	int group_bw = 0;
> +
> +	for_each_tunnel_state(new_group_state, new_tunnel_state) {
> +		struct drm_dp_tunnel *tunnel = new_tunnel_state-
> >tunnel_ref.tunnel;
> +		int max_dprx_bw = get_max_dprx_bw(tunnel);
> +		int tunnel_bw =
> drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
> +
> +		tun_dbg(tunnel,
> +			"%sRequired %d/%d Mb/s total for tunnel.\n",
> +			tunnel_bw > max_dprx_bw ? "Not enough BW: " : "",
> +			DPTUN_BW_ARG(tunnel_bw),
> +			DPTUN_BW_ARG(max_dprx_bw));
> +
> +		if (tunnel_bw > max_dprx_bw) {
> +			*failed_stream_mask = new_tunnel_state-
> >stream_mask;
> +			return -ENOSPC;
> +		}
> +
> +		group_bw += min(roundup(tunnel_bw, tunnel->bw_granularity),
> +				max_dprx_bw);
> +		group_stream_mask |= new_tunnel_state->stream_mask;
> +	}
> +
> +	tun_grp_dbg(group,
> +		    "%sRequired %d/%d Mb/s total for tunnel group.\n",
> +		    group_bw > group->available_bw ? "Not enough BW: " : "",
> +		    DPTUN_BW_ARG(group_bw),
> +		    DPTUN_BW_ARG(group->available_bw));
> +
> +	if (group_bw > group->available_bw) {
> +		*failed_stream_mask = group_stream_mask;
> +		return -ENOSPC;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * drm_dp_tunnel_atomic_check_stream_bws - Check BW limit for all streams
> in state
> + * @state: Atomic state
> + * @failed_stream_mask: Mask of stream IDs with a BW limit failure
> + *
> + * Check the required BW of each DP tunnel in @state against both the DPRX
> BW
> + * limit of the tunnel and the BW limit of the tunnel group. Return a mask of
> + * stream IDs in @failed_stream_mask once a check fails. The mask will contain
> + * either all the streams in a tunnel (in case a DPRX BW limit check failed) or
> + * all the streams in a tunnel group (in case a group BW limit check failed).
> + *
> + * Return 0 if all the BW limit checks passed, -ENOSPC in case a BW limit
> + * check failed - with @failed_stream_mask containing the streams failing the
> + * check - or a negative error code otherwise.
> + */
> +int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
> +					  u32 *failed_stream_mask)
> +{
> +	struct drm_dp_tunnel_group_state *new_group_state;
> +	int i;
> +
> +	for_each_new_group_in_state(state, new_group_state, i) {
> +		int ret;
> +
> +		ret =
> drm_dp_tunnel_atomic_check_group_bw(new_group_state,
> +							  failed_stream_mask);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_atomic_check_stream_bws);
> +
> +static void destroy_mgr(struct drm_dp_tunnel_mgr *mgr)
> +{
> +	int i;
> +
> +	for (i = 0; i < mgr->group_count; i++) {
> +		cleanup_group(&mgr->groups[i]);
> +		drm_WARN_ON(mgr->dev, !list_empty(&mgr-
> >groups[i].tunnels));
> +	}
> +
> +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> +	ref_tracker_dir_exit(&mgr->ref_tracker);
> +#endif
> +
> +	kfree(mgr->groups);
> +	kfree(mgr);
> +}
> +
> +/**
> + * drm_dp_tunnel_mgr_create - Create a DP tunnel manager
> + * @dev: DRM device object
> + *
> + * Creates a DP tunnel manager for @dev.
> + *
> + * Returns a pointer to the tunnel manager if created successfully or NULL in
> + * case of an error.
> + */
> +struct drm_dp_tunnel_mgr *
> +drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
> +{
> +	struct drm_dp_tunnel_mgr *mgr;
> +	int i;
> +
> +	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> +	if (!mgr)
> +		return NULL;
> +
> +	mgr->dev = dev;
> +	init_waitqueue_head(&mgr->bw_req_queue);
> +
> +	mgr->groups = kcalloc(max_group_count, sizeof(*mgr->groups),
> GFP_KERNEL);
> +	if (!mgr->groups) {
> +		kfree(mgr);
> +
> +		return NULL;
> +	}
> +
> +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> +	ref_tracker_dir_init(&mgr->ref_tracker, 16, "dptun");
> +#endif
> +
> +	for (i = 0; i < max_group_count; i++) {
> +		if (!init_group(mgr, &mgr->groups[i])) {
> +			destroy_mgr(mgr);
> +
> +			return NULL;
> +		}
> +
> +		mgr->group_count++;
> +	}
> +
> +	return mgr;
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_mgr_create);
> +
> +/**
> + * drm_dp_tunnel_mgr_destroy - Destroy DP tunnel manager
> + * @mgr: Tunnel manager object
> + *
> + * Destroy the tunnel manager.
> + */
> +void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr)
> +{
> +	destroy_mgr(mgr);
> +}
> +EXPORT_SYMBOL(drm_dp_tunnel_mgr_destroy);
> diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
> index 281afff6ee4e5..8bfd5d007be8d 100644
> --- a/include/drm/display/drm_dp.h
> +++ b/include/drm/display/drm_dp.h
> @@ -1382,6 +1382,66 @@
>  #define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET	0x69494
>  #define DP_HDCP_2_2_REG_DBG_OFFSET		0x69518
> 
> +/* DP-tunneling */
> +#define DP_TUNNELING_OUI				0xe0000
> +#define  DP_TUNNELING_OUI_BYTES				3
> +
> +#define DP_TUNNELING_DEV_ID				0xe0003
> +#define  DP_TUNNELING_DEV_ID_BYTES			6
> +
> +#define DP_TUNNELING_HW_REV				0xe0009
> +#define  DP_TUNNELING_HW_REV_MAJOR_SHIFT		4
> +#define  DP_TUNNELING_HW_REV_MAJOR_MASK			(0xf
> << DP_TUNNELING_HW_REV_MAJOR_SHIFT)
> +#define  DP_TUNNELING_HW_REV_MINOR_SHIFT		0
> +#define  DP_TUNNELING_HW_REV_MINOR_MASK			(0xf
> << DP_TUNNELING_HW_REV_MINOR_SHIFT)
> +
> +#define DP_TUNNELING_SW_REV_MAJOR			0xe000a
> +#define DP_TUNNELING_SW_REV_MINOR			0xe000b
> +
> +#define DP_TUNNELING_CAPABILITIES			0xe000d
> +#define  DP_IN_BW_ALLOCATION_MODE_SUPPORT		(1 << 7)
> +#define  DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT		(1 << 6)
> +#define  DP_TUNNELING_SUPPORT				(1 << 0)
> +
> +#define DP_IN_ADAPTER_INFO				0xe000e
> +#define  DP_IN_ADAPTER_NUMBER_BITS			7
> +#define  DP_IN_ADAPTER_NUMBER_MASK			((1 <<
> DP_IN_ADAPTER_NUMBER_BITS) - 1)
> +
> +#define DP_USB4_DRIVER_ID				0xe000f
> +#define  DP_USB4_DRIVER_ID_BITS				4
> +#define  DP_USB4_DRIVER_ID_MASK				((1 <<
> DP_USB4_DRIVER_ID_BITS) - 1)
> +
> +#define DP_USB4_DRIVER_BW_CAPABILITY			0xe0020
> +#define  DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT	(1 << 7)
> +
> +#define DP_IN_ADAPTER_TUNNEL_INFORMATION		0xe0021
> +#define  DP_GROUP_ID_BITS				3
> +#define  DP_GROUP_ID_MASK				((1 <<
> DP_GROUP_ID_BITS) - 1)
> +
> +#define DP_BW_GRANULARITY				0xe0022
> +#define  DP_BW_GRANULARITY_MASK				0x3
> +
> +#define DP_ESTIMATED_BW					0xe0023
> +#define DP_ALLOCATED_BW					0xe0024
> +
> +#define DP_TUNNELING_STATUS				0xe0025
> +#define  DP_BW_ALLOCATION_CAPABILITY_CHANGED		(1 << 3)
> +#define  DP_ESTIMATED_BW_CHANGED			(1 << 2)
> +#define  DP_BW_REQUEST_SUCCEEDED			(1 << 1)
> +#define  DP_BW_REQUEST_FAILED				(1 << 0)
> +
> +#define DP_TUNNELING_MAX_LINK_RATE			0xe0028
> +
> +#define DP_TUNNELING_MAX_LANE_COUNT			0xe0029
> +#define  DP_TUNNELING_MAX_LANE_COUNT_MASK		0x1f
> +
> +#define DP_DPTX_BW_ALLOCATION_MODE_CONTROL		0xe0030
> +#define  DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE	(1 <<
> 7)
> +#define  DP_UNMASK_BW_ALLOCATION_IRQ			(1 << 6)
> +
> +#define DP_REQUEST_BW					0xe0031
> +#define  MAX_DP_REQUEST_BW				255
> +
>  /* LTTPR: Link Training (LT)-tunable PHY Repeaters */
>  #define DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV
> 0xf0000 /* 1.3 */
>  #define DP_MAX_LINK_RATE_PHY_REPEATER			    0xf0001 /*
> 1.4a */
> diff --git a/include/drm/display/drm_dp_tunnel.h
> b/include/drm/display/drm_dp_tunnel.h
> new file mode 100644
> index 0000000000000..476252021f15c
> --- /dev/null
> +++ b/include/drm/display/drm_dp_tunnel.h
> @@ -0,0 +1,248 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#ifndef __DRM_DP_TUNNEL_H__
> +#define __DRM_DP_TUNNEL_H__
> +
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/types.h>
> +
> +struct drm_dp_aux;
> +
> +struct drm_device;
> +
> +struct drm_atomic_state;
> +struct drm_dp_tunnel_mgr;
> +struct drm_dp_tunnel_state;
> +
> +struct ref_tracker;
> +
> +struct drm_dp_tunnel_ref {
> +	struct drm_dp_tunnel *tunnel;
> +	struct ref_tracker *tracker;
> +};
> +
> +#ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL
> +
> +struct drm_dp_tunnel *
> +drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker
> **tracker);
> +
> +void
> +drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker
> **tracker);
> +
> +static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
> +					 struct drm_dp_tunnel_ref *tunnel_ref)
> +{
> +	tunnel_ref->tunnel = drm_dp_tunnel_get(tunnel, &tunnel_ref->tracker);
> +}
> +
> +static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
> +{
> +	drm_dp_tunnel_put(tunnel_ref->tunnel, &tunnel_ref->tracker);
> +}
> +
> +struct drm_dp_tunnel *
> +drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
> +		     struct drm_dp_aux *aux);
> +int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel);
> +
> +int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel);
> +int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel);
> +bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel
> *tunnel);
> +int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw);
> +int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel);
> +int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel);
> +
> +void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel);
> +
> +int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
> +			     struct drm_dp_aux *aux);
> +
> +int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel);
> +int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel);
> +int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel);
> +
> +const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel);
> +
> +struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
> +			       struct drm_dp_tunnel *tunnel);
> +
> +struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
> +				   const struct drm_dp_tunnel *tunnel);
> +
> +struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
> +				   const struct drm_dp_tunnel *tunnel);
> +
> +int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
> +				       struct drm_dp_tunnel *tunnel,
> +				       u8 stream_id, int bw);
> +int drm_dp_tunnel_atomic_get_group_streams_in_state(struct
> drm_atomic_state *state,
> +						    const struct drm_dp_tunnel
> *tunnel,
> +						    u32 *stream_mask);
> +
> +int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
> +					  u32 *failed_stream_mask);
> +
> +int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state
> *tunnel_state);
> +
> +struct drm_dp_tunnel_mgr *
> +drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count);
> +void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr);
> +
> +#else
> +
> +static inline struct drm_dp_tunnel *
> +drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker)
> +{
> +	return NULL;
> +}
> +
> +static inline void
> +drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker)
> {}
> +
> +static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
> +					 struct drm_dp_tunnel_ref *tunnel_ref)
> {}
> +
> +static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
> {}
> +
> +static inline struct drm_dp_tunnel *
> +drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
> +		     struct drm_dp_aux *aux)
> +{
> +	return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +static inline int
> +drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
> +{
> +	return 0;
> +}
> +
> +static inline int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel
> *tunnel)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline bool drm_dp_tunnel_bw_alloc_is_enabled(const struct
> drm_dp_tunnel *tunnel)
> +{
> +	return false;
> +}
> +
> +static inline int
> +drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int
> +drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
> +{
> +	return -1;
> +}
> +
> +static inline int
> +drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel) {}
> +
> +static inline int
> +drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
> +			 struct drm_dp_aux *aux)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int
> +drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
> +{
> +	return 0;
> +}
> +
> +static inline int
> +drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
> +{
> +	return 0;
> +}
> +
> +static inline int
> +drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
> +{
> +	return -1;
> +}
> +
> +static inline const char *
> +drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
> +{
> +	return NULL;
> +}
> +
> +static inline struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
> +			       struct drm_dp_tunnel *tunnel)
> +{
> +	return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +static inline struct drm_dp_tunnel_state *
> +drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
> +				   const struct drm_dp_tunnel *tunnel)
> +{
> +	return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +static inline int
> +drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
> +				   struct drm_dp_tunnel *tunnel,
> +				   u8 stream_id, int bw)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int
> +drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state
> *state,
> +						const struct drm_dp_tunnel
> *tunnel,
> +						u32 *stream_mask)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int
> +drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
> +				      u32 *failed_stream_mask)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int
> +drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state
> *tunnel_state)
> +{
> +	return 0;
> +}
> +
> +static inline struct drm_dp_tunnel_mgr *
> +drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
> +{
> +	return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +static inline
> +void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr) {}
> +
> +
> +#endif /* CONFIG_DRM_DISPLAY_DP_TUNNEL */
> +
> +#endif /* __DRM_DP_TUNNEL_H__ */
> --
> 2.39.2


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

* RE: [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during system resume
  2024-02-20 21:18 ` [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during system resume Imre Deak
@ 2024-02-23  6:38   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23  6:38 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel



> -----Original Message-----
> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:48 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during
> system resume
> 
> The system resume display mode restoration should happen with an output
> configuration matching that of the suspend time saved mode. Since the restored
> mode configuration is subject to the bpp fallback logic, starting out with an
> unlimited bpp and reducing the bpp as required by any (MST) link BW limit, the
> resulting bpp will match the one during suspend only if the BW limit checks during
> suspend and resume are applied in an identical way. The latter is not guaranteed
> at the moment, since the pre-suspend MST topology may not be in place during
> resume (for instance if the MST sink was disconnected while being suspended),
> which makes the MST link BW check accept the unlimited bpp mode
> configuration unconditionally without ensuring that the required BW fits into the
> available MST link BW.
> 
> To fix the above, initialize the bpp fallback logic with the max link bpp / force-FEC
> limits left behind by the suspend time mode save.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c |  3 +--
> drivers/gpu/drm/i915/display/intel_link_bw.c | 22 ++++++++++++++++----
> drivers/gpu/drm/i915/display/intel_link_bw.h |  2 +-
>  3 files changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 00ac65a140298..485c38d71f106 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6252,12 +6252,11 @@ static int intel_atomic_check_config(struct
> intel_atomic_state *state,
> 
>  static int intel_atomic_check_config_and_link(struct intel_atomic_state *state)  {
> -	struct drm_i915_private *i915 = to_i915(state->base.dev);
>  	struct intel_link_bw_limits new_limits;
>  	struct intel_link_bw_limits old_limits;
>  	int ret;
> 
> -	intel_link_bw_init_limits(i915, &new_limits);
> +	intel_link_bw_init_limits(state, &new_limits);
>  	old_limits = new_limits;
> 
>  	while (true) {
> diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c
> b/drivers/gpu/drm/i915/display/intel_link_bw.c
> index 9c6d35a405a18..27ea858897c9f 100644
> --- a/drivers/gpu/drm/i915/display/intel_link_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
> @@ -6,6 +6,7 @@
>  #include "i915_drv.h"
> 
>  #include "intel_atomic.h"
> +#include "intel_crtc.h"
>  #include "intel_display_types.h"
>  #include "intel_dp_mst.h"
>  #include "intel_fdi.h"
> @@ -13,19 +14,32 @@
> 
>  /**
>   * intel_link_bw_init_limits - initialize BW limits
> - * @i915: device instance
> + * @state: Atomic state
>   * @limits: link BW limits
>   *
>   * Initialize @limits.
>   */
> -void intel_link_bw_init_limits(struct drm_i915_private *i915, struct
> intel_link_bw_limits *limits)
> +void intel_link_bw_init_limits(struct intel_atomic_state *state,
> +			       struct intel_link_bw_limits *limits)
>  {
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
>  	enum pipe pipe;
> 
>  	limits->force_fec_pipes = 0;
>  	limits->bpp_limit_reached_pipes = 0;
> -	for_each_pipe(i915, pipe)
> -		limits->max_bpp_x16[pipe] = INT_MAX;
> +	for_each_pipe(i915, pipe) {
> +		const struct intel_crtc_state *crtc_state =
> +			intel_atomic_get_new_crtc_state(state,
> +
> 	intel_crtc_for_pipe(i915, pipe));
> +
> +		if (state->base.duplicated && crtc_state) {
> +			limits->max_bpp_x16[pipe] = crtc_state-
> >max_link_bpp_x16;
> +			if (crtc_state->fec_enable)
> +				limits->force_fec_pipes |= BIT(pipe);
> +		} else {
> +			limits->max_bpp_x16[pipe] = INT_MAX;
> +		}
> +	}
>  }
> 
>  /**
> diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.h
> b/drivers/gpu/drm/i915/display/intel_link_bw.h
> index 2cf57307cc249..6b0ccfff59dab 100644
> --- a/drivers/gpu/drm/i915/display/intel_link_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_link_bw.h
> @@ -22,7 +22,7 @@ struct intel_link_bw_limits {
>  	int max_bpp_x16[I915_MAX_PIPES];
>  };
> 
> -void intel_link_bw_init_limits(struct drm_i915_private *i915,
> +void intel_link_bw_init_limits(struct intel_atomic_state *state,
>  			       struct intel_link_bw_limits *limits);  int
> intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
>  			     struct intel_link_bw_limits *limits,
> --
> 2.39.2


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

* RE: [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to retry modesets
  2024-02-20 21:18 ` [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to retry modesets Imre Deak
@ 2024-02-23  7:59   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23  7:59 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel; +Cc: Hogander, Jouni



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:48 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Hogander, Jouni <jouni.hogander@intel.com>
> Subject: [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to
> retry modesets
> 
> On shared (Thunderbolt) links with DP tunnels, the modeset may need to be
> retried on all connectors on the link due to a link BW limitation arising only after
> the atomic check phase. To support this add a helper function queuing a work to
> retry the modeset on a given port's connector and at the same time any MST
> connector with streams through the same port. A follow-up change enabling the
> DP tunnel Bandwidth Allocation Mode will take this into use.
> 
> v2:
> - Send the uevent only to enabled MST connectors. (Jouni)

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Cc: Jouni Högander <jouni.hogander@intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  |  5 ++-
>  drivers/gpu/drm/i915/display/intel_dp.c       | 45 ++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp.h       |  6 +++
>  .../drm/i915/display/intel_dp_link_training.c |  3 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  2 +
>  5 files changed, 55 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 485c38d71f106..2ee26d19c200b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8085,8 +8085,9 @@ void intel_hpd_poll_fini(struct drm_i915_private
> *i915)
>  	/* Kill all the work that may have been queued by hpd. */
>  	drm_connector_list_iter_begin(&i915->drm, &conn_iter);
>  	for_each_intel_connector_iter(connector, &conn_iter) {
> -		if (connector->modeset_retry_work.func)
> -			cancel_work_sync(&connector->modeset_retry_work);
> +		if (connector->modeset_retry_work.func &&
> +		    cancel_work_sync(&connector->modeset_retry_work))
> +			drm_connector_put(&connector->base);
>  		if (connector->hdcp.shim) {
>  			cancel_delayed_work_sync(&connector-
> >hdcp.check_work);
>  			cancel_work_sync(&connector->hdcp.prop_work);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 217196196e50a..88606e336a920 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2842,6 +2842,40 @@ intel_dp_audio_compute_config(struct intel_encoder
> *encoder,
>  					intel_dp_is_uhbr(pipe_config);
>  }
> 
> +void intel_dp_queue_modeset_retry_work(struct intel_connector
> +*connector) {
> +	struct drm_i915_private *i915 = to_i915(connector->base.dev);
> +
> +	drm_connector_get(&connector->base);
> +	if (!queue_work(i915->unordered_wq, &connector-
> >modeset_retry_work))
> +		drm_connector_put(&connector->base);
> +}
> +
> +void
> +intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
> +				      struct intel_encoder *encoder,
> +				      const struct intel_crtc_state *crtc_state) {
> +	struct intel_connector *connector;
> +	struct intel_digital_connector_state *conn_state;
> +	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +	int i;
> +
> +	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
> +		intel_dp_queue_modeset_retry_work(intel_dp-
> >attached_connector);
> +
> +		return;
> +	}
> +
> +	for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
> +		if (!conn_state->base.crtc)
> +			continue;
> +
> +		if (connector->mst_port == intel_dp)
> +			intel_dp_queue_modeset_retry_work(connector);
> +	}
> +}
> +
>  int
>  intel_dp_compute_config(struct intel_encoder *encoder,
>  			struct intel_crtc_state *pipe_config, @@ -6441,6
> +6475,14 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct
> *work)
>  	mutex_unlock(&connector->dev->mode_config.mutex);
>  	/* Send Hotplug uevent so userspace can reprobe */
>  	drm_kms_helper_connector_hotplug_event(connector);
> +
> +	drm_connector_put(connector);
> +}
> +
> +void intel_dp_init_modeset_retry_work(struct intel_connector
> +*connector) {
> +	INIT_WORK(&connector->modeset_retry_work,
> +		  intel_dp_modeset_retry_work_fn);
>  }
> 
>  bool
> @@ -6457,8 +6499,7 @@ intel_dp_init_connector(struct intel_digital_port
> *dig_port,
>  	int type;
> 
>  	/* Initialize the work for modeset in case of link train failure */
> -	INIT_WORK(&intel_connector->modeset_retry_work,
> -		  intel_dp_modeset_retry_work_fn);
> +	intel_dp_init_modeset_retry_work(intel_connector);
> 
>  	if (drm_WARN(dev, dig_port->max_lanes < 1,
>  		     "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n", diff -
> -git a/drivers/gpu/drm/i915/display/intel_dp.h
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index 530cc97bc42f4..e2875e03afba0 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -43,6 +43,12 @@ void intel_dp_adjust_compliance_config(struct intel_dp
> *intel_dp,  bool intel_dp_limited_color_range(const struct intel_crtc_state
> *crtc_state,
>  				  const struct drm_connector_state
> *conn_state);  int intel_dp_min_bpp(enum intel_output_format output_format);
> +void intel_dp_init_modeset_retry_work(struct intel_connector
> +*connector); void intel_dp_queue_modeset_retry_work(struct
> +intel_connector *connector); void
> +intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
> +				      struct intel_encoder *encoder,
> +				      const struct intel_crtc_state *crtc_state);
>  bool intel_dp_init_connector(struct intel_digital_port *dig_port,
>  			     struct intel_connector *intel_connector);  void
> intel_dp_set_link_params(struct intel_dp *intel_dp, diff --git
> a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> index 1abfafbbfa757..7b140cbf8dd31 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -1075,7 +1075,6 @@ static void
> intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
>  						     const struct intel_crtc_state
> *crtc_state)  {
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
> -	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> 
>  	if (!intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) {
>  		lt_dbg(intel_dp, DP_PHY_DPRX, "Link Training failed on
> disconnected sink.\n"); @@ -1093,7 +1092,7 @@ static void
> intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
>  	}
> 
>  	/* Schedule a Hotplug Uevent to userspace to start modeset */
> -	queue_work(i915->unordered_wq, &intel_connector-
> >modeset_retry_work);
> +	intel_dp_queue_modeset_retry_work(intel_connector);
>  }
> 
>  /* Perform the link training on all LTTPRs and the DPRX on a link. */ diff --git
> a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 5307ddd4edcf5..c685b64bb7810 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -1546,6 +1546,8 @@ static struct drm_connector
> *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>  	intel_connector->port = port;
>  	drm_dp_mst_get_port_malloc(port);
> 
> +	intel_dp_init_modeset_retry_work(intel_connector);
> +
>  	intel_connector->dp.dsc_decompression_aux =
> drm_dp_mst_dsc_aux_for_port(port);
>  	intel_dp_mst_read_decompression_port_dsc_caps(intel_dp,
> intel_connector);
>  	intel_connector->dp.dsc_hblank_expansion_quirk =
> --
> 2.39.2


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

* RE: [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits
  2024-02-20 21:18 ` [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits Imre Deak
@ 2024-02-23  8:10   ` Shankar, Uma
  2024-02-23 21:11   ` Ville Syrjälä
  2024-02-26 18:52   ` [PATCH v3 11/21] drm/i915/dp: Sync instead of try-sync commits when getting active pipes Imre Deak
  2 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23  8:10 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel; +Cc: Ville Syrjälä



> -----Original Message-----
> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Subject: [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing
> commits
> 
> Add a way to get the active pipes through a given DP port by syncing against a
> related pending non-blocking commit. Atm
> intel_dp_get_active_pipes() will only try to sync a given pipe and if that would
> block ignore the pipe. A follow-up change enabling the DP tunnel BW allocation
> mode will need to ensure that all active pipes are returned.
> 
> This change will use intel_crtc_state::uapi.commit instead of the corresponding
> commit in the connector state. This shouldn't make a difference, since the two
> commit objects match for an active pipe.
> 
> A follow-up patchset will remove syncing during TC port reset, which should reset
> a port/pipe even if syncing against a commit would block.
> Syncing OTOH is not needed there, since the commit used for the reset implies a
> sync already. For now add a TODO comment for this.
> 
> v2:
> - Add a separate function to try-sync the pipes. (Ville)

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_crtc.c | 27 +++++++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_crtc.h |  1 +
>  drivers/gpu/drm/i915/display/intel_dp.c   |  6 ++---
>  drivers/gpu/drm/i915/display/intel_tc.c   |  7 ++++++
>  4 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c
> b/drivers/gpu/drm/i915/display/intel_crtc.c
> index 25593f6aae7de..17ed2e62cc66a 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -654,3 +654,30 @@ void intel_pipe_update_end(struct intel_atomic_state
> *state,
>  out:
>  	intel_psr_unlock(new_crtc_state);
>  }
> +
> +/**
> + * intel_crtc_try_sync_pipes - Try syncing pending commits on a set of
> +pipes
> + * @i915: i915 device object
> + * @pipe_mask: Mask of pipes to sync
> + *
> + * Try to sync a pending non-blocking commit for the provided pipes in
> + * @pipe_mask. The commit won't be synced if this would block.
> + *
> + * Return a mask of the pipes that got synced or didn't need syncing.
> + */
> +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32
> +pipe_mask) {
> +	struct intel_crtc *crtc;
> +	u32 synced = 0;
> +
> +	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
> +		const struct intel_crtc_state *crtc_state =
> +			to_intel_crtc_state(crtc->base.state);
> +
> +		if (!crtc_state->uapi.commit ||
> +		    try_wait_for_completion(&crtc_state->uapi.commit-
> >hw_done))
> +			synced |= BIT(crtc->pipe);
> +	}
> +
> +	return synced;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h
> b/drivers/gpu/drm/i915/display/intel_crtc.h
> index 22d7993d1f0ba..71a5b93166da7 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.h
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.h
> @@ -47,5 +47,6 @@ struct intel_crtc *intel_crtc_for_pipe(struct
> drm_i915_private *i915,  void intel_wait_for_vblank_if_active(struct
> drm_i915_private *i915,
>  				     enum pipe pipe);
>  void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
> +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32
> +pipe_mask);
> 
>  #endif
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index d9e75922ff8f5..d0452d3e534a7 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5048,10 +5048,6 @@ int intel_dp_get_active_pipes(struct intel_dp
> *intel_dp,
>  		if (!crtc_state->hw.active)
>  			continue;
> 
> -		if (conn_state->commit &&
> -		    !try_wait_for_completion(&conn_state->commit->hw_done))
> -			continue;
> -
>  		*pipe_mask |= BIT(crtc->pipe);
>  	}
>  	drm_connector_list_iter_end(&conn_iter);
> @@ -5091,6 +5087,8 @@ int intel_dp_retrain_link(struct intel_encoder
> *encoder,
>  	if (ret)
>  		return ret;
> 
> +	pipe_mask &= intel_crtc_try_sync_pipes(dev_priv, pipe_mask);
> +
>  	if (pipe_mask == 0)
>  		return 0;
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_tc.c
> b/drivers/gpu/drm/i915/display/intel_tc.c
> index 6b374d481cd9e..14d17903a81f5 100644
> --- a/drivers/gpu/drm/i915/display/intel_tc.c
> +++ b/drivers/gpu/drm/i915/display/intel_tc.c
> @@ -7,6 +7,7 @@
>  #include "i915_reg.h"
>  #include "intel_atomic.h"
>  #include "intel_cx0_phy_regs.h"
> +#include "intel_crtc.h"
>  #include "intel_ddi.h"
>  #include "intel_de.h"
>  #include "intel_display.h"
> @@ -1663,6 +1664,12 @@ static int reset_link_commit(struct intel_tc_port *tc,
>  	if (ret)
>  		return ret;
> 
> +	/*
> +	 * TODO: remove the following, since an output must be reset
> +	 * even if we had to wait for a non-blocking commit on a pipe.
> +	 */
> +	pipe_mask &= intel_crtc_try_sync_pipes(i915, pipe_mask);
> +
>  	if (!pipe_mask)
>  		return 0;
> 
> --
> 2.39.2


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

* RE: [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check BW limit
  2024-02-20 21:18 ` [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check BW limit Imre Deak
@ 2024-02-23 10:13   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23 10:13 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel; +Cc: Ville Syrjälä



> -----Original Message-----
> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Subject: [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check
> BW limit
> 
> Add the atomic state during a modeset required to enable the DP tunnel BW
> allocation mode on links where such a tunnel was detected. This state applies to
> an already enabled output, the state added for a newly enabled output will be
> computed and added/cleared to/from the atomic state in a follow-up patch.
> 
> v2:
> - s/old_crtc_state/crtc_state in intel_crtc_duplicate_state().
> - Move intel_dp_tunnel_atomic_cleanup_inherited_state() to a follow-up
>   patch adding the corresponding state. (Ville)
> - Move intel_dp_tunnel_atomic_clear_stream_bw() to a follow-up
>   patch adding the corresponding state.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c  |  6 ++++++
> drivers/gpu/drm/i915/display/intel_display.c | 12 ++++++++++++
> drivers/gpu/drm/i915/display/intel_link_bw.c |  5 +++++
>  3 files changed, 23 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c
> b/drivers/gpu/drm/i915/display/intel_atomic.c
> index 96ab37e158995..798cb90361a83 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -260,6 +260,10 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	if (crtc_state->post_csc_lut)
>  		drm_property_blob_get(crtc_state->post_csc_lut);
> 
> +	if (crtc_state->dp_tunnel_ref.tunnel)
> +		drm_dp_tunnel_ref_get(crtc_state->dp_tunnel_ref.tunnel,
> +				      &crtc_state->dp_tunnel_ref);
> +
>  	crtc_state->update_pipe = false;
>  	crtc_state->update_m_n = false;
>  	crtc_state->update_lrr = false;
> @@ -311,6 +315,8 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
> 
>  	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>  	intel_crtc_free_hw_state(crtc_state);
> +	if (crtc_state->dp_tunnel_ref.tunnel)
> +		drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref);
>  	kfree(crtc_state);
>  }
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index e1a4200f67a7e..16973ebb7865d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -33,6 +33,7 @@
>  #include <linux/string_helpers.h>
> 
>  #include <drm/display/drm_dp_helper.h>
> +#include <drm/display/drm_dp_tunnel.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_atomic_uapi.h>
> @@ -73,6 +74,7 @@
>  #include "intel_dp.h"
>  #include "intel_dp_link_training.h"
>  #include "intel_dp_mst.h"
> +#include "intel_dp_tunnel.h"
>  #include "intel_dpll.h"
>  #include "intel_dpll_mgr.h"
>  #include "intel_dpt.h"
> @@ -4490,6 +4492,8 @@ copy_bigjoiner_crtc_state_modeset(struct
> intel_atomic_state *state,
>  	saved_state->crc_enabled = slave_crtc_state->crc_enabled;
> 
>  	intel_crtc_free_hw_state(slave_crtc_state);
> +	if (slave_crtc_state->dp_tunnel_ref.tunnel)
> +		drm_dp_tunnel_ref_put(&slave_crtc_state->dp_tunnel_ref);
>  	memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
>  	kfree(saved_state);
> 
> @@ -4505,6 +4509,10 @@ copy_bigjoiner_crtc_state_modeset(struct
> intel_atomic_state *state,
>  		      &master_crtc_state->hw.adjusted_mode);
>  	slave_crtc_state->hw.scaling_filter = master_crtc_state-
> >hw.scaling_filter;
> 
> +	if (master_crtc_state->dp_tunnel_ref.tunnel)
> +		drm_dp_tunnel_ref_get(master_crtc_state-
> >dp_tunnel_ref.tunnel,
> +					&slave_crtc_state->dp_tunnel_ref);
> +
>  	copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
> 
>  	slave_crtc_state->uapi.mode_changed = master_crtc_state-
> >uapi.mode_changed;
> @@ -5365,6 +5373,10 @@ static int intel_modeset_pipe(struct
> intel_atomic_state *state,
>  	if (ret)
>  		return ret;
> 
> +	ret = intel_dp_tunnel_atomic_add_state_for_crtc(state, crtc);
> +	if (ret)
> +		return ret;
> +
>  	ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c
> b/drivers/gpu/drm/i915/display/intel_link_bw.c
> index 27ea858897c9f..dfd7d5e23f3fa 100644
> --- a/drivers/gpu/drm/i915/display/intel_link_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
> @@ -9,6 +9,7 @@
>  #include "intel_crtc.h"
>  #include "intel_display_types.h"
>  #include "intel_dp_mst.h"
> +#include "intel_dp_tunnel.h"
>  #include "intel_fdi.h"
>  #include "intel_link_bw.h"
> 
> @@ -163,6 +164,10 @@ static int check_all_link_config(struct
> intel_atomic_state *state,
>  	if (ret)
>  		return ret;
> 
> +	ret = intel_dp_tunnel_atomic_check_link(state, limits);
> +	if (ret)
> +		return ret;
> +
>  	ret = intel_fdi_atomic_check_link(state, limits);
>  	if (ret)
>  		return ret;
> --
> 2.39.2


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

* RE: [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs
  2024-02-20 21:18 ` [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs Imre Deak
@ 2024-02-23 10:19   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23 10:19 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs
> 
> Handle DP tunnel IRQs a sink (or rather a BW management component like the
> Thunderbolt Connection Manager) raises to signal the completion of a BW
> request by the driver, or to signal any state change related to the link BW.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
X`
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 37 +++++++++++++++++++------
>  include/drm/display/drm_dp.h            |  1 +
>  2 files changed, 29 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 5ad7808788745..a3dfcbb710027 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4904,13 +4904,15 @@ static bool intel_dp_mst_link_status(struct intel_dp
> *intel_dp)
>   * - %true if pending interrupts were serviced (or no interrupts were
>   *   pending) w/o detecting an error condition.
>   * - %false if an error condition - like AUX failure or a loss of link - is
> - *   detected, which needs servicing from the hotplug work.
> + *   detected, or another condition - like a DP tunnel BW state change - needs
> + *   servicing from the hotplug work.
>   */
>  static bool
>  intel_dp_check_mst_status(struct intel_dp *intel_dp)  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	bool link_ok = true;
> +	bool reprobe_needed = false;
> 
>  	drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
> 
> @@ -4937,6 +4939,13 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
> 
>  		intel_dp_mst_hpd_irq(intel_dp, esi, ack);
> 
> +		if (esi[3] & DP_TUNNELING_IRQ) {
> +			if (drm_dp_tunnel_handle_irq(i915-
> >display.dp_tunnel_mgr,
> +						     &intel_dp->aux))
> +				reprobe_needed = true;
> +			ack[3] |= DP_TUNNELING_IRQ;
> +		}
> +
>  		if (!memchr_inv(ack, 0, sizeof(ack)))
>  			break;
> 
> @@ -4947,7 +4956,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
>  			drm_dp_mst_hpd_irq_send_new_request(&intel_dp-
> >mst_mgr);
>  	}
> 
> -	return link_ok;
> +	return link_ok && !reprobe_needed;
>  }
> 
>  static void
> @@ -5304,23 +5313,32 @@ static void
> intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
>  		drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n");  }
> 
> -static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
> +static bool intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
>  {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	bool reprobe_needed = false;
>  	u8 val;
> 
>  	if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
> -		return;
> +		return false;
> 
>  	if (drm_dp_dpcd_readb(&intel_dp->aux,
>  			      DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 ||
> !val)
> -		return;
> +		return false;
> +
> +	if ((val & DP_TUNNELING_IRQ) &&
> +	    drm_dp_tunnel_handle_irq(i915->display.dp_tunnel_mgr,
> +				     &intel_dp->aux))
> +		reprobe_needed = true;
> 
>  	if (drm_dp_dpcd_writeb(&intel_dp->aux,
>  			       DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1)
> -		return;
> +		return reprobe_needed;
> 
>  	if (val & HDMI_LINK_STATUS_CHANGED)
>  		intel_dp_handle_hdmi_link_status_change(intel_dp);
> +
> +	return reprobe_needed;
>  }
> 
>  /*
> @@ -5341,6 +5359,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	u8 old_sink_count = intel_dp->sink_count;
> +	bool reprobe_needed = false;
>  	bool ret;
> 
>  	/*
> @@ -5363,7 +5382,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
>  	}
> 
>  	intel_dp_check_device_service_irq(intel_dp);
> -	intel_dp_check_link_service_irq(intel_dp);
> +	reprobe_needed = intel_dp_check_link_service_irq(intel_dp);
> 
>  	/* Handle CEC interrupts, if any */
>  	drm_dp_cec_irq(&intel_dp->aux);
> @@ -5390,10 +5409,10 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
>  		 * FIXME get rid of the ad-hoc phy test modeset code
>  		 * and properly incorporate it into the normal modeset.
>  		 */
> -		return false;
> +		reprobe_needed = true;
>  	}
> 
> -	return true;
> +	return !reprobe_needed;
>  }
> 
>  /* XXX this is probably wrong for multiple downstream ports */ diff --git
> a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index
> 8bfd5d007be8d..4891bd916d26a 100644
> --- a/include/drm/display/drm_dp.h
> +++ b/include/drm/display/drm_dp.h
> @@ -1081,6 +1081,7 @@
>  # define STREAM_STATUS_CHANGED               (1 << 2)
>  # define HDMI_LINK_STATUS_CHANGED            (1 << 3)
>  # define CONNECTED_OFF_ENTRY_REQUESTED       (1 << 4)
> +# define DP_TUNNELING_IRQ                    (1 << 5)
> 
>  #define DP_PSR_ERROR_STATUS                 0x2006  /* XXX 1.2? */
>  # define DP_PSR_LINK_CRC_ERROR              (1 << 0)
> --
> 2.39.2


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

* RE: [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels
  2024-02-20 21:18 ` [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels Imre Deak
@ 2024-02-23 10:23   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23 10:23 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels
> 
> Suspend and resume DP tunnels during system suspend/resume, disabling the BW
> allocation mode during suspend, re-enabling it after resume. This reflects the
> link's BW management component (Thunderbolt CM) disabling BWA during
> suspend. Before any BW requests the driver must read the sink's DPRX
> capabilities (since the BW manager requires this information, so snoops for it on
> AUX), so ensure this read takes place.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index a3dfcbb710027..35ef17439038a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -36,6 +36,7 @@
>  #include <asm/byteorder.h>
> 
>  #include <drm/display/drm_dp_helper.h>
> +#include <drm/display/drm_dp_tunnel.h>
>  #include <drm/display/drm_dsc_helper.h>  #include
> <drm/display/drm_hdmi_helper.h>  #include <drm/drm_atomic_helper.h> @@ -
> 3313,18 +3314,21 @@ void intel_dp_sync_state(struct intel_encoder *encoder,
>  			 const struct intel_crtc_state *crtc_state)  {
>  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> -
> -	if (!crtc_state)
> -		return;
> +	bool dpcd_updated = false;
> 
>  	/*
>  	 * Don't clobber DPCD if it's been already read out during output
>  	 * setup (eDP) or detect.
>  	 */
> -	if (intel_dp->dpcd[DP_DPCD_REV] == 0)
> +	if (crtc_state && intel_dp->dpcd[DP_DPCD_REV] == 0) {
>  		intel_dp_get_dpcd(intel_dp);
> +		dpcd_updated = true;
> +	}
> 
> -	intel_dp_reset_max_link_params(intel_dp);
> +	intel_dp_tunnel_resume(intel_dp, crtc_state, dpcd_updated);
> +
> +	if (crtc_state)
> +		intel_dp_reset_max_link_params(intel_dp);
>  }
> 
>  bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, @@ -5947,6
> +5951,8 @@ void intel_dp_encoder_suspend(struct intel_encoder
> *intel_encoder)
>  	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
> 
>  	intel_pps_vdd_off_sync(intel_dp);
> +
> +	intel_dp_tunnel_suspend(intel_dp);
>  }
> 
>  void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder)
> --
> 2.39.2


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

* RE: [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses
  2024-02-20 21:18 ` [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses Imre Deak
@ 2024-02-23 10:33   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23 10:33 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses
> 
> The TBT DP tunnel BW request logic in the Thunderbolt Connection Manager
> depends on the GFX driver reading out the sink's DPRX capabilities in response to
> a long HPD pulse. Since in i915 this read-out can be blocked by another
> connector's/encoder's hotplug event handling (which is serialized by
> drm_mode_config::connection_mutex), do a dummy DPRX read-out in the
> encoder's HPD pulse handler (which is not blocked by other encoders).

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 35ef17439038a..f7f8bd5742ad4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -6162,6 +6162,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port,
> bool long_hpd)  {
>  	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
>  	struct intel_dp *intel_dp = &dig_port->dp;
> +	u8 dpcd[DP_RECEIVER_CAP_SIZE];
> 
>  	if (dig_port->base.type == INTEL_OUTPUT_EDP &&
>  	    (long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) { @@ -
> 6184,6 +6185,17 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port,
> bool long_hpd)
>  		    dig_port->base.base.name,
>  		    long_hpd ? "long" : "short");
> 
> +	/*
> +	 * TBT DP tunnels require the GFX driver to read out the DPRX caps in
> +	 * response to long HPD pulses. The DP hotplug handler does that,
> +	 * however the hotplug handler may be blocked by another
> +	 * connector's/encoder's hotplug handler. Since the TBT CM may not
> +	 * complete the DP tunnel BW request for the latter connector/encoder
> +	 * waiting for this encoder's DPRX read, perform a dummy read here.
> +	 */
> +	if (long_hpd)
> +		intel_dp_read_dprx_caps(intel_dp, dpcd);
> +
>  	if (long_hpd) {
>  		intel_dp->reset_link_params = true;
>  		return IRQ_NONE;
> --
> 2.39.2


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

* RE: [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode
  2024-02-20 21:18 ` [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode Imre Deak
@ 2024-02-23 10:36   ` Shankar, Uma
  0 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-23 10:36 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel



> -----Original Message-----
> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode
> 
> Detect DP tunnels and enable the BW allocation mode on them. Send a hotplug
> notification to userspace in response to a BW change.

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  .../drm/i915/display/intel_display_driver.c   | 20 +++++++++++++++----
>  drivers/gpu/drm/i915/display/intel_dp.c       | 14 +++++++++++--
>  2 files changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c
> b/drivers/gpu/drm/i915/display/intel_display_driver.c
> index 4f7ba7eb03d27..87dd07e0d138d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_driver.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
> @@ -35,6 +35,7 @@
>  #include "intel_dkl_phy.h"
>  #include "intel_dmc.h"
>  #include "intel_dp.h"
> +#include "intel_dp_tunnel.h"
>  #include "intel_dpll.h"
>  #include "intel_dpll_mgr.h"
>  #include "intel_fb.h"
> @@ -434,10 +435,8 @@ int intel_display_driver_probe_nogem(struct
> drm_i915_private *i915)
> 
>  	for_each_pipe(i915, pipe) {
>  		ret = intel_crtc_init(i915, pipe);
> -		if (ret) {
> -			intel_mode_config_cleanup(i915);
> -			return ret;
> -		}
> +		if (ret)
> +			goto err_mode_config;
>  	}
> 
>  	intel_plane_possible_crtcs_init(i915);
> @@ -457,6 +456,10 @@ int intel_display_driver_probe_nogem(struct
> drm_i915_private *i915)
>  	intel_vga_disable(i915);
>  	intel_setup_outputs(i915);
> 
> +	ret = intel_dp_tunnel_mgr_init(i915);
> +	if (ret)
> +		goto err_hdcp;
> +
>  	intel_display_driver_disable_user_access(i915);
> 
>  	drm_modeset_lock_all(dev);
> @@ -475,6 +478,13 @@ int intel_display_driver_probe_nogem(struct
> drm_i915_private *i915)
>  		ilk_wm_sanitize(i915);
> 
>  	return 0;
> +
> +err_hdcp:
> +	intel_hdcp_component_fini(i915);
> +err_mode_config:
> +	intel_mode_config_cleanup(i915);
> +
> +	return ret;
>  }
> 
>  /* part #3: call after gem init */
> @@ -599,6 +609,8 @@ void intel_display_driver_remove_noirq(struct
> drm_i915_private *i915)
> 
>  	intel_mode_config_cleanup(i915);
> 
> +	intel_dp_tunnel_mgr_cleanup(i915);
> +
>  	intel_overlay_cleanup(i915);
> 
>  	intel_gmbus_teardown(i915);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index f7f8bd5742ad4..789b5fa074fd0 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5726,6 +5726,7 @@ intel_dp_detect(struct drm_connector *connector,
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>  	struct intel_encoder *encoder = &dig_port->base;
>  	enum drm_connector_status status;
> +	int ret;
> 
>  	drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
>  		    connector->base.id, connector->name); @@ -5761,9 +5762,18
> @@ intel_dp_detect(struct drm_connector *connector,
>  							intel_dp->is_mst);
>  		}
> 
> +		intel_dp_tunnel_disconnect(intel_dp);
> +
>  		goto out;
>  	}
> 
> +	ret = intel_dp_tunnel_detect(intel_dp, ctx);
> +	if (ret == -EDEADLK)
> +		return ret;
> +
> +	if (ret == 1)
> +		intel_connector->base.epoch_counter++;
> +
>  	intel_dp_detect_dsc_caps(intel_dp, intel_connector);
> 
>  	intel_dp_configure_mst(intel_dp);
> @@ -5794,8 +5804,6 @@ intel_dp_detect(struct drm_connector *connector,
>  	 * with an IRQ_HPD, so force a link status check.
>  	 */
>  	if (!intel_dp_is_edp(intel_dp)) {
> -		int ret;
> -
>  		ret = intel_dp_retrain_link(encoder, ctx);
>  		if (ret)
>  			return ret;
> @@ -5935,6 +5943,8 @@ void intel_dp_encoder_flush_work(struct
> drm_encoder *encoder)
> 
>  	intel_dp_mst_encoder_cleanup(dig_port);
> 
> +	intel_dp_tunnel_destroy(intel_dp);
> +
>  	intel_pps_vdd_off_sync(intel_dp);
> 
>  	/*
> --
> 2.39.2


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

* Re: [PATCH v2 02/21] drm/dp: Add support for DP tunneling
  2024-02-23  6:25   ` Shankar, Uma
@ 2024-02-23 14:33     ` Imre Deak
  0 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-23 14:33 UTC (permalink / raw)
  To: Shankar, Uma; +Cc: intel-gfx, dri-devel, Ville Syrjälä

On Fri, Feb 23, 2024 at 08:25:38AM +0200, Shankar, Uma wrote:
> [...]
> > diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
> > index 09712b88a5b83..c0f56888c3280 100644
> > --- a/drivers/gpu/drm/display/Kconfig
> > +++ b/drivers/gpu/drm/display/Kconfig
> [...]
> > +struct drm_dp_tunnel {
> > +     struct drm_dp_tunnel_group *group;
> > +
> > +     struct list_head node;
> > +
> > +     struct kref kref;
> > +     struct ref_tracker *tracker;
> > +     struct drm_dp_aux *aux;
> > +     char name[8];
> > +
> > +     int bw_granularity;
> > +     int estimated_bw;
> > +     int allocated_bw;
> > +
> > +     int max_dprx_rate;
> > +     u8 max_dprx_lane_count;
> > +
> > +     u8 adapter_id;
> > +
> > +     bool bw_alloc_supported:1;
> > +     bool bw_alloc_enabled:1;
> > +     bool has_io_error:1;
> > +     bool destroyed:1;
> > +};
> > +
> > +struct drm_dp_tunnel_group_state;
> > +
> > +struct drm_dp_tunnel_state {
> > +     struct drm_dp_tunnel_group_state *group_state;
> > +
> > +     struct drm_dp_tunnel_ref tunnel_ref;
> > +
> > +     struct list_head node;
> > +
> > +     u32 stream_mask;
> > +     int *stream_bw;
> > +};
> > +
> > +struct drm_dp_tunnel_group_state {
> > +     struct drm_private_state base;
> > +
> > +     struct list_head tunnel_states;
> > +};
> > +
> > +struct drm_dp_tunnel_group {
> > +     struct drm_private_obj base;
> > +     struct drm_dp_tunnel_mgr *mgr;
> > +
> > +     struct list_head tunnels;
> > +
> > +     /* available BW including the allocated_bw of all tunnels in the group */
> > +     int available_bw;
> > +     u8 drv_group_id;
> > +
> > +     char name[8];
> > +
> 
> We can drop these line gaps.

Those are used in general to keep related fields together, but the above
three fields could be better grouped, can do that.

> > +     bool active:1;
> > +};
> > +
> > +struct drm_dp_tunnel_mgr {
> > +     struct drm_device *dev;
> > +
> > +     int group_count;
> > +     struct drm_dp_tunnel_group *groups;
> > +     wait_queue_head_t bw_req_queue;
> > +
> > +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> > +     struct ref_tracker_dir ref_tracker;
> > +#endif
> > +};
> > +
> > + [...]
> > +/* Return granularity in kB/s units */
> > +static int tunnel_reg_bw_granularity(const struct drm_dp_tunnel_regs *regs)
> > +{
> > +     int gr = tunnel_reg(regs, DP_BW_GRANULARITY) &
> > DP_BW_GRANULARITY_MASK;
> > +
> > +     WARN_ON(gr > 2);
> > +
> 
> I think it should fail as well along with WARN, > 2 is not supported.
> However, this situation is highly unlikely though.

Yes, validating this in tunnel_regs_are_valid() is missing, will add
that.

> > +     return (250000 << gr) / 8;
> [...]
> > +
> > +static int check_and_clear_status_change(struct drm_dp_tunnel *tunnel)
> > +{
> > +     u8 mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED;
> > +     u8 val;
> > +
> > +     if (drm_dp_dpcd_readb(tunnel->aux, DP_TUNNELING_STATUS, &val) < 0)
> > +             goto out_err;
> > +
> > +     val &= mask;
> > +
> > +     if (val) {
> > +             if (drm_dp_dpcd_writeb(tunnel->aux, DP_TUNNELING_STATUS, val) < 0)
> > +                     goto out_err;
> > +
> > +             return 1;
> 
> Seems this return value is not considered by the caller.

It indicates a status change and handled accordingly by the caller.
Probably it's better to document this, can add that.

> Hi Imre,
> Overall changes look good to me.
> It would be ideal if we can break this patch down, no major concern though.
> Leaving to your judgment.

The current way adds the DRM/i915 specific support separately, each
adding one .c file, the rest of the patchset taking these into use, each
patch doing this for a given scope of functionality. Didn't have a
better idea, maybe the DPCD registers could be added separately, but not
sure if that would make reviewing easier.

> With some above minor nits addressed, this is
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> 
> Note: Have checked the register definitions/addresses, offsets. Have Logically checked the code
> in general, as well. It would be good if tunnel manager and tunnel groups related logic can be double
> confirmed by someone. Having said that, no issue I could spot there.

Thanks.

> Regards,
> Uma Shankar
> 
> > +     }
> > +
> > +     if (!drm_dp_tunnel_bw_alloc_is_enabled(tunnel))
> > +             return 0;
> > +
> > +     /*
> > +      * Check for estimated BW changes explicitly to account for lost
> > +      * BW change notifications.
> > +      */
> > +     if (drm_dp_dpcd_readb(tunnel->aux, DP_ESTIMATED_BW, &val) < 0)
> > +             goto out_err;
> > +
> > +     if (val * tunnel->bw_granularity != tunnel->estimated_bw)
> > +             return 1;
> > +
> > +     return 0;
> > +
> > +out_err:
> > +     drm_dp_tunnel_set_io_error(tunnel);
> > +
> > +     return -EIO;
> > +}
> > +
> > +/**
> > + * drm_dp_tunnel_update_state - Update DP tunnel SW state with the HW state
> > + * @tunnel: Tunnel object
> > + *
> > + * Update the SW state of @tunnel with the HW state.
> > + *
> > + * Returns 0 if the state has not changed, 1 if it has changed and got updated
> > + * successfully and a negative error code otherwise.
> > + */
> > +int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_regs regs;
> > +     bool changed = false;
> > +     int ret;
> > +
> > +     ret = check_tunnel(tunnel);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     ret = check_and_clear_status_change(tunnel);
> > +     if (ret < 0)
> > +             goto out;
> > +
> > +     if (!ret)
> > +             return 0;
> > +
> > +     ret = read_and_verify_tunnel_regs(tunnel, &regs, 0);
> > +     if (ret)
> > +             goto out;
> > +
> > +     if (update_dprx_caps(tunnel, &regs))
> > +             changed = true;
> > +
> > +     ret = update_group_available_bw(tunnel, &regs);
> > +     if (ret == 1)
> > +             changed = true;
> > +
> > +out:
> > +     tun_dbg_stat(tunnel, ret < 0 ? ret : 0,
> > +                  "State update: Changed:%s DPRX:%dx%d Tunnel alloc:%d/%d
> > Group alloc:%d/%d Mb/s",
> > +                  str_yes_no(changed),
> > +                  tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
> > +                  DPTUN_BW_ARG(tunnel->allocated_bw),
> > +                  DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
> > +                  DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
> > +                  DPTUN_BW_ARG(tunnel->group->available_bw));
> > +
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     if (changed)
> > +             return 1;
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_update_state);
> > +
> > +/*
> > + * drm_dp_tunnel_handle_irq - Handle DP tunnel IRQs
> > + *
> > + * Handle any pending DP tunnel IRQs, waking up waiters for a completion
> > + * event.
> > + *
> > + * Returns 1 if the state of the tunnel has changed which requires calling
> > + * drm_dp_tunnel_update_state(), a negative error code in case of a failure,
> > + * 0 otherwise.
> > + */
> > +int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr, struct
> > drm_dp_aux *aux)
> > +{
> > +     u8 val;
> > +
> > +     if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
> > +             return -EIO;
> > +
> > +     if (val & (DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED))
> > +             wake_up_all(&mgr->bw_req_queue);
> > +
> > +     if (val & (DP_BW_ALLOCATION_CAPABILITY_CHANGED |
> > DP_ESTIMATED_BW_CHANGED))
> > +             return 1;
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_handle_irq);
> > +
> > +/**
> > + * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's
> > DPRX
> > + * @tunnel: Tunnel object
> > + *
> > + * The function is used to query the maximum link rate of the DPRX connected
> > + * to @tunnel. Note that this rate will not be limited by the BW limit of the
> > + * tunnel, as opposed to the standard and extended DP_MAX_LINK_RATE DPCD
> > + * registers.
> > + *
> > + * Returns the maximum link rate in 10 kbit/s units.
> > + */
> > +int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return tunnel->max_dprx_rate;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_rate);
> > +
> > +/**
> > + * drm_dp_tunnel_max_dprx_lane_count - Query the maximum lane count of
> > the tunnel's DPRX
> > + * @tunnel: Tunnel object
> > + *
> > + * The function is used to query the maximum lane count of the DPRX connected
> > + * to @tunnel. Note that this lane count will not be limited by the BW limit of
> > + * the tunnel, as opposed to the standard and extended DP_MAX_LANE_COUNT
> > DPCD
> > + * registers.
> > + *
> > + * Returns the maximum lane count.
> > + */
> > +int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return tunnel->max_dprx_lane_count;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_lane_count);
> > +
> > +/**
> > + * drm_dp_tunnel_available_bw - Query the estimated total available BW of the
> > tunnel
> > + * @tunnel: Tunnel object
> > + *
> > + * This function is used to query the estimated total available BW of the
> > + * tunnel. This includes the currently allocated and free BW for all the
> > + * tunnels in @tunnel's group. The available BW is valid only after the BW
> > + * allocation mode has been enabled for the tunnel and its state got updated
> > + * calling drm_dp_tunnel_update_state().
> > + *
> > + * Returns the @tunnel group's estimated total available bandwidth in kB/s
> > + * units, or -1 if the available BW isn't valid (the BW allocation mode is
> > + * not enabled or the tunnel's state hasn't been updated).
> > + */
> > +int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return tunnel->group->available_bw;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_available_bw);
> > +
> > +static struct drm_dp_tunnel_group_state *
> > +drm_dp_tunnel_atomic_get_group_state(struct drm_atomic_state *state,
> > +                                  const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return (struct drm_dp_tunnel_group_state *)
> > +             drm_atomic_get_private_obj_state(state,
> > +                                              &tunnel->group->base);
> > +}
> > +
> > +static struct drm_dp_tunnel_state *
> > +add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
> > +              struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +
> > +     tun_dbg_atomic(tunnel,
> > +                    "Adding state for tunnel %p to group state %p\n",
> > +                    tunnel, group_state);
> > +
> > +     tunnel_state = kzalloc(sizeof(*tunnel_state), GFP_KERNEL);
> > +     if (!tunnel_state)
> > +             return NULL;
> > +
> > +     tunnel_state->group_state = group_state;
> > +
> > +     drm_dp_tunnel_ref_get(tunnel, &tunnel_state->tunnel_ref);
> > +
> > +     INIT_LIST_HEAD(&tunnel_state->node);
> > +     list_add(&tunnel_state->node, &group_state->tunnel_states);
> > +
> > +     return tunnel_state;
> > +}
> > +
> > +static void free_tunnel_state(struct drm_dp_tunnel_state *tunnel_state)
> > +{
> > +     tun_dbg_atomic(tunnel_state->tunnel_ref.tunnel,
> > +                    "Freeing state for tunnel %p\n",
> > +                    tunnel_state->tunnel_ref.tunnel);
> > +
> > +     list_del(&tunnel_state->node);
> > +
> > +     kfree(tunnel_state->stream_bw);
> > +     drm_dp_tunnel_ref_put(&tunnel_state->tunnel_ref);
> > +
> > +     kfree(tunnel_state);
> > +}
> > +
> > +static void free_group_state(struct drm_dp_tunnel_group_state *group_state)
> > +{
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +     struct drm_dp_tunnel_state *tunnel_state_tmp;
> > +
> > +     for_each_tunnel_state_safe(group_state, tunnel_state,
> > tunnel_state_tmp)
> > +             free_tunnel_state(tunnel_state);
> > +
> > +     kfree(group_state);
> > +}
> > +
> > +static struct drm_dp_tunnel_state *
> > +get_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
> > +              const struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +
> > +     for_each_tunnel_state(group_state, tunnel_state)
> > +             if (tunnel_state->tunnel_ref.tunnel == tunnel)
> > +                     return tunnel_state;
> > +
> > +     return NULL;
> > +}
> > +
> > +static struct drm_dp_tunnel_state *
> > +get_or_add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
> > +                     struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +
> > +     tunnel_state = get_tunnel_state(group_state, tunnel);
> > +     if (tunnel_state)
> > +             return tunnel_state;
> > +
> > +     return add_tunnel_state(group_state, tunnel);
> > +}
> > +
> > +static struct drm_private_state *
> > +tunnel_group_duplicate_state(struct drm_private_obj *obj)
> > +{
> > +     struct drm_dp_tunnel_group_state *group_state;
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +
> > +     group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
> > +     if (!group_state)
> > +             return NULL;
> > +
> > +     INIT_LIST_HEAD(&group_state->tunnel_states);
> > +
> > +     __drm_atomic_helper_private_obj_duplicate_state(obj, &group_state-
> > >base);
> > +
> > +     for_each_tunnel_state(to_group_state(obj->state), tunnel_state) {
> > +             struct drm_dp_tunnel_state *new_tunnel_state;
> > +
> > +             new_tunnel_state = get_or_add_tunnel_state(group_state,
> > +                                                        tunnel_state-
> > >tunnel_ref.tunnel);
> > +             if (!new_tunnel_state)
> > +                     goto out_free_state;
> > +
> > +             new_tunnel_state->stream_mask = tunnel_state-
> > >stream_mask;
> > +             new_tunnel_state->stream_bw = kmemdup(tunnel_state-
> > >stream_bw,
> > +                                                   sizeof(*tunnel_state-
> > >stream_bw) *
> > +
> >       hweight32(tunnel_state->stream_mask),
> > +                                                   GFP_KERNEL);
> > +
> > +             if (!new_tunnel_state->stream_bw)
> > +                     goto out_free_state;
> > +     }
> > +
> > +     return &group_state->base;
> > +
> > +out_free_state:
> > +     free_group_state(group_state);
> > +
> > +     return NULL;
> > +}
> > +
> > +static void tunnel_group_destroy_state(struct drm_private_obj *obj, struct
> > drm_private_state *state)
> > +{
> > +     free_group_state(to_group_state(state));
> > +}
> > +
> > +static const struct drm_private_state_funcs tunnel_group_funcs = {
> > +     .atomic_duplicate_state = tunnel_group_duplicate_state,
> > +     .atomic_destroy_state = tunnel_group_destroy_state,
> > +};
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_get_state - get/allocate the new atomic state for a
> > tunnel
> > + * @state: Atomic state
> > + * @tunnel: Tunnel to get the state for
> > + *
> > + * Get the new atomic state for @tunnel, duplicating it from the old tunnel
> > + * state if not yet allocated.
> > + *
> > + * Return the state or an ERR_PTR() error on failure.
> > + */
> > +struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
> > +                            struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_group_state *group_state;
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +
> > +     group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
> > +     if (IS_ERR(group_state))
> > +             return ERR_CAST(group_state);
> > +
> > +     tunnel_state = get_or_add_tunnel_state(group_state, tunnel);
> > +     if (!tunnel_state)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     return tunnel_state;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_state);
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_get_old_state - get the old atomic state for a tunnel
> > + * @state: Atomic state
> > + * @tunnel: Tunnel to get the state for
> > + *
> > + * Get the old atomic state for @tunnel.
> > + *
> > + * Return the old state or NULL if the tunnel's atomic state is not in @state.
> > + */
> > +struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
> > +                                const struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_group_state *old_group_state;
> > +     int i;
> > +
> > +     for_each_old_group_in_state(state, old_group_state, i)
> > +             if (to_group(old_group_state->base.obj) == tunnel->group)
> > +                     return get_tunnel_state(old_group_state, tunnel);
> > +
> > +     return NULL;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_old_state);
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_get_new_state - get the new atomic state for a
> > tunnel
> > + * @state: Atomic state
> > + * @tunnel: Tunnel to get the state for
> > + *
> > + * Get the new atomic state for @tunnel.
> > + *
> > + * Return the new state or NULL if the tunnel's atomic state is not in @state.
> > + */
> > +struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
> > +                                const struct drm_dp_tunnel *tunnel)
> > +{
> > +     struct drm_dp_tunnel_group_state *new_group_state;
> > +     int i;
> > +
> > +     for_each_new_group_in_state(state, new_group_state, i)
> > +             if (to_group(new_group_state->base.obj) == tunnel->group)
> > +                     return get_tunnel_state(new_group_state, tunnel);
> > +
> > +     return NULL;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_new_state);
> > +
> > +static bool init_group(struct drm_dp_tunnel_mgr *mgr, struct
> > drm_dp_tunnel_group *group)
> > +{
> > +     struct drm_dp_tunnel_group_state *group_state;
> > +
> > +     group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
> > +     if (!group_state)
> > +             return false;
> > +
> > +     INIT_LIST_HEAD(&group_state->tunnel_states);
> > +
> > +     group->mgr = mgr;
> > +     group->available_bw = -1;
> > +     INIT_LIST_HEAD(&group->tunnels);
> > +
> > +     drm_atomic_private_obj_init(mgr->dev, &group->base, &group_state-
> > >base,
> > +                                 &tunnel_group_funcs);
> > +
> > +     return true;
> > +}
> > +
> > +static void cleanup_group(struct drm_dp_tunnel_group *group)
> > +{
> > +     drm_atomic_private_obj_fini(&group->base);
> > +}
> > +
> > +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> > +static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state
> > *group_state)
> > +{
> > +     const struct drm_dp_tunnel_state *tunnel_state;
> > +     u32 stream_mask = 0;
> > +
> > +     for_each_tunnel_state(group_state, tunnel_state) {
> > +             drm_WARN(to_group(group_state->base.obj)->mgr->dev,
> > +                      tunnel_state->stream_mask & stream_mask,
> > +                      "[DPTUN %s]: conflicting stream IDs %x (IDs in other
> > tunnels %x)\n",
> > +                      tunnel_state->tunnel_ref.tunnel->name,
> > +                      tunnel_state->stream_mask,
> > +                      stream_mask);
> > +
> > +             stream_mask |= tunnel_state->stream_mask;
> > +     }
> > +}
> > +#else
> > +static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state
> > *group_state)
> > +{
> > +}
> > +#endif
> > +
> > +static int stream_id_to_idx(u32 stream_mask, u8 stream_id)
> > +{
> > +     return hweight32(stream_mask & (BIT(stream_id) - 1));
> > +}
> > +
> > +static int resize_bw_array(struct drm_dp_tunnel_state *tunnel_state,
> > +                        unsigned long old_mask, unsigned long new_mask)
> > +{
> > +     unsigned long move_mask = old_mask & new_mask;
> > +     int *new_bws = NULL;
> > +     int id;
> > +
> > +     WARN_ON(!new_mask);
> > +
> > +     if (old_mask == new_mask)
> > +             return 0;
> > +
> > +     new_bws = kcalloc(hweight32(new_mask), sizeof(*new_bws),
> > GFP_KERNEL);
> > +     if (!new_bws)
> > +             return -ENOMEM;
> > +
> > +     for_each_set_bit(id, &move_mask, BITS_PER_TYPE(move_mask))
> > +             new_bws[stream_id_to_idx(new_mask, id)] =
> > +                     tunnel_state->stream_bw[stream_id_to_idx(old_mask,
> > id)];
> > +
> > +     kfree(tunnel_state->stream_bw);
> > +     tunnel_state->stream_bw = new_bws;
> > +     tunnel_state->stream_mask = new_mask;
> > +
> > +     return 0;
> > +}
> > +
> > +static int set_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
> > +                      u8 stream_id, int bw)
> > +{
> > +     int err;
> > +
> > +     err = resize_bw_array(tunnel_state,
> > +                           tunnel_state->stream_mask,
> > +                           tunnel_state->stream_mask | BIT(stream_id));
> > +     if (err)
> > +             return err;
> > +
> > +     tunnel_state->stream_bw[stream_id_to_idx(tunnel_state-
> > >stream_mask, stream_id)] = bw;
> > +
> > +     return 0;
> > +}
> > +
> > +static int clear_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
> > +                        u8 stream_id)
> > +{
> > +     if (!(tunnel_state->stream_mask & ~BIT(stream_id))) {
> > +             free_tunnel_state(tunnel_state);
> > +             return 0;
> > +     }
> > +
> > +     return resize_bw_array(tunnel_state,
> > +                            tunnel_state->stream_mask,
> > +                            tunnel_state->stream_mask & ~BIT(stream_id));
> > +}
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_set_stream_bw - Set the BW for a DP tunnel stream
> > + * @state: Atomic state
> > + * @tunnel: DP tunnel containing the stream
> > + * @stream_id: Stream ID
> > + * @bw: BW of the stream
> > + *
> > + * Set a DP tunnel stream's required BW in the atomic state.
> > + *
> > + * Returns 0 in case of success, a negative error code otherwise.
> > + */
> > +int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
> > +                                    struct drm_dp_tunnel *tunnel,
> > +                                    u8 stream_id, int bw)
> > +{
> > +     struct drm_dp_tunnel_group_state *new_group_state;
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +     int err;
> > +
> > +     if (drm_WARN_ON(tunnel->group->mgr->dev,
> > +                     stream_id > BITS_PER_TYPE(tunnel_state-
> > >stream_mask)))
> > +             return -EINVAL;
> > +
> > +     tun_dbg(tunnel,
> > +             "Setting %d Mb/s for stream %d\n",
> > +             DPTUN_BW_ARG(bw), stream_id);
> > +
> > +     new_group_state = drm_dp_tunnel_atomic_get_group_state(state,
> > tunnel);
> > +     if (IS_ERR(new_group_state))
> > +             return PTR_ERR(new_group_state);
> > +
> > +     if (bw == 0) {
> > +             tunnel_state = get_tunnel_state(new_group_state, tunnel);
> > +             if (!tunnel_state)
> > +                     return 0;
> > +
> > +             return clear_stream_bw(tunnel_state, stream_id);
> > +     }
> > +
> > +     tunnel_state = get_or_add_tunnel_state(new_group_state, tunnel);
> > +     if (drm_WARN_ON(state->dev, !tunnel_state))
> > +             return -EINVAL;
> > +
> > +     err = set_stream_bw(tunnel_state, stream_id, bw);
> > +     if (err)
> > +             return err;
> > +
> > +     check_unique_stream_ids(new_group_state);
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_set_stream_bw);
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_get_required_bw - Get the BW required by a DP
> > tunnel
> > + * @tunnel_state: Atomic state of the queried tunnel
> > + *
> > + * Calculate the BW required by a tunnel adding up the required BW of all
> > + * the streams in the tunnel.
> > + *
> > + * Return the total BW required by the tunnel.
> > + */
> > +int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state
> > *tunnel_state)
> > +{
> > +     int tunnel_bw = 0;
> > +     int i;
> > +
> > +     if (!tunnel_state || !tunnel_state->stream_mask)
> > +             return 0;
> > +
> > +     for (i = 0; i < hweight32(tunnel_state->stream_mask); i++)
> > +             tunnel_bw += tunnel_state->stream_bw[i];
> > +
> > +     return tunnel_bw;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_required_bw);
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_get_group_streams_in_state - Get mask of stream
> > IDs in a group
> > + * @state: Atomic state
> > + * @tunnel: Tunnel object
> > + * @stream_mask: Mask of streams in @tunnel's group
> > + *
> > + * Get the mask of all the stream IDs in the tunnel group of @tunnel.
> > + *
> > + * Return 0 in case of success - with the stream IDs in @stream_mask - or a
> > + * negative error code in case of failure.
> > + */
> > +int drm_dp_tunnel_atomic_get_group_streams_in_state(struct
> > drm_atomic_state *state,
> > +                                                 const struct drm_dp_tunnel
> > *tunnel,
> > +                                                 u32 *stream_mask)
> > +{
> > +     struct drm_dp_tunnel_group_state *group_state;
> > +     struct drm_dp_tunnel_state *tunnel_state;
> > +
> > +     group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
> > +     if (IS_ERR(group_state))
> > +             return PTR_ERR(group_state);
> > +
> > +     *stream_mask = 0;
> > +     for_each_tunnel_state(group_state, tunnel_state)
> > +             *stream_mask |= tunnel_state->stream_mask;
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_group_streams_in_state);
> > +
> > +static int
> > +drm_dp_tunnel_atomic_check_group_bw(struct drm_dp_tunnel_group_state
> > *new_group_state,
> > +                                 u32 *failed_stream_mask)
> > +{
> > +     struct drm_dp_tunnel_group *group = to_group(new_group_state-
> > >base.obj);
> > +     struct drm_dp_tunnel_state *new_tunnel_state;
> > +     u32 group_stream_mask = 0;
> > +     int group_bw = 0;
> > +
> > +     for_each_tunnel_state(new_group_state, new_tunnel_state) {
> > +             struct drm_dp_tunnel *tunnel = new_tunnel_state-
> > >tunnel_ref.tunnel;
> > +             int max_dprx_bw = get_max_dprx_bw(tunnel);
> > +             int tunnel_bw =
> > drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
> > +
> > +             tun_dbg(tunnel,
> > +                     "%sRequired %d/%d Mb/s total for tunnel.\n",
> > +                     tunnel_bw > max_dprx_bw ? "Not enough BW: " : "",
> > +                     DPTUN_BW_ARG(tunnel_bw),
> > +                     DPTUN_BW_ARG(max_dprx_bw));
> > +
> > +             if (tunnel_bw > max_dprx_bw) {
> > +                     *failed_stream_mask = new_tunnel_state-
> > >stream_mask;
> > +                     return -ENOSPC;
> > +             }
> > +
> > +             group_bw += min(roundup(tunnel_bw, tunnel->bw_granularity),
> > +                             max_dprx_bw);
> > +             group_stream_mask |= new_tunnel_state->stream_mask;
> > +     }
> > +
> > +     tun_grp_dbg(group,
> > +                 "%sRequired %d/%d Mb/s total for tunnel group.\n",
> > +                 group_bw > group->available_bw ? "Not enough BW: " : "",
> > +                 DPTUN_BW_ARG(group_bw),
> > +                 DPTUN_BW_ARG(group->available_bw));
> > +
> > +     if (group_bw > group->available_bw) {
> > +             *failed_stream_mask = group_stream_mask;
> > +             return -ENOSPC;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +/**
> > + * drm_dp_tunnel_atomic_check_stream_bws - Check BW limit for all streams
> > in state
> > + * @state: Atomic state
> > + * @failed_stream_mask: Mask of stream IDs with a BW limit failure
> > + *
> > + * Check the required BW of each DP tunnel in @state against both the DPRX
> > BW
> > + * limit of the tunnel and the BW limit of the tunnel group. Return a mask of
> > + * stream IDs in @failed_stream_mask once a check fails. The mask will contain
> > + * either all the streams in a tunnel (in case a DPRX BW limit check failed) or
> > + * all the streams in a tunnel group (in case a group BW limit check failed).
> > + *
> > + * Return 0 if all the BW limit checks passed, -ENOSPC in case a BW limit
> > + * check failed - with @failed_stream_mask containing the streams failing the
> > + * check - or a negative error code otherwise.
> > + */
> > +int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
> > +                                       u32 *failed_stream_mask)
> > +{
> > +     struct drm_dp_tunnel_group_state *new_group_state;
> > +     int i;
> > +
> > +     for_each_new_group_in_state(state, new_group_state, i) {
> > +             int ret;
> > +
> > +             ret =
> > drm_dp_tunnel_atomic_check_group_bw(new_group_state,
> > +                                                       failed_stream_mask);
> > +             if (ret)
> > +                     return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_atomic_check_stream_bws);
> > +
> > +static void destroy_mgr(struct drm_dp_tunnel_mgr *mgr)
> > +{
> > +     int i;
> > +
> > +     for (i = 0; i < mgr->group_count; i++) {
> > +             cleanup_group(&mgr->groups[i]);
> > +             drm_WARN_ON(mgr->dev, !list_empty(&mgr-
> > >groups[i].tunnels));
> > +     }
> > +
> > +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> > +     ref_tracker_dir_exit(&mgr->ref_tracker);
> > +#endif
> > +
> > +     kfree(mgr->groups);
> > +     kfree(mgr);
> > +}
> > +
> > +/**
> > + * drm_dp_tunnel_mgr_create - Create a DP tunnel manager
> > + * @dev: DRM device object
> > + *
> > + * Creates a DP tunnel manager for @dev.
> > + *
> > + * Returns a pointer to the tunnel manager if created successfully or NULL in
> > + * case of an error.
> > + */
> > +struct drm_dp_tunnel_mgr *
> > +drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
> > +{
> > +     struct drm_dp_tunnel_mgr *mgr;
> > +     int i;
> > +
> > +     mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> > +     if (!mgr)
> > +             return NULL;
> > +
> > +     mgr->dev = dev;
> > +     init_waitqueue_head(&mgr->bw_req_queue);
> > +
> > +     mgr->groups = kcalloc(max_group_count, sizeof(*mgr->groups),
> > GFP_KERNEL);
> > +     if (!mgr->groups) {
> > +             kfree(mgr);
> > +
> > +             return NULL;
> > +     }
> > +
> > +#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
> > +     ref_tracker_dir_init(&mgr->ref_tracker, 16, "dptun");
> > +#endif
> > +
> > +     for (i = 0; i < max_group_count; i++) {
> > +             if (!init_group(mgr, &mgr->groups[i])) {
> > +                     destroy_mgr(mgr);
> > +
> > +                     return NULL;
> > +             }
> > +
> > +             mgr->group_count++;
> > +     }
> > +
> > +     return mgr;
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_mgr_create);
> > +
> > +/**
> > + * drm_dp_tunnel_mgr_destroy - Destroy DP tunnel manager
> > + * @mgr: Tunnel manager object
> > + *
> > + * Destroy the tunnel manager.
> > + */
> > +void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr)
> > +{
> > +     destroy_mgr(mgr);
> > +}
> > +EXPORT_SYMBOL(drm_dp_tunnel_mgr_destroy);
> > diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
> > index 281afff6ee4e5..8bfd5d007be8d 100644
> > --- a/include/drm/display/drm_dp.h
> > +++ b/include/drm/display/drm_dp.h
> > @@ -1382,6 +1382,66 @@
> >  #define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET   0x69494
> >  #define DP_HDCP_2_2_REG_DBG_OFFSET           0x69518
> >
> > +/* DP-tunneling */
> > +#define DP_TUNNELING_OUI                             0xe0000
> > +#define  DP_TUNNELING_OUI_BYTES                              3
> > +
> > +#define DP_TUNNELING_DEV_ID                          0xe0003
> > +#define  DP_TUNNELING_DEV_ID_BYTES                   6
> > +
> > +#define DP_TUNNELING_HW_REV                          0xe0009
> > +#define  DP_TUNNELING_HW_REV_MAJOR_SHIFT             4
> > +#define  DP_TUNNELING_HW_REV_MAJOR_MASK                      (0xf
> > << DP_TUNNELING_HW_REV_MAJOR_SHIFT)
> > +#define  DP_TUNNELING_HW_REV_MINOR_SHIFT             0
> > +#define  DP_TUNNELING_HW_REV_MINOR_MASK                      (0xf
> > << DP_TUNNELING_HW_REV_MINOR_SHIFT)
> > +
> > +#define DP_TUNNELING_SW_REV_MAJOR                    0xe000a
> > +#define DP_TUNNELING_SW_REV_MINOR                    0xe000b
> > +
> > +#define DP_TUNNELING_CAPABILITIES                    0xe000d
> > +#define  DP_IN_BW_ALLOCATION_MODE_SUPPORT            (1 << 7)
> > +#define  DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT                (1 << 6)
> > +#define  DP_TUNNELING_SUPPORT                                (1 << 0)
> > +
> > +#define DP_IN_ADAPTER_INFO                           0xe000e
> > +#define  DP_IN_ADAPTER_NUMBER_BITS                   7
> > +#define  DP_IN_ADAPTER_NUMBER_MASK                   ((1 <<
> > DP_IN_ADAPTER_NUMBER_BITS) - 1)
> > +
> > +#define DP_USB4_DRIVER_ID                            0xe000f
> > +#define  DP_USB4_DRIVER_ID_BITS                              4
> > +#define  DP_USB4_DRIVER_ID_MASK                              ((1 <<
> > DP_USB4_DRIVER_ID_BITS) - 1)
> > +
> > +#define DP_USB4_DRIVER_BW_CAPABILITY                 0xe0020
> > +#define  DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT   (1 << 7)
> > +
> > +#define DP_IN_ADAPTER_TUNNEL_INFORMATION             0xe0021
> > +#define  DP_GROUP_ID_BITS                            3
> > +#define  DP_GROUP_ID_MASK                            ((1 <<
> > DP_GROUP_ID_BITS) - 1)
> > +
> > +#define DP_BW_GRANULARITY                            0xe0022
> > +#define  DP_BW_GRANULARITY_MASK                              0x3
> > +
> > +#define DP_ESTIMATED_BW                                      0xe0023
> > +#define DP_ALLOCATED_BW                                      0xe0024
> > +
> > +#define DP_TUNNELING_STATUS                          0xe0025
> > +#define  DP_BW_ALLOCATION_CAPABILITY_CHANGED         (1 << 3)
> > +#define  DP_ESTIMATED_BW_CHANGED                     (1 << 2)
> > +#define  DP_BW_REQUEST_SUCCEEDED                     (1 << 1)
> > +#define  DP_BW_REQUEST_FAILED                                (1 << 0)
> > +
> > +#define DP_TUNNELING_MAX_LINK_RATE                   0xe0028
> > +
> > +#define DP_TUNNELING_MAX_LANE_COUNT                  0xe0029
> > +#define  DP_TUNNELING_MAX_LANE_COUNT_MASK            0x1f
> > +
> > +#define DP_DPTX_BW_ALLOCATION_MODE_CONTROL           0xe0030
> > +#define  DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE (1 <<
> > 7)
> > +#define  DP_UNMASK_BW_ALLOCATION_IRQ                 (1 << 6)
> > +
> > +#define DP_REQUEST_BW                                        0xe0031
> > +#define  MAX_DP_REQUEST_BW                           255
> > +
> >  /* LTTPR: Link Training (LT)-tunable PHY Repeaters */
> >  #define DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV
> > 0xf0000 /* 1.3 */
> >  #define DP_MAX_LINK_RATE_PHY_REPEATER                            0xf0001 /*
> > 1.4a */
> > diff --git a/include/drm/display/drm_dp_tunnel.h
> > b/include/drm/display/drm_dp_tunnel.h
> > new file mode 100644
> > index 0000000000000..476252021f15c
> > --- /dev/null
> > +++ b/include/drm/display/drm_dp_tunnel.h
> > @@ -0,0 +1,248 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright © 2023 Intel Corporation
> > + */
> > +
> > +#ifndef __DRM_DP_TUNNEL_H__
> > +#define __DRM_DP_TUNNEL_H__
> > +
> > +#include <linux/err.h>
> > +#include <linux/errno.h>
> > +#include <linux/types.h>
> > +
> > +struct drm_dp_aux;
> > +
> > +struct drm_device;
> > +
> > +struct drm_atomic_state;
> > +struct drm_dp_tunnel_mgr;
> > +struct drm_dp_tunnel_state;
> > +
> > +struct ref_tracker;
> > +
> > +struct drm_dp_tunnel_ref {
> > +     struct drm_dp_tunnel *tunnel;
> > +     struct ref_tracker *tracker;
> > +};
> > +
> > +#ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL
> > +
> > +struct drm_dp_tunnel *
> > +drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker
> > **tracker);
> > +
> > +void
> > +drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker
> > **tracker);
> > +
> > +static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
> > +                                      struct drm_dp_tunnel_ref *tunnel_ref)
> > +{
> > +     tunnel_ref->tunnel = drm_dp_tunnel_get(tunnel, &tunnel_ref->tracker);
> > +}
> > +
> > +static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
> > +{
> > +     drm_dp_tunnel_put(tunnel_ref->tunnel, &tunnel_ref->tracker);
> > +}
> > +
> > +struct drm_dp_tunnel *
> > +drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
> > +                  struct drm_dp_aux *aux);
> > +int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel);
> > +
> > +int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel);
> > +int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel);
> > +bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel
> > *tunnel);
> > +int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw);
> > +int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel);
> > +int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel);
> > +
> > +void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel);
> > +
> > +int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
> > +                          struct drm_dp_aux *aux);
> > +
> > +int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel);
> > +int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel);
> > +int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel);
> > +
> > +const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel);
> > +
> > +struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
> > +                            struct drm_dp_tunnel *tunnel);
> > +
> > +struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
> > +                                const struct drm_dp_tunnel *tunnel);
> > +
> > +struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
> > +                                const struct drm_dp_tunnel *tunnel);
> > +
> > +int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
> > +                                    struct drm_dp_tunnel *tunnel,
> > +                                    u8 stream_id, int bw);
> > +int drm_dp_tunnel_atomic_get_group_streams_in_state(struct
> > drm_atomic_state *state,
> > +                                                 const struct drm_dp_tunnel
> > *tunnel,
> > +                                                 u32 *stream_mask);
> > +
> > +int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
> > +                                       u32 *failed_stream_mask);
> > +
> > +int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state
> > *tunnel_state);
> > +
> > +struct drm_dp_tunnel_mgr *
> > +drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count);
> > +void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr);
> > +
> > +#else
> > +
> > +static inline struct drm_dp_tunnel *
> > +drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker)
> > +{
> > +     return NULL;
> > +}
> > +
> > +static inline void
> > +drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker)
> > {}
> > +
> > +static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
> > +                                      struct drm_dp_tunnel_ref *tunnel_ref)
> > {}
> > +
> > +static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
> > {}
> > +
> > +static inline struct drm_dp_tunnel *
> > +drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
> > +                  struct drm_dp_aux *aux)
> > +{
> > +     return ERR_PTR(-EOPNOTSUPP);
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
> > +{
> > +     return 0;
> > +}
> > +
> > +static inline int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel
> > *tunnel)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline bool drm_dp_tunnel_bw_alloc_is_enabled(const struct
> > drm_dp_tunnel *tunnel)
> > +{
> > +     return false;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
> > +{
> > +     return -1;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel) {}
> > +
> > +static inline int
> > +drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
> > +                      struct drm_dp_aux *aux)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return 0;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return 0;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return -1;
> > +}
> > +
> > +static inline const char *
> > +drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return NULL;
> > +}
> > +
> > +static inline struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
> > +                            struct drm_dp_tunnel *tunnel)
> > +{
> > +     return ERR_PTR(-EOPNOTSUPP);
> > +}
> > +
> > +static inline struct drm_dp_tunnel_state *
> > +drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
> > +                                const struct drm_dp_tunnel *tunnel)
> > +{
> > +     return ERR_PTR(-EOPNOTSUPP);
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
> > +                                struct drm_dp_tunnel *tunnel,
> > +                                u8 stream_id, int bw)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state
> > *state,
> > +                                             const struct drm_dp_tunnel
> > *tunnel,
> > +                                             u32 *stream_mask)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
> > +                                   u32 *failed_stream_mask)
> > +{
> > +     return -EOPNOTSUPP;
> > +}
> > +
> > +static inline int
> > +drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state
> > *tunnel_state)
> > +{
> > +     return 0;
> > +}
> > +
> > +static inline struct drm_dp_tunnel_mgr *
> > +drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
> > +{
> > +     return ERR_PTR(-EOPNOTSUPP);
> > +}
> > +
> > +static inline
> > +void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr) {}
> > +
> > +
> > +#endif /* CONFIG_DRM_DISPLAY_DP_TUNNEL */
> > +
> > +#endif /* __DRM_DP_TUNNEL_H__ */
> > --
> > 2.39.2
> 

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

* Re: [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits
  2024-02-20 21:18 ` [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits Imre Deak
  2024-02-23  8:10   ` Shankar, Uma
@ 2024-02-23 21:11   ` Ville Syrjälä
  2024-02-23 22:09     ` Imre Deak
  2024-02-26 18:52   ` [PATCH v3 11/21] drm/i915/dp: Sync instead of try-sync commits when getting active pipes Imre Deak
  2 siblings, 1 reply; 61+ messages in thread
From: Ville Syrjälä @ 2024-02-23 21:11 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx, dri-devel

On Tue, Feb 20, 2024 at 11:18:31PM +0200, Imre Deak wrote:
> Add a way to get the active pipes through a given DP port by syncing
> against a related pending non-blocking commit. Atm
> intel_dp_get_active_pipes() will only try to sync a given pipe and if
> that would block ignore the pipe. A follow-up change enabling the DP
> tunnel BW allocation mode will need to ensure that all active pipes are
> returned.
> 
> This change will use intel_crtc_state::uapi.commit instead of the
> corresponding commit in the connector state. This shouldn't make a
> difference, since the two commit objects match for an active pipe.

There is a slight difference here in that a non-modeset/fastset commit
will not have the connector inluded in the state and thus
connector->state.commit will be updated.

I think the original idea of the code was to just skip anything that
looks like it's already undergoing a full modeset. With this we might
skip the retrain if there happens to be any kind of commit happening
on the crtc. Althoguh it seems that the original code is already
broken in the same way when there's a fastset happening in parallel.

> 
> A follow-up patchset will remove syncing during TC port reset, which
> should reset a port/pipe even if syncing against a commit would block.
> Syncing OTOH is not needed there, since the commit used for the reset
> implies a sync already. For now add a TODO comment for this.
> 
> v2:
> - Add a separate function to try-sync the pipes. (Ville)
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_crtc.c | 27 +++++++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_crtc.h |  1 +
>  drivers/gpu/drm/i915/display/intel_dp.c   |  6 ++---
>  drivers/gpu/drm/i915/display/intel_tc.c   |  7 ++++++
>  4 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> index 25593f6aae7de..17ed2e62cc66a 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -654,3 +654,30 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
>  out:
>  	intel_psr_unlock(new_crtc_state);
>  }
> +
> +/**
> + * intel_crtc_try_sync_pipes - Try syncing pending commits on a set of pipes
> + * @i915: i915 device object
> + * @pipe_mask: Mask of pipes to sync
> + *
> + * Try to sync a pending non-blocking commit for the provided pipes in
> + * @pipe_mask. The commit won't be synced if this would block.
> + *
> + * Return a mask of the pipes that got synced or didn't need syncing.
> + */
> +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask)
> +{
> +	struct intel_crtc *crtc;
> +	u32 synced = 0;
> +
> +	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
> +		const struct intel_crtc_state *crtc_state =
> +			to_intel_crtc_state(crtc->base.state);
> +
> +		if (!crtc_state->uapi.commit ||
> +		    try_wait_for_completion(&crtc_state->uapi.commit->hw_done))
> +			synced |= BIT(crtc->pipe);
> +	}
> +
> +	return synced;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
> index 22d7993d1f0ba..71a5b93166da7 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.h
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.h
> @@ -47,5 +47,6 @@ struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
>  void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
>  				     enum pipe pipe);
>  void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
> +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
>  
>  #endif
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index d9e75922ff8f5..d0452d3e534a7 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5048,10 +5048,6 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
>  		if (!crtc_state->hw.active)
>  			continue;
>  
> -		if (conn_state->commit &&
> -		    !try_wait_for_completion(&conn_state->commit->hw_done))
> -			continue;
> -
>  		*pipe_mask |= BIT(crtc->pipe);
>  	}
>  	drm_connector_list_iter_end(&conn_iter);
> @@ -5091,6 +5087,8 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
>  	if (ret)
>  		return ret;
>  
> +	pipe_mask &= intel_crtc_try_sync_pipes(dev_priv, pipe_mask);
> +
>  	if (pipe_mask == 0)
>  		return 0;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
> index 6b374d481cd9e..14d17903a81f5 100644
> --- a/drivers/gpu/drm/i915/display/intel_tc.c
> +++ b/drivers/gpu/drm/i915/display/intel_tc.c
> @@ -7,6 +7,7 @@
>  #include "i915_reg.h"
>  #include "intel_atomic.h"
>  #include "intel_cx0_phy_regs.h"
> +#include "intel_crtc.h"
>  #include "intel_ddi.h"
>  #include "intel_de.h"
>  #include "intel_display.h"
> @@ -1663,6 +1664,12 @@ static int reset_link_commit(struct intel_tc_port *tc,
>  	if (ret)
>  		return ret;
>  
> +	/*
> +	 * TODO: remove the following, since an output must be reset
> +	 * even if we had to wait for a non-blocking commit on a pipe.
> +	 */
> +	pipe_mask &= intel_crtc_try_sync_pipes(i915, pipe_mask);
> +
>  	if (!pipe_mask)
>  		return 0;
>  
> -- 
> 2.39.2

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 16/21] drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
  2024-02-20 21:18 ` [PATCH v2 16/21] drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks Imre Deak
@ 2024-02-23 21:25   ` Ville Syrjälä
  0 siblings, 0 replies; 61+ messages in thread
From: Ville Syrjälä @ 2024-02-23 21:25 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx, dri-devel, Uma Shankar

On Tue, Feb 20, 2024 at 11:18:36PM +0200, Imre Deak wrote:
> Allocate and free the DP tunnel BW required by a stream while
> enabling/disabling the stream during a modeset.
> 
> v2:
> - Move the allocation up from encoder hooks to
>   intel_atomic_commit_tail().

Subject should be adjusted to match.

> 
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com> (v1)
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     | 1 +
>  drivers/gpu/drm/i915/display/intel_display.c | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bea4415902044..ed7301808604d 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -54,6 +54,7 @@
>  #include "intel_dp_aux.h"
>  #include "intel_dp_link_training.h"
>  #include "intel_dp_mst.h"
> +#include "intel_dp_tunnel.h"
>  #include "intel_dpio_phy.h"
>  #include "intel_dsi.h"
>  #include "intel_fdi.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 20647c97e86fa..445efe0087cde 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7123,6 +7123,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  
>  	intel_commit_modeset_disables(state);
>  
> +	intel_dp_tunnel_atomic_alloc_bw(state);
> +
>  	/* FIXME: Eventually get rid of our crtc->config pointer */
>  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
>  		crtc->config = new_crtc_state;
> -- 
> 2.39.2

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 02/21] drm/dp: Add support for DP tunneling
  2024-02-20 21:18 ` [PATCH v2 02/21] drm/dp: Add support for DP tunneling Imre Deak
  2024-02-23  6:25   ` Shankar, Uma
@ 2024-02-23 21:32   ` Ville Syrjälä
  2024-02-26 11:40     ` Imre Deak
  2024-02-26 18:52   ` [PATCH v3 " Imre Deak
  2 siblings, 1 reply; 61+ messages in thread
From: Ville Syrjälä @ 2024-02-23 21:32 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx, dri-devel

On Tue, Feb 20, 2024 at 11:18:22PM +0200, Imre Deak wrote:
> +static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
> +{
> +	drm_dp_tunnel_put(tunnel_ref->tunnel, &tunnel_ref->tracker);

Should we set tunnel_ref->tunnel=NULL here?

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation
  2024-02-20 21:18 ` [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation Imre Deak
@ 2024-02-23 21:37   ` Ville Syrjälä
  2024-02-26 11:42     ` Imre Deak
  2024-02-26 10:47   ` Shankar, Uma
  2024-02-26 18:52   ` [PATCH v3 " Imre Deak
  2 siblings, 1 reply; 61+ messages in thread
From: Ville Syrjälä @ 2024-02-23 21:37 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx, dri-devel

On Tue, Feb 20, 2024 at 11:18:32PM +0200, Imre Deak wrote:
> +static void queue_retry_work(struct intel_atomic_state *state,
> +			     struct drm_dp_tunnel *tunnel,
> +			     const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> +	struct intel_encoder *encoder;
> +
> +	encoder = intel_get_crtc_new_encoder(state, crtc_state);

I was pondering what happens if we have no encoder here?
But I guess crtc_state->tunnel_ref.tunnel should be NULL in
that case and so we should not end up here.

> +
> +	if (!intel_digital_port_connected(encoder))
> +		return;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN %s][ENCODER:%d:%s] BW allocation failed on a connected sink\n",
> +		    drm_dp_tunnel_name(tunnel),
> +		    encoder->base.base.id,
> +		    encoder->base.name);
> +
> +	intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
> +}
> +

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits
  2024-02-23 21:11   ` Ville Syrjälä
@ 2024-02-23 22:09     ` Imre Deak
  2024-02-23 22:13       ` Ville Syrjälä
  0 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-23 22:09 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Fri, Feb 23, 2024 at 11:11:45PM +0200, Ville Syrjälä wrote:
> On Tue, Feb 20, 2024 at 11:18:31PM +0200, Imre Deak wrote:
> > Add a way to get the active pipes through a given DP port by syncing
> > against a related pending non-blocking commit. Atm
> > intel_dp_get_active_pipes() will only try to sync a given pipe and if
> > that would block ignore the pipe. A follow-up change enabling the DP
> > tunnel BW allocation mode will need to ensure that all active pipes are
> > returned.
> > 
> > This change will use intel_crtc_state::uapi.commit instead of the
> > corresponding commit in the connector state. This shouldn't make a
> > difference, since the two commit objects match for an active pipe.
> 
> There is a slight difference here in that a non-modeset/fastset commit
> will not have the connector inluded in the state and thus
> connector->state.commit will be updated.
> 
> I think the original idea of the code was to just skip anything that
> looks like it's already undergoing a full modeset. With this we might
> skip the retrain if there happens to be any kind of commit happening
> on the crtc. Althoguh it seems that the original code is already
> broken in the same way when there's a fastset happening in parallel.

Ok, didn't think of it. Are you ok to sync instead of try-sync the pipes
in case of link re-training?

> > A follow-up patchset will remove syncing during TC port reset, which
> > should reset a port/pipe even if syncing against a commit would block.
> > Syncing OTOH is not needed there, since the commit used for the reset
> > implies a sync already. For now add a TODO comment for this.
> > 
> > v2:
> > - Add a separate function to try-sync the pipes. (Ville)
> > 
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: Imre Deak <imre.deak@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_crtc.c | 27 +++++++++++++++++++++++
> >  drivers/gpu/drm/i915/display/intel_crtc.h |  1 +
> >  drivers/gpu/drm/i915/display/intel_dp.c   |  6 ++---
> >  drivers/gpu/drm/i915/display/intel_tc.c   |  7 ++++++
> >  4 files changed, 37 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> > index 25593f6aae7de..17ed2e62cc66a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> > +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> > @@ -654,3 +654,30 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
> >  out:
> >  	intel_psr_unlock(new_crtc_state);
> >  }
> > +
> > +/**
> > + * intel_crtc_try_sync_pipes - Try syncing pending commits on a set of pipes
> > + * @i915: i915 device object
> > + * @pipe_mask: Mask of pipes to sync
> > + *
> > + * Try to sync a pending non-blocking commit for the provided pipes in
> > + * @pipe_mask. The commit won't be synced if this would block.
> > + *
> > + * Return a mask of the pipes that got synced or didn't need syncing.
> > + */
> > +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask)
> > +{
> > +	struct intel_crtc *crtc;
> > +	u32 synced = 0;
> > +
> > +	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
> > +		const struct intel_crtc_state *crtc_state =
> > +			to_intel_crtc_state(crtc->base.state);
> > +
> > +		if (!crtc_state->uapi.commit ||
> > +		    try_wait_for_completion(&crtc_state->uapi.commit->hw_done))
> > +			synced |= BIT(crtc->pipe);
> > +	}
> > +
> > +	return synced;
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
> > index 22d7993d1f0ba..71a5b93166da7 100644
> > --- a/drivers/gpu/drm/i915/display/intel_crtc.h
> > +++ b/drivers/gpu/drm/i915/display/intel_crtc.h
> > @@ -47,5 +47,6 @@ struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
> >  void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
> >  				     enum pipe pipe);
> >  void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
> > +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
> >  
> >  #endif
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index d9e75922ff8f5..d0452d3e534a7 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -5048,10 +5048,6 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
> >  		if (!crtc_state->hw.active)
> >  			continue;
> >  
> > -		if (conn_state->commit &&
> > -		    !try_wait_for_completion(&conn_state->commit->hw_done))
> > -			continue;
> > -
> >  		*pipe_mask |= BIT(crtc->pipe);
> >  	}
> >  	drm_connector_list_iter_end(&conn_iter);
> > @@ -5091,6 +5087,8 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
> >  	if (ret)
> >  		return ret;
> >  
> > +	pipe_mask &= intel_crtc_try_sync_pipes(dev_priv, pipe_mask);
> > +
> >  	if (pipe_mask == 0)
> >  		return 0;
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
> > index 6b374d481cd9e..14d17903a81f5 100644
> > --- a/drivers/gpu/drm/i915/display/intel_tc.c
> > +++ b/drivers/gpu/drm/i915/display/intel_tc.c
> > @@ -7,6 +7,7 @@
> >  #include "i915_reg.h"
> >  #include "intel_atomic.h"
> >  #include "intel_cx0_phy_regs.h"
> > +#include "intel_crtc.h"
> >  #include "intel_ddi.h"
> >  #include "intel_de.h"
> >  #include "intel_display.h"
> > @@ -1663,6 +1664,12 @@ static int reset_link_commit(struct intel_tc_port *tc,
> >  	if (ret)
> >  		return ret;
> >  
> > +	/*
> > +	 * TODO: remove the following, since an output must be reset
> > +	 * even if we had to wait for a non-blocking commit on a pipe.
> > +	 */
> > +	pipe_mask &= intel_crtc_try_sync_pipes(i915, pipe_mask);
> > +
> >  	if (!pipe_mask)
> >  		return 0;
> >  
> > -- 
> > 2.39.2
> 
> -- 
> Ville Syrjälä
> Intel

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

* Re: [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits
  2024-02-23 22:09     ` Imre Deak
@ 2024-02-23 22:13       ` Ville Syrjälä
  0 siblings, 0 replies; 61+ messages in thread
From: Ville Syrjälä @ 2024-02-23 22:13 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx, dri-devel

On Sat, Feb 24, 2024 at 12:09:41AM +0200, Imre Deak wrote:
> On Fri, Feb 23, 2024 at 11:11:45PM +0200, Ville Syrjälä wrote:
> > On Tue, Feb 20, 2024 at 11:18:31PM +0200, Imre Deak wrote:
> > > Add a way to get the active pipes through a given DP port by syncing
> > > against a related pending non-blocking commit. Atm
> > > intel_dp_get_active_pipes() will only try to sync a given pipe and if
> > > that would block ignore the pipe. A follow-up change enabling the DP
> > > tunnel BW allocation mode will need to ensure that all active pipes are
> > > returned.
> > > 
> > > This change will use intel_crtc_state::uapi.commit instead of the
> > > corresponding commit in the connector state. This shouldn't make a
> > > difference, since the two commit objects match for an active pipe.
> > 
> > There is a slight difference here in that a non-modeset/fastset commit
> > will not have the connector inluded in the state and thus
> > connector->state.commit will be updated.
> > 
> > I think the original idea of the code was to just skip anything that
> > looks like it's already undergoing a full modeset. With this we might
> > skip the retrain if there happens to be any kind of commit happening
> > on the crtc. Althoguh it seems that the original code is already
> > broken in the same way when there's a fastset happening in parallel.
> 
> Ok, didn't think of it. Are you ok to sync instead of try-sync the pipes
> in case of link re-training?

Yeah, I guess that should be safer option, and we do recheck the
condition after the sync anyway so it shouldn't cause too much
extra stuff to happen. We can think about optimizing it correctly
later if necessary.

> 
> > > A follow-up patchset will remove syncing during TC port reset, which
> > > should reset a port/pipe even if syncing against a commit would block.
> > > Syncing OTOH is not needed there, since the commit used for the reset
> > > implies a sync already. For now add a TODO comment for this.
> > > 
> > > v2:
> > > - Add a separate function to try-sync the pipes. (Ville)
> > > 
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Signed-off-by: Imre Deak <imre.deak@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_crtc.c | 27 +++++++++++++++++++++++
> > >  drivers/gpu/drm/i915/display/intel_crtc.h |  1 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c   |  6 ++---
> > >  drivers/gpu/drm/i915/display/intel_tc.c   |  7 ++++++
> > >  4 files changed, 37 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> > > index 25593f6aae7de..17ed2e62cc66a 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> > > @@ -654,3 +654,30 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
> > >  out:
> > >  	intel_psr_unlock(new_crtc_state);
> > >  }
> > > +
> > > +/**
> > > + * intel_crtc_try_sync_pipes - Try syncing pending commits on a set of pipes
> > > + * @i915: i915 device object
> > > + * @pipe_mask: Mask of pipes to sync
> > > + *
> > > + * Try to sync a pending non-blocking commit for the provided pipes in
> > > + * @pipe_mask. The commit won't be synced if this would block.
> > > + *
> > > + * Return a mask of the pipes that got synced or didn't need syncing.
> > > + */
> > > +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask)
> > > +{
> > > +	struct intel_crtc *crtc;
> > > +	u32 synced = 0;
> > > +
> > > +	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
> > > +		const struct intel_crtc_state *crtc_state =
> > > +			to_intel_crtc_state(crtc->base.state);
> > > +
> > > +		if (!crtc_state->uapi.commit ||
> > > +		    try_wait_for_completion(&crtc_state->uapi.commit->hw_done))
> > > +			synced |= BIT(crtc->pipe);
> > > +	}
> > > +
> > > +	return synced;
> > > +}
> > > diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
> > > index 22d7993d1f0ba..71a5b93166da7 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_crtc.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_crtc.h
> > > @@ -47,5 +47,6 @@ struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
> > >  void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
> > >  				     enum pipe pipe);
> > >  void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
> > > +u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
> > >  
> > >  #endif
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index d9e75922ff8f5..d0452d3e534a7 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -5048,10 +5048,6 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
> > >  		if (!crtc_state->hw.active)
> > >  			continue;
> > >  
> > > -		if (conn_state->commit &&
> > > -		    !try_wait_for_completion(&conn_state->commit->hw_done))
> > > -			continue;
> > > -
> > >  		*pipe_mask |= BIT(crtc->pipe);
> > >  	}
> > >  	drm_connector_list_iter_end(&conn_iter);
> > > @@ -5091,6 +5087,8 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > +	pipe_mask &= intel_crtc_try_sync_pipes(dev_priv, pipe_mask);
> > > +
> > >  	if (pipe_mask == 0)
> > >  		return 0;
> > >  
> > > diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
> > > index 6b374d481cd9e..14d17903a81f5 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_tc.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_tc.c
> > > @@ -7,6 +7,7 @@
> > >  #include "i915_reg.h"
> > >  #include "intel_atomic.h"
> > >  #include "intel_cx0_phy_regs.h"
> > > +#include "intel_crtc.h"
> > >  #include "intel_ddi.h"
> > >  #include "intel_de.h"
> > >  #include "intel_display.h"
> > > @@ -1663,6 +1664,12 @@ static int reset_link_commit(struct intel_tc_port *tc,
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > +	/*
> > > +	 * TODO: remove the following, since an output must be reset
> > > +	 * even if we had to wait for a non-blocking commit on a pipe.
> > > +	 */
> > > +	pipe_mask &= intel_crtc_try_sync_pipes(i915, pipe_mask);
> > > +
> > >  	if (!pipe_mask)
> > >  		return 0;
> > >  
> > > -- 
> > > 2.39.2
> > 
> > -- 
> > Ville Syrjälä
> > Intel

-- 
Ville Syrjälä
Intel

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

* Re: [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (24 preceding siblings ...)
  2024-02-21  5:25 ` ✗ Fi.CI.IGT: failure " Patchwork
@ 2024-02-23 22:14 ` Ville Syrjälä
  2024-02-26 13:54 ` Jani Nikula
                   ` (6 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Ville Syrjälä @ 2024-02-23 22:14 UTC (permalink / raw)
  To: Imre Deak
  Cc: intel-gfx, dri-devel, Mika Westerberg, Uma Shankar,
	Jouni Högander, Saranya Gopal, Rajaram Regupathy, Gil Fine,
	Naama Shachar, Pengfei Xu

On Tue, Feb 20, 2024 at 11:18:20PM +0200, Imre Deak wrote:
> This is v2 of [1], with the following changes:
> 
> - Several functional/typo/formatting fixes, detailed in the patches.
> - Move the BW allocation from encoder hooks to
>   intel_atomic_commit_tail() fixing the allocation for MST streams
>   enabled/disabled w/o a full modeset (i.e. w/o re-enabling the master
>   stream).
> - Fix an MST mode restore issue during system resume, which also lead
>   to a tunnel BW allocation failure. (Patch 3)
> - Ensure a DPCD DPRX cap read as required by the TBT CM any time a long
>   HPD pulse is detected. (Patch 20)
> - Explicitly disable the BW allocation mode during system suspend.
> 
> The patchset is also available at:
> https://github.com/ideak/linux/commits/dp_tun_bw_alloc
> 
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Cc: Jouni Högander <jouni.hogander@intel.com>
> Cc: Saranya Gopal <saranya.gopal@intel.com>
> Cc: Rajaram Regupathy <rajaram.regupathy@intel.com>
> Cc: Gil Fine <gil.fine@intel.com>
> Cc: Naama Shachar <naamax.shachar@intel.com>
> Cc: Pengfei Xu <pengfei.xu@intel.com>
> 
> [1] https://lore.kernel.org/all/20240123102850.390126-1-imre.deak@intel.com
> 
> Imre Deak (21):
>   drm/dp: Add drm_dp_max_dprx_data_rate()
>   drm/dp: Add support for DP tunneling
>   drm/i915: Fix display bpp limit computation during system resume
>   drm/i915/dp: Add support to notify MST connectors to retry modesets
>   drm/i915/dp: Use drm_dp_max_dprx_data_rate()
>   drm/i915/dp: Factor out intel_dp_config_required_rate()
>   drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
>   drm/i915/dp: Factor out intel_dp_update_sink_caps()
>   drm/i915/dp: Factor out intel_dp_read_dprx_caps()
>   drm/i915/dp: Add intel_dp_max_link_data_rate()
>   drm/i915/dp: Add way to get active pipes with syncing commits
>   drm/i915/dp: Add support for DP tunnel BW allocation
>   drm/i915/dp: Add DP tunnel atomic state and check BW limit
>   drm/i915/dp: Account for tunnel BW limit in
>     intel_dp_max_link_data_rate()
>   drm/i915/dp: Compute DP tunnel BW during encoder state computation
>   drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable
>     hooks
>   drm/i915/dp: Handle DP tunnel IRQs
>   drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
>   drm/i915/dp: Suspend/resume DP tunnels
>   drm/i915/dp: Read DPRX for all long HPD pulses
>   drm/i915/dp: Enable DP tunnel BW allocation mode

I think I eyeballed this sufficiently now. 

Only a few minor issues which I pointed out already. 
Otherwise this is:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
>  drivers/gpu/drm/display/Kconfig               |   21 +
>  drivers/gpu/drm/display/Makefile              |    2 +
>  drivers/gpu/drm/display/drm_dp_helper.c       |   30 +
>  drivers/gpu/drm/display/drm_dp_tunnel.c       | 1929 +++++++++++++++++
>  drivers/gpu/drm/i915/Kconfig                  |   14 +
>  drivers/gpu/drm/i915/Kconfig.debug            |    1 +
>  drivers/gpu/drm/i915/Makefile                 |    3 +
>  drivers/gpu/drm/i915/display/intel_atomic.c   |   10 +
>  drivers/gpu/drm/i915/display/intel_crtc.c     |   52 +
>  drivers/gpu/drm/i915/display/intel_crtc.h     |    2 +
>  drivers/gpu/drm/i915/display/intel_ddi.c      |    3 +-
>  drivers/gpu/drm/i915/display/intel_display.c  |   26 +-
>  .../gpu/drm/i915/display/intel_display_core.h |    1 +
>  .../drm/i915/display/intel_display_driver.c   |   20 +-
>  .../drm/i915/display/intel_display_types.h    |    9 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  292 ++-
>  drivers/gpu/drm/i915/display/intel_dp.h       |   13 +-
>  .../drm/i915/display/intel_dp_link_training.c |   33 +-
>  .../drm/i915/display/intel_dp_link_training.h |    1 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   18 +-
>  .../gpu/drm/i915/display/intel_dp_tunnel.c    |  815 +++++++
>  .../gpu/drm/i915/display/intel_dp_tunnel.h    |  133 ++
>  drivers/gpu/drm/i915/display/intel_link_bw.c  |   27 +-
>  drivers/gpu/drm/i915/display/intel_link_bw.h  |    2 +-
>  drivers/gpu/drm/i915/display/intel_tc.c       |    7 +
>  include/drm/display/drm_dp.h                  |   61 +
>  include/drm/display/drm_dp_helper.h           |    2 +
>  include/drm/display/drm_dp_tunnel.h           |  248 +++
>  28 files changed, 3650 insertions(+), 125 deletions(-)
>  create mode 100644 drivers/gpu/drm/display/drm_dp_tunnel.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h
>  create mode 100644 include/drm/display/drm_dp_tunnel.h
> 
> -- 
> 2.39.2

-- 
Ville Syrjälä
Intel

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

* RE: [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation
  2024-02-20 21:18 ` [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation Imre Deak
  2024-02-23 21:37   ` Ville Syrjälä
@ 2024-02-26 10:47   ` Shankar, Uma
  2024-02-26 18:52   ` [PATCH v3 " Imre Deak
  2 siblings, 0 replies; 61+ messages in thread
From: Shankar, Uma @ 2024-02-26 10:47 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, dri-devel; +Cc: Ville Syrjälä



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Wednesday, February 21, 2024 2:49 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Subject: [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation
> 
> Add support to enable the DP tunnel BW allocation mode. Follow-up patches will
> call the required helpers added here to prepare for a modeset on a link with DP
> tunnels, the last change in the patchset actually enabling BWA.
> 
> With BWA enabled, the driver will expose the full mode list a display supports,
> regardless of any BW limitation on a shared (Thunderbolt) link. Such BW limits will
> be checked against only during a modeset, when the driver has the full knowledge
> of each display's BW requirement.
> 
> If the link BW changes in a way that a connector's modelist may also change,
> userspace will get a hotplug notification for all the connectors sharing the same
> link (so it can adjust the mode used for a display).
> 
> The BW limitation can change at any point, asynchronously to modesets on a
> given connector, so a modeset can fail even though the atomic check for it
> passed. In such scenarios userspace will get a bad link notification and in
> response is supposed to retry the modeset.
> 
> v2:
> - Fix old vs. new connector state in intel_dp_tunnel_atomic_check_state().
>   (Ville)
> - Fix propagating the error from
>   intel_dp_tunnel_atomic_compute_stream_bw(). (Ville)
> - Move tunnel==NULL checks from driver to DRM core helpers. (Ville)
> - Simplify return flow from intel_dp_tunnel_detect(). (Ville)
> - s/dp_tunnel_state/inherited_dp_tunnels (Ville)
> - Simplify struct intel_dp_tunnel_inherited_state. (Ville)
> - Unconstify object pointers (vs. states) where possible. (Ville)
> - Init crtc_state while declaring it in check_group_state(). (Ville)
> - Join obj->base.id, obj->name arg lines in debug prints to reduce LOC.
>   (Ville)
> - Add/rework intel_dp_tunnel_atomic_alloc_bw() to prepare for moving the
>   BW allocation from encoder hooks up to intel_atomic_commit_tail()
>   later in the patchset.
> - Disable BW alloc mode during system suspend.
> - Allocate the required BW for all tunnels during system resume.
> - Add intel_dp_tunnel_atomic_clear_stream_bw() instead of the open-coded
>   sequence in a follow-up patch.
> - Add function documentation to all exported functions.
> - Add CONFIG_USB4 dependency to CONFIG_DRM_I915_DP_TUNNEL.

Changes look good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/Kconfig                  |  14 +
>  drivers/gpu/drm/i915/Kconfig.debug            |   1 +
>  drivers/gpu/drm/i915/Makefile                 |   3 +
>  drivers/gpu/drm/i915/display/intel_atomic.c   |   2 +
>  drivers/gpu/drm/i915/display/intel_crtc.c     |  25 +
>  drivers/gpu/drm/i915/display/intel_crtc.h     |   1 +
>  .../gpu/drm/i915/display/intel_display_core.h |   1 +
>  .../drm/i915/display/intel_display_types.h    |   9 +
>  .../gpu/drm/i915/display/intel_dp_tunnel.c    | 815 ++++++++++++++++++
>  .../gpu/drm/i915/display/intel_dp_tunnel.h    | 133 +++
>  10 files changed, 1004 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index
> 3089029abba48..5932024f8f954 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -155,6 +155,20 @@ config DRM_I915_PXP
>  	  protected session and manage the status of the alive software session,
>  	  as well as its life cycle.
> 
> +config DRM_I915_DP_TUNNEL
> +	bool "Enable DP tunnel support"
> +	depends on DRM_I915
> +	depends on USB4
> +	select DRM_DISPLAY_DP_TUNNEL
> +	default y
> +	help
> +	  Choose this option to detect DP tunnels and enable the Bandwidth
> +	  Allocation mode for such tunnels. This allows using the maximum
> +	  resolution allowed by the link BW on all displays sharing the
> +	  link BW, for instance on a Thunderbolt link.
> +
> +	  If in doubt, say "Y".
> +
>  menu "drm/i915 Debugging"
>  depends on DRM_I915
>  depends on EXPERT
> diff --git a/drivers/gpu/drm/i915/Kconfig.debug
> b/drivers/gpu/drm/i915/Kconfig.debug
> index 5b7162076850c..bc18e2d9ea05d 100644
> --- a/drivers/gpu/drm/i915/Kconfig.debug
> +++ b/drivers/gpu/drm/i915/Kconfig.debug
> @@ -28,6 +28,7 @@ config DRM_I915_DEBUG
>  	select STACKDEPOT
>  	select STACKTRACE
>  	select DRM_DP_AUX_CHARDEV
> +	select DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE if
> DRM_I915_DP_TUNNEL
>  	select X86_MSR # used by igt/pm_rpm
>  	select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
>  	select DRM_DEBUG_MM if DRM=y
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index c13f14edb5088..3ef6ed41e62b4 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -369,6 +369,9 @@ i915-y += \
>  	display/vlv_dsi.o \
>  	display/vlv_dsi_pll.o
> 
> +i915-$(CONFIG_DRM_I915_DP_TUNNEL) += \
> +	display/intel_dp_tunnel.o
> +
>  i915-y += \
>  	i915_perf.o
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c
> b/drivers/gpu/drm/i915/display/intel_atomic.c
> index ec0d5168b5035..96ab37e158995 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -29,6 +29,7 @@
>   * See intel_atomic_plane.c for the plane-specific atomic functionality.
>   */
> 
> +#include <drm/display/drm_dp_tunnel.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_fourcc.h>
> @@ -38,6 +39,7 @@
>  #include "intel_atomic.h"
>  #include "intel_cdclk.h"
>  #include "intel_display_types.h"
> +#include "intel_dp_tunnel.h"
>  #include "intel_global_state.h"
>  #include "intel_hdcp.h"
>  #include "intel_psr.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c
> b/drivers/gpu/drm/i915/display/intel_crtc.c
> index 17ed2e62cc66a..8224400b5b72c 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -681,3 +681,28 @@ u32 intel_crtc_try_sync_pipes(struct drm_i915_private
> *i915, u32 pipe_mask)
> 
>  	return synced;
>  }
> +
> +/**
> + * intel_crtc_sync_pipes - Sync pending commits on a set of pipes
> + * @i915: i915 device object
> + * @pipe_mask: Mask of pipes to sync
> + *
> + * Sync a pending non-blocking commit for the provided pipes in
> + * @pipe_mask.
> + */
> +void intel_crtc_sync_pipes(struct drm_i915_private *i915, u32
> +pipe_mask) {
> +	struct intel_crtc *crtc;
> +
> +	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
> +		const struct intel_crtc_state *crtc_state =
> +			to_intel_crtc_state(crtc->base.state);
> +		bool synced = true;
> +
> +		if (crtc_state->uapi.commit)
> +			synced = wait_for_completion_timeout(&crtc_state-
> >uapi.commit->hw_done,
> +
> msecs_to_jiffies(5000));
> +
> +		drm_WARN_ON(&i915->drm, !synced);
> +	}
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h
> b/drivers/gpu/drm/i915/display/intel_crtc.h
> index 71a5b93166da7..ffee73b8df74e 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.h
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.h
> @@ -48,5 +48,6 @@ void intel_wait_for_vblank_if_active(struct
> drm_i915_private *i915,
>  				     enum pipe pipe);
>  void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
>  u32 intel_crtc_try_sync_pipes(struct drm_i915_private *i915, u32 pipe_mask);
> +void intel_crtc_sync_pipes(struct drm_i915_private *i915, u32
> +pipe_mask);
> 
>  #endif
> diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h
> b/drivers/gpu/drm/i915/display/intel_display_core.h
> index fdeaac994e17b..2167dbee5eea7 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> @@ -524,6 +524,7 @@ struct intel_display {
>  	} wq;
> 
>  	/* Grouping using named structs. Keep sorted. */
> +	struct drm_dp_tunnel_mgr *dp_tunnel_mgr;
>  	struct intel_audio audio;
>  	struct intel_dpll dpll;
>  	struct intel_fbc *fbc[I915_MAX_FBCS];
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 578763e202c01..601e7f88e6c61 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -33,6 +33,7 @@
> 
>  #include <drm/display/drm_dp_dual_mode_helper.h>
>  #include <drm/display/drm_dp_mst_helper.h>
> +#include <drm/display/drm_dp_tunnel.h>
>  #include <drm/display/drm_dsc.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_crtc.h>
> @@ -678,6 +679,8 @@ struct intel_atomic_state {
> 
>  	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
> 
> +	struct intel_dp_tunnel_inherited_state *inherited_dp_tunnels;
> +
>  	/*
>  	 * Current watermarks can't be trusted during hardware readout, so
>  	 * don't bother calculating intermediate watermarks.
> @@ -1375,6 +1378,9 @@ struct intel_crtc_state {
>  		struct drm_dsc_config config;
>  	} dsc;
> 
> +	/* DP tunnel used for BW allocation. */
> +	struct drm_dp_tunnel_ref dp_tunnel_ref;
> +
>  	/* HSW+ linetime watermarks */
>  	u16 linetime;
>  	u16 ips_linetime;
> @@ -1785,6 +1791,9 @@ struct intel_dp {
>  	/* connector directly attached - won't be use for modeset in mst world */
>  	struct intel_connector *attached_connector;
> 
> +	struct drm_dp_tunnel *tunnel;
> +	bool tunnel_suspended:1;
> +
>  	/* mst connector list */
>  	struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
>  	struct drm_dp_mst_topology_mgr mst_mgr; diff --git
> a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
> b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
> new file mode 100644
> index 0000000000000..fd639ded853ae
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
> @@ -0,0 +1,815 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#include "i915_drv.h"
> +
> +#include <drm/display/drm_dp_tunnel.h>
> +
> +#include "intel_atomic.h"
> +#include "intel_crtc.h"
> +#include "intel_display_limits.h"
> +#include "intel_display_types.h"
> +#include "intel_dp.h"
> +#include "intel_dp_link_training.h"
> +#include "intel_dp_mst.h"
> +#include "intel_dp_tunnel.h"
> +#include "intel_link_bw.h"
> +
> +struct intel_dp_tunnel_inherited_state {
> +	struct drm_dp_tunnel_ref ref[I915_MAX_PIPES]; };
> +
> +/**
> + * intel_dp_tunnel_disconnect - Disconnect a DP tunnel from a port
> + * @intel_dp: DP port object the tunnel is connected to
> + *
> + * Disconnect a DP tunnel from @intel_dp, destroying any related state.
> +This
> + * should be called after detecting a sink-disconnect event from the port.
> + */
> +void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp) {
> +	drm_dp_tunnel_destroy(intel_dp->tunnel);
> +	intel_dp->tunnel = NULL;
> +}
> +
> +/**
> + * intel_dp_tunnel_destroy - Destroy a DP tunnel
> + * @intel_dp: DP port object the tunnel is connected to
> + *
> + * Destroy a DP tunnel connected to @intel_dp, after disabling the BW
> + * allocation mode on the tunnel. This should be called while
> +destroying the
> + * port.
> + */
> +void intel_dp_tunnel_destroy(struct intel_dp *intel_dp) {
> +	if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
> +		drm_dp_tunnel_disable_bw_alloc(intel_dp->tunnel);
> +
> +	intel_dp_tunnel_disconnect(intel_dp);
> +}
> +
> +static int kbytes_to_mbits(int kbytes)
> +{
> +	return DIV_ROUND_UP(kbytes * 8, 1000); }
> +
> +static int get_current_link_bw(struct intel_dp *intel_dp,
> +			       bool *below_dprx_bw)
> +{
> +	int rate = intel_dp_max_common_rate(intel_dp);
> +	int lane_count = intel_dp_max_common_lane_count(intel_dp);
> +	int bw;
> +
> +	bw = intel_dp_max_link_data_rate(intel_dp, rate, lane_count);
> +	*below_dprx_bw = bw < drm_dp_max_dprx_data_rate(rate, lane_count);
> +
> +	return bw;
> +}
> +
> +static int update_tunnel_state(struct intel_dp *intel_dp) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	bool old_bw_below_dprx;
> +	bool new_bw_below_dprx;
> +	int old_bw;
> +	int new_bw;
> +	int ret;
> +
> +	old_bw = get_current_link_bw(intel_dp, &old_bw_below_dprx);
> +
> +	ret = drm_dp_tunnel_update_state(intel_dp->tunnel);
> +	if (ret < 0) {
> +		drm_dbg_kms(&i915->drm,
> +			    "[DPTUN %s][ENCODER:%d:%s] State update failed
> (err %pe)\n",
> +			    drm_dp_tunnel_name(intel_dp->tunnel),
> +			    encoder->base.base.id, encoder->base.name,
> +			    ERR_PTR(ret));
> +
> +		return ret;
> +	}
> +
> +	if (ret == 0 ||
> +	    !drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel))
> +		return 0;
> +
> +	intel_dp_update_sink_caps(intel_dp);
> +
> +	new_bw = get_current_link_bw(intel_dp, &new_bw_below_dprx);
> +
> +	/* Suppress the notification if the mode list can't change due to bw. */
> +	if (old_bw_below_dprx == new_bw_below_dprx &&
> +	    !new_bw_below_dprx)
> +		return 0;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN %s][ENCODER:%d:%s] Notify users about BW
> change: %d -> %d\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    encoder->base.base.id, encoder->base.name,
> +		    kbytes_to_mbits(old_bw), kbytes_to_mbits(new_bw));
> +
> +	return 1;
> +}
> +
> +/*
> + * Allocate the BW for a tunnel on a DP connector/port if the
> +connector/port
> + * was already active when detecting the tunnel. The allocated BW must
> +be
> + * freed by the next atomic modeset, storing the BW in the
> + * intel_atomic_state::inherited_dp_tunnels, and calling
> + * intel_dp_tunnel_atomic_free_bw().
> + */
> +static int allocate_initial_tunnel_bw_for_pipes(struct intel_dp
> +*intel_dp, u8 pipe_mask) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	struct intel_crtc *crtc;
> +	int tunnel_bw = 0;
> +	int err;
> +
> +	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
> +		const struct intel_crtc_state *crtc_state =
> +			to_intel_crtc_state(crtc->base.state);
> +		int stream_bw = intel_dp_config_required_rate(crtc_state);
> +
> +		tunnel_bw += stream_bw;
> +
> +		drm_dbg_kms(&i915->drm,
> +			    "[DPTUN %s][ENCODER:%d:%s][CRTC:%d:%s] Initial
> BW for stream %d: %d/%d Mb/s\n",
> +			    drm_dp_tunnel_name(intel_dp->tunnel),
> +			    encoder->base.base.id, encoder->base.name,
> +			    crtc->base.base.id, crtc->base.name,
> +			    crtc->pipe,
> +			    kbytes_to_mbits(stream_bw),
> kbytes_to_mbits(tunnel_bw));
> +	}
> +
> +	err = drm_dp_tunnel_alloc_bw(intel_dp->tunnel, tunnel_bw);
> +	if (err) {
> +		drm_dbg_kms(&i915->drm,
> +			    "[DPTUN %s][ENCODER:%d:%s] Initial BW allocation
> failed (err %pe)\n",
> +			    drm_dp_tunnel_name(intel_dp->tunnel),
> +			    encoder->base.base.id, encoder->base.name,
> +			    ERR_PTR(err));
> +
> +		return err;
> +	}
> +
> +	return update_tunnel_state(intel_dp);
> +}
> +
> +static int allocate_initial_tunnel_bw(struct intel_dp *intel_dp,
> +				      struct drm_modeset_acquire_ctx *ctx) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	u8 pipe_mask;
> +	int err;
> +
> +	err = intel_dp_get_active_pipes(intel_dp, ctx, &pipe_mask);
> +	if (err)
> +		return err;
> +
> +	intel_crtc_sync_pipes(i915, pipe_mask);
> +
> +	return allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask); }
> +
> +static int detect_new_tunnel(struct intel_dp *intel_dp, struct
> +drm_modeset_acquire_ctx *ctx) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	struct drm_dp_tunnel *tunnel;
> +	int ret;
> +
> +	tunnel = drm_dp_tunnel_detect(i915->display.dp_tunnel_mgr,
> +					&intel_dp->aux);
> +	if (IS_ERR(tunnel))
> +		return PTR_ERR(tunnel);
> +
> +	intel_dp->tunnel = tunnel;
> +
> +	ret = drm_dp_tunnel_enable_bw_alloc(intel_dp->tunnel);
> +	if (ret) {
> +		if (ret == -EOPNOTSUPP)
> +			return 0;
> +
> +		drm_dbg_kms(&i915->drm,
> +			    "[DPTUN %s][ENCODER:%d:%s] Failed to enable BW
> allocation mode (ret %pe)\n",
> +			    drm_dp_tunnel_name(intel_dp->tunnel),
> +			    encoder->base.base.id, encoder->base.name,
> +			    ERR_PTR(ret));
> +
> +		/* Keep the tunnel with BWA disabled */
> +		return 0;
> +	}
> +
> +	ret = allocate_initial_tunnel_bw(intel_dp, ctx);
> +	if (ret < 0)
> +		intel_dp_tunnel_destroy(intel_dp);
> +
> +	return ret;
> +}
> +
> +/**
> + * intel_dp_tunnel_detect - Detect a DP tunnel on a port
> + * @intel_dp: DP port object
> + * @ctx: lock context acquired by the connector detection handler
> + *
> + * Detect a DP tunnel on the @intel_dp port, enabling the BW allocation
> +mode
> + * on it if supported and allocating the BW required on an already active port.
> + * The BW allocated this way must be freed by the next atomic modeset
> +calling
> + * intel_dp_tunnel_atomic_free_bw().
> + *
> + * If @intel_dp has already a tunnel detected on it, update the
> +tunnel's state
> + * wrt. its support for BW allocation mode and the available BW via the
> + * tunnel. If the tunnel's state change requires this - for instance
> +the
> + * tunnel's group ID has changed - the tunnel will be dropped and recreated.
> + *
> + * Return 0 in case of success - after any tunnel detected and added to
> + * @intel_dp - 1 in case the BW on an already existing tunnel has
> +changed in a
> + * way that requires notifying user space.
> + */
> +int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct
> +drm_modeset_acquire_ctx *ctx) {
> +	int ret;
> +
> +	if (intel_dp_is_edp(intel_dp))
> +		return 0;
> +
> +	if (intel_dp->tunnel) {
> +		ret = update_tunnel_state(intel_dp);
> +		if (ret >= 0)
> +			return ret;
> +
> +		/* Try to recreate the tunnel after an update error. */
> +		intel_dp_tunnel_destroy(intel_dp);
> +	}
> +
> +	return detect_new_tunnel(intel_dp, ctx); }
> +
> +/**
> + * intel_dp_tunnel_bw_alloc_is_enabled - Query the BW allocation
> +support on a tunnel
> + * @intel_dp: DP port object
> + *
> + * Query whether a DP tunnel is connected on @intel_dp and the tunnel
> +supports
> + * the BW allocation mode.
> + *
> + * Returns %true if the BW allocation mode is supported on @intel_dp.
> + */
> +bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp) {
> +	return drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel);
> +}
> +
> +/**
> + * intel_dp_tunnel_suspend - Suspend a DP tunnel connected on a port
> + * @intel_dp: DP port object
> + *
> + * Suspend a DP tunnel on @intel_dp with BW allocation mode enabled on it.
> + */
> +void intel_dp_tunnel_suspend(struct intel_dp *intel_dp) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +
> +	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
> +		return;
> +
> +	drm_dbg_kms(&i915->drm, "[DPTUN
> %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Suspend\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    connector->base.base.id, connector->base.name,
> +		    encoder->base.base.id, encoder->base.name);
> +
> +	drm_dp_tunnel_disable_bw_alloc(intel_dp->tunnel);
> +
> +	intel_dp->tunnel_suspended = true;
> +}
> +
> +/**
> + * intel_dp_tunnel_resume - Resume a DP tunnel connected on a port
> + * @intel_dp: DP port object
> + * @crtc_state: CRTC state
> + * @dpcd_updated: the DPCD DPRX capabilities got updated during resume
> + *
> + * Resume a DP tunnel on @intel_dp with BW allocation mode enabled on it.
> + */
> +void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
> +			    const struct intel_crtc_state *crtc_state,
> +			    bool dpcd_updated)
> +{
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	u8 dpcd[DP_RECEIVER_CAP_SIZE];
> +	u8 pipe_mask;
> +	int err = 0;
> +
> +	if (!intel_dp->tunnel_suspended)
> +		return;
> +
> +	intel_dp->tunnel_suspended = false;
> +
> +	drm_dbg_kms(&i915->drm, "[DPTUN
> %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Resume\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    connector->base.base.id, connector->base.name,
> +		    encoder->base.base.id, encoder->base.name);
> +
> +	/*
> +	 * The TBT Connection Manager requires the GFX driver to read out
> +	 * the sink's DPRX caps to be able to service any BW requests later.
> +	 * During resume overriding the caps in @intel_dp cached before
> +	 * suspend must be avoided, so do here only a dummy read, unless the
> +	 * capabilities were updated already during resume.
> +	 */
> +	if (!dpcd_updated) {
> +		err = intel_dp_read_dprx_caps(intel_dp, dpcd);
> +
> +		if (err) {
> +			drm_dp_tunnel_set_io_error(intel_dp->tunnel);
> +			goto out_err;
> +		}
> +	}
> +
> +	err = drm_dp_tunnel_enable_bw_alloc(intel_dp->tunnel);
> +	if (err)
> +		goto out_err;
> +
> +	pipe_mask = 0;
> +	if (crtc_state) {
> +		struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> +		/* TODO: Add support for MST */
> +		pipe_mask |= BIT(crtc->pipe);
> +	}
> +
> +	err = allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask);
> +	if (err)
> +		goto out_err;
> +
> +	return;
> +
> +out_err:
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Tunnel
> can't be resumed, will drop and redect it (err %pe)\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    connector->base.base.id, connector->base.name,
> +		    encoder->base.base.id, encoder->base.name,
> +		    ERR_PTR(err));
> +}
> +
> +static struct drm_dp_tunnel *
> +get_inherited_tunnel(struct intel_atomic_state *state, struct
> +intel_crtc *crtc) {
> +	if (!state->inherited_dp_tunnels)
> +		return NULL;
> +
> +	return state->inherited_dp_tunnels->ref[crtc->pipe].tunnel;
> +}
> +
> +static int
> +add_inherited_tunnel(struct intel_atomic_state *state,
> +		     struct drm_dp_tunnel *tunnel,
> +		     struct intel_crtc *crtc)
> +{
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> +	struct drm_dp_tunnel *old_tunnel;
> +
> +	old_tunnel = get_inherited_tunnel(state, crtc);
> +	if (old_tunnel) {
> +		drm_WARN_ON(&i915->drm, old_tunnel != tunnel);
> +		return 0;
> +	}
> +
> +	if (!state->inherited_dp_tunnels) {
> +		state->inherited_dp_tunnels = kzalloc(sizeof(*state-
> >inherited_dp_tunnels),
> +						      GFP_KERNEL);
> +		if (!state->inherited_dp_tunnels)
> +			return -ENOMEM;
> +	}
> +
> +	drm_dp_tunnel_ref_get(tunnel,
> +&state->inherited_dp_tunnels->ref[crtc->pipe]);
> +
> +	return 0;
> +}
> +
> +static int check_inherited_tunnel_state(struct intel_atomic_state *state,
> +					struct intel_dp *intel_dp,
> +					const struct
> intel_digital_connector_state *old_conn_state) {
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	struct intel_connector *connector =
> +		to_intel_connector(old_conn_state->base.connector);
> +	struct intel_crtc *old_crtc;
> +	const struct intel_crtc_state *old_crtc_state;
> +
> +	/*
> +	 * If a BWA tunnel gets detected only after the corresponding
> +	 * connector got enabled already without a BWA tunnel, or a different
> +	 * BWA tunnel (which was removed meanwhile) the old CRTC state won't
> +	 * contain the state of the current tunnel. This tunnel still has a
> +	 * reserved BW, which needs to be released, add the state for such
> +	 * inherited tunnels separately only to this atomic state.
> +	 */
> +	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
> +		return 0;
> +
> +	if (!old_conn_state->base.crtc)
> +		return 0;
> +
> +	old_crtc = to_intel_crtc(old_conn_state->base.crtc);
> +	old_crtc_state = intel_atomic_get_old_crtc_state(state, old_crtc);
> +
> +	if (!old_crtc_state->hw.active ||
> +	    old_crtc_state->dp_tunnel_ref.tunnel == intel_dp->tunnel)
> +		return 0;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN
> %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Adding state for
> inherited tunnel %p\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    connector->base.base.id, connector->base.name,
> +		    encoder->base.base.id, encoder->base.name,
> +		    old_crtc->base.base.id, old_crtc->base.name,
> +		    intel_dp->tunnel);
> +
> +	return add_inherited_tunnel(state, intel_dp->tunnel, old_crtc); }
> +
> +/**
> + * intel_dp_tunnel_atomic_cleanup_inherited_state - Free any inherited
> +DP tunnel state
> + * @state: Atomic state
> + *
> + * Free the inherited DP tunnel state in @state.
> + */
> +void intel_dp_tunnel_atomic_cleanup_inherited_state(struct
> +intel_atomic_state *state) {
> +	enum pipe pipe;
> +
> +	if (!state->inherited_dp_tunnels)
> +		return;
> +
> +	for_each_pipe(to_i915(state->base.dev), pipe)
> +		if (state->inherited_dp_tunnels->ref[pipe].tunnel)
> +			drm_dp_tunnel_ref_put(&state->inherited_dp_tunnels-
> >ref[pipe]);
> +
> +	kfree(state->inherited_dp_tunnels);
> +	state->inherited_dp_tunnels = NULL;
> +}
> +
> +static int intel_dp_tunnel_atomic_add_group_state(struct intel_atomic_state
> *state,
> +						  struct drm_dp_tunnel
> *tunnel)
> +{
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> +	u32 pipe_mask;
> +	int err;
> +
> +	err = drm_dp_tunnel_atomic_get_group_streams_in_state(&state-
> >base,
> +							      tunnel,
> &pipe_mask);
> +	if (err)
> +		return err;
> +
> +	drm_WARN_ON(&i915->drm, pipe_mask & ~((1 << I915_MAX_PIPES) -
> 1));
> +
> +	return intel_modeset_pipes_in_mask_early(state, "DPTUN", pipe_mask);
> }
> +
> +/**
> + * intel_dp_tunnel_atomic_add_state_for_crtc - Add CRTC specific DP
> +tunnel state
> + * @state: Atomic state
> + * @crtc: CRTC to add the tunnel state for
> + *
> + * Add the DP tunnel state for @crtc if the CRTC (aka DP tunnel stream)
> +is enabled
> + * via a DP tunnel.
> + *
> + * Return 0 in case of success, a negative error code otherwise.
> + */
> +int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state
> *state,
> +					      struct intel_crtc *crtc)
> +{
> +	const struct intel_crtc_state *new_crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	const struct drm_dp_tunnel_state *tunnel_state;
> +	struct drm_dp_tunnel *tunnel = new_crtc_state->dp_tunnel_ref.tunnel;
> +
> +	if (!tunnel)
> +		return 0;
> +
> +	tunnel_state = drm_dp_tunnel_atomic_get_state(&state->base, tunnel);
> +	if (IS_ERR(tunnel_state))
> +		return PTR_ERR(tunnel_state);
> +
> +	return 0;
> +}
> +
> +static int check_group_state(struct intel_atomic_state *state,
> +			     struct intel_dp *intel_dp,
> +			     struct intel_connector *connector,
> +			     struct intel_crtc *crtc)
> +{
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	const struct intel_crtc_state *crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +
> +	if (!crtc_state->dp_tunnel_ref.tunnel)
> +		return 0;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN
> %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Adding group state for
> tunnel %p\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    connector->base.base.id, connector->base.name,
> +		    encoder->base.base.id, encoder->base.name,
> +		    crtc->base.base.id, crtc->base.name,
> +		    crtc_state->dp_tunnel_ref.tunnel);
> +
> +	return intel_dp_tunnel_atomic_add_group_state(state,
> +crtc_state->dp_tunnel_ref.tunnel);
> +}
> +
> +/**
> + * intel_dp_tunnel_atomic_check_state - Check a connector's DP tunnel
> +specific state
> + * @state: Atomic state
> + * @intel_dp: DP port object
> + * @connector: connector using @intel_dp
> + *
> + * Check and add the DP tunnel atomic state for @intel_dp/@connector to
> + * @state, if there is a DP tunnel detected on @intel_dp with BW
> +allocation
> + * mode enabled on it, or if @intel_dp/@connector was previously
> +enabled via a
> + * DP tunnel.
> + *
> + * Returns 0 in case of success, or a negative error code otherwise.
> + */
> +int intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
> +				       struct intel_dp *intel_dp,
> +				       struct intel_connector *connector) {
> +	const struct intel_digital_connector_state *old_conn_state =
> +		intel_atomic_get_old_connector_state(state, connector);
> +	const struct intel_digital_connector_state *new_conn_state =
> +		intel_atomic_get_new_connector_state(state, connector);
> +	int err;
> +
> +	if (old_conn_state->base.crtc) {
> +		err = check_group_state(state, intel_dp, connector,
> +					to_intel_crtc(old_conn_state-
> >base.crtc));
> +		if (err)
> +			return err;
> +	}
> +
> +	if (new_conn_state->base.crtc &&
> +	    new_conn_state->base.crtc != old_conn_state->base.crtc) {
> +		err = check_group_state(state, intel_dp, connector,
> +					to_intel_crtc(new_conn_state-
> >base.crtc));
> +		if (err)
> +			return err;
> +	}
> +
> +	return check_inherited_tunnel_state(state, intel_dp, old_conn_state);
> +}
> +
> +/**
> + * intel_dp_tunnel_atomic_compute_stream_bw - Compute the BW required
> +by a DP tunnel stream
> + * @state: Atomic state
> + * @intel_dp: DP object
> + * @connector: connector using @intel_dp
> + * @crtc_state: state of CRTC of the given DP tunnel stream
> + *
> + * Compute the required BW of CRTC (aka DP tunnel stream), storing this
> +BW to
> + * the DP tunnel state containing the stream in @state. Before
> +re-calculating a
> + * BW requirement in the crtc_state state the old BW requirement
> +computed by this
> + * function must be cleared by calling
> intel_dp_tunnel_atomic_clear_stream_bw().
> + *
> + * Returns 0 in case of success, a negative error code otherwise.
> + */
> +int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state
> *state,
> +					     struct intel_dp *intel_dp,
> +					     const struct intel_connector
> *connector,
> +					     struct intel_crtc_state *crtc_state) {
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	int required_rate = intel_dp_config_required_rate(crtc_state);
> +	int ret;
> +
> +	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
> +		return 0;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN
> %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Stream %d required
> BW %d Mb/s\n",
> +		    drm_dp_tunnel_name(intel_dp->tunnel),
> +		    connector->base.base.id, connector->base.name,
> +		    encoder->base.base.id, encoder->base.name,
> +		    crtc->base.base.id, crtc->base.name,
> +		    crtc->pipe,
> +		    kbytes_to_mbits(required_rate));
> +
> +	ret = drm_dp_tunnel_atomic_set_stream_bw(&state->base, intel_dp-
> >tunnel,
> +						 crtc->pipe, required_rate);
> +	if (ret < 0)
> +		return ret;
> +
> +	drm_dp_tunnel_ref_get(intel_dp->tunnel,
> +			      &crtc_state->dp_tunnel_ref);
> +
> +	return 0;
> +}
> +
> +/**
> + * intel_dp_tunnel_atomic_clear_stream_bw - Clear any DP tunnel stream
> +BW requirement
> + * @state: Atomic state
> + * @crtc_state: state of CRTC of the given DP tunnel stream
> + *
> + * Clear any DP tunnel stream BW requirement set by
> + * intel_dp_tunnel_atomic_compute_stream_bw().
> + */
> +void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state
> *state,
> +					    struct intel_crtc_state *crtc_state) {
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> +	if (!crtc_state->dp_tunnel_ref.tunnel)
> +		return;
> +
> +	drm_dp_tunnel_atomic_set_stream_bw(&state->base,
> +					   crtc_state->dp_tunnel_ref.tunnel,
> +					   crtc->pipe, 0);
> +	drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref);
> +}
> +
> +/**
> + * intel_dp_tunnel_atomic_check_link - Check the DP tunnel atomic state
> + * @state: intel atomic state
> + * @limits: link BW limits
> + *
> + * Check the link configuration for all DP tunnels in @state. If the
> + * configuration is invalid @limits will be updated if possible to
> + * reduce the total BW, after which the configuration for all CRTCs in
> + * @state must be recomputed with the updated @limits.
> + *
> + * Returns:
> + *   - 0 if the confugration is valid
> + *   - %-EAGAIN, if the configuration is invalid and @limits got updated
> + *     with fallback values with which the configuration of all CRTCs in
> + *     @state must be recomputed
> + *   - Other negative error, if the configuration is invalid without a
> + *     fallback possibility, or the check failed for another reason
> + */
> +int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
> +				      struct intel_link_bw_limits *limits) {
> +	u32 failed_stream_mask;
> +	int err;
> +
> +	err = drm_dp_tunnel_atomic_check_stream_bws(&state->base,
> +						    &failed_stream_mask);
> +	if (err != -ENOSPC)
> +		return err;
> +
> +	err = intel_link_bw_reduce_bpp(state, limits,
> +				       failed_stream_mask, "DP tunnel link BW");
> +
> +	return err ? : -EAGAIN;
> +}
> +
> +static void atomic_decrease_bw(struct intel_atomic_state *state) {
> +	struct intel_crtc *crtc;
> +	const struct intel_crtc_state *old_crtc_state;
> +	const struct intel_crtc_state *new_crtc_state;
> +	int i;
> +
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> new_crtc_state, i) {
> +		const struct drm_dp_tunnel_state *new_tunnel_state;
> +		struct drm_dp_tunnel *tunnel;
> +		int old_bw;
> +		int new_bw;
> +
> +		if (!intel_crtc_needs_modeset(new_crtc_state))
> +			continue;
> +
> +		tunnel = get_inherited_tunnel(state, crtc);
> +		if (!tunnel)
> +			tunnel = old_crtc_state->dp_tunnel_ref.tunnel;
> +
> +		if (!tunnel)
> +			continue;
> +
> +		old_bw = drm_dp_tunnel_get_allocated_bw(tunnel);
> +
> +		new_tunnel_state =
> drm_dp_tunnel_atomic_get_new_state(&state->base, tunnel);
> +		new_bw =
> drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
> +
> +		if (new_bw >= old_bw)
> +			continue;
> +
> +		drm_dp_tunnel_alloc_bw(tunnel, new_bw);
> +	}
> +}
> +
> +static void queue_retry_work(struct intel_atomic_state *state,
> +			     struct drm_dp_tunnel *tunnel,
> +			     const struct intel_crtc_state *crtc_state) {
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> +	struct intel_encoder *encoder;
> +
> +	encoder = intel_get_crtc_new_encoder(state, crtc_state);
> +
> +	if (!intel_digital_port_connected(encoder))
> +		return;
> +
> +	drm_dbg_kms(&i915->drm,
> +		    "[DPTUN %s][ENCODER:%d:%s] BW allocation failed on a
> connected sink\n",
> +		    drm_dp_tunnel_name(tunnel),
> +		    encoder->base.base.id,
> +		    encoder->base.name);
> +
> +	intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state); }
> +
> +static void atomic_increase_bw(struct intel_atomic_state *state) {
> +	struct intel_crtc *crtc;
> +	const struct intel_crtc_state *crtc_state;
> +	int i;
> +
> +	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> +		struct drm_dp_tunnel_state *tunnel_state;
> +		struct drm_dp_tunnel *tunnel = crtc_state-
> >dp_tunnel_ref.tunnel;
> +		int bw;
> +
> +		if (!intel_crtc_needs_modeset(crtc_state))
> +			continue;
> +
> +		if (!tunnel)
> +			continue;
> +
> +		tunnel_state = drm_dp_tunnel_atomic_get_new_state(&state-
> >base,
> +tunnel);
> +
> +		bw = drm_dp_tunnel_atomic_get_required_bw(tunnel_state);
> +
> +		if (drm_dp_tunnel_alloc_bw(tunnel, bw) != 0)
> +			queue_retry_work(state, tunnel, crtc_state);
> +	}
> +}
> +
> +/**
> + * intel_dp_tunnel_atomic_alloc_bw - Allocate the BW for all modeset
> +tunnels
> + * @state: Atomic state
> + *
> + * Allocate the required BW for all tunnels in @state.
> + */
> +void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state)
> +{
> +	atomic_decrease_bw(state);
> +	atomic_increase_bw(state);
> +}
> +
> +/**
> + * intel_dp_tunnel_mgr_init - Initialize the DP tunnel manager
> + * @i915: i915 device object
> + *
> + * Initialize the DP tunnel manager. The tunnel manager will support
> +the
> + * detection/management of DP tunnels on all DP connectors, so the
> +function
> + * must be called after all these connectors have been registered already.
> + *
> + * Return 0 in case of success, a negative error code otherwise.
> + */
> +int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915) {
> +	struct drm_dp_tunnel_mgr *tunnel_mgr;
> +	struct drm_connector_list_iter connector_list_iter;
> +	struct intel_connector *connector;
> +	int dp_connectors = 0;
> +
> +	drm_connector_list_iter_begin(&i915->drm, &connector_list_iter);
> +	for_each_intel_connector_iter(connector, &connector_list_iter) {
> +		if (connector->base.connector_type !=
> DRM_MODE_CONNECTOR_DisplayPort)
> +			continue;
> +
> +		dp_connectors++;
> +	}
> +	drm_connector_list_iter_end(&connector_list_iter);
> +
> +	tunnel_mgr = drm_dp_tunnel_mgr_create(&i915->drm, dp_connectors);
> +	if (IS_ERR(tunnel_mgr))
> +		return PTR_ERR(tunnel_mgr);
> +
> +	i915->display.dp_tunnel_mgr = tunnel_mgr;
> +
> +	return 0;
> +}
> +
> +/**
> + * intel_dp_tunnel_mgr_cleanup - Clean up the DP tunnel manager state
> + * @i915: i915 device object
> + *
> + * Clean up the DP tunnel manager state.
> + */
> +void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915) {
> +	drm_dp_tunnel_mgr_destroy(i915->display.dp_tunnel_mgr);
> +	i915->display.dp_tunnel_mgr = NULL;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
> b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
> new file mode 100644
> index 0000000000000..08b2cba84af2b
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
> @@ -0,0 +1,133 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#ifndef __INTEL_DP_TUNNEL_H__
> +#define __INTEL_DP_TUNNEL_H__
> +
> +#include <linux/errno.h>
> +#include <linux/types.h>
> +
> +struct drm_i915_private;
> +struct drm_connector_state;
> +struct drm_modeset_acquire_ctx;
> +
> +struct intel_atomic_state;
> +struct intel_connector;
> +struct intel_crtc;
> +struct intel_crtc_state;
> +struct intel_dp;
> +struct intel_encoder;
> +struct intel_link_bw_limits;
> +
> +#if defined(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
> +
> +int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct
> +drm_modeset_acquire_ctx *ctx); void intel_dp_tunnel_disconnect(struct
> +intel_dp *intel_dp); void intel_dp_tunnel_destroy(struct intel_dp
> +*intel_dp); void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
> +			    const struct intel_crtc_state *crtc_state,
> +			    bool dpcd_updated);
> +void intel_dp_tunnel_suspend(struct intel_dp *intel_dp);
> +
> +bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp);
> +
> +void
> +intel_dp_tunnel_atomic_cleanup_inherited_state(struct
> +intel_atomic_state *state);
> +
> +int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state
> *state,
> +					     struct intel_dp *intel_dp,
> +					     const struct intel_connector
> *connector,
> +					     struct intel_crtc_state *crtc_state);
> void
> +intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
> +					    struct intel_crtc_state *crtc_state);
> +
> +int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state
> *state,
> +					      struct intel_crtc *crtc);
> +int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
> +				      struct intel_link_bw_limits *limits); int
> +intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
> +				       struct intel_dp *intel_dp,
> +				       struct intel_connector *connector);
> +
> +void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state);
> +
> +int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915); void
> +intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915);
> +
> +#else
> +
> +static inline int
> +intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct
> +drm_modeset_acquire_ctx *ctx) {
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline void intel_dp_tunnel_disconnect(struct intel_dp
> +*intel_dp) {} static inline void intel_dp_tunnel_destroy(struct
> +intel_dp *intel_dp) {} static inline void intel_dp_tunnel_resume(struct intel_dp
> *intel_dp,
> +					  const struct intel_crtc_state
> *crtc_state,
> +					  bool dpcd_updated) {}
> +static inline void intel_dp_tunnel_suspend(struct intel_dp *intel_dp)
> +{}
> +
> +static inline bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp
> +*intel_dp) {
> +	return false;
> +}
> +
> +static inline void
> +intel_dp_tunnel_atomic_cleanup_inherited_state(struct
> +intel_atomic_state *state) {}
> +
> +static inline int
> +intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
> +					 struct intel_dp *intel_dp,
> +					 const struct intel_connector
> *connector,
> +					 struct intel_crtc_state *crtc_state) {
> +	return 0;
> +}
> +
> +static inline void
> +intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
> +				       struct intel_crtc_state *crtc_state) {}
> +
> +static inline int
> +intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
> +					  struct intel_crtc *crtc)
> +{
> +	return 0;
> +}
> +
> +static inline int
> +intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
> +				  struct intel_link_bw_limits *limits) {
> +	return 0;
> +}
> +
> +static inline int
> +intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
> +				   struct intel_dp *intel_dp,
> +				   struct intel_connector *connector) {
> +	return 0;
> +}
> +
> +static inline int
> +intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state) {
> +	return 0;
> +}
> +
> +static inline int
> +intel_dp_tunnel_mgr_init(struct drm_i915_private *i915) {
> +	return 0;
> +}
> +
> +static inline void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private
> +*i915) {}
> +
> +#endif /* CONFIG_DRM_I915_DP_TUNNEL */
> +
> +#endif /* __INTEL_DP_TUNNEL_H__ */
> --
> 2.39.2


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

* Re: [PATCH v2 02/21] drm/dp: Add support for DP tunneling
  2024-02-23 21:32   ` Ville Syrjälä
@ 2024-02-26 11:40     ` Imre Deak
  0 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-26 11:40 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Fri, Feb 23, 2024 at 11:32:21PM +0200, Ville Syrjälä wrote:
> On Tue, Feb 20, 2024 at 11:18:22PM +0200, Imre Deak wrote:
> > +static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
> > +{
> > +	drm_dp_tunnel_put(tunnel_ref->tunnel, &tunnel_ref->tracker);
> 
> Should we set tunnel_ref->tunnel=NULL here?

Yes, thanks for spotting this. It also fixes 
intel_crtc_prepare_cleared_state()->
intel_dp_tunnel_atomic_clear_stream_bw()

if crtc_state::dp_tunnel_ref state doesn't get recomputed, for instance
when disabling the crtc.

> 
> -- 
> Ville Syrjälä
> Intel

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

* Re: [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation
  2024-02-23 21:37   ` Ville Syrjälä
@ 2024-02-26 11:42     ` Imre Deak
  0 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-26 11:42 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Fri, Feb 23, 2024 at 11:37:41PM +0200, Ville Syrjälä wrote:
> On Tue, Feb 20, 2024 at 11:18:32PM +0200, Imre Deak wrote:
> > +static void queue_retry_work(struct intel_atomic_state *state,
> > +			     struct drm_dp_tunnel *tunnel,
> > +			     const struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(state->base.dev);
> > +	struct intel_encoder *encoder;
> > +
> > +	encoder = intel_get_crtc_new_encoder(state, crtc_state);
> 
> I was pondering what happens if we have no encoder here?

That is when the crtc is disabled.

> But I guess crtc_state->tunnel_ref.tunnel should be NULL in
> that case and so we should not end up here.

Yes, in case crtc is disabled tunnel should be NULL, so
queue_retry_work() is not called.

> > +
> > +	if (!intel_digital_port_connected(encoder))
> > +		return;
> > +
> > +	drm_dbg_kms(&i915->drm,
> > +		    "[DPTUN %s][ENCODER:%d:%s] BW allocation failed on a connected sink\n",
> > +		    drm_dp_tunnel_name(tunnel),
> > +		    encoder->base.base.id,
> > +		    encoder->base.name);
> > +
> > +	intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
> > +}
> > +
> 
> -- 
> Ville Syrjälä
> Intel

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

* Re: [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (25 preceding siblings ...)
  2024-02-23 22:14 ` [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Ville Syrjälä
@ 2024-02-26 13:54 ` Jani Nikula
  2024-02-26 13:59   ` Maxime Ripard
  2024-02-27  1:02 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev6) Patchwork
                   ` (5 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Jani Nikula @ 2024-02-26 13:54 UTC (permalink / raw)
  To: Imre Deak, intel-gfx, dri-devel, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann
  Cc: Mika Westerberg, Ville Syrjälä,
	Uma Shankar, Jouni Högander, Saranya Gopal,
	Rajaram Regupathy, Gil Fine, Naama Shachar, Pengfei Xu

On Tue, 20 Feb 2024, Imre Deak <imre.deak@intel.com> wrote:
> This is v2 of [1], with the following changes:
>
> - Several functional/typo/formatting fixes, detailed in the patches.
> - Move the BW allocation from encoder hooks to
>   intel_atomic_commit_tail() fixing the allocation for MST streams
>   enabled/disabled w/o a full modeset (i.e. w/o re-enabling the master
>   stream).
> - Fix an MST mode restore issue during system resume, which also lead
>   to a tunnel BW allocation failure. (Patch 3)
> - Ensure a DPCD DPRX cap read as required by the TBT CM any time a long
>   HPD pulse is detected. (Patch 20)
> - Explicitly disable the BW allocation mode during system suspend.
>
> The patchset is also available at:
> https://github.com/ideak/linux/commits/dp_tun_bw_alloc
>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Cc: Jouni Högander <jouni.hogander@intel.com>
> Cc: Saranya Gopal <saranya.gopal@intel.com>
> Cc: Rajaram Regupathy <rajaram.regupathy@intel.com>
> Cc: Gil Fine <gil.fine@intel.com>
> Cc: Naama Shachar <naamax.shachar@intel.com>
> Cc: Pengfei Xu <pengfei.xu@intel.com>
>
> [1] https://lore.kernel.org/all/20240123102850.390126-1-imre.deak@intel.com
>
> Imre Deak (21):
>   drm/dp: Add drm_dp_max_dprx_data_rate()
>   drm/dp: Add support for DP tunneling

Maarten, Maxime, Thomas -

Ack for merging these two patches via drm-intel-next?

BR,
Jani.


>   drm/i915: Fix display bpp limit computation during system resume
>   drm/i915/dp: Add support to notify MST connectors to retry modesets
>   drm/i915/dp: Use drm_dp_max_dprx_data_rate()
>   drm/i915/dp: Factor out intel_dp_config_required_rate()
>   drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
>   drm/i915/dp: Factor out intel_dp_update_sink_caps()
>   drm/i915/dp: Factor out intel_dp_read_dprx_caps()
>   drm/i915/dp: Add intel_dp_max_link_data_rate()
>   drm/i915/dp: Add way to get active pipes with syncing commits
>   drm/i915/dp: Add support for DP tunnel BW allocation
>   drm/i915/dp: Add DP tunnel atomic state and check BW limit
>   drm/i915/dp: Account for tunnel BW limit in
>     intel_dp_max_link_data_rate()
>   drm/i915/dp: Compute DP tunnel BW during encoder state computation
>   drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable
>     hooks
>   drm/i915/dp: Handle DP tunnel IRQs
>   drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
>   drm/i915/dp: Suspend/resume DP tunnels
>   drm/i915/dp: Read DPRX for all long HPD pulses
>   drm/i915/dp: Enable DP tunnel BW allocation mode
>
>  drivers/gpu/drm/display/Kconfig               |   21 +
>  drivers/gpu/drm/display/Makefile              |    2 +
>  drivers/gpu/drm/display/drm_dp_helper.c       |   30 +
>  drivers/gpu/drm/display/drm_dp_tunnel.c       | 1929 +++++++++++++++++
>  drivers/gpu/drm/i915/Kconfig                  |   14 +
>  drivers/gpu/drm/i915/Kconfig.debug            |    1 +
>  drivers/gpu/drm/i915/Makefile                 |    3 +
>  drivers/gpu/drm/i915/display/intel_atomic.c   |   10 +
>  drivers/gpu/drm/i915/display/intel_crtc.c     |   52 +
>  drivers/gpu/drm/i915/display/intel_crtc.h     |    2 +
>  drivers/gpu/drm/i915/display/intel_ddi.c      |    3 +-
>  drivers/gpu/drm/i915/display/intel_display.c  |   26 +-
>  .../gpu/drm/i915/display/intel_display_core.h |    1 +
>  .../drm/i915/display/intel_display_driver.c   |   20 +-
>  .../drm/i915/display/intel_display_types.h    |    9 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  292 ++-
>  drivers/gpu/drm/i915/display/intel_dp.h       |   13 +-
>  .../drm/i915/display/intel_dp_link_training.c |   33 +-
>  .../drm/i915/display/intel_dp_link_training.h |    1 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   18 +-
>  .../gpu/drm/i915/display/intel_dp_tunnel.c    |  815 +++++++
>  .../gpu/drm/i915/display/intel_dp_tunnel.h    |  133 ++
>  drivers/gpu/drm/i915/display/intel_link_bw.c  |   27 +-
>  drivers/gpu/drm/i915/display/intel_link_bw.h  |    2 +-
>  drivers/gpu/drm/i915/display/intel_tc.c       |    7 +
>  include/drm/display/drm_dp.h                  |   61 +
>  include/drm/display/drm_dp_helper.h           |    2 +
>  include/drm/display/drm_dp_tunnel.h           |  248 +++
>  28 files changed, 3650 insertions(+), 125 deletions(-)
>  create mode 100644 drivers/gpu/drm/display/drm_dp_tunnel.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
>  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h
>  create mode 100644 include/drm/display/drm_dp_tunnel.h

-- 
Jani Nikula, Intel

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

* Re: [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support
  2024-02-26 13:54 ` Jani Nikula
@ 2024-02-26 13:59   ` Maxime Ripard
  0 siblings, 0 replies; 61+ messages in thread
From: Maxime Ripard @ 2024-02-26 13:59 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Imre Deak, intel-gfx, dri-devel, Maarten Lankhorst,
	Thomas Zimmermann, Mika Westerberg, Ville Syrjälä,
	Uma Shankar, Jouni Högander, Saranya Gopal,
	Rajaram Regupathy, Gil Fine, Naama Shachar, Pengfei Xu

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

On Mon, Feb 26, 2024 at 03:54:19PM +0200, Jani Nikula wrote:
> On Tue, 20 Feb 2024, Imre Deak <imre.deak@intel.com> wrote:
> > This is v2 of [1], with the following changes:
> >
> > - Several functional/typo/formatting fixes, detailed in the patches.
> > - Move the BW allocation from encoder hooks to
> >   intel_atomic_commit_tail() fixing the allocation for MST streams
> >   enabled/disabled w/o a full modeset (i.e. w/o re-enabling the master
> >   stream).
> > - Fix an MST mode restore issue during system resume, which also lead
> >   to a tunnel BW allocation failure. (Patch 3)
> > - Ensure a DPCD DPRX cap read as required by the TBT CM any time a long
> >   HPD pulse is detected. (Patch 20)
> > - Explicitly disable the BW allocation mode during system suspend.
> >
> > The patchset is also available at:
> > https://github.com/ideak/linux/commits/dp_tun_bw_alloc
> >
> > Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Cc: Jouni Högander <jouni.hogander@intel.com>
> > Cc: Saranya Gopal <saranya.gopal@intel.com>
> > Cc: Rajaram Regupathy <rajaram.regupathy@intel.com>
> > Cc: Gil Fine <gil.fine@intel.com>
> > Cc: Naama Shachar <naamax.shachar@intel.com>
> > Cc: Pengfei Xu <pengfei.xu@intel.com>
> >
> > [1] https://lore.kernel.org/all/20240123102850.390126-1-imre.deak@intel.com
> >
> > Imre Deak (21):
> >   drm/dp: Add drm_dp_max_dprx_data_rate()
> >   drm/dp: Add support for DP tunneling
> 
> Maarten, Maxime, Thomas -
> 
> Ack for merging these two patches via drm-intel-next?

Yep, go ahead

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* [PATCH v3 01/21] drm/dp: Add drm_dp_max_dprx_data_rate()
  2024-02-20 21:18 ` [PATCH v2 01/21] drm/dp: Add drm_dp_max_dprx_data_rate() Imre Deak
@ 2024-02-26 18:52   ` Imre Deak
  0 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-26 18:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ville Syrjälä, Uma Shankar

Copy intel_dp_max_data_rate() to DRM core. It will be needed by a
follow-up DP tunnel patch, checking the maximum rate the DPRX (sink)
supports. Accordingly use the drm_dp_max_dprx_data_rate() name for
clarity. This patchset will also switch calling the new DRM function
in i915 instead of intel_dp_max_data_rate().

While at it simplify the function documentation/comments, removing
parts described already by drm_dp_bw_channel_coding_efficiency().

v2: (Ville)
- Remove max_link_rate_kbps.
- Simplify the function documentation.
v3:
- Rebased on latest drm-tip.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/display/drm_dp_helper.c | 30 +++++++++++++++++++++++++
 include/drm/display/drm_dp_helper.h     |  1 +
 2 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 9ac52cf5d4d87..314509d999f14 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -4152,3 +4152,33 @@ int drm_dp_bw_channel_coding_efficiency(bool is_uhbr)
 		return 800000;
 }
 EXPORT_SYMBOL(drm_dp_bw_channel_coding_efficiency);
+
+/**
+ * drm_dp_max_dprx_data_rate - Get the max data bandwidth of a DPRX sink
+ * @max_link_rate: max DPRX link rate in 10kbps units
+ * @max_lanes: max DPRX lane count
+ *
+ * Given a link rate and lanes, get the data bandwidth.
+ *
+ * Data bandwidth is the actual payload rate, which depends on the data
+ * bandwidth efficiency and the link rate.
+ *
+ * Note that protocol layers above the DPRX link level considered here can
+ * further limit the maximum data rate. Such layers are the MST topology (with
+ * limits on the link between the source and first branch device as well as on
+ * the whole MST path until the DPRX link) and (Thunderbolt) DP tunnels -
+ * which in turn can encapsulate an MST link with its own limit - with each
+ * SST or MST encapsulated tunnel sharing the BW of a tunnel group.
+ *
+ * Returns the maximum data rate in kBps units.
+ */
+int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes)
+{
+	int ch_coding_efficiency =
+		drm_dp_bw_channel_coding_efficiency(drm_dp_is_uhbr_rate(max_link_rate));
+
+	return DIV_ROUND_DOWN_ULL(mul_u32_u32(max_link_rate * 10 * max_lanes,
+					      ch_coding_efficiency),
+				  1000000 * 8);
+}
+EXPORT_SYMBOL(drm_dp_max_dprx_data_rate);
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index 0c1a4021e098e..91fb404dd5310 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -813,6 +813,7 @@ int drm_dp_bw_overhead(int lane_count, int hactive,
 		       int dsc_slice_count,
 		       int bpp_x16, unsigned long flags);
 int drm_dp_bw_channel_coding_efficiency(bool is_uhbr);
+int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes);
 
 ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, struct dp_sdp *sdp);
 
-- 
2.39.2


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

* [PATCH v3 02/21] drm/dp: Add support for DP tunneling
  2024-02-20 21:18 ` [PATCH v2 02/21] drm/dp: Add support for DP tunneling Imre Deak
  2024-02-23  6:25   ` Shankar, Uma
  2024-02-23 21:32   ` Ville Syrjälä
@ 2024-02-26 18:52   ` Imre Deak
  2 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-26 18:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ville Syrjälä, Uma Shankar

Add support for Display Port tunneling. For now this includes the
support for Bandwidth Allocation Mode (BWA), leaving adding Panel Replay
support for later.

BWA allows using displays that share the same (Thunderbolt) link with
their maximum resolution. Atm, this may not be possible due to the
coarse granularity of partitioning the link BW among the displays on the
link: the BW allocation policy is in a SW/FW/HW component on the link
(on Thunderbolt it's the SW or FW Connection Manager), independent of
the driver. This policy will set the DPRX maximum rate and lane count
DPCD registers the GFX driver will see (0x00000, 0x00001, 0x02200,
0x02201) based on the available link BW.

The granularity of the current BW allocation policy is coarse, based on
the required link rate in the 1.62Gbs..8.1Gbps range and it may prevent
using higher resolutions all together: the display connected first will
get a share of the link BW which corresponds to its full DPRX capability
(regardless of the actual mode it uses). A subsequent display connected
will only get the remaining BW, which could be well below its full
capability.

BWA solves the above coarse granularity (reducing it to a 250Mbs..1Gps
range) and first-come/first-served issues by letting the driver request
the BW for each display on a link which reflects the actual modes the
displays use.

This patch adds the DRM core helper functions, while a follow-up change
in the patchset takes them into use in the i915 driver.

v2:
- Fix prepare_to_wait vs. wake-up cond check order in
  allocate_tunnel_bw(). (Ville)
- Move tunnel==NULL checks from callers in drivers to here. (Ville)
- Avoid var inits in declaration blocks that can fail or have
  side-effects. (Ville)
- Use u8 for driver and group IDs. (Ville)
- Simplify API removing drm_dp_tunnel_get/put_untracked(). (Ville)
- Reuse str_yes_no() instead of a local yes_no_chr(). (Ville)
- s/drm_dp_tunnel_atomic_clear_state()/free_tunnel_state() and unexport
  the function. (Ville)
- s/clear_tunnel_group_state()/free_group_state() and move kfree() to
  this function. (Ville)
- Add separate group_free_bw() helper and describe what the tunnel
  estimated BW includes. (Ville)
- Improve help text for CONFIG_DRM_DISPLAY_DP_TUNNEL. (Ville)
- Add code comment explaining the purpose of DPCD reg read helpers.
  (Ville)
- Add code comment describing the tunnel group name prefix format.
  (Ville)
- Report the allocated BW as undetermined until the first allocation
  request.
- Skip allocation requests matching the previous request.
- Clear any stale BW request status flags before a new request.
- Add missing error return check of drm_dp_tunnel_atomic_get_group_state()
  in drm_dp_tunnel_atomic_set_stream_bw().
- Add drm_dp_tunnel_get_allocated_bw().
- s/drm_dp_tunnel_atomic_get_tunnel_bw/drm_dp_tunnel_atomic_get_required_bw
- Fix return value description in function doc of drm_dp_tunnel_detect().
- Add function documentation to all exported functions.

v3:
- Improve grouping of fields in drm_dp_tunnel_group struct. (Uma)
- Fix validating the BW granularity DPCD reg value. (Uma)
- Document return value of check_and_clear_status_change(). (Uma)
- Fix resetting drm_dp_tunnel_ref::tunnel in drm_dp_tunnel_ref_put().
  (Ville)
- Allow for ALLOCATED_BW to change after a BWA enable/disable sequence.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/display/Kconfig         |   21 +
 drivers/gpu/drm/display/Makefile        |    2 +
 drivers/gpu/drm/display/drm_dp_tunnel.c | 1949 +++++++++++++++++++++++
 include/drm/display/drm_dp.h            |   60 +
 include/drm/display/drm_dp_tunnel.h     |  249 +++
 5 files changed, 2281 insertions(+)
 create mode 100644 drivers/gpu/drm/display/drm_dp_tunnel.c
 create mode 100644 include/drm/display/drm_dp_tunnel.h

diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 09712b88a5b83..c0f56888c3280 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -17,6 +17,27 @@ config DRM_DISPLAY_DP_HELPER
 	help
 	  DRM display helpers for DisplayPort.
 
+config DRM_DISPLAY_DP_TUNNEL
+	bool
+	select DRM_DISPLAY_DP_HELPER
+	help
+	  Enable support for DisplayPort tunnels. This allows drivers to use
+	  DP tunnel features like the Bandwidth Allocation mode to maximize the
+	  BW utilization for display streams on Thunderbolt links.
+
+config DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	bool "Enable debugging the DP tunnel state"
+	depends on REF_TRACKER
+	depends on DRM_DISPLAY_DP_TUNNEL
+	depends on DEBUG_KERNEL
+	depends on EXPERT
+	help
+	  Enables debugging the DP tunnel manager's state, including the
+	  consistency of all managed tunnels' reference counting and the state of
+	  streams contained in tunnels.
+
+	  If in doubt, say "N".
+
 config DRM_DISPLAY_HDCP_HELPER
 	bool
 	depends on DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 17ac4a1006a80..7ca61333c6696 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -8,6 +8,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \
 	drm_dp_helper.o \
 	drm_dp_mst_topology.o \
 	drm_dsc_helper.o
+drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \
+	drm_dp_tunnel.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
 	drm_hdmi_helper.o \
diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c
new file mode 100644
index 0000000000000..c428e7e7d6b56
--- /dev/null
+++ b/drivers/gpu/drm/display/drm_dp_tunnel.c
@@ -0,0 +1,1949 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <linux/ref_tracker.h>
+#include <linux/types.h>
+
+#include <drm/drm_atomic_state_helper.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_print.h>
+#include <drm/display/drm_dp.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
+
+#define to_group(__private_obj) \
+	container_of(__private_obj, struct drm_dp_tunnel_group, base)
+
+#define to_group_state(__private_state) \
+	container_of(__private_state, struct drm_dp_tunnel_group_state, base)
+
+#define is_dp_tunnel_private_obj(__obj) \
+	((__obj)->funcs == &tunnel_group_funcs)
+
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))
+
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))
+
+#define for_each_tunnel_in_group(__group, __tunnel) \
+	list_for_each_entry(__tunnel, &(__group)->tunnels, node)
+
+#define for_each_tunnel_state(__group_state, __tunnel_state) \
+	list_for_each_entry(__tunnel_state, &(__group_state)->tunnel_states, node)
+
+#define for_each_tunnel_state_safe(__group_state, __tunnel_state, __tunnel_state_tmp) \
+	list_for_each_entry_safe(__tunnel_state, __tunnel_state_tmp, \
+				 &(__group_state)->tunnel_states, node)
+
+#define kbytes_to_mbits(__kbytes) \
+	DIV_ROUND_UP((__kbytes) * 8, 1000)
+
+#define DPTUN_BW_ARG(__bw) ((__bw) < 0 ? (__bw) : kbytes_to_mbits(__bw))
+
+#define __tun_prn(__tunnel, __level, __type, __fmt, ...) \
+	drm_##__level##__type((__tunnel)->group->mgr->dev, \
+			      "[DPTUN %s][%s] " __fmt, \
+			      drm_dp_tunnel_name(__tunnel), \
+			      (__tunnel)->aux->name, ## \
+			      __VA_ARGS__)
+
+#define tun_dbg(__tunnel, __fmt, ...) \
+	__tun_prn(__tunnel, dbg, _kms, __fmt, ## __VA_ARGS__)
+
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)
+
+#define tun_dbg_atomic(__tunnel, __fmt, ...) \
+	__tun_prn(__tunnel, dbg, _atomic, __fmt, ## __VA_ARGS__)
+
+#define tun_grp_dbg(__group, __fmt, ...) \
+	drm_dbg_kms((__group)->mgr->dev, \
+		    "[DPTUN %s] " __fmt, \
+		    drm_dp_tunnel_group_name(__group), ## \
+		    __VA_ARGS__)
+
+#define DP_TUNNELING_BASE DP_TUNNELING_OUI
+
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)
+
+#define DPTUN_REG_RANGE(addr, size) \
+	__DPTUN_REG_RANGE((addr) - DP_TUNNELING_BASE, size)
+
+#define DPTUN_REG(addr) DPTUN_REG_RANGE(addr, 1)
+
+#define DPTUN_INFO_REG_MASK ( \
+	DPTUN_REG_RANGE(DP_TUNNELING_OUI, DP_TUNNELING_OUI_BYTES) | \
+	DPTUN_REG_RANGE(DP_TUNNELING_DEV_ID, DP_TUNNELING_DEV_ID_BYTES) | \
+	DPTUN_REG(DP_TUNNELING_HW_REV) | \
+	DPTUN_REG(DP_TUNNELING_SW_REV_MAJOR) | \
+	DPTUN_REG(DP_TUNNELING_SW_REV_MINOR) | \
+	DPTUN_REG(DP_TUNNELING_CAPABILITIES) | \
+	DPTUN_REG(DP_IN_ADAPTER_INFO) | \
+	DPTUN_REG(DP_USB4_DRIVER_ID) | \
+	DPTUN_REG(DP_USB4_DRIVER_BW_CAPABILITY) | \
+	DPTUN_REG(DP_IN_ADAPTER_TUNNEL_INFORMATION) | \
+	DPTUN_REG(DP_BW_GRANULARITY) | \
+	DPTUN_REG(DP_ESTIMATED_BW) | \
+	DPTUN_REG(DP_ALLOCATED_BW) | \
+	DPTUN_REG(DP_TUNNELING_MAX_LINK_RATE) | \
+	DPTUN_REG(DP_TUNNELING_MAX_LANE_COUNT) | \
+	DPTUN_REG(DP_DPTX_BW_ALLOCATION_MODE_CONTROL))
+
+static const DECLARE_BITMAP(dptun_info_regs, 64) = {
+	DPTUN_INFO_REG_MASK & -1UL,
+#if BITS_PER_LONG == 32
+	DPTUN_INFO_REG_MASK >> 32,
+#endif
+};
+
+struct drm_dp_tunnel_regs {
+	u8 buf[HWEIGHT64(DPTUN_INFO_REG_MASK)];
+};
+
+struct drm_dp_tunnel_group;
+
+struct drm_dp_tunnel {
+	struct drm_dp_tunnel_group *group;
+
+	struct list_head node;
+
+	struct kref kref;
+	struct ref_tracker *tracker;
+	struct drm_dp_aux *aux;
+	char name[8];
+
+	int bw_granularity;
+	int estimated_bw;
+	int allocated_bw;
+
+	int max_dprx_rate;
+	u8 max_dprx_lane_count;
+
+	u8 adapter_id;
+
+	bool bw_alloc_supported:1;
+	bool bw_alloc_enabled:1;
+	bool has_io_error:1;
+	bool destroyed:1;
+};
+
+struct drm_dp_tunnel_group_state;
+
+struct drm_dp_tunnel_state {
+	struct drm_dp_tunnel_group_state *group_state;
+
+	struct drm_dp_tunnel_ref tunnel_ref;
+
+	struct list_head node;
+
+	u32 stream_mask;
+	int *stream_bw;
+};
+
+struct drm_dp_tunnel_group_state {
+	struct drm_private_state base;
+
+	struct list_head tunnel_states;
+};
+
+struct drm_dp_tunnel_group {
+	struct drm_private_obj base;
+	struct drm_dp_tunnel_mgr *mgr;
+
+	struct list_head tunnels;
+
+	/* available BW including the allocated_bw of all tunnels in the group */
+	int available_bw;
+
+	u8 drv_group_id;
+	char name[8];
+
+	bool active:1;
+};
+
+struct drm_dp_tunnel_mgr {
+	struct drm_device *dev;
+
+	int group_count;
+	struct drm_dp_tunnel_group *groups;
+	wait_queue_head_t bw_req_queue;
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	struct ref_tracker_dir ref_tracker;
+#endif
+};
+
+/*
+ * The following helpers provide a way to read out the tunneling DPCD
+ * registers with a minimal amount of AUX transfers (1 transfer per contiguous
+ * range, as permitted by the 16 byte per transfer AUX limit), not accessing
+ * other registers to avoid any read side-effects.
+ */
+static int next_reg_area(int *offset)
+{
+	*offset = find_next_bit(dptun_info_regs, 64, *offset);
+
+	return find_next_zero_bit(dptun_info_regs, 64, *offset + 1) - *offset;
+}
+
+#define tunnel_reg_ptr(__regs, __address) ({ \
+	WARN_ON(!test_bit((__address) - DP_TUNNELING_BASE, dptun_info_regs)); \
+	&(__regs)->buf[bitmap_weight(dptun_info_regs, (__address) - DP_TUNNELING_BASE)]; \
+})
+
+static int read_tunnel_regs(struct drm_dp_aux *aux, struct drm_dp_tunnel_regs *regs)
+{
+	int offset = 0;
+	int len;
+
+	while ((len = next_reg_area(&offset))) {
+		int address = DP_TUNNELING_BASE + offset;
+
+		if (drm_dp_dpcd_read(aux, address, tunnel_reg_ptr(regs, address), len) < 0)
+			return -EIO;
+
+		offset += len;
+	}
+
+	return 0;
+}
+
+static u8 tunnel_reg(const struct drm_dp_tunnel_regs *regs, int address)
+{
+	return *tunnel_reg_ptr(regs, address);
+}
+
+static u8 tunnel_reg_drv_group_id(const struct drm_dp_tunnel_regs *regs)
+{
+	u8 drv_id = tunnel_reg(regs, DP_USB4_DRIVER_ID) & DP_USB4_DRIVER_ID_MASK;
+	u8 group_id = tunnel_reg(regs, DP_IN_ADAPTER_TUNNEL_INFORMATION) & DP_GROUP_ID_MASK;
+
+	if (!group_id)
+		return 0;
+
+	return (drv_id << DP_GROUP_ID_BITS) | group_id;
+}
+
+/* Return granularity in kB/s units */
+static int tunnel_reg_bw_granularity(const struct drm_dp_tunnel_regs *regs)
+{
+	int gr = tunnel_reg(regs, DP_BW_GRANULARITY) & DP_BW_GRANULARITY_MASK;
+
+	if (gr > 2)
+		return -1;
+
+	return (250000 << gr) / 8;
+}
+
+static int tunnel_reg_max_dprx_rate(const struct drm_dp_tunnel_regs *regs)
+{
+	u8 bw_code = tunnel_reg(regs, DP_TUNNELING_MAX_LINK_RATE);
+
+	return drm_dp_bw_code_to_link_rate(bw_code);
+}
+
+static int tunnel_reg_max_dprx_lane_count(const struct drm_dp_tunnel_regs *regs)
+{
+	return tunnel_reg(regs, DP_TUNNELING_MAX_LANE_COUNT) &
+	       DP_TUNNELING_MAX_LANE_COUNT_MASK;
+}
+
+static bool tunnel_reg_bw_alloc_supported(const struct drm_dp_tunnel_regs *regs)
+{
+	u8 cap_mask = DP_TUNNELING_SUPPORT | DP_IN_BW_ALLOCATION_MODE_SUPPORT;
+
+	if ((tunnel_reg(regs, DP_TUNNELING_CAPABILITIES) & cap_mask) != cap_mask)
+		return false;
+
+	return tunnel_reg(regs, DP_USB4_DRIVER_BW_CAPABILITY) &
+	       DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT;
+}
+
+static bool tunnel_reg_bw_alloc_enabled(const struct drm_dp_tunnel_regs *regs)
+{
+	return tunnel_reg(regs, DP_DPTX_BW_ALLOCATION_MODE_CONTROL) &
+	       DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE;
+}
+
+static u8 tunnel_group_drv_id(u8 drv_group_id)
+{
+	return drv_group_id >> DP_GROUP_ID_BITS;
+}
+
+static u8 tunnel_group_id(u8 drv_group_id)
+{
+	return drv_group_id & DP_GROUP_ID_MASK;
+}
+
+const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->name;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_name);
+
+static const char *drm_dp_tunnel_group_name(const struct drm_dp_tunnel_group *group)
+{
+	return group->name;
+}
+
+static struct drm_dp_tunnel_group *
+lookup_or_alloc_group(struct drm_dp_tunnel_mgr *mgr, u8 drv_group_id)
+{
+	struct drm_dp_tunnel_group *group = NULL;
+	int i;
+
+	for (i = 0; i < mgr->group_count; i++) {
+		/*
+		 * A tunnel group with 0 group ID shouldn't have more than one
+		 * tunnels.
+		 */
+		if (tunnel_group_id(drv_group_id) &&
+		    mgr->groups[i].drv_group_id == drv_group_id)
+			return &mgr->groups[i];
+
+		if (!group && !mgr->groups[i].active)
+			group = &mgr->groups[i];
+	}
+
+	if (!group) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Can't allocate more tunnel groups\n");
+		return NULL;
+	}
+
+	group->drv_group_id = drv_group_id;
+	group->active = true;
+
+	/*
+	 * The group name format here and elsewhere: Driver-ID:Group-ID:*
+	 * (* standing for all DP-Adapters/tunnels in the group).
+	 */
+	snprintf(group->name, sizeof(group->name), "%d:%d:*",
+		 tunnel_group_drv_id(drv_group_id) & ((1 << DP_GROUP_ID_BITS) - 1),
+		 tunnel_group_id(drv_group_id) & ((1 << DP_USB4_DRIVER_ID_BITS) - 1));
+
+	return group;
+}
+
+static void free_group(struct drm_dp_tunnel_group *group)
+{
+	struct drm_dp_tunnel_mgr *mgr = group->mgr;
+
+	if (drm_WARN_ON(mgr->dev, !list_empty(&group->tunnels)))
+		return;
+
+	group->drv_group_id = 0;
+	group->available_bw = -1;
+	group->active = false;
+}
+
+static struct drm_dp_tunnel *
+tunnel_get(struct drm_dp_tunnel *tunnel)
+{
+	kref_get(&tunnel->kref);
+
+	return tunnel;
+}
+
+static void free_tunnel(struct kref *kref)
+{
+	struct drm_dp_tunnel *tunnel = container_of(kref, typeof(*tunnel), kref);
+	struct drm_dp_tunnel_group *group = tunnel->group;
+
+	list_del(&tunnel->node);
+	if (list_empty(&group->tunnels))
+		free_group(group);
+
+	kfree(tunnel);
+}
+
+static void tunnel_put(struct drm_dp_tunnel *tunnel)
+{
+	kref_put(&tunnel->kref, free_tunnel);
+}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+static void track_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			     struct ref_tracker **tracker)
+{
+	ref_tracker_alloc(&tunnel->group->mgr->ref_tracker,
+			  tracker, GFP_KERNEL);
+}
+
+static void untrack_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			       struct ref_tracker **tracker)
+{
+	ref_tracker_free(&tunnel->group->mgr->ref_tracker,
+			 tracker);
+}
+#else
+static void track_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			     struct ref_tracker **tracker)
+{
+}
+
+static void untrack_tunnel_ref(struct drm_dp_tunnel *tunnel,
+			       struct ref_tracker **tracker)
+{
+}
+#endif
+
+/**
+ * drm_dp_tunnel_get - Get a reference for a DP tunnel
+ * @tunnel: Tunnel object
+ * @tracker: Debug tracker for the reference
+ *
+ * Get a reference for @tunnel, along with a debug tracker to help locating
+ * the source of a reference leak/double reference put etc. issue.
+ *
+ * The reference must be dropped after use calling drm_dp_tunnel_put()
+ * passing @tunnel and *@tracker returned from here.
+ *
+ * Returns @tunnel - as a convenience - along with *@tracker.
+ */
+struct drm_dp_tunnel *
+drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel,
+		  struct ref_tracker **tracker)
+{
+	track_tunnel_ref(tunnel, tracker);
+
+	return tunnel_get(tunnel);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_get);
+
+/**
+ * drm_dp_tunnel_put - Put a reference for a DP tunnel
+ * @tunnel - Tunnel object
+ * @tracker - Debug tracker for the reference
+ *
+ * Put a reference for @tunnel along with its debug *@tracker, which
+ * was obtained with drm_dp_tunnel_get().
+ */
+void drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel,
+			 struct ref_tracker **tracker)
+{
+	untrack_tunnel_ref(tunnel, tracker);
+
+	tunnel_put(tunnel);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_put);
+
+static bool add_tunnel_to_group(struct drm_dp_tunnel_mgr *mgr,
+				u8 drv_group_id,
+				struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group *group;
+
+	group = lookup_or_alloc_group(mgr, drv_group_id);
+	if (!group)
+		return false;
+
+	tunnel->group = group;
+	list_add(&tunnel->node, &group->tunnels);
+
+	return true;
+}
+
+static struct drm_dp_tunnel *
+create_tunnel(struct drm_dp_tunnel_mgr *mgr,
+	      struct drm_dp_aux *aux,
+	      const struct drm_dp_tunnel_regs *regs)
+{
+	u8 drv_group_id = tunnel_reg_drv_group_id(regs);
+	struct drm_dp_tunnel *tunnel;
+
+	tunnel = kzalloc(sizeof(*tunnel), GFP_KERNEL);
+	if (!tunnel)
+		return NULL;
+
+	INIT_LIST_HEAD(&tunnel->node);
+
+	kref_init(&tunnel->kref);
+
+	tunnel->aux = aux;
+
+	tunnel->adapter_id = tunnel_reg(regs, DP_IN_ADAPTER_INFO) & DP_IN_ADAPTER_NUMBER_MASK;
+
+	snprintf(tunnel->name, sizeof(tunnel->name), "%d:%d:%d",
+		 tunnel_group_drv_id(drv_group_id) & ((1 << DP_GROUP_ID_BITS) - 1),
+		 tunnel_group_id(drv_group_id) & ((1 << DP_USB4_DRIVER_ID_BITS) - 1),
+		 tunnel->adapter_id & ((1 << DP_IN_ADAPTER_NUMBER_BITS) - 1));
+
+	tunnel->bw_granularity = tunnel_reg_bw_granularity(regs);
+	tunnel->allocated_bw = tunnel_reg(regs, DP_ALLOCATED_BW) *
+			       tunnel->bw_granularity;
+	/*
+	 * An initial allocated BW of 0 indicates an undefined state: the
+	 * actual allocation is determined by the TBT CM, usually following a
+	 * legacy allocation policy (based on the max DPRX caps). From the
+	 * driver's POV the state becomes defined only after the first
+	 * allocation request.
+	 */
+	if (!tunnel->allocated_bw)
+		tunnel->allocated_bw = -1;
+
+	tunnel->bw_alloc_supported = tunnel_reg_bw_alloc_supported(regs);
+	tunnel->bw_alloc_enabled = tunnel_reg_bw_alloc_enabled(regs);
+
+	if (!add_tunnel_to_group(mgr, drv_group_id, tunnel)) {
+		kfree(tunnel);
+
+		return NULL;
+	}
+
+	track_tunnel_ref(tunnel, &tunnel->tracker);
+
+	return tunnel;
+}
+
+static void destroy_tunnel(struct drm_dp_tunnel *tunnel)
+{
+	untrack_tunnel_ref(tunnel, &tunnel->tracker);
+	tunnel_put(tunnel);
+}
+
+/**
+ * drm_dp_tunnel_set_io_error - Set the IO error flag for a DP tunnel
+ * @tunnel: Tunnel object
+ *
+ * Set the IO error flag for @tunnel. Drivers can call this function upon
+ * detecting a failure that affects the tunnel functionality, for instance
+ * after a DP AUX transfer failure on the port @tunnel is connected to.
+ *
+ * This disables further management of @tunnel, including any related
+ * AUX accesses for tunneling DPCD registers, returning error to the
+ * initiators of these. The driver is supposed to drop this tunnel and -
+ * optionally - recreate it.
+ */
+void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel)
+{
+	tunnel->has_io_error = true;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_set_io_error);
+
+#define SKIP_DPRX_CAPS_CHECK		BIT(0)
+#define ALLOW_ALLOCATED_BW_CHANGE	BIT(1)
+static bool tunnel_regs_are_valid(struct drm_dp_tunnel_mgr *mgr,
+				  const struct drm_dp_tunnel_regs *regs,
+				  unsigned int flags)
+{
+	u8 drv_group_id = tunnel_reg_drv_group_id(regs);
+	bool check_dprx = !(flags & SKIP_DPRX_CAPS_CHECK);
+	bool ret = true;
+
+	if (!tunnel_reg_bw_alloc_supported(regs)) {
+		if (tunnel_group_id(drv_group_id)) {
+			drm_dbg_kms(mgr->dev,
+				    "DPTUN: A non-zero group ID is only allowed with BWA support\n");
+			ret = false;
+		}
+
+		if (tunnel_reg(regs, DP_ALLOCATED_BW)) {
+			drm_dbg_kms(mgr->dev,
+				    "DPTUN: BW is allocated without BWA support\n");
+			ret = false;
+		}
+
+		return ret;
+	}
+
+	if (!tunnel_group_id(drv_group_id)) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: BWA support requires a non-zero group ID\n");
+		ret = false;
+	}
+
+	if (check_dprx && hweight8(tunnel_reg_max_dprx_lane_count(regs)) != 1) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Invalid DPRX lane count: %d\n",
+			    tunnel_reg_max_dprx_lane_count(regs));
+
+		ret = false;
+	}
+
+	if (check_dprx && !tunnel_reg_max_dprx_rate(regs)) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: DPRX rate is 0\n");
+
+		ret = false;
+	}
+
+	if (tunnel_reg_bw_granularity(regs) < 0) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Invalid BW granularity\n");
+
+		ret = false;
+	}
+
+	if (tunnel_reg(regs, DP_ALLOCATED_BW) > tunnel_reg(regs, DP_ESTIMATED_BW)) {
+		drm_dbg_kms(mgr->dev,
+			    "DPTUN: Allocated BW %d > estimated BW %d Mb/s\n",
+			    DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) *
+					 tunnel_reg_bw_granularity(regs)),
+			    DPTUN_BW_ARG(tunnel_reg(regs, DP_ESTIMATED_BW) *
+					 tunnel_reg_bw_granularity(regs)));
+
+		ret = false;
+	}
+
+	return ret;
+}
+
+static int tunnel_allocated_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return max(tunnel->allocated_bw, 0);
+}
+
+static bool tunnel_info_changes_are_valid(struct drm_dp_tunnel *tunnel,
+					  const struct drm_dp_tunnel_regs *regs,
+					  unsigned int flags)
+{
+	u8 new_drv_group_id = tunnel_reg_drv_group_id(regs);
+	bool ret = true;
+
+	if (tunnel->bw_alloc_supported != tunnel_reg_bw_alloc_supported(regs)) {
+		tun_dbg(tunnel,
+			"BW alloc support has changed %s -> %s\n",
+			str_yes_no(tunnel->bw_alloc_supported),
+			str_yes_no(tunnel_reg_bw_alloc_supported(regs)));
+
+		ret = false;
+	}
+
+	if (tunnel->group->drv_group_id != new_drv_group_id) {
+		tun_dbg(tunnel,
+			"Driver/group ID has changed %d:%d:* -> %d:%d:*\n",
+			tunnel_group_drv_id(tunnel->group->drv_group_id),
+			tunnel_group_id(tunnel->group->drv_group_id),
+			tunnel_group_drv_id(new_drv_group_id),
+			tunnel_group_id(new_drv_group_id));
+
+		ret = false;
+	}
+
+	if (!tunnel->bw_alloc_supported)
+		return ret;
+
+	if (tunnel->bw_granularity != tunnel_reg_bw_granularity(regs)) {
+		tun_dbg(tunnel,
+			"BW granularity has changed: %d -> %d Mb/s\n",
+			DPTUN_BW_ARG(tunnel->bw_granularity),
+			DPTUN_BW_ARG(tunnel_reg_bw_granularity(regs)));
+
+		ret = false;
+	}
+
+	/*
+	 * On some devices at least the BW alloc mode enabled status is always
+	 * reported as 0, so skip checking that here.
+	 */
+
+	if (!(flags & ALLOW_ALLOCATED_BW_CHANGE) &&
+	    tunnel_allocated_bw(tunnel) !=
+	    tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity) {
+		tun_dbg(tunnel,
+			"Allocated BW has changed: %d -> %d Mb/s\n",
+			DPTUN_BW_ARG(tunnel->allocated_bw),
+			DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity));
+
+		ret = false;
+	}
+
+	return ret;
+}
+
+static int
+read_and_verify_tunnel_regs(struct drm_dp_tunnel *tunnel,
+			    struct drm_dp_tunnel_regs *regs,
+			    unsigned int flags)
+{
+	int err;
+
+	err = read_tunnel_regs(tunnel->aux, regs);
+	if (err < 0) {
+		drm_dp_tunnel_set_io_error(tunnel);
+
+		return err;
+	}
+
+	if (!tunnel_regs_are_valid(tunnel->group->mgr, regs, flags))
+		return -EINVAL;
+
+	if (!tunnel_info_changes_are_valid(tunnel, regs, flags))
+		return -EINVAL;
+
+	return 0;
+}
+
+static bool update_dprx_caps(struct drm_dp_tunnel *tunnel, const struct drm_dp_tunnel_regs *regs)
+{
+	bool changed = false;
+
+	if (tunnel_reg_max_dprx_rate(regs) != tunnel->max_dprx_rate) {
+		tunnel->max_dprx_rate = tunnel_reg_max_dprx_rate(regs);
+		changed = true;
+	}
+
+	if (tunnel_reg_max_dprx_lane_count(regs) != tunnel->max_dprx_lane_count) {
+		tunnel->max_dprx_lane_count = tunnel_reg_max_dprx_lane_count(regs);
+		changed = true;
+	}
+
+	return changed;
+}
+
+static int dev_id_len(const u8 *dev_id, int max_len)
+{
+	while (max_len && dev_id[max_len - 1] == '\0')
+		max_len--;
+
+	return max_len;
+}
+
+static int get_max_dprx_bw(const struct drm_dp_tunnel *tunnel)
+{
+	int max_dprx_bw = drm_dp_max_dprx_data_rate(tunnel->max_dprx_rate,
+						    tunnel->max_dprx_lane_count);
+
+	/*
+	 * A BW request of roundup(max_dprx_bw, tunnel->bw_granularity) results in
+	 * an allocation of max_dprx_bw. A BW request above this rounded-up
+	 * value will fail.
+	 */
+	return min(roundup(max_dprx_bw, tunnel->bw_granularity),
+		   MAX_DP_REQUEST_BW * tunnel->bw_granularity);
+}
+
+static int get_max_tunnel_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return min(get_max_dprx_bw(tunnel), tunnel->group->available_bw);
+}
+
+/**
+ * drm_dp_tunnel_detect - Detect DP tunnel on the link
+ * @mgr: Tunnel manager
+ * @aux: DP AUX on which the tunnel will be detected
+ *
+ * Detect if there is any DP tunnel on the link and add it to the tunnel
+ * group's tunnel list.
+ *
+ * Returns a pointer to a tunnel on success, or an ERR_PTR() error on
+ * failure.
+ */
+struct drm_dp_tunnel *
+drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
+		     struct drm_dp_aux *aux)
+{
+	struct drm_dp_tunnel_regs regs;
+	struct drm_dp_tunnel *tunnel;
+	int err;
+
+	err = read_tunnel_regs(aux, &regs);
+	if (err)
+		return ERR_PTR(err);
+
+	if (!(tunnel_reg(&regs, DP_TUNNELING_CAPABILITIES) &
+	      DP_TUNNELING_SUPPORT))
+		return ERR_PTR(-ENODEV);
+
+	/* The DPRX caps are valid only after enabling BW alloc mode. */
+	if (!tunnel_regs_are_valid(mgr, &regs, SKIP_DPRX_CAPS_CHECK))
+		return ERR_PTR(-EINVAL);
+
+	tunnel = create_tunnel(mgr, aux, &regs);
+	if (!tunnel)
+		return ERR_PTR(-ENOMEM);
+
+	tun_dbg(tunnel,
+		"OUI:%*phD DevID:%*pE Rev-HW:%d.%d SW:%d.%d PR-Sup:%s BWA-Sup:%s BWA-En:%s\n",
+		DP_TUNNELING_OUI_BYTES,
+			tunnel_reg_ptr(&regs, DP_TUNNELING_OUI),
+		dev_id_len(tunnel_reg_ptr(&regs, DP_TUNNELING_DEV_ID), DP_TUNNELING_DEV_ID_BYTES),
+			tunnel_reg_ptr(&regs, DP_TUNNELING_DEV_ID),
+		(tunnel_reg(&regs, DP_TUNNELING_HW_REV) & DP_TUNNELING_HW_REV_MAJOR_MASK) >>
+			DP_TUNNELING_HW_REV_MAJOR_SHIFT,
+		(tunnel_reg(&regs, DP_TUNNELING_HW_REV) & DP_TUNNELING_HW_REV_MINOR_MASK) >>
+			DP_TUNNELING_HW_REV_MINOR_SHIFT,
+		tunnel_reg(&regs, DP_TUNNELING_SW_REV_MAJOR),
+		tunnel_reg(&regs, DP_TUNNELING_SW_REV_MINOR),
+		str_yes_no(tunnel_reg(&regs, DP_TUNNELING_CAPABILITIES) &
+			   DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT),
+		str_yes_no(tunnel->bw_alloc_supported),
+		str_yes_no(tunnel->bw_alloc_enabled));
+
+	return tunnel;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_detect);
+
+/**
+ * drm_dp_tunnel_destroy - Destroy tunnel object
+ * @tunnel: Tunnel object
+ *
+ * Remove the tunnel from the tunnel topology and destroy it.
+ *
+ * Returns 0 on success, -ENODEV if the tunnel has been destroyed already.
+ */
+int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
+{
+	if (!tunnel)
+		return 0;
+
+	if (drm_WARN_ON(tunnel->group->mgr->dev, tunnel->destroyed))
+		return -ENODEV;
+
+	tun_dbg(tunnel, "destroying\n");
+
+	tunnel->destroyed = true;
+	destroy_tunnel(tunnel);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_destroy);
+
+static int check_tunnel(const struct drm_dp_tunnel *tunnel)
+{
+	if (tunnel->destroyed)
+		return -ENODEV;
+
+	if (tunnel->has_io_error)
+		return -EIO;
+
+	return 0;
+}
+
+static int group_allocated_bw(struct drm_dp_tunnel_group *group)
+{
+	struct drm_dp_tunnel *tunnel;
+	int group_allocated_bw = 0;
+
+	for_each_tunnel_in_group(group, tunnel) {
+		if (check_tunnel(tunnel) == 0 &&
+		    tunnel->bw_alloc_enabled)
+			group_allocated_bw += tunnel_allocated_bw(tunnel);
+	}
+
+	return group_allocated_bw;
+}
+
+/*
+ * The estimated BW reported by the TBT Connection Manager for each tunnel in
+ * a group includes the BW already allocated for the given tunnel and the
+ * unallocated BW which is free to be used by any tunnel in the group.
+ */
+static int group_free_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->estimated_bw - tunnel_allocated_bw(tunnel);
+}
+
+static int calc_group_available_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return group_allocated_bw(tunnel->group) +
+	       group_free_bw(tunnel);
+}
+
+static int update_group_available_bw(struct drm_dp_tunnel *tunnel,
+				     const struct drm_dp_tunnel_regs *regs)
+{
+	struct drm_dp_tunnel *tunnel_iter;
+	int group_available_bw;
+	bool changed;
+
+	tunnel->estimated_bw = tunnel_reg(regs, DP_ESTIMATED_BW) * tunnel->bw_granularity;
+
+	if (calc_group_available_bw(tunnel) == tunnel->group->available_bw)
+		return 0;
+
+	for_each_tunnel_in_group(tunnel->group, tunnel_iter) {
+		int err;
+
+		if (tunnel_iter == tunnel)
+			continue;
+
+		if (check_tunnel(tunnel_iter) != 0 ||
+		    !tunnel_iter->bw_alloc_enabled)
+			continue;
+
+		err = drm_dp_dpcd_probe(tunnel_iter->aux, DP_DPCD_REV);
+		if (err) {
+			tun_dbg(tunnel_iter,
+				"Probe failed, assume disconnected (err %pe)\n",
+				ERR_PTR(err));
+			drm_dp_tunnel_set_io_error(tunnel_iter);
+		}
+	}
+
+	group_available_bw = calc_group_available_bw(tunnel);
+
+	tun_dbg(tunnel, "Updated group available BW: %d->%d\n",
+		DPTUN_BW_ARG(tunnel->group->available_bw),
+		DPTUN_BW_ARG(group_available_bw));
+
+	changed = tunnel->group->available_bw != group_available_bw;
+
+	tunnel->group->available_bw = group_available_bw;
+
+	return changed ? 1 : 0;
+}
+
+static int set_bw_alloc_mode(struct drm_dp_tunnel *tunnel, bool enable)
+{
+	u8 mask = DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE | DP_UNMASK_BW_ALLOCATION_IRQ;
+	u8 val;
+
+	if (drm_dp_dpcd_readb(tunnel->aux, DP_DPTX_BW_ALLOCATION_MODE_CONTROL, &val) < 0)
+		goto out_err;
+
+	if (enable)
+		val |= mask;
+	else
+		val &= ~mask;
+
+	if (drm_dp_dpcd_writeb(tunnel->aux, DP_DPTX_BW_ALLOCATION_MODE_CONTROL, val) < 0)
+		goto out_err;
+
+	tunnel->bw_alloc_enabled = enable;
+
+	return 0;
+
+out_err:
+	drm_dp_tunnel_set_io_error(tunnel);
+
+	return -EIO;
+}
+
+/**
+ * drm_dp_tunnel_enable_bw_alloc - Enable DP tunnel BW allocation mode
+ * @tunnel: Tunnel object
+ *
+ * Enable the DP tunnel BW allocation mode on @tunnel if it supports it.
+ *
+ * Returns 0 in case of success, negative error code otherwise.
+ */
+int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_regs regs;
+	int err;
+
+	err = check_tunnel(tunnel);
+	if (err)
+		return err;
+
+	if (!tunnel->bw_alloc_supported)
+		return -EOPNOTSUPP;
+
+	if (!tunnel_group_id(tunnel->group->drv_group_id))
+		return -EINVAL;
+
+	err = set_bw_alloc_mode(tunnel, true);
+	if (err)
+		goto out;
+
+	/*
+	 * After a BWA disable/re-enable sequence the allocated BW can either
+	 * stay at its last requested value or, for instance after system
+	 * suspend/resume, TBT CM can reset back the allocation to the amount
+	 * allocated in the legacy/non-BWA mode. Accordingly allow for the
+	 * allocation to change wrt. the last SW state.
+	 */
+	err = read_and_verify_tunnel_regs(tunnel, &regs,
+					  ALLOW_ALLOCATED_BW_CHANGE);
+	if (err) {
+		set_bw_alloc_mode(tunnel, false);
+
+		goto out;
+	}
+
+	if (!tunnel->max_dprx_rate)
+		update_dprx_caps(tunnel, &regs);
+
+	if (tunnel->group->available_bw == -1) {
+		err = update_group_available_bw(tunnel, &regs);
+		if (err > 0)
+			err = 0;
+	}
+out:
+	tun_dbg_stat(tunnel, err,
+		     "Enabling BW alloc mode: DPRX:%dx%d Group alloc:%d/%d Mb/s",
+		     tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
+		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
+		     DPTUN_BW_ARG(tunnel->group->available_bw));
+
+	return err;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_enable_bw_alloc);
+
+/**
+ * drm_dp_tunnel_disable_bw_alloc - Disable DP tunnel BW allocation mode
+ * @tunnel: Tunnel object
+ *
+ * Disable the DP tunnel BW allocation mode on @tunnel.
+ *
+ * Returns 0 in case of success, negative error code otherwise.
+ */
+int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	int err;
+
+	err = check_tunnel(tunnel);
+	if (err)
+		return err;
+
+	tunnel->allocated_bw = -1;
+
+	err = set_bw_alloc_mode(tunnel, false);
+
+	tun_dbg_stat(tunnel, err, "Disabling BW alloc mode");
+
+	return err;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_disable_bw_alloc);
+
+/**
+ * drm_dp_tunnel_bw_alloc_is_enabled - Query the BW allocation mode enabled state
+ * @tunnel: Tunnel object
+ *
+ * Query if the BW allocation mode is enabled for @tunnel.
+ *
+ * Returns %true if the BW allocation mode is enabled for @tunnel.
+ */
+bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel && tunnel->bw_alloc_enabled;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_bw_alloc_is_enabled);
+
+static int clear_bw_req_state(struct drm_dp_aux *aux)
+{
+	u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED;
+
+	if (drm_dp_dpcd_writeb(aux, DP_TUNNELING_STATUS, bw_req_mask) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int bw_req_complete(struct drm_dp_aux *aux, bool *status_changed)
+{
+	u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED;
+	u8 status_change_mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED;
+	u8 val;
+	int err;
+
+	if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
+		return -EIO;
+
+	*status_changed = val & status_change_mask;
+
+	val &= bw_req_mask;
+
+	if (!val)
+		return -EAGAIN;
+
+	err = clear_bw_req_state(aux);
+	if (err < 0)
+		return err;
+
+	return val == DP_BW_REQUEST_SUCCEEDED ? 0 : -ENOSPC;
+}
+
+static int allocate_tunnel_bw(struct drm_dp_tunnel *tunnel, int bw)
+{
+	struct drm_dp_tunnel_mgr *mgr = tunnel->group->mgr;
+	int request_bw = DIV_ROUND_UP(bw, tunnel->bw_granularity);
+	DEFINE_WAIT_FUNC(wait, woken_wake_function);
+	long timeout;
+	int err;
+
+	if (bw < 0) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (request_bw * tunnel->bw_granularity == tunnel->allocated_bw)
+		return 0;
+
+	/* Atomic check should prevent the following. */
+	if (drm_WARN_ON(mgr->dev, request_bw > MAX_DP_REQUEST_BW)) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	err = clear_bw_req_state(tunnel->aux);
+	if (err)
+		goto out;
+
+	if (drm_dp_dpcd_writeb(tunnel->aux, DP_REQUEST_BW, request_bw) < 0) {
+		err = -EIO;
+		goto out;
+	}
+
+	timeout = msecs_to_jiffies(3000);
+	add_wait_queue(&mgr->bw_req_queue, &wait);
+
+	for (;;) {
+		bool status_changed;
+
+		err = bw_req_complete(tunnel->aux, &status_changed);
+		if (err != -EAGAIN)
+			break;
+
+		if (status_changed) {
+			struct drm_dp_tunnel_regs regs;
+
+			err = read_and_verify_tunnel_regs(tunnel, &regs,
+							  ALLOW_ALLOCATED_BW_CHANGE);
+			if (err)
+				break;
+		}
+
+		if (!timeout) {
+			err = -ETIMEDOUT;
+			break;
+		}
+
+		timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE, timeout);
+	};
+
+	remove_wait_queue(&mgr->bw_req_queue, &wait);
+
+	if (err)
+		goto out;
+
+	tunnel->allocated_bw = request_bw * tunnel->bw_granularity;
+
+out:
+	tun_dbg_stat(tunnel, err, "Allocating %d/%d Mb/s for tunnel: Group alloc:%d/%d Mb/s",
+		     DPTUN_BW_ARG(request_bw * tunnel->bw_granularity),
+		     DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
+		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
+		     DPTUN_BW_ARG(tunnel->group->available_bw));
+
+	if (err == -EIO)
+		drm_dp_tunnel_set_io_error(tunnel);
+
+	return err;
+}
+
+/**
+ * drm_dp_tunnel_alloc_bw - Allocate BW for a DP tunnel
+ * @tunnel: Tunnel object
+ * @bw: BW in kB/s units
+ *
+ * Allocate @bw kB/s for @tunnel. The allocated BW must be freed after use by
+ * calling this function for the same tunnel setting @bw to 0.
+ *
+ * Returns 0 in case of success, a negative error code otherwise.
+ */
+int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
+{
+	int err;
+
+	err = check_tunnel(tunnel);
+	if (err)
+		return err;
+
+	return allocate_tunnel_bw(tunnel, bw);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_alloc_bw);
+
+/**
+ * drm_dp_tunnel_atomic_get_allocated_bw - Get the BW allocated for a DP tunnel
+ * @tunnel: Tunnel object
+ *
+ * Get the current BW allocated for @tunnel. After the tunnel is created /
+ * resumed and the BW allocation mode is enabled for it, the allocation
+ * becomes determined only after the first allocation request by the driver
+ * calling drm_dp_tunnel_alloc_bw().
+ *
+ * Return the BW allocated for the tunnel, or -1 if the allocation is
+ * undetermined.
+ */
+int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->allocated_bw;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_get_allocated_bw);
+
+/*
+ * Return 0 if the status hasn't changed, 1 if the status has changed, a
+ * negative error code in case of an I/O failure.
+ */
+static int check_and_clear_status_change(struct drm_dp_tunnel *tunnel)
+{
+	u8 mask = DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED;
+	u8 val;
+
+	if (drm_dp_dpcd_readb(tunnel->aux, DP_TUNNELING_STATUS, &val) < 0)
+		goto out_err;
+
+	val &= mask;
+
+	if (val) {
+		if (drm_dp_dpcd_writeb(tunnel->aux, DP_TUNNELING_STATUS, val) < 0)
+			goto out_err;
+
+		return 1;
+	}
+
+	if (!drm_dp_tunnel_bw_alloc_is_enabled(tunnel))
+		return 0;
+
+	/*
+	 * Check for estimated BW changes explicitly to account for lost
+	 * BW change notifications.
+	 */
+	if (drm_dp_dpcd_readb(tunnel->aux, DP_ESTIMATED_BW, &val) < 0)
+		goto out_err;
+
+	if (val * tunnel->bw_granularity != tunnel->estimated_bw)
+		return 1;
+
+	return 0;
+
+out_err:
+	drm_dp_tunnel_set_io_error(tunnel);
+
+	return -EIO;
+}
+
+/**
+ * drm_dp_tunnel_update_state - Update DP tunnel SW state with the HW state
+ * @tunnel: Tunnel object
+ *
+ * Update the SW state of @tunnel with the HW state.
+ *
+ * Returns 0 if the state has not changed, 1 if it has changed and got updated
+ * successfully and a negative error code otherwise.
+ */
+int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_regs regs;
+	bool changed = false;
+	int ret;
+
+	ret = check_tunnel(tunnel);
+	if (ret < 0)
+		return ret;
+
+	ret = check_and_clear_status_change(tunnel);
+	if (ret < 0)
+		goto out;
+
+	if (!ret)
+		return 0;
+
+	ret = read_and_verify_tunnel_regs(tunnel, &regs, 0);
+	if (ret)
+		goto out;
+
+	if (update_dprx_caps(tunnel, &regs))
+		changed = true;
+
+	ret = update_group_available_bw(tunnel, &regs);
+	if (ret == 1)
+		changed = true;
+
+out:
+	tun_dbg_stat(tunnel, ret < 0 ? ret : 0,
+		     "State update: Changed:%s DPRX:%dx%d Tunnel alloc:%d/%d Group alloc:%d/%d Mb/s",
+		     str_yes_no(changed),
+		     tunnel->max_dprx_rate / 100, tunnel->max_dprx_lane_count,
+		     DPTUN_BW_ARG(tunnel->allocated_bw),
+		     DPTUN_BW_ARG(get_max_tunnel_bw(tunnel)),
+		     DPTUN_BW_ARG(group_allocated_bw(tunnel->group)),
+		     DPTUN_BW_ARG(tunnel->group->available_bw));
+
+	if (ret < 0)
+		return ret;
+
+	if (changed)
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_update_state);
+
+/*
+ * drm_dp_tunnel_handle_irq - Handle DP tunnel IRQs
+ *
+ * Handle any pending DP tunnel IRQs, waking up waiters for a completion
+ * event.
+ *
+ * Returns 1 if the state of the tunnel has changed which requires calling
+ * drm_dp_tunnel_update_state(), a negative error code in case of a failure,
+ * 0 otherwise.
+ */
+int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_aux *aux)
+{
+	u8 val;
+
+	if (drm_dp_dpcd_readb(aux, DP_TUNNELING_STATUS, &val) < 0)
+		return -EIO;
+
+	if (val & (DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED))
+		wake_up_all(&mgr->bw_req_queue);
+
+	if (val & (DP_BW_ALLOCATION_CAPABILITY_CHANGED | DP_ESTIMATED_BW_CHANGED))
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_handle_irq);
+
+/**
+ * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's DPRX
+ * @tunnel: Tunnel object
+ *
+ * The function is used to query the maximum link rate of the DPRX connected
+ * to @tunnel. Note that this rate will not be limited by the BW limit of the
+ * tunnel, as opposed to the standard and extended DP_MAX_LINK_RATE DPCD
+ * registers.
+ *
+ * Returns the maximum link rate in 10 kbit/s units.
+ */
+int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->max_dprx_rate;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_rate);
+
+/**
+ * drm_dp_tunnel_max_dprx_lane_count - Query the maximum lane count of the tunnel's DPRX
+ * @tunnel: Tunnel object
+ *
+ * The function is used to query the maximum lane count of the DPRX connected
+ * to @tunnel. Note that this lane count will not be limited by the BW limit of
+ * the tunnel, as opposed to the standard and extended DP_MAX_LANE_COUNT DPCD
+ * registers.
+ *
+ * Returns the maximum lane count.
+ */
+int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->max_dprx_lane_count;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_max_dprx_lane_count);
+
+/**
+ * drm_dp_tunnel_available_bw - Query the estimated total available BW of the tunnel
+ * @tunnel: Tunnel object
+ *
+ * This function is used to query the estimated total available BW of the
+ * tunnel. This includes the currently allocated and free BW for all the
+ * tunnels in @tunnel's group. The available BW is valid only after the BW
+ * allocation mode has been enabled for the tunnel and its state got updated
+ * calling drm_dp_tunnel_update_state().
+ *
+ * Returns the @tunnel group's estimated total available bandwidth in kB/s
+ * units, or -1 if the available BW isn't valid (the BW allocation mode is
+ * not enabled or the tunnel's state hasn't been updated).
+ */
+int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return tunnel->group->available_bw;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_available_bw);
+
+static struct drm_dp_tunnel_group_state *
+drm_dp_tunnel_atomic_get_group_state(struct drm_atomic_state *state,
+				     const struct drm_dp_tunnel *tunnel)
+{
+	return (struct drm_dp_tunnel_group_state *)
+		drm_atomic_get_private_obj_state(state,
+						 &tunnel->group->base);
+}
+
+static struct drm_dp_tunnel_state *
+add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
+		 struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	tun_dbg_atomic(tunnel,
+		       "Adding state for tunnel %p to group state %p\n",
+		       tunnel, group_state);
+
+	tunnel_state = kzalloc(sizeof(*tunnel_state), GFP_KERNEL);
+	if (!tunnel_state)
+		return NULL;
+
+	tunnel_state->group_state = group_state;
+
+	drm_dp_tunnel_ref_get(tunnel, &tunnel_state->tunnel_ref);
+
+	INIT_LIST_HEAD(&tunnel_state->node);
+	list_add(&tunnel_state->node, &group_state->tunnel_states);
+
+	return tunnel_state;
+}
+
+static void free_tunnel_state(struct drm_dp_tunnel_state *tunnel_state)
+{
+	tun_dbg_atomic(tunnel_state->tunnel_ref.tunnel,
+		       "Freeing state for tunnel %p\n",
+		       tunnel_state->tunnel_ref.tunnel);
+
+	list_del(&tunnel_state->node);
+
+	kfree(tunnel_state->stream_bw);
+	drm_dp_tunnel_ref_put(&tunnel_state->tunnel_ref);
+
+	kfree(tunnel_state);
+}
+
+static void free_group_state(struct drm_dp_tunnel_group_state *group_state)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+	struct drm_dp_tunnel_state *tunnel_state_tmp;
+
+	for_each_tunnel_state_safe(group_state, tunnel_state, tunnel_state_tmp)
+		free_tunnel_state(tunnel_state);
+
+	kfree(group_state);
+}
+
+static struct drm_dp_tunnel_state *
+get_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
+		 const struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	for_each_tunnel_state(group_state, tunnel_state)
+		if (tunnel_state->tunnel_ref.tunnel == tunnel)
+			return tunnel_state;
+
+	return NULL;
+}
+
+static struct drm_dp_tunnel_state *
+get_or_add_tunnel_state(struct drm_dp_tunnel_group_state *group_state,
+			struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	tunnel_state = get_tunnel_state(group_state, tunnel);
+	if (tunnel_state)
+		return tunnel_state;
+
+	return add_tunnel_state(group_state, tunnel);
+}
+
+static struct drm_private_state *
+tunnel_group_duplicate_state(struct drm_private_obj *obj)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
+	if (!group_state)
+		return NULL;
+
+	INIT_LIST_HEAD(&group_state->tunnel_states);
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &group_state->base);
+
+	for_each_tunnel_state(to_group_state(obj->state), tunnel_state) {
+		struct drm_dp_tunnel_state *new_tunnel_state;
+
+		new_tunnel_state = get_or_add_tunnel_state(group_state,
+							   tunnel_state->tunnel_ref.tunnel);
+		if (!new_tunnel_state)
+			goto out_free_state;
+
+		new_tunnel_state->stream_mask = tunnel_state->stream_mask;
+		new_tunnel_state->stream_bw = kmemdup(tunnel_state->stream_bw,
+						      sizeof(*tunnel_state->stream_bw) *
+							hweight32(tunnel_state->stream_mask),
+						      GFP_KERNEL);
+
+		if (!new_tunnel_state->stream_bw)
+			goto out_free_state;
+	}
+
+	return &group_state->base;
+
+out_free_state:
+	free_group_state(group_state);
+
+	return NULL;
+}
+
+static void tunnel_group_destroy_state(struct drm_private_obj *obj, struct drm_private_state *state)
+{
+	free_group_state(to_group_state(state));
+}
+
+static const struct drm_private_state_funcs tunnel_group_funcs = {
+	.atomic_duplicate_state = tunnel_group_duplicate_state,
+	.atomic_destroy_state = tunnel_group_destroy_state,
+};
+
+/**
+ * drm_dp_tunnel_atomic_get_state - get/allocate the new atomic state for a tunnel
+ * @state: Atomic state
+ * @tunnel: Tunnel to get the state for
+ *
+ * Get the new atomic state for @tunnel, duplicating it from the old tunnel
+ * state if not yet allocated.
+ *
+ * Return the state or an ERR_PTR() error on failure.
+ */
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
+			       struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
+	if (IS_ERR(group_state))
+		return ERR_CAST(group_state);
+
+	tunnel_state = get_or_add_tunnel_state(group_state, tunnel);
+	if (!tunnel_state)
+		return ERR_PTR(-ENOMEM);
+
+	return tunnel_state;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_state);
+
+/**
+ * drm_dp_tunnel_atomic_get_old_state - get the old atomic state for a tunnel
+ * @state: Atomic state
+ * @tunnel: Tunnel to get the state for
+ *
+ * Get the old atomic state for @tunnel.
+ *
+ * Return the old state or NULL if the tunnel's atomic state is not in @state.
+ */
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group_state *old_group_state;
+	int i;
+
+	for_each_old_group_in_state(state, old_group_state, i)
+		if (to_group(old_group_state->base.obj) == tunnel->group)
+			return get_tunnel_state(old_group_state, tunnel);
+
+	return NULL;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_old_state);
+
+/**
+ * drm_dp_tunnel_atomic_get_new_state - get the new atomic state for a tunnel
+ * @state: Atomic state
+ * @tunnel: Tunnel to get the state for
+ *
+ * Get the new atomic state for @tunnel.
+ *
+ * Return the new state or NULL if the tunnel's atomic state is not in @state.
+ */
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel)
+{
+	struct drm_dp_tunnel_group_state *new_group_state;
+	int i;
+
+	for_each_new_group_in_state(state, new_group_state, i)
+		if (to_group(new_group_state->base.obj) == tunnel->group)
+			return get_tunnel_state(new_group_state, tunnel);
+
+	return NULL;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_new_state);
+
+static bool init_group(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_tunnel_group *group)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+
+	group_state = kzalloc(sizeof(*group_state), GFP_KERNEL);
+	if (!group_state)
+		return false;
+
+	INIT_LIST_HEAD(&group_state->tunnel_states);
+
+	group->mgr = mgr;
+	group->available_bw = -1;
+	INIT_LIST_HEAD(&group->tunnels);
+
+	drm_atomic_private_obj_init(mgr->dev, &group->base, &group_state->base,
+				    &tunnel_group_funcs);
+
+	return true;
+}
+
+static void cleanup_group(struct drm_dp_tunnel_group *group)
+{
+	drm_atomic_private_obj_fini(&group->base);
+}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state *group_state)
+{
+	const struct drm_dp_tunnel_state *tunnel_state;
+	u32 stream_mask = 0;
+
+	for_each_tunnel_state(group_state, tunnel_state) {
+		drm_WARN(to_group(group_state->base.obj)->mgr->dev,
+			 tunnel_state->stream_mask & stream_mask,
+			 "[DPTUN %s]: conflicting stream IDs %x (IDs in other tunnels %x)\n",
+			 tunnel_state->tunnel_ref.tunnel->name,
+			 tunnel_state->stream_mask,
+			 stream_mask);
+
+		stream_mask |= tunnel_state->stream_mask;
+	}
+}
+#else
+static void check_unique_stream_ids(const struct drm_dp_tunnel_group_state *group_state)
+{
+}
+#endif
+
+static int stream_id_to_idx(u32 stream_mask, u8 stream_id)
+{
+	return hweight32(stream_mask & (BIT(stream_id) - 1));
+}
+
+static int resize_bw_array(struct drm_dp_tunnel_state *tunnel_state,
+			   unsigned long old_mask, unsigned long new_mask)
+{
+	unsigned long move_mask = old_mask & new_mask;
+	int *new_bws = NULL;
+	int id;
+
+	WARN_ON(!new_mask);
+
+	if (old_mask == new_mask)
+		return 0;
+
+	new_bws = kcalloc(hweight32(new_mask), sizeof(*new_bws), GFP_KERNEL);
+	if (!new_bws)
+		return -ENOMEM;
+
+	for_each_set_bit(id, &move_mask, BITS_PER_TYPE(move_mask))
+		new_bws[stream_id_to_idx(new_mask, id)] =
+			tunnel_state->stream_bw[stream_id_to_idx(old_mask, id)];
+
+	kfree(tunnel_state->stream_bw);
+	tunnel_state->stream_bw = new_bws;
+	tunnel_state->stream_mask = new_mask;
+
+	return 0;
+}
+
+static int set_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
+			 u8 stream_id, int bw)
+{
+	int err;
+
+	err = resize_bw_array(tunnel_state,
+			      tunnel_state->stream_mask,
+			      tunnel_state->stream_mask | BIT(stream_id));
+	if (err)
+		return err;
+
+	tunnel_state->stream_bw[stream_id_to_idx(tunnel_state->stream_mask, stream_id)] = bw;
+
+	return 0;
+}
+
+static int clear_stream_bw(struct drm_dp_tunnel_state *tunnel_state,
+			   u8 stream_id)
+{
+	if (!(tunnel_state->stream_mask & ~BIT(stream_id))) {
+		free_tunnel_state(tunnel_state);
+		return 0;
+	}
+
+	return resize_bw_array(tunnel_state,
+			       tunnel_state->stream_mask,
+			       tunnel_state->stream_mask & ~BIT(stream_id));
+}
+
+/**
+ * drm_dp_tunnel_atomic_set_stream_bw - Set the BW for a DP tunnel stream
+ * @state: Atomic state
+ * @tunnel: DP tunnel containing the stream
+ * @stream_id: Stream ID
+ * @bw: BW of the stream
+ *
+ * Set a DP tunnel stream's required BW in the atomic state.
+ *
+ * Returns 0 in case of success, a negative error code otherwise.
+ */
+int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
+				       struct drm_dp_tunnel *tunnel,
+				       u8 stream_id, int bw)
+{
+	struct drm_dp_tunnel_group_state *new_group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+	int err;
+
+	if (drm_WARN_ON(tunnel->group->mgr->dev,
+			stream_id > BITS_PER_TYPE(tunnel_state->stream_mask)))
+		return -EINVAL;
+
+	tun_dbg(tunnel,
+		"Setting %d Mb/s for stream %d\n",
+		DPTUN_BW_ARG(bw), stream_id);
+
+	new_group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
+	if (IS_ERR(new_group_state))
+		return PTR_ERR(new_group_state);
+
+	if (bw == 0) {
+		tunnel_state = get_tunnel_state(new_group_state, tunnel);
+		if (!tunnel_state)
+			return 0;
+
+		return clear_stream_bw(tunnel_state, stream_id);
+	}
+
+	tunnel_state = get_or_add_tunnel_state(new_group_state, tunnel);
+	if (drm_WARN_ON(state->dev, !tunnel_state))
+		return -EINVAL;
+
+	err = set_stream_bw(tunnel_state, stream_id, bw);
+	if (err)
+		return err;
+
+	check_unique_stream_ids(new_group_state);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_set_stream_bw);
+
+/**
+ * drm_dp_tunnel_atomic_get_required_bw - Get the BW required by a DP tunnel
+ * @tunnel_state: Atomic state of the queried tunnel
+ *
+ * Calculate the BW required by a tunnel adding up the required BW of all
+ * the streams in the tunnel.
+ *
+ * Return the total BW required by the tunnel.
+ */
+int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state *tunnel_state)
+{
+	int tunnel_bw = 0;
+	int i;
+
+	if (!tunnel_state || !tunnel_state->stream_mask)
+		return 0;
+
+	for (i = 0; i < hweight32(tunnel_state->stream_mask); i++)
+		tunnel_bw += tunnel_state->stream_bw[i];
+
+	return tunnel_bw;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_required_bw);
+
+/**
+ * drm_dp_tunnel_atomic_get_group_streams_in_state - Get mask of stream IDs in a group
+ * @state: Atomic state
+ * @tunnel: Tunnel object
+ * @stream_mask: Mask of streams in @tunnel's group
+ *
+ * Get the mask of all the stream IDs in the tunnel group of @tunnel.
+ *
+ * Return 0 in case of success - with the stream IDs in @stream_mask - or a
+ * negative error code in case of failure.
+ */
+int drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state *state,
+						    const struct drm_dp_tunnel *tunnel,
+						    u32 *stream_mask)
+{
+	struct drm_dp_tunnel_group_state *group_state;
+	struct drm_dp_tunnel_state *tunnel_state;
+
+	group_state = drm_dp_tunnel_atomic_get_group_state(state, tunnel);
+	if (IS_ERR(group_state))
+		return PTR_ERR(group_state);
+
+	*stream_mask = 0;
+	for_each_tunnel_state(group_state, tunnel_state)
+		*stream_mask |= tunnel_state->stream_mask;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_get_group_streams_in_state);
+
+static int
+drm_dp_tunnel_atomic_check_group_bw(struct drm_dp_tunnel_group_state *new_group_state,
+				    u32 *failed_stream_mask)
+{
+	struct drm_dp_tunnel_group *group = to_group(new_group_state->base.obj);
+	struct drm_dp_tunnel_state *new_tunnel_state;
+	u32 group_stream_mask = 0;
+	int group_bw = 0;
+
+	for_each_tunnel_state(new_group_state, new_tunnel_state) {
+		struct drm_dp_tunnel *tunnel = new_tunnel_state->tunnel_ref.tunnel;
+		int max_dprx_bw = get_max_dprx_bw(tunnel);
+		int tunnel_bw = drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
+
+		tun_dbg(tunnel,
+			"%sRequired %d/%d Mb/s total for tunnel.\n",
+			tunnel_bw > max_dprx_bw ? "Not enough BW: " : "",
+			DPTUN_BW_ARG(tunnel_bw),
+			DPTUN_BW_ARG(max_dprx_bw));
+
+		if (tunnel_bw > max_dprx_bw) {
+			*failed_stream_mask = new_tunnel_state->stream_mask;
+			return -ENOSPC;
+		}
+
+		group_bw += min(roundup(tunnel_bw, tunnel->bw_granularity),
+				max_dprx_bw);
+		group_stream_mask |= new_tunnel_state->stream_mask;
+	}
+
+	tun_grp_dbg(group,
+		    "%sRequired %d/%d Mb/s total for tunnel group.\n",
+		    group_bw > group->available_bw ? "Not enough BW: " : "",
+		    DPTUN_BW_ARG(group_bw),
+		    DPTUN_BW_ARG(group->available_bw));
+
+	if (group_bw > group->available_bw) {
+		*failed_stream_mask = group_stream_mask;
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+
+/**
+ * drm_dp_tunnel_atomic_check_stream_bws - Check BW limit for all streams in state
+ * @state: Atomic state
+ * @failed_stream_mask: Mask of stream IDs with a BW limit failure
+ *
+ * Check the required BW of each DP tunnel in @state against both the DPRX BW
+ * limit of the tunnel and the BW limit of the tunnel group. Return a mask of
+ * stream IDs in @failed_stream_mask once a check fails. The mask will contain
+ * either all the streams in a tunnel (in case a DPRX BW limit check failed) or
+ * all the streams in a tunnel group (in case a group BW limit check failed).
+ *
+ * Return 0 if all the BW limit checks passed, -ENOSPC in case a BW limit
+ * check failed - with @failed_stream_mask containing the streams failing the
+ * check - or a negative error code otherwise.
+ */
+int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
+					  u32 *failed_stream_mask)
+{
+	struct drm_dp_tunnel_group_state *new_group_state;
+	int i;
+
+	for_each_new_group_in_state(state, new_group_state, i) {
+		int ret;
+
+		ret = drm_dp_tunnel_atomic_check_group_bw(new_group_state,
+							  failed_stream_mask);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_atomic_check_stream_bws);
+
+static void destroy_mgr(struct drm_dp_tunnel_mgr *mgr)
+{
+	int i;
+
+	for (i = 0; i < mgr->group_count; i++) {
+		cleanup_group(&mgr->groups[i]);
+		drm_WARN_ON(mgr->dev, !list_empty(&mgr->groups[i].tunnels));
+	}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	ref_tracker_dir_exit(&mgr->ref_tracker);
+#endif
+
+	kfree(mgr->groups);
+	kfree(mgr);
+}
+
+/**
+ * drm_dp_tunnel_mgr_create - Create a DP tunnel manager
+ * @dev: DRM device object
+ *
+ * Creates a DP tunnel manager for @dev.
+ *
+ * Returns a pointer to the tunnel manager if created successfully or NULL in
+ * case of an error.
+ */
+struct drm_dp_tunnel_mgr *
+drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
+{
+	struct drm_dp_tunnel_mgr *mgr;
+	int i;
+
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+	if (!mgr)
+		return NULL;
+
+	mgr->dev = dev;
+	init_waitqueue_head(&mgr->bw_req_queue);
+
+	mgr->groups = kcalloc(max_group_count, sizeof(*mgr->groups), GFP_KERNEL);
+	if (!mgr->groups) {
+		kfree(mgr);
+
+		return NULL;
+	}
+
+#ifdef CONFIG_DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE
+	ref_tracker_dir_init(&mgr->ref_tracker, 16, "dptun");
+#endif
+
+	for (i = 0; i < max_group_count; i++) {
+		if (!init_group(mgr, &mgr->groups[i])) {
+			destroy_mgr(mgr);
+
+			return NULL;
+		}
+
+		mgr->group_count++;
+	}
+
+	return mgr;
+}
+EXPORT_SYMBOL(drm_dp_tunnel_mgr_create);
+
+/**
+ * drm_dp_tunnel_mgr_destroy - Destroy DP tunnel manager
+ * @mgr: Tunnel manager object
+ *
+ * Destroy the tunnel manager.
+ */
+void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr)
+{
+	destroy_mgr(mgr);
+}
+EXPORT_SYMBOL(drm_dp_tunnel_mgr_destroy);
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 281afff6ee4e5..8bfd5d007be8d 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1382,6 +1382,66 @@
 #define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET	0x69494
 #define DP_HDCP_2_2_REG_DBG_OFFSET		0x69518
 
+/* DP-tunneling */
+#define DP_TUNNELING_OUI				0xe0000
+#define  DP_TUNNELING_OUI_BYTES				3
+
+#define DP_TUNNELING_DEV_ID				0xe0003
+#define  DP_TUNNELING_DEV_ID_BYTES			6
+
+#define DP_TUNNELING_HW_REV				0xe0009
+#define  DP_TUNNELING_HW_REV_MAJOR_SHIFT		4
+#define  DP_TUNNELING_HW_REV_MAJOR_MASK			(0xf << DP_TUNNELING_HW_REV_MAJOR_SHIFT)
+#define  DP_TUNNELING_HW_REV_MINOR_SHIFT		0
+#define  DP_TUNNELING_HW_REV_MINOR_MASK			(0xf << DP_TUNNELING_HW_REV_MINOR_SHIFT)
+
+#define DP_TUNNELING_SW_REV_MAJOR			0xe000a
+#define DP_TUNNELING_SW_REV_MINOR			0xe000b
+
+#define DP_TUNNELING_CAPABILITIES			0xe000d
+#define  DP_IN_BW_ALLOCATION_MODE_SUPPORT		(1 << 7)
+#define  DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT		(1 << 6)
+#define  DP_TUNNELING_SUPPORT				(1 << 0)
+
+#define DP_IN_ADAPTER_INFO				0xe000e
+#define  DP_IN_ADAPTER_NUMBER_BITS			7
+#define  DP_IN_ADAPTER_NUMBER_MASK			((1 << DP_IN_ADAPTER_NUMBER_BITS) - 1)
+
+#define DP_USB4_DRIVER_ID				0xe000f
+#define  DP_USB4_DRIVER_ID_BITS				4
+#define  DP_USB4_DRIVER_ID_MASK				((1 << DP_USB4_DRIVER_ID_BITS) - 1)
+
+#define DP_USB4_DRIVER_BW_CAPABILITY			0xe0020
+#define  DP_USB4_DRIVER_BW_ALLOCATION_MODE_SUPPORT	(1 << 7)
+
+#define DP_IN_ADAPTER_TUNNEL_INFORMATION		0xe0021
+#define  DP_GROUP_ID_BITS				3
+#define  DP_GROUP_ID_MASK				((1 << DP_GROUP_ID_BITS) - 1)
+
+#define DP_BW_GRANULARITY				0xe0022
+#define  DP_BW_GRANULARITY_MASK				0x3
+
+#define DP_ESTIMATED_BW					0xe0023
+#define DP_ALLOCATED_BW					0xe0024
+
+#define DP_TUNNELING_STATUS				0xe0025
+#define  DP_BW_ALLOCATION_CAPABILITY_CHANGED		(1 << 3)
+#define  DP_ESTIMATED_BW_CHANGED			(1 << 2)
+#define  DP_BW_REQUEST_SUCCEEDED			(1 << 1)
+#define  DP_BW_REQUEST_FAILED				(1 << 0)
+
+#define DP_TUNNELING_MAX_LINK_RATE			0xe0028
+
+#define DP_TUNNELING_MAX_LANE_COUNT			0xe0029
+#define  DP_TUNNELING_MAX_LANE_COUNT_MASK		0x1f
+
+#define DP_DPTX_BW_ALLOCATION_MODE_CONTROL		0xe0030
+#define  DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE	(1 << 7)
+#define  DP_UNMASK_BW_ALLOCATION_IRQ			(1 << 6)
+
+#define DP_REQUEST_BW					0xe0031
+#define  MAX_DP_REQUEST_BW				255
+
 /* LTTPR: Link Training (LT)-tunable PHY Repeaters */
 #define DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV 0xf0000 /* 1.3 */
 #define DP_MAX_LINK_RATE_PHY_REPEATER			    0xf0001 /* 1.4a */
diff --git a/include/drm/display/drm_dp_tunnel.h b/include/drm/display/drm_dp_tunnel.h
new file mode 100644
index 0000000000000..69267d2f7980f
--- /dev/null
+++ b/include/drm/display/drm_dp_tunnel.h
@@ -0,0 +1,249 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __DRM_DP_TUNNEL_H__
+#define __DRM_DP_TUNNEL_H__
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct drm_dp_aux;
+
+struct drm_device;
+
+struct drm_atomic_state;
+struct drm_dp_tunnel_mgr;
+struct drm_dp_tunnel_state;
+
+struct ref_tracker;
+
+struct drm_dp_tunnel_ref {
+	struct drm_dp_tunnel *tunnel;
+	struct ref_tracker *tracker;
+};
+
+#ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL
+
+struct drm_dp_tunnel *
+drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker);
+
+void
+drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker);
+
+static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
+					 struct drm_dp_tunnel_ref *tunnel_ref)
+{
+	tunnel_ref->tunnel = drm_dp_tunnel_get(tunnel, &tunnel_ref->tracker);
+}
+
+static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref)
+{
+	drm_dp_tunnel_put(tunnel_ref->tunnel, &tunnel_ref->tracker);
+	tunnel_ref->tunnel = NULL;
+}
+
+struct drm_dp_tunnel *
+drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
+		     struct drm_dp_aux *aux);
+int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel);
+
+int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel);
+bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw);
+int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel);
+
+void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel);
+
+int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
+			     struct drm_dp_aux *aux);
+
+int drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel);
+int drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel);
+
+const char *drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel);
+
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
+			       struct drm_dp_tunnel *tunnel);
+
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_old_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel);
+
+struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel);
+
+int drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
+				       struct drm_dp_tunnel *tunnel,
+				       u8 stream_id, int bw);
+int drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state *state,
+						    const struct drm_dp_tunnel *tunnel,
+						    u32 *stream_mask);
+
+int drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
+					  u32 *failed_stream_mask);
+
+int drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state *tunnel_state);
+
+struct drm_dp_tunnel_mgr *
+drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count);
+void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr);
+
+#else
+
+static inline struct drm_dp_tunnel *
+drm_dp_tunnel_get(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker)
+{
+	return NULL;
+}
+
+static inline void
+drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel, struct ref_tracker **tracker) {}
+
+static inline void drm_dp_tunnel_ref_get(struct drm_dp_tunnel *tunnel,
+					 struct drm_dp_tunnel_ref *tunnel_ref) {}
+
+static inline void drm_dp_tunnel_ref_put(struct drm_dp_tunnel_ref *tunnel_ref) {}
+
+static inline struct drm_dp_tunnel *
+drm_dp_tunnel_detect(struct drm_dp_tunnel_mgr *mgr,
+		     struct drm_dp_aux *aux)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int
+drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel)
+{
+	return 0;
+}
+
+static inline int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel)
+{
+	return false;
+}
+
+static inline int
+drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel)
+{
+	return -1;
+}
+
+static inline int
+drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void drm_dp_tunnel_set_io_error(struct drm_dp_tunnel *tunnel) {}
+
+static inline int
+drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr,
+			 struct drm_dp_aux *aux)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_max_dprx_rate(const struct drm_dp_tunnel *tunnel)
+{
+	return 0;
+}
+
+static inline int
+drm_dp_tunnel_max_dprx_lane_count(const struct drm_dp_tunnel *tunnel)
+{
+	return 0;
+}
+
+static inline int
+drm_dp_tunnel_available_bw(const struct drm_dp_tunnel *tunnel)
+{
+	return -1;
+}
+
+static inline const char *
+drm_dp_tunnel_name(const struct drm_dp_tunnel *tunnel)
+{
+	return NULL;
+}
+
+static inline struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_state(struct drm_atomic_state *state,
+			       struct drm_dp_tunnel *tunnel)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline struct drm_dp_tunnel_state *
+drm_dp_tunnel_atomic_get_new_state(struct drm_atomic_state *state,
+				   const struct drm_dp_tunnel *tunnel)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int
+drm_dp_tunnel_atomic_set_stream_bw(struct drm_atomic_state *state,
+				   struct drm_dp_tunnel *tunnel,
+				   u8 stream_id, int bw)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_atomic_get_group_streams_in_state(struct drm_atomic_state *state,
+						const struct drm_dp_tunnel *tunnel,
+						u32 *stream_mask)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_atomic_check_stream_bws(struct drm_atomic_state *state,
+				      u32 *failed_stream_mask)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+drm_dp_tunnel_atomic_get_required_bw(const struct drm_dp_tunnel_state *tunnel_state)
+{
+	return 0;
+}
+
+static inline struct drm_dp_tunnel_mgr *
+drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline
+void drm_dp_tunnel_mgr_destroy(struct drm_dp_tunnel_mgr *mgr) {}
+
+
+#endif /* CONFIG_DRM_DISPLAY_DP_TUNNEL */
+
+#endif /* __DRM_DP_TUNNEL_H__ */
-- 
2.39.2


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

* [PATCH v3 11/21] drm/i915/dp: Sync instead of try-sync commits when getting active pipes
  2024-02-20 21:18 ` [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits Imre Deak
  2024-02-23  8:10   ` Shankar, Uma
  2024-02-23 21:11   ` Ville Syrjälä
@ 2024-02-26 18:52   ` Imre Deak
  2 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-26 18:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ville Syrjälä, Uma Shankar

Sync instead of only try-sync non-blocking commits when getting the
active pipes through a given DP port. Atm intel_dp_get_active_pipes()
will only try to sync a given pipe and if that would block ignore the
pipe. This was supposed to avoid link retraining in case a pending
modeset would do that anyway, however that could incorrectly ignore
fastset pipes as well for instance (which don't retraing the link).
The TC port reset path needs to handle all pipes, even if a waiting for
a pending commit would block. To account for the above cases sync all
the pipes unconditionally.

This also prepares for a follow-up change enabling the DP tunnel BW
allocation mode which needs to ensure that all active pipes are synced
and returned from intel_dp_get_active_pipes().

v2:
- Add a separate function to try-sync the pipes. (Ville)
v3:
- Just sync the pipes unconditionally in intel_dp_get_active_pipes().
  (Ville)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com> (v2)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index ebf5a6a344a40..b49dc3836b29b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4980,9 +4980,10 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
 		if (!crtc_state->hw.active)
 			continue;
 
-		if (conn_state->commit &&
-		    !try_wait_for_completion(&conn_state->commit->hw_done))
-			continue;
+		if (conn_state->commit)
+			drm_WARN_ON(&i915->drm,
+				    !wait_for_completion_timeout(&conn_state->commit->hw_done,
+								 msecs_to_jiffies(5000)));
 
 		*pipe_mask |= BIT(crtc->pipe);
 	}
-- 
2.39.2


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

* [PATCH v3 12/21] drm/i915/dp: Add support for DP tunnel BW allocation
  2024-02-20 21:18 ` [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation Imre Deak
  2024-02-23 21:37   ` Ville Syrjälä
  2024-02-26 10:47   ` Shankar, Uma
@ 2024-02-26 18:52   ` Imre Deak
  2 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-26 18:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ville Syrjälä, Uma Shankar

Add support to enable the DP tunnel BW allocation mode. Follow-up
patches will call the required helpers added here to prepare for a
modeset on a link with DP tunnels, the last change in the patchset
actually enabling BWA.

With BWA enabled, the driver will expose the full mode list a display
supports, regardless of any BW limitation on a shared (Thunderbolt)
link. Such BW limits will be checked against only during a modeset, when
the driver has the full knowledge of each display's BW requirement.

If the link BW changes in a way that a connector's modelist may also
change, userspace will get a hotplug notification for all the connectors
sharing the same link (so it can adjust the mode used for a display).

The BW limitation can change at any point, asynchronously to modesets
on a given connector, so a modeset can fail even though the atomic check
for it passed. In such scenarios userspace will get a bad link
notification and in response is supposed to retry the modeset.

v2:
- Fix old vs. new connector state in intel_dp_tunnel_atomic_check_state().
  (Ville)
- Fix propagating the error from
  intel_dp_tunnel_atomic_compute_stream_bw(). (Ville)
- Move tunnel==NULL checks from driver to DRM core helpers. (Ville)
- Simplify return flow from intel_dp_tunnel_detect(). (Ville)
- s/dp_tunnel_state/inherited_dp_tunnels (Ville)
- Simplify struct intel_dp_tunnel_inherited_state. (Ville)
- Unconstify object pointers (vs. states) where possible. (Ville)
- Init crtc_state while declaring it in check_group_state(). (Ville)
- Join obj->base.id, obj->name arg lines in debug prints to reduce LOC.
  (Ville)
- Add/rework intel_dp_tunnel_atomic_alloc_bw() to prepare for moving the
  BW allocation from encoder hooks up to intel_atomic_commit_tail()
  later in the patchset.
- Disable BW alloc mode during system suspend.
- Allocate the required BW for all tunnels during system resume.
- Add intel_dp_tunnel_atomic_clear_stream_bw() instead of the open-coded
  sequence in a follow-up patch.
- Add function documentation to all exported functions.
- Add CONFIG_USB4 dependency to CONFIG_DRM_I915_DP_TUNNEL.

v3:
- Rebase on intel_dp_get_active_pipes() change in previous patch.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/Kconfig                  |  14 +
 drivers/gpu/drm/i915/Kconfig.debug            |   1 +
 drivers/gpu/drm/i915/Makefile                 |   3 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |   2 +
 .../gpu/drm/i915/display/intel_display_core.h |   1 +
 .../drm/i915/display/intel_display_types.h    |   9 +
 .../gpu/drm/i915/display/intel_dp_tunnel.c    | 811 ++++++++++++++++++
 .../gpu/drm/i915/display/intel_dp_tunnel.h    | 133 +++
 8 files changed, 974 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 3089029abba48..5932024f8f954 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -155,6 +155,20 @@ config DRM_I915_PXP
 	  protected session and manage the status of the alive software session,
 	  as well as its life cycle.
 
+config DRM_I915_DP_TUNNEL
+	bool "Enable DP tunnel support"
+	depends on DRM_I915
+	depends on USB4
+	select DRM_DISPLAY_DP_TUNNEL
+	default y
+	help
+	  Choose this option to detect DP tunnels and enable the Bandwidth
+	  Allocation mode for such tunnels. This allows using the maximum
+	  resolution allowed by the link BW on all displays sharing the
+	  link BW, for instance on a Thunderbolt link.
+
+	  If in doubt, say "Y".
+
 menu "drm/i915 Debugging"
 depends on DRM_I915
 depends on EXPERT
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 5b7162076850c..bc18e2d9ea05d 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -28,6 +28,7 @@ config DRM_I915_DEBUG
 	select STACKDEPOT
 	select STACKTRACE
 	select DRM_DP_AUX_CHARDEV
+	select DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE if DRM_I915_DP_TUNNEL
 	select X86_MSR # used by igt/pm_rpm
 	select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
 	select DRM_DEBUG_MM if DRM=y
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c13f14edb5088..3ef6ed41e62b4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -369,6 +369,9 @@ i915-y += \
 	display/vlv_dsi.o \
 	display/vlv_dsi_pll.o
 
+i915-$(CONFIG_DRM_I915_DP_TUNNEL) += \
+	display/intel_dp_tunnel.o
+
 i915-y += \
 	i915_perf.o
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index ec0d5168b5035..96ab37e158995 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -29,6 +29,7 @@
  * See intel_atomic_plane.c for the plane-specific atomic functionality.
  */
 
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_fourcc.h>
@@ -38,6 +39,7 @@
 #include "intel_atomic.h"
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
+#include "intel_dp_tunnel.h"
 #include "intel_global_state.h"
 #include "intel_hdcp.h"
 #include "intel_psr.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index fdeaac994e17b..2167dbee5eea7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -524,6 +524,7 @@ struct intel_display {
 	} wq;
 
 	/* Grouping using named structs. Keep sorted. */
+	struct drm_dp_tunnel_mgr *dp_tunnel_mgr;
 	struct intel_audio audio;
 	struct intel_dpll dpll;
 	struct intel_fbc *fbc[I915_MAX_FBCS];
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 8ce986fadd9aa..860e867586f48 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -33,6 +33,7 @@
 
 #include <drm/display/drm_dp_dual_mode_helper.h>
 #include <drm/display/drm_dp_mst_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/display/drm_dsc.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_crtc.h>
@@ -682,6 +683,8 @@ struct intel_atomic_state {
 
 	struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
 
+	struct intel_dp_tunnel_inherited_state *inherited_dp_tunnels;
+
 	/*
 	 * Current watermarks can't be trusted during hardware readout, so
 	 * don't bother calculating intermediate watermarks.
@@ -1379,6 +1382,9 @@ struct intel_crtc_state {
 		struct drm_dsc_config config;
 	} dsc;
 
+	/* DP tunnel used for BW allocation. */
+	struct drm_dp_tunnel_ref dp_tunnel_ref;
+
 	/* HSW+ linetime watermarks */
 	u16 linetime;
 	u16 ips_linetime;
@@ -1789,6 +1795,9 @@ struct intel_dp {
 	/* connector directly attached - won't be use for modeset in mst world */
 	struct intel_connector *attached_connector;
 
+	struct drm_dp_tunnel *tunnel;
+	bool tunnel_suspended:1;
+
 	/* mst connector list */
 	struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
 	struct drm_dp_mst_topology_mgr mst_mgr;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
new file mode 100644
index 0000000000000..2f144aefb89f4
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
@@ -0,0 +1,811 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include "i915_drv.h"
+
+#include <drm/display/drm_dp_tunnel.h>
+
+#include "intel_atomic.h"
+#include "intel_display_limits.h"
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_dp_link_training.h"
+#include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
+#include "intel_link_bw.h"
+
+struct intel_dp_tunnel_inherited_state {
+	struct drm_dp_tunnel_ref ref[I915_MAX_PIPES];
+};
+
+/**
+ * intel_dp_tunnel_disconnect - Disconnect a DP tunnel from a port
+ * @intel_dp: DP port object the tunnel is connected to
+ *
+ * Disconnect a DP tunnel from @intel_dp, destroying any related state. This
+ * should be called after detecting a sink-disconnect event from the port.
+ */
+void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp)
+{
+	drm_dp_tunnel_destroy(intel_dp->tunnel);
+	intel_dp->tunnel = NULL;
+}
+
+/**
+ * intel_dp_tunnel_destroy - Destroy a DP tunnel
+ * @intel_dp: DP port object the tunnel is connected to
+ *
+ * Destroy a DP tunnel connected to @intel_dp, after disabling the BW
+ * allocation mode on the tunnel. This should be called while destroying the
+ * port.
+ */
+void intel_dp_tunnel_destroy(struct intel_dp *intel_dp)
+{
+	if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		drm_dp_tunnel_disable_bw_alloc(intel_dp->tunnel);
+
+	intel_dp_tunnel_disconnect(intel_dp);
+}
+
+static int kbytes_to_mbits(int kbytes)
+{
+	return DIV_ROUND_UP(kbytes * 8, 1000);
+}
+
+static int get_current_link_bw(struct intel_dp *intel_dp,
+			       bool *below_dprx_bw)
+{
+	int rate = intel_dp_max_common_rate(intel_dp);
+	int lane_count = intel_dp_max_common_lane_count(intel_dp);
+	int bw;
+
+	bw = intel_dp_max_link_data_rate(intel_dp, rate, lane_count);
+	*below_dprx_bw = bw < drm_dp_max_dprx_data_rate(rate, lane_count);
+
+	return bw;
+}
+
+static int update_tunnel_state(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	bool old_bw_below_dprx;
+	bool new_bw_below_dprx;
+	int old_bw;
+	int new_bw;
+	int ret;
+
+	old_bw = get_current_link_bw(intel_dp, &old_bw_below_dprx);
+
+	ret = drm_dp_tunnel_update_state(intel_dp->tunnel);
+	if (ret < 0) {
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s] State update failed (err %pe)\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    ERR_PTR(ret));
+
+		return ret;
+	}
+
+	if (ret == 0 ||
+	    !drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel))
+		return 0;
+
+	intel_dp_update_sink_caps(intel_dp);
+
+	new_bw = get_current_link_bw(intel_dp, &new_bw_below_dprx);
+
+	/* Suppress the notification if the mode list can't change due to bw. */
+	if (old_bw_below_dprx == new_bw_below_dprx &&
+	    !new_bw_below_dprx)
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][ENCODER:%d:%s] Notify users about BW change: %d -> %d\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    encoder->base.base.id, encoder->base.name,
+		    kbytes_to_mbits(old_bw), kbytes_to_mbits(new_bw));
+
+	return 1;
+}
+
+/*
+ * Allocate the BW for a tunnel on a DP connector/port if the connector/port
+ * was already active when detecting the tunnel. The allocated BW must be
+ * freed by the next atomic modeset, storing the BW in the
+ * intel_atomic_state::inherited_dp_tunnels, and calling
+ * intel_dp_tunnel_atomic_free_bw().
+ */
+static int allocate_initial_tunnel_bw_for_pipes(struct intel_dp *intel_dp, u8 pipe_mask)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct intel_crtc *crtc;
+	int tunnel_bw = 0;
+	int err;
+
+	for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
+		const struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+		int stream_bw = intel_dp_config_required_rate(crtc_state);
+
+		tunnel_bw += stream_bw;
+
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s][CRTC:%d:%s] Initial BW for stream %d: %d/%d Mb/s\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    crtc->base.base.id, crtc->base.name,
+			    crtc->pipe,
+			    kbytes_to_mbits(stream_bw), kbytes_to_mbits(tunnel_bw));
+	}
+
+	err = drm_dp_tunnel_alloc_bw(intel_dp->tunnel, tunnel_bw);
+	if (err) {
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s] Initial BW allocation failed (err %pe)\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    ERR_PTR(err));
+
+		return err;
+	}
+
+	return update_tunnel_state(intel_dp);
+}
+
+static int allocate_initial_tunnel_bw(struct intel_dp *intel_dp,
+				      struct drm_modeset_acquire_ctx *ctx)
+{
+	u8 pipe_mask;
+	int err;
+
+	err = intel_dp_get_active_pipes(intel_dp, ctx, &pipe_mask);
+	if (err)
+		return err;
+
+	return allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask);
+}
+
+static int detect_new_tunnel(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct drm_dp_tunnel *tunnel;
+	int ret;
+
+	tunnel = drm_dp_tunnel_detect(i915->display.dp_tunnel_mgr,
+					&intel_dp->aux);
+	if (IS_ERR(tunnel))
+		return PTR_ERR(tunnel);
+
+	intel_dp->tunnel = tunnel;
+
+	ret = drm_dp_tunnel_enable_bw_alloc(intel_dp->tunnel);
+	if (ret) {
+		if (ret == -EOPNOTSUPP)
+			return 0;
+
+		drm_dbg_kms(&i915->drm,
+			    "[DPTUN %s][ENCODER:%d:%s] Failed to enable BW allocation mode (ret %pe)\n",
+			    drm_dp_tunnel_name(intel_dp->tunnel),
+			    encoder->base.base.id, encoder->base.name,
+			    ERR_PTR(ret));
+
+		/* Keep the tunnel with BWA disabled */
+		return 0;
+	}
+
+	ret = allocate_initial_tunnel_bw(intel_dp, ctx);
+	if (ret < 0)
+		intel_dp_tunnel_destroy(intel_dp);
+
+	return ret;
+}
+
+/**
+ * intel_dp_tunnel_detect - Detect a DP tunnel on a port
+ * @intel_dp: DP port object
+ * @ctx: lock context acquired by the connector detection handler
+ *
+ * Detect a DP tunnel on the @intel_dp port, enabling the BW allocation mode
+ * on it if supported and allocating the BW required on an already active port.
+ * The BW allocated this way must be freed by the next atomic modeset calling
+ * intel_dp_tunnel_atomic_free_bw().
+ *
+ * If @intel_dp has already a tunnel detected on it, update the tunnel's state
+ * wrt. its support for BW allocation mode and the available BW via the
+ * tunnel. If the tunnel's state change requires this - for instance the
+ * tunnel's group ID has changed - the tunnel will be dropped and recreated.
+ *
+ * Return 0 in case of success - after any tunnel detected and added to
+ * @intel_dp - 1 in case the BW on an already existing tunnel has changed in a
+ * way that requires notifying user space.
+ */
+int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
+{
+	int ret;
+
+	if (intel_dp_is_edp(intel_dp))
+		return 0;
+
+	if (intel_dp->tunnel) {
+		ret = update_tunnel_state(intel_dp);
+		if (ret >= 0)
+			return ret;
+
+		/* Try to recreate the tunnel after an update error. */
+		intel_dp_tunnel_destroy(intel_dp);
+	}
+
+	return detect_new_tunnel(intel_dp, ctx);
+}
+
+/**
+ * intel_dp_tunnel_bw_alloc_is_enabled - Query the BW allocation support on a tunnel
+ * @intel_dp: DP port object
+ *
+ * Query whether a DP tunnel is connected on @intel_dp and the tunnel supports
+ * the BW allocation mode.
+ *
+ * Returns %true if the BW allocation mode is supported on @intel_dp.
+ */
+bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp)
+{
+	return drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel);
+}
+
+/**
+ * intel_dp_tunnel_suspend - Suspend a DP tunnel connected on a port
+ * @intel_dp: DP port object
+ *
+ * Suspend a DP tunnel on @intel_dp with BW allocation mode enabled on it.
+ */
+void intel_dp_tunnel_suspend(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+
+	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return;
+
+	drm_dbg_kms(&i915->drm, "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Suspend\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name);
+
+	drm_dp_tunnel_disable_bw_alloc(intel_dp->tunnel);
+
+	intel_dp->tunnel_suspended = true;
+}
+
+/**
+ * intel_dp_tunnel_resume - Resume a DP tunnel connected on a port
+ * @intel_dp: DP port object
+ * @crtc_state: CRTC state
+ * @dpcd_updated: the DPCD DPRX capabilities got updated during resume
+ *
+ * Resume a DP tunnel on @intel_dp with BW allocation mode enabled on it.
+ */
+void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state,
+			    bool dpcd_updated)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	u8 dpcd[DP_RECEIVER_CAP_SIZE];
+	u8 pipe_mask;
+	int err = 0;
+
+	if (!intel_dp->tunnel_suspended)
+		return;
+
+	intel_dp->tunnel_suspended = false;
+
+	drm_dbg_kms(&i915->drm, "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Resume\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name);
+
+	/*
+	 * The TBT Connection Manager requires the GFX driver to read out
+	 * the sink's DPRX caps to be able to service any BW requests later.
+	 * During resume overriding the caps in @intel_dp cached before
+	 * suspend must be avoided, so do here only a dummy read, unless the
+	 * capabilities were updated already during resume.
+	 */
+	if (!dpcd_updated) {
+		err = intel_dp_read_dprx_caps(intel_dp, dpcd);
+
+		if (err) {
+			drm_dp_tunnel_set_io_error(intel_dp->tunnel);
+			goto out_err;
+		}
+	}
+
+	err = drm_dp_tunnel_enable_bw_alloc(intel_dp->tunnel);
+	if (err)
+		goto out_err;
+
+	pipe_mask = 0;
+	if (crtc_state) {
+		struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+		/* TODO: Add support for MST */
+		pipe_mask |= BIT(crtc->pipe);
+	}
+
+	err = allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask);
+	if (err)
+		goto out_err;
+
+	return;
+
+out_err:
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s] Tunnel can't be resumed, will drop and redect it (err %pe)\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    ERR_PTR(err));
+}
+
+static struct drm_dp_tunnel *
+get_inherited_tunnel(struct intel_atomic_state *state, struct intel_crtc *crtc)
+{
+	if (!state->inherited_dp_tunnels)
+		return NULL;
+
+	return state->inherited_dp_tunnels->ref[crtc->pipe].tunnel;
+}
+
+static int
+add_inherited_tunnel(struct intel_atomic_state *state,
+		     struct drm_dp_tunnel *tunnel,
+		     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct drm_dp_tunnel *old_tunnel;
+
+	old_tunnel = get_inherited_tunnel(state, crtc);
+	if (old_tunnel) {
+		drm_WARN_ON(&i915->drm, old_tunnel != tunnel);
+		return 0;
+	}
+
+	if (!state->inherited_dp_tunnels) {
+		state->inherited_dp_tunnels = kzalloc(sizeof(*state->inherited_dp_tunnels),
+						      GFP_KERNEL);
+		if (!state->inherited_dp_tunnels)
+			return -ENOMEM;
+	}
+
+	drm_dp_tunnel_ref_get(tunnel, &state->inherited_dp_tunnels->ref[crtc->pipe]);
+
+	return 0;
+}
+
+static int check_inherited_tunnel_state(struct intel_atomic_state *state,
+					struct intel_dp *intel_dp,
+					const struct intel_digital_connector_state *old_conn_state)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct intel_connector *connector =
+		to_intel_connector(old_conn_state->base.connector);
+	struct intel_crtc *old_crtc;
+	const struct intel_crtc_state *old_crtc_state;
+
+	/*
+	 * If a BWA tunnel gets detected only after the corresponding
+	 * connector got enabled already without a BWA tunnel, or a different
+	 * BWA tunnel (which was removed meanwhile) the old CRTC state won't
+	 * contain the state of the current tunnel. This tunnel still has a
+	 * reserved BW, which needs to be released, add the state for such
+	 * inherited tunnels separately only to this atomic state.
+	 */
+	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return 0;
+
+	if (!old_conn_state->base.crtc)
+		return 0;
+
+	old_crtc = to_intel_crtc(old_conn_state->base.crtc);
+	old_crtc_state = intel_atomic_get_old_crtc_state(state, old_crtc);
+
+	if (!old_crtc_state->hw.active ||
+	    old_crtc_state->dp_tunnel_ref.tunnel == intel_dp->tunnel)
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Adding state for inherited tunnel %p\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    old_crtc->base.base.id, old_crtc->base.name,
+		    intel_dp->tunnel);
+
+	return add_inherited_tunnel(state, intel_dp->tunnel, old_crtc);
+}
+
+/**
+ * intel_dp_tunnel_atomic_cleanup_inherited_state - Free any inherited DP tunnel state
+ * @state: Atomic state
+ *
+ * Free the inherited DP tunnel state in @state.
+ */
+void intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state)
+{
+	enum pipe pipe;
+
+	if (!state->inherited_dp_tunnels)
+		return;
+
+	for_each_pipe(to_i915(state->base.dev), pipe)
+		if (state->inherited_dp_tunnels->ref[pipe].tunnel)
+			drm_dp_tunnel_ref_put(&state->inherited_dp_tunnels->ref[pipe]);
+
+	kfree(state->inherited_dp_tunnels);
+	state->inherited_dp_tunnels = NULL;
+}
+
+static int intel_dp_tunnel_atomic_add_group_state(struct intel_atomic_state *state,
+						  struct drm_dp_tunnel *tunnel)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	u32 pipe_mask;
+	int err;
+
+	err = drm_dp_tunnel_atomic_get_group_streams_in_state(&state->base,
+							      tunnel, &pipe_mask);
+	if (err)
+		return err;
+
+	drm_WARN_ON(&i915->drm, pipe_mask & ~((1 << I915_MAX_PIPES) - 1));
+
+	return intel_modeset_pipes_in_mask_early(state, "DPTUN", pipe_mask);
+}
+
+/**
+ * intel_dp_tunnel_atomic_add_state_for_crtc - Add CRTC specific DP tunnel state
+ * @state: Atomic state
+ * @crtc: CRTC to add the tunnel state for
+ *
+ * Add the DP tunnel state for @crtc if the CRTC (aka DP tunnel stream) is enabled
+ * via a DP tunnel.
+ *
+ * Return 0 in case of success, a negative error code otherwise.
+ */
+int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
+					      struct intel_crtc *crtc)
+{
+	const struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct drm_dp_tunnel_state *tunnel_state;
+	struct drm_dp_tunnel *tunnel = new_crtc_state->dp_tunnel_ref.tunnel;
+
+	if (!tunnel)
+		return 0;
+
+	tunnel_state = drm_dp_tunnel_atomic_get_state(&state->base, tunnel);
+	if (IS_ERR(tunnel_state))
+		return PTR_ERR(tunnel_state);
+
+	return 0;
+}
+
+static int check_group_state(struct intel_atomic_state *state,
+			     struct intel_dp *intel_dp,
+			     struct intel_connector *connector,
+			     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	const struct intel_crtc_state *crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+
+	if (!crtc_state->dp_tunnel_ref.tunnel)
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Adding group state for tunnel %p\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    crtc->base.base.id, crtc->base.name,
+		    crtc_state->dp_tunnel_ref.tunnel);
+
+	return intel_dp_tunnel_atomic_add_group_state(state, crtc_state->dp_tunnel_ref.tunnel);
+}
+
+/**
+ * intel_dp_tunnel_atomic_check_state - Check a connector's DP tunnel specific state
+ * @state: Atomic state
+ * @intel_dp: DP port object
+ * @connector: connector using @intel_dp
+ *
+ * Check and add the DP tunnel atomic state for @intel_dp/@connector to
+ * @state, if there is a DP tunnel detected on @intel_dp with BW allocation
+ * mode enabled on it, or if @intel_dp/@connector was previously enabled via a
+ * DP tunnel.
+ *
+ * Returns 0 in case of success, or a negative error code otherwise.
+ */
+int intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
+				       struct intel_dp *intel_dp,
+				       struct intel_connector *connector)
+{
+	const struct intel_digital_connector_state *old_conn_state =
+		intel_atomic_get_old_connector_state(state, connector);
+	const struct intel_digital_connector_state *new_conn_state =
+		intel_atomic_get_new_connector_state(state, connector);
+	int err;
+
+	if (old_conn_state->base.crtc) {
+		err = check_group_state(state, intel_dp, connector,
+					to_intel_crtc(old_conn_state->base.crtc));
+		if (err)
+			return err;
+	}
+
+	if (new_conn_state->base.crtc &&
+	    new_conn_state->base.crtc != old_conn_state->base.crtc) {
+		err = check_group_state(state, intel_dp, connector,
+					to_intel_crtc(new_conn_state->base.crtc));
+		if (err)
+			return err;
+	}
+
+	return check_inherited_tunnel_state(state, intel_dp, old_conn_state);
+}
+
+/**
+ * intel_dp_tunnel_atomic_compute_stream_bw - Compute the BW required by a DP tunnel stream
+ * @state: Atomic state
+ * @intel_dp: DP object
+ * @connector: connector using @intel_dp
+ * @crtc_state: state of CRTC of the given DP tunnel stream
+ *
+ * Compute the required BW of CRTC (aka DP tunnel stream), storing this BW to
+ * the DP tunnel state containing the stream in @state. Before re-calculating a
+ * BW requirement in the crtc_state state the old BW requirement computed by this
+ * function must be cleared by calling intel_dp_tunnel_atomic_clear_stream_bw().
+ *
+ * Returns 0 in case of success, a negative error code otherwise.
+ */
+int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
+					     struct intel_dp *intel_dp,
+					     const struct intel_connector *connector,
+					     struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	int required_rate = intel_dp_config_required_rate(crtc_state);
+	int ret;
+
+	if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
+		return 0;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][CONNECTOR:%d:%s][ENCODER:%d:%s][CRTC:%d:%s] Stream %d required BW %d Mb/s\n",
+		    drm_dp_tunnel_name(intel_dp->tunnel),
+		    connector->base.base.id, connector->base.name,
+		    encoder->base.base.id, encoder->base.name,
+		    crtc->base.base.id, crtc->base.name,
+		    crtc->pipe,
+		    kbytes_to_mbits(required_rate));
+
+	ret = drm_dp_tunnel_atomic_set_stream_bw(&state->base, intel_dp->tunnel,
+						 crtc->pipe, required_rate);
+	if (ret < 0)
+		return ret;
+
+	drm_dp_tunnel_ref_get(intel_dp->tunnel,
+			      &crtc_state->dp_tunnel_ref);
+
+	return 0;
+}
+
+/**
+ * intel_dp_tunnel_atomic_clear_stream_bw - Clear any DP tunnel stream BW requirement
+ * @state: Atomic state
+ * @crtc_state: state of CRTC of the given DP tunnel stream
+ *
+ * Clear any DP tunnel stream BW requirement set by
+ * intel_dp_tunnel_atomic_compute_stream_bw().
+ */
+void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
+					    struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+	if (!crtc_state->dp_tunnel_ref.tunnel)
+		return;
+
+	drm_dp_tunnel_atomic_set_stream_bw(&state->base,
+					   crtc_state->dp_tunnel_ref.tunnel,
+					   crtc->pipe, 0);
+	drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref);
+}
+
+/**
+ * intel_dp_tunnel_atomic_check_link - Check the DP tunnel atomic state
+ * @state: intel atomic state
+ * @limits: link BW limits
+ *
+ * Check the link configuration for all DP tunnels in @state. If the
+ * configuration is invalid @limits will be updated if possible to
+ * reduce the total BW, after which the configuration for all CRTCs in
+ * @state must be recomputed with the updated @limits.
+ *
+ * Returns:
+ *   - 0 if the confugration is valid
+ *   - %-EAGAIN, if the configuration is invalid and @limits got updated
+ *     with fallback values with which the configuration of all CRTCs in
+ *     @state must be recomputed
+ *   - Other negative error, if the configuration is invalid without a
+ *     fallback possibility, or the check failed for another reason
+ */
+int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
+				      struct intel_link_bw_limits *limits)
+{
+	u32 failed_stream_mask;
+	int err;
+
+	err = drm_dp_tunnel_atomic_check_stream_bws(&state->base,
+						    &failed_stream_mask);
+	if (err != -ENOSPC)
+		return err;
+
+	err = intel_link_bw_reduce_bpp(state, limits,
+				       failed_stream_mask, "DP tunnel link BW");
+
+	return err ? : -EAGAIN;
+}
+
+static void atomic_decrease_bw(struct intel_atomic_state *state)
+{
+	struct intel_crtc *crtc;
+	const struct intel_crtc_state *old_crtc_state;
+	const struct intel_crtc_state *new_crtc_state;
+	int i;
+
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+		const struct drm_dp_tunnel_state *new_tunnel_state;
+		struct drm_dp_tunnel *tunnel;
+		int old_bw;
+		int new_bw;
+
+		if (!intel_crtc_needs_modeset(new_crtc_state))
+			continue;
+
+		tunnel = get_inherited_tunnel(state, crtc);
+		if (!tunnel)
+			tunnel = old_crtc_state->dp_tunnel_ref.tunnel;
+
+		if (!tunnel)
+			continue;
+
+		old_bw = drm_dp_tunnel_get_allocated_bw(tunnel);
+
+		new_tunnel_state = drm_dp_tunnel_atomic_get_new_state(&state->base, tunnel);
+		new_bw = drm_dp_tunnel_atomic_get_required_bw(new_tunnel_state);
+
+		if (new_bw >= old_bw)
+			continue;
+
+		drm_dp_tunnel_alloc_bw(tunnel, new_bw);
+	}
+}
+
+static void queue_retry_work(struct intel_atomic_state *state,
+			     struct drm_dp_tunnel *tunnel,
+			     const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
+	struct intel_encoder *encoder;
+
+	encoder = intel_get_crtc_new_encoder(state, crtc_state);
+
+	if (!intel_digital_port_connected(encoder))
+		return;
+
+	drm_dbg_kms(&i915->drm,
+		    "[DPTUN %s][ENCODER:%d:%s] BW allocation failed on a connected sink\n",
+		    drm_dp_tunnel_name(tunnel),
+		    encoder->base.base.id,
+		    encoder->base.name);
+
+	intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
+}
+
+static void atomic_increase_bw(struct intel_atomic_state *state)
+{
+	struct intel_crtc *crtc;
+	const struct intel_crtc_state *crtc_state;
+	int i;
+
+	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+		struct drm_dp_tunnel_state *tunnel_state;
+		struct drm_dp_tunnel *tunnel = crtc_state->dp_tunnel_ref.tunnel;
+		int bw;
+
+		if (!intel_crtc_needs_modeset(crtc_state))
+			continue;
+
+		if (!tunnel)
+			continue;
+
+		tunnel_state = drm_dp_tunnel_atomic_get_new_state(&state->base, tunnel);
+
+		bw = drm_dp_tunnel_atomic_get_required_bw(tunnel_state);
+
+		if (drm_dp_tunnel_alloc_bw(tunnel, bw) != 0)
+			queue_retry_work(state, tunnel, crtc_state);
+	}
+}
+
+/**
+ * intel_dp_tunnel_atomic_alloc_bw - Allocate the BW for all modeset tunnels
+ * @state: Atomic state
+ *
+ * Allocate the required BW for all tunnels in @state.
+ */
+void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state)
+{
+	atomic_decrease_bw(state);
+	atomic_increase_bw(state);
+}
+
+/**
+ * intel_dp_tunnel_mgr_init - Initialize the DP tunnel manager
+ * @i915: i915 device object
+ *
+ * Initialize the DP tunnel manager. The tunnel manager will support the
+ * detection/management of DP tunnels on all DP connectors, so the function
+ * must be called after all these connectors have been registered already.
+ *
+ * Return 0 in case of success, a negative error code otherwise.
+ */
+int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915)
+{
+	struct drm_dp_tunnel_mgr *tunnel_mgr;
+	struct drm_connector_list_iter connector_list_iter;
+	struct intel_connector *connector;
+	int dp_connectors = 0;
+
+	drm_connector_list_iter_begin(&i915->drm, &connector_list_iter);
+	for_each_intel_connector_iter(connector, &connector_list_iter) {
+		if (connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		dp_connectors++;
+	}
+	drm_connector_list_iter_end(&connector_list_iter);
+
+	tunnel_mgr = drm_dp_tunnel_mgr_create(&i915->drm, dp_connectors);
+	if (IS_ERR(tunnel_mgr))
+		return PTR_ERR(tunnel_mgr);
+
+	i915->display.dp_tunnel_mgr = tunnel_mgr;
+
+	return 0;
+}
+
+/**
+ * intel_dp_tunnel_mgr_cleanup - Clean up the DP tunnel manager state
+ * @i915: i915 device object
+ *
+ * Clean up the DP tunnel manager state.
+ */
+void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915)
+{
+	drm_dp_tunnel_mgr_destroy(i915->display.dp_tunnel_mgr);
+	i915->display.dp_tunnel_mgr = NULL;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
new file mode 100644
index 0000000000000..08b2cba84af2b
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __INTEL_DP_TUNNEL_H__
+#define __INTEL_DP_TUNNEL_H__
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct drm_connector_state;
+struct drm_modeset_acquire_ctx;
+
+struct intel_atomic_state;
+struct intel_connector;
+struct intel_crtc;
+struct intel_crtc_state;
+struct intel_dp;
+struct intel_encoder;
+struct intel_link_bw_limits;
+
+#if defined(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
+
+int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx);
+void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp);
+void intel_dp_tunnel_destroy(struct intel_dp *intel_dp);
+void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state,
+			    bool dpcd_updated);
+void intel_dp_tunnel_suspend(struct intel_dp *intel_dp);
+
+bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp);
+
+void
+intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state);
+
+int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
+					     struct intel_dp *intel_dp,
+					     const struct intel_connector *connector,
+					     struct intel_crtc_state *crtc_state);
+void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
+					    struct intel_crtc_state *crtc_state);
+
+int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
+					      struct intel_crtc *crtc);
+int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
+				      struct intel_link_bw_limits *limits);
+int intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
+				       struct intel_dp *intel_dp,
+				       struct intel_connector *connector);
+
+void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state);
+
+int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915);
+void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915);
+
+#else
+
+static inline int
+intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp) {}
+static inline void intel_dp_tunnel_destroy(struct intel_dp *intel_dp) {}
+static inline void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
+					  const struct intel_crtc_state *crtc_state,
+					  bool dpcd_updated) {}
+static inline void intel_dp_tunnel_suspend(struct intel_dp *intel_dp) {}
+
+static inline bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp)
+{
+	return false;
+}
+
+static inline void
+intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state) {}
+
+static inline int
+intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
+					 struct intel_dp *intel_dp,
+					 const struct intel_connector *connector,
+					 struct intel_crtc_state *crtc_state)
+{
+	return 0;
+}
+
+static inline void
+intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
+				       struct intel_crtc_state *crtc_state) {}
+
+static inline int
+intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
+					  struct intel_crtc *crtc)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
+				  struct intel_link_bw_limits *limits)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
+				   struct intel_dp *intel_dp,
+				   struct intel_connector *connector)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state)
+{
+	return 0;
+}
+
+static inline int
+intel_dp_tunnel_mgr_init(struct drm_i915_private *i915)
+{
+	return 0;
+}
+
+static inline void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915) {}
+
+#endif /* CONFIG_DRM_I915_DP_TUNNEL */
+
+#endif /* __INTEL_DP_TUNNEL_H__ */
-- 
2.39.2


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

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (26 preceding siblings ...)
  2024-02-26 13:54 ` Jani Nikula
@ 2024-02-27  1:02 ` Patchwork
  2024-02-27  1:02 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (4 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-27  1:02 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
URL   : https://patchwork.freedesktop.org/series/129082/
State : warning

== Summary ==

Error: dim checkpatch failed
855f2818d384 drm/dp: Add drm_dp_max_dprx_data_rate()
c1dbb46b64c9 drm/dp: Add support for DP tunneling
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:128: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#128: 
new file mode 100644

-:158: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#158: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:26:
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))

-:158: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__state' - possible side-effects?
#158: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:26:
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))

-:158: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__i' - possible side-effects?
#158: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:26:
+#define for_each_new_group_in_state(__state, __new_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__new_group_state) = \
+				to_group_state((__state)->private_objs[__i].new_state), 1))

-:162: WARNING:SPACING: space prohibited between function name and open parenthesis '('
#162: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:30:
+		for_each_if ((__state)->private_objs[__i].ptr && \

-:167: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#167: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:35:
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))

-:167: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__state' - possible side-effects?
#167: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:35:
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))

-:167: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__i' - possible side-effects?
#167: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:35:
+#define for_each_old_group_in_state(__state, __old_group_state, __i) \
+	for ((__i) = 0; \
+	     (__i) < (__state)->num_private_objs; \
+	     (__i)++) \
+		for_each_if ((__state)->private_objs[__i].ptr && \
+			     is_dp_tunnel_private_obj((__state)->private_objs[__i].ptr) && \
+			     ((__old_group_state) = \
+				to_group_state((__state)->private_objs[__i].old_state), 1))

-:171: WARNING:SPACING: space prohibited between function name and open parenthesis '('
#171: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:39:
+		for_each_if ((__state)->private_objs[__i].ptr && \

-:189: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__bw' - possible side-effects?
#189: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:57:
+#define DPTUN_BW_ARG(__bw) ((__bw) < 0 ? (__bw) : kbytes_to_mbits(__bw))

-:191: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__tunnel' - possible side-effects?
#191: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:59:
+#define __tun_prn(__tunnel, __level, __type, __fmt, ...) \
+	drm_##__level##__type((__tunnel)->group->mgr->dev, \
+			      "[DPTUN %s][%s] " __fmt, \
+			      drm_dp_tunnel_name(__tunnel), \
+			      (__tunnel)->aux->name, ## \
+			      __VA_ARGS__)

-:201: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__tunnel' - possible side-effects?
#201: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:69:
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)

-:201: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__err' - possible side-effects?
#201: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:69:
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)

-:201: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__fmt' - possible side-effects?
#201: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:69:
+#define tun_dbg_stat(__tunnel, __err, __fmt, ...) do { \
+	if (__err) \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Failed, err: %pe)\n", \
+			  ## __VA_ARGS__, ERR_PTR(__err)); \
+	else \
+		__tun_prn(__tunnel, dbg, _kms, __fmt " (Ok)\n", \
+			  ## __VA_ARGS__); \
+} while (0)

-:213: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__group' - possible side-effects?
#213: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:81:
+#define tun_grp_dbg(__group, __fmt, ...) \
+	drm_dbg_kms((__group)->mgr->dev, \
+		    "[DPTUN %s] " __fmt, \
+		    drm_dp_tunnel_group_name(__group), ## \
+		    __VA_ARGS__)

-:221: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'start' - possible side-effects?
#221: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:89:
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)

-:221: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'start' may be better as '(start)' to avoid precedence issues
#221: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:89:
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)

-:221: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'size' may be better as '(size)' to avoid precedence issues
#221: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:89:
+#define __DPTUN_REG_RANGE(start, size) \
+	GENMASK_ULL(start + size - 1, start)

-:344: CHECK:MACRO_ARG_REUSE: Macro argument reuse '__address' - possible side-effects?
#344: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:212:
+#define tunnel_reg_ptr(__regs, __address) ({ \
+	WARN_ON(!test_bit((__address) - DP_TUNNELING_BASE, dptun_info_regs)); \
+	&(__regs)->buf[bitmap_weight(dptun_info_regs, (__address) - DP_TUNNELING_BASE)]; \
+})

-:578: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#578: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:446:
+void drm_dp_tunnel_put(struct drm_dp_tunnel *tunnel,
+			 struct ref_tracker **tracker)

-:1923: CHECK:SPACING: spaces preferred around that '*' (ctx:ExV)
#1923: FILE: drivers/gpu/drm/display/drm_dp_tunnel.c:1791:
+		*stream_mask |= tunnel_state->stream_mask;
 		^

-:2404: CHECK:LINE_SPACING: Please don't use multiple blank lines
#2404: FILE: include/drm/display/drm_dp_tunnel.h:246:
+
+

total: 2 errors, 3 warnings, 17 checks, 2299 lines checked
c5b9625671bf drm/i915: Fix display bpp limit computation during system resume
6102beb39ffa drm/i915/dp: Add support to notify MST connectors to retry modesets
3a6c343dec7b drm/i915/dp: Use drm_dp_max_dprx_data_rate()
502dafa07a8c drm/i915/dp: Factor out intel_dp_config_required_rate()
37d21e1b0e36 drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
29bbbdc9a40d drm/i915/dp: Factor out intel_dp_update_sink_caps()
f9964a7f5358 drm/i915/dp: Factor out intel_dp_read_dprx_caps()
6486bf027f7f drm/i915/dp: Add intel_dp_max_link_data_rate()
1be9204a0c6d drm/i915/dp: Sync instead of try-sync commits when getting active pipes
d1a39e4fa3b2 drm/i915/dp: Add support for DP tunnel BW allocation
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
-:184: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#184: 
new file mode 100644

-:369: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#369: FILE: drivers/gpu/drm/i915/display/intel_dp_tunnel.c:181:
+	tunnel = drm_dp_tunnel_detect(i915->display.dp_tunnel_mgr,
+					&intel_dp->aux);

total: 0 errors, 1 warnings, 1 checks, 1034 lines checked
c3d8ac0fc515 drm/i915/dp: Add DP tunnel atomic state and check BW limit
-:85: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#85: FILE: drivers/gpu/drm/i915/display/intel_display.c:4514:
+		drm_dp_tunnel_ref_get(master_crtc_state->dp_tunnel_ref.tunnel,
+					&slave_crtc_state->dp_tunnel_ref);

total: 0 errors, 0 warnings, 1 checks, 77 lines checked
9ed1e50cafe4 drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
5d649abce36e drm/i915/dp: Compute DP tunnel BW during encoder state computation
e23397e03930 drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
ada8fd52f665 drm/i915/dp: Handle DP tunnel IRQs
3d3f7be752bc drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
ddd5c4aa048e drm/i915/dp: Suspend/resume DP tunnels
74b8ab88ef8b drm/i915/dp: Read DPRX for all long HPD pulses
ee228100bd91 drm/i915/dp: Enable DP tunnel BW allocation mode



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

* ✗ Fi.CI.SPARSE: warning for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (27 preceding siblings ...)
  2024-02-27  1:02 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev6) Patchwork
@ 2024-02-27  1:02 ` Patchwork
  2024-02-27  1:18 ` ✗ Fi.CI.BAT: failure " Patchwork
                   ` (3 subsequent siblings)
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-27  1:02 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
URL   : https://patchwork.freedesktop.org/series/129082/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.



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

* ✗ Fi.CI.BAT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (28 preceding siblings ...)
  2024-02-27  1:02 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2024-02-27  1:18 ` Patchwork
  2024-02-27 10:59   ` Imre Deak
  2024-02-27 11:32 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  32 siblings, 1 reply; 61+ messages in thread
From: Patchwork @ 2024-02-27  1:18 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
URL   : https://patchwork.freedesktop.org/series/129082/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_14345 -> Patchwork_129082v6
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_129082v6 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_129082v6, 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_129082v6/index.html

Participating hosts (39 -> 38)
------------------------------

  Missing    (1): fi-snb-2520m 

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

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

### IGT changes ###

#### Possible regressions ####

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1:
    - bat-arls-2:         [PASS][1] -> [ABORT][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html

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

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

### CI changes ###

#### Issues hit ####

  * boot:
    - fi-cfl-8109u:       [PASS][3] -> [FAIL][4] ([i915#8293])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/fi-cfl-8109u/boot.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/fi-cfl-8109u/boot.html

  

### IGT changes ###

#### Possible fixes ####

  * igt@i915_selftest@live@gem_contexts:
    - bat-atsm-1:         [INCOMPLETE][5] ([i915#10094] / [i915#10137]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html

  * igt@i915_selftest@live@hangcheck:
    - {bat-rpls-3}:       [DMESG-WARN][7] ([i915#5591]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-rpls-3/igt@i915_selftest@live@hangcheck.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-rpls-3/igt@i915_selftest@live@hangcheck.html

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

  [i915#10094]: https://gitlab.freedesktop.org/drm/intel/issues/10094
  [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
  [i915#5591]: https://gitlab.freedesktop.org/drm/intel/issues/5591
  [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293


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

  * Linux: CI_DRM_14345 -> Patchwork_129082v6

  CI-20190529: 20190529
  CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux


### Linux commits

6f0303321631 drm/i915/dp: Enable DP tunnel BW allocation mode
8b160bd78946 drm/i915/dp: Read DPRX for all long HPD pulses
84f928739de0 drm/i915/dp: Suspend/resume DP tunnels
232a81c3545b drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
d6e68e72eeea drm/i915/dp: Handle DP tunnel IRQs
77a316a5547c drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
904f8ff4847c drm/i915/dp: Compute DP tunnel BW during encoder state computation
e30c2b294042 drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
cfe003896226 drm/i915/dp: Add DP tunnel atomic state and check BW limit
e845d3e65f57 drm/i915/dp: Add support for DP tunnel BW allocation
1e491673dd40 drm/i915/dp: Sync instead of try-sync commits when getting active pipes
f9a23c72455c drm/i915/dp: Add intel_dp_max_link_data_rate()
d02f06d5e00c drm/i915/dp: Factor out intel_dp_read_dprx_caps()
95a664a77474 drm/i915/dp: Factor out intel_dp_update_sink_caps()
e587647c4a35 drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
cc6689daacbe drm/i915/dp: Factor out intel_dp_config_required_rate()
e76c8cac43f0 drm/i915/dp: Use drm_dp_max_dprx_data_rate()
8fea4c43fb32 drm/i915/dp: Add support to notify MST connectors to retry modesets
a50d19596539 drm/i915: Fix display bpp limit computation during system resume
cfae6a8751d6 drm/dp: Add support for DP tunneling
5bed9d5b20dc drm/dp: Add drm_dp_max_dprx_data_rate()

== Logs ==

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

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

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

* Re: ✗ Fi.CI.BAT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-27  1:18 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2024-02-27 10:59   ` Imre Deak
  2024-02-27 11:34     ` Illipilli, TejasreeX
  0 siblings, 1 reply; 61+ messages in thread
From: Imre Deak @ 2024-02-27 10:59 UTC (permalink / raw)
  To: intel-gfx, I915-ci-infra; +Cc: Jani Saarinen

On Tue, Feb 27, 2024 at 01:18:36AM +0000, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
> URL   : https://patchwork.freedesktop.org/series/129082/
> State : failure
> 
> == Summary ==
> 
> CI Bug Log - changes from CI_DRM_14345 -> Patchwork_129082v6
> ====================================================
> 
> Summary
> -------
> 
>   **FAILURE**
> 
>   Serious unknown changes coming with Patchwork_129082v6 absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_129082v6, 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_129082v6/index.html
> 
> Participating hosts (39 -> 38)
> ------------------------------
> 
>   Missing    (1): fi-snb-2520m 
> 
> Possible new issues
> -------------------
> 
>   Here are the unknown changes that may have been introduced in Patchwork_129082v6:
> 
> ### IGT changes ###
> 
> #### Possible regressions ####
> 
>   * igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1:
>     - bat-arls-2:         [PASS][1] -> [ABORT][2]
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html
>    [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html

It's an unrelated issue:

There is only an eDP panel connected to the above ARL, so no TBT/DP
tunnel where the patchset would have an effect.

Looks like some core memory management issue:

<0> [223.728871] BUG: spinlock bad magic on CPU#1, kworker/1:1/224
<0> [223.728880]  lock: obj_hash+0xec060/0x120000, .magic: d6ad4ead, .owner: <none>/-1, .owner_cpu: -1
<4> [223.728890] CPU: 1 PID: 224 Comm: kworker/1:1 Not tainted 6.8.0-rc6-Patchwork_129082v6-gb3552bf1e79d+ #1
<4> [223.728894] Hardware name: Intel Corporation Arrow Lake Client Platform/MTL-S UDIMM 2DPC EVCRB, BIOS MTLSFWI1.R00.3473.D80.2311222130 11/22/2023
<4> [223.728898] Workqueue: events delayed_fput
<7> [223.728778] i915 0000:00:02.0: [drm:pipe_config_mismatch [i915]] [CRTC:233:pipe D] fastset requirement not met in hw.adjusted_mode.crtc_htotal (expected 3040, found 0)
<4> [223.728906] Call Trace:
<4> [223.728909]  <TASK>
<4> [223.728911]  dump_stack_lvl+0x64/0xb0
<4> [223.728919]  do_raw_spin_lock+0x74/0xc0
<4> [223.728925]  _raw_spin_lock_irqsave+0x45/0x60
<4> [223.728931]  ? debug_check_no_obj_freed+0xcc/0x240
<4> [223.728936]  debug_check_no_obj_freed+0xcc/0x240
<4> [223.728940]  ? lock_acquire+0xd8/0x2d0
<4> [223.728943]  ? find_held_lock+0x2b/0x80
<4> [223.728949]  free_unref_page_prepare+0xec/0x350
<4> [223.728955]  free_unref_page+0x33/0x160
<4> [223.728959]  release_pages+0x6c/0x580
<4> [223.728966]  __folio_batch_release+0x1a/0x30
<4> [223.728970]  shmem_undo_range+0x248/0x6c0
<4> [223.728977]  ? cpu_attach_domain+0x74f/0x9a0
<4> [223.728982]  shmem_truncate_range+0x14/0x40
<4> [223.728985]  shmem_evict_inode+0xd7/0x270
<4> [223.728989]  evict+0xc8/0x170

probably CI noticing this and aborting with:

[224.019721] Subtest hang-read-crc: SUCCESS (11.568s
[224.948083] Aborting: Lockdep not active

> 
>   
> Known issues
> ------------
> 
>   Here are the changes found in Patchwork_129082v6 that come from known issues:
> 
> ### CI changes ###
> 
> #### Issues hit ####
> 
>   * boot:
>     - fi-cfl-8109u:       [PASS][3] -> [FAIL][4] ([i915#8293])
>    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/fi-cfl-8109u/boot.html
>    [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/fi-cfl-8109u/boot.html
> 
>   
> 
> ### IGT changes ###
> 
> #### Possible fixes ####
> 
>   * igt@i915_selftest@live@gem_contexts:
>     - bat-atsm-1:         [INCOMPLETE][5] ([i915#10094] / [i915#10137]) -> [PASS][6]
>    [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html
>    [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html
> 
>   * igt@i915_selftest@live@hangcheck:
>     - {bat-rpls-3}:       [DMESG-WARN][7] ([i915#5591]) -> [PASS][8]
>    [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-rpls-3/igt@i915_selftest@live@hangcheck.html
>    [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-rpls-3/igt@i915_selftest@live@hangcheck.html
> 
>   
>   {name}: This element is suppressed. This means it is ignored when computing
>           the status of the difference (SUCCESS, WARNING, or FAILURE).
> 
>   [i915#10094]: https://gitlab.freedesktop.org/drm/intel/issues/10094
>   [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
>   [i915#5591]: https://gitlab.freedesktop.org/drm/intel/issues/5591
>   [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293
> 
> 
> Build changes
> -------------
> 
>   * Linux: CI_DRM_14345 -> Patchwork_129082v6
> 
>   CI-20190529: 20190529
>   CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
>   Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
> 
> 
> ### Linux commits
> 
> 6f0303321631 drm/i915/dp: Enable DP tunnel BW allocation mode
> 8b160bd78946 drm/i915/dp: Read DPRX for all long HPD pulses
> 84f928739de0 drm/i915/dp: Suspend/resume DP tunnels
> 232a81c3545b drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
> d6e68e72eeea drm/i915/dp: Handle DP tunnel IRQs
> 77a316a5547c drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
> 904f8ff4847c drm/i915/dp: Compute DP tunnel BW during encoder state computation
> e30c2b294042 drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
> cfe003896226 drm/i915/dp: Add DP tunnel atomic state and check BW limit
> e845d3e65f57 drm/i915/dp: Add support for DP tunnel BW allocation
> 1e491673dd40 drm/i915/dp: Sync instead of try-sync commits when getting active pipes
> f9a23c72455c drm/i915/dp: Add intel_dp_max_link_data_rate()
> d02f06d5e00c drm/i915/dp: Factor out intel_dp_read_dprx_caps()
> 95a664a77474 drm/i915/dp: Factor out intel_dp_update_sink_caps()
> e587647c4a35 drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
> cc6689daacbe drm/i915/dp: Factor out intel_dp_config_required_rate()
> e76c8cac43f0 drm/i915/dp: Use drm_dp_max_dprx_data_rate()
> 8fea4c43fb32 drm/i915/dp: Add support to notify MST connectors to retry modesets
> a50d19596539 drm/i915: Fix display bpp limit computation during system resume
> cfae6a8751d6 drm/dp: Add support for DP tunneling
> 5bed9d5b20dc drm/dp: Add drm_dp_max_dprx_data_rate()
> 
> == Logs ==
> 
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/index.html

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

* ✓ Fi.CI.BAT: success for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (29 preceding siblings ...)
  2024-02-27  1:18 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2024-02-27 11:32 ` Patchwork
  2024-02-27 14:21 ` ✗ Fi.CI.IGT: failure " Patchwork
  2024-02-28  5:55 ` ✓ Fi.CI.IGT: success " Patchwork
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-27 11:32 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
URL   : https://patchwork.freedesktop.org/series/129082/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_14345 -> Patchwork_129082v6
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

Participating hosts (39 -> 38)
------------------------------

  Missing    (1): fi-snb-2520m 

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

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

### CI changes ###

#### Issues hit ####

  * boot:
    - fi-cfl-8109u:       [PASS][1] -> [FAIL][2] ([i915#8293])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/fi-cfl-8109u/boot.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/fi-cfl-8109u/boot.html

  

### IGT changes ###

#### Issues hit ####

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1:
    - bat-arls-2:         [PASS][3] -> [ABORT][4] ([i915#10327])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@gem_contexts:
    - bat-atsm-1:         [INCOMPLETE][5] ([i915#10094] / [i915#10137]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html

  * igt@i915_selftest@live@hangcheck:
    - {bat-rpls-3}:       [DMESG-WARN][7] ([i915#5591]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-rpls-3/igt@i915_selftest@live@hangcheck.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-rpls-3/igt@i915_selftest@live@hangcheck.html

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

  [i915#10094]: https://gitlab.freedesktop.org/drm/intel/issues/10094
  [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
  [i915#10327]: https://gitlab.freedesktop.org/drm/intel/issues/10327
  [i915#5591]: https://gitlab.freedesktop.org/drm/intel/issues/5591
  [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293


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

  * Linux: CI_DRM_14345 -> Patchwork_129082v6

  CI-20190529: 20190529
  CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux


### Linux commits

6f0303321631 drm/i915/dp: Enable DP tunnel BW allocation mode
8b160bd78946 drm/i915/dp: Read DPRX for all long HPD pulses
84f928739de0 drm/i915/dp: Suspend/resume DP tunnels
232a81c3545b drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders
d6e68e72eeea drm/i915/dp: Handle DP tunnel IRQs
77a316a5547c drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks
904f8ff4847c drm/i915/dp: Compute DP tunnel BW during encoder state computation
e30c2b294042 drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate()
cfe003896226 drm/i915/dp: Add DP tunnel atomic state and check BW limit
e845d3e65f57 drm/i915/dp: Add support for DP tunnel BW allocation
1e491673dd40 drm/i915/dp: Sync instead of try-sync commits when getting active pipes
f9a23c72455c drm/i915/dp: Add intel_dp_max_link_data_rate()
d02f06d5e00c drm/i915/dp: Factor out intel_dp_read_dprx_caps()
95a664a77474 drm/i915/dp: Factor out intel_dp_update_sink_caps()
e587647c4a35 drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
cc6689daacbe drm/i915/dp: Factor out intel_dp_config_required_rate()
e76c8cac43f0 drm/i915/dp: Use drm_dp_max_dprx_data_rate()
8fea4c43fb32 drm/i915/dp: Add support to notify MST connectors to retry modesets
a50d19596539 drm/i915: Fix display bpp limit computation during system resume
cfae6a8751d6 drm/dp: Add support for DP tunneling
5bed9d5b20dc drm/dp: Add drm_dp_max_dprx_data_rate()

== Logs ==

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

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

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

* RE: ✗ Fi.CI.BAT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-27 10:59   ` Imre Deak
@ 2024-02-27 11:34     ` Illipilli, TejasreeX
  0 siblings, 0 replies; 61+ messages in thread
From: Illipilli, TejasreeX @ 2024-02-27 11:34 UTC (permalink / raw)
  To: Deak, Imre, intel-gfx, I915-ci-infra; +Cc: Saarinen, Jani

Hi,

https://patchwork.freedesktop.org/series/129082/ - Re-reported.

Thanks,
Tejasree

-----Original Message-----
From: I915-ci-infra <i915-ci-infra-bounces@lists.freedesktop.org> On Behalf Of Imre Deak
Sent: Tuesday, February 27, 2024 4:29 PM
To: intel-gfx@lists.freedesktop.org; I915-ci-infra@lists.freedesktop.org
Cc: Saarinen, Jani <jani.saarinen@intel.com>
Subject: Re: ✗ Fi.CI.BAT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev6)

On Tue, Feb 27, 2024 at 01:18:36AM +0000, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
> URL   : https://patchwork.freedesktop.org/series/129082/
> State : failure
> 
> == Summary ==
> 
> CI Bug Log - changes from CI_DRM_14345 -> Patchwork_129082v6 
> ====================================================
> 
> Summary
> -------
> 
>   **FAILURE**
> 
>   Serious unknown changes coming with Patchwork_129082v6 absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_129082v6, 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_129082v6/index.html
> 
> Participating hosts (39 -> 38)
> ------------------------------
> 
>   Missing    (1): fi-snb-2520m 
> 
> Possible new issues
> -------------------
> 
>   Here are the unknown changes that may have been introduced in Patchwork_129082v6:
> 
> ### IGT changes ###
> 
> #### Possible regressions ####
> 
>   * igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1:
>     - bat-arls-2:         [PASS][1] -> [ABORT][2]
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-arls-2/igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html
>    [2]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-arls-2
> /igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-edp-1.html

It's an unrelated issue:

There is only an eDP panel connected to the above ARL, so no TBT/DP tunnel where the patchset would have an effect.

Looks like some core memory management issue:

<0> [223.728871] BUG: spinlock bad magic on CPU#1, kworker/1:1/224 <0> [223.728880]  lock: obj_hash+0xec060/0x120000, .magic: d6ad4ead, .owner: <none>/-1, .owner_cpu: -1 <4> [223.728890] CPU: 1 PID: 224 Comm: kworker/1:1 Not tainted 6.8.0-rc6-Patchwork_129082v6-gb3552bf1e79d+ #1 <4> [223.728894] Hardware name: Intel Corporation Arrow Lake Client Platform/MTL-S UDIMM 2DPC EVCRB, BIOS MTLSFWI1.R00.3473.D80.2311222130 11/22/2023 <4> [223.728898] Workqueue: events delayed_fput <7> [223.728778] i915 0000:00:02.0: [drm:pipe_config_mismatch [i915]] [CRTC:233:pipe D] fastset requirement not met in hw.adjusted_mode.crtc_htotal (expected 3040, found 0) <4> [223.728906] Call Trace:
<4> [223.728909]  <TASK>
<4> [223.728911]  dump_stack_lvl+0x64/0xb0 <4> [223.728919]  do_raw_spin_lock+0x74/0xc0 <4> [223.728925]  _raw_spin_lock_irqsave+0x45/0x60 <4> [223.728931]  ? debug_check_no_obj_freed+0xcc/0x240
<4> [223.728936]  debug_check_no_obj_freed+0xcc/0x240
<4> [223.728940]  ? lock_acquire+0xd8/0x2d0 <4> [223.728943]  ? find_held_lock+0x2b/0x80 <4> [223.728949]  free_unref_page_prepare+0xec/0x350
<4> [223.728955]  free_unref_page+0x33/0x160 <4> [223.728959]  release_pages+0x6c/0x580 <4> [223.728966]  __folio_batch_release+0x1a/0x30 <4> [223.728970]  shmem_undo_range+0x248/0x6c0 <4> [223.728977]  ? cpu_attach_domain+0x74f/0x9a0 <4> [223.728982]  shmem_truncate_range+0x14/0x40 <4> [223.728985]  shmem_evict_inode+0xd7/0x270 <4> [223.728989]  evict+0xc8/0x170

probably CI noticing this and aborting with:

[224.019721] Subtest hang-read-crc: SUCCESS (11.568s [224.948083] Aborting: Lockdep not active

> 
>   
> Known issues
> ------------
> 
>   Here are the changes found in Patchwork_129082v6 that come from known issues:
> 
> ### CI changes ###
> 
> #### Issues hit ####
> 
>   * boot:
>     - fi-cfl-8109u:       [PASS][3] -> [FAIL][4] ([i915#8293])
>    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/fi-cfl-8109u/boot.html
>    [4]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/fi-cfl-810
> 9u/boot.html
> 
>   
> 
> ### IGT changes ###
> 
> #### Possible fixes ####
> 
>   * igt@i915_selftest@live@gem_contexts:
>     - bat-atsm-1:         [INCOMPLETE][5] ([i915#10094] / [i915#10137]) -> [PASS][6]
>    [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-atsm-1/igt@i915_selftest@live@gem_contexts.html
>    [6]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-atsm-1
> /igt@i915_selftest@live@gem_contexts.html
> 
>   * igt@i915_selftest@live@hangcheck:
>     - {bat-rpls-3}:       [DMESG-WARN][7] ([i915#5591]) -> [PASS][8]
>    [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/bat-rpls-3/igt@i915_selftest@live@hangcheck.html
>    [8]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/bat-rpls-3
> /igt@i915_selftest@live@hangcheck.html
> 
>   
>   {name}: This element is suppressed. This means it is ignored when computing
>           the status of the difference (SUCCESS, WARNING, or FAILURE).
> 
>   [i915#10094]: https://gitlab.freedesktop.org/drm/intel/issues/10094
>   [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
>   [i915#5591]: https://gitlab.freedesktop.org/drm/intel/issues/5591
>   [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293
> 
> 
> Build changes
> -------------
> 
>   * Linux: CI_DRM_14345 -> Patchwork_129082v6
> 
>   CI-20190529: 20190529
>   CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
>   Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ 
> git://anongit.freedesktop.org/gfx-ci/linux
> 
> 
> ### Linux commits
> 
> 6f0303321631 drm/i915/dp: Enable DP tunnel BW allocation mode
> 8b160bd78946 drm/i915/dp: Read DPRX for all long HPD pulses
> 84f928739de0 drm/i915/dp: Suspend/resume DP tunnels 232a81c3545b 
> drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders 
> d6e68e72eeea drm/i915/dp: Handle DP tunnel IRQs 77a316a5547c 
> drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable 
> hooks 904f8ff4847c drm/i915/dp: Compute DP tunnel BW during encoder 
> state computation
> e30c2b294042 drm/i915/dp: Account for tunnel BW limit in 
> intel_dp_max_link_data_rate()
> cfe003896226 drm/i915/dp: Add DP tunnel atomic state and check BW 
> limit
> e845d3e65f57 drm/i915/dp: Add support for DP tunnel BW allocation
> 1e491673dd40 drm/i915/dp: Sync instead of try-sync commits when 
> getting active pipes f9a23c72455c drm/i915/dp: Add 
> intel_dp_max_link_data_rate() d02f06d5e00c drm/i915/dp: Factor out 
> intel_dp_read_dprx_caps()
> 95a664a77474 drm/i915/dp: Factor out intel_dp_update_sink_caps()
> e587647c4a35 drm/i915/dp: Export intel_dp_max_common_rate/lane_count()
> cc6689daacbe drm/i915/dp: Factor out intel_dp_config_required_rate()
> e76c8cac43f0 drm/i915/dp: Use drm_dp_max_dprx_data_rate()
> 8fea4c43fb32 drm/i915/dp: Add support to notify MST connectors to 
> retry modesets
> a50d19596539 drm/i915: Fix display bpp limit computation during system 
> resume
> cfae6a8751d6 drm/dp: Add support for DP tunneling 5bed9d5b20dc drm/dp: 
> Add drm_dp_max_dprx_data_rate()
> 
> == Logs ==
> 
> For more details see: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/index.html

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

* ✗ Fi.CI.IGT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (30 preceding siblings ...)
  2024-02-27 11:32 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2024-02-27 14:21 ` Patchwork
  2024-02-27 15:51   ` Imre Deak
  2024-02-28  5:55 ` ✓ Fi.CI.IGT: success " Patchwork
  32 siblings, 1 reply; 61+ messages in thread
From: Patchwork @ 2024-02-27 14:21 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
URL   : https://patchwork.freedesktop.org/series/129082/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_14345_full -> Patchwork_129082v6_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_129082v6_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_129082v6_full, 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.

  

Participating hosts (8 -> 8)
------------------------------

  No changes in participating hosts

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

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

### IGT changes ###

#### Possible regressions ####

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-snb:          [PASS][1] -> [DMESG-WARN][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_fbcon_fbt@fbc-suspend.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_fbcon_fbt@fbc-suspend.html

  
#### Warnings ####

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move:
    - shard-snb:          [SKIP][3] ([fdo#109271]) -> [FAIL][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb5/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb4/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html

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

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

### CI changes ###

#### Possible fixes ####

  * boot:
    - shard-glk:          ([PASS][5], [PASS][6], [PASS][7], [PASS][8], [PASS][9], [PASS][10], [PASS][11], [PASS][12], [PASS][13], [FAIL][14], [PASS][15], [PASS][16], [PASS][17], [PASS][18], [PASS][19], [PASS][20], [PASS][21], [PASS][22], [PASS][23], [PASS][24], [PASS][25], [PASS][26], [PASS][27], [PASS][28], [FAIL][29]) ([i915#8293]) -> ([PASS][30], [PASS][31], [PASS][32], [PASS][33], [PASS][34], [PASS][35], [PASS][36], [PASS][37], [PASS][38], [PASS][39], [PASS][40], [PASS][41], [PASS][42], [PASS][43], [PASS][44], [PASS][45], [PASS][46], [PASS][47], [PASS][48], [PASS][49], [PASS][50], [PASS][51], [PASS][52], [PASS][53])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk8/boot.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk8/boot.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html

  

### IGT changes ###

#### Issues hit ####

  * igt@api_intel_bb@object-reloc-purge-cache:
    - shard-dg2:          NOTRUN -> [SKIP][54] ([i915#8411]) +2 other tests skip
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@api_intel_bb@object-reloc-purge-cache.html

  * igt@device_reset@unbind-cold-reset-rebind:
    - shard-mtlp:         NOTRUN -> [SKIP][55] ([i915#7701])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@device_reset@unbind-cold-reset-rebind.html

  * igt@drm_fdinfo@virtual-busy-idle-all:
    - shard-dg2:          NOTRUN -> [SKIP][56] ([i915#8414]) +1 other test skip
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@drm_fdinfo@virtual-busy-idle-all.html

  * igt@gem_ctx_persistence@heartbeat-stop:
    - shard-dg1:          NOTRUN -> [SKIP][57] ([i915#8555])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_ctx_persistence@heartbeat-stop.html

  * igt@gem_ctx_sseu@invalid-args:
    - shard-tglu:         NOTRUN -> [SKIP][58] ([i915#280])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_ctx_sseu@invalid-args.html

  * igt@gem_eio@kms:
    - shard-dg1:          NOTRUN -> [FAIL][59] ([i915#5784])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_eio@kms.html

  * igt@gem_eio@unwedge-stress:
    - shard-dg1:          [PASS][60] -> [FAIL][61] ([i915#5784])
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-18/igt@gem_eio@unwedge-stress.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-19/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_balancer@bonded-true-hang:
    - shard-mtlp:         NOTRUN -> [SKIP][62] ([i915#4812])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_balancer@bonded-true-hang.html

  * igt@gem_exec_fair@basic-deadline:
    - shard-glk:          NOTRUN -> [FAIL][63] ([i915#2846])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-flow:
    - shard-mtlp:         NOTRUN -> [SKIP][64] ([i915#4473] / [i915#4771]) +1 other test skip
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_fair@basic-flow.html

  * igt@gem_exec_fair@basic-none-rrul@rcs0:
    - shard-tglu:         NOTRUN -> [FAIL][65] ([i915#2842])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_exec_fair@basic-none-rrul@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-glk:          NOTRUN -> [FAIL][66] ([i915#2842])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@vecs0:
    - shard-rkl:          [PASS][67] -> [FAIL][68] ([i915#2842]) +4 other tests fail
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@gem_exec_fair@basic-pace@vecs0.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@gem_exec_fair@basic-pace@vecs0.html

  * igt@gem_exec_flush@basic-batch-kernel-default-uc:
    - shard-dg1:          NOTRUN -> [SKIP][69] ([i915#3539] / [i915#4852])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_exec_flush@basic-batch-kernel-default-uc.html

  * igt@gem_exec_flush@basic-uc-ro-default:
    - shard-dg2:          NOTRUN -> [SKIP][70] ([i915#3539] / [i915#4852]) +1 other test skip
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_exec_flush@basic-uc-ro-default.html

  * igt@gem_exec_params@rsvd2-dirt:
    - shard-mtlp:         NOTRUN -> [SKIP][71] ([i915#5107])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_params@rsvd2-dirt.html

  * igt@gem_exec_params@secure-non-master:
    - shard-mtlp:         NOTRUN -> [SKIP][72] ([fdo#112283]) +1 other test skip
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_params@secure-non-master.html

  * igt@gem_exec_reloc@basic-concurrent0:
    - shard-dg1:          NOTRUN -> [SKIP][73] ([i915#3281]) +4 other tests skip
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@gem_exec_reloc@basic-cpu-wc-noreloc:
    - shard-mtlp:         NOTRUN -> [SKIP][74] ([i915#3281]) +3 other tests skip
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_reloc@basic-cpu-wc-noreloc.html

  * igt@gem_exec_reloc@basic-write-gtt:
    - shard-dg2:          NOTRUN -> [SKIP][75] ([i915#3281]) +7 other tests skip
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_exec_reloc@basic-write-gtt.html

  * igt@gem_exec_suspend@basic-s0@lmem0:
    - shard-dg2:          [PASS][76] -> [INCOMPLETE][77] ([i915#9275])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-5/igt@gem_exec_suspend@basic-s0@lmem0.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_exec_suspend@basic-s0@lmem0.html

  * igt@gem_exec_suspend@basic-s4-devices@lmem0:
    - shard-dg2:          NOTRUN -> [ABORT][78] ([i915#7975] / [i915#8213])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_exec_suspend@basic-s4-devices@lmem0.html

  * igt@gem_fence_thrash@bo-copy:
    - shard-dg2:          NOTRUN -> [SKIP][79] ([i915#4860]) +1 other test skip
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_fence_thrash@bo-copy.html

  * igt@gem_fenced_exec_thrash@no-spare-fences:
    - shard-dg1:          NOTRUN -> [SKIP][80] ([i915#4860]) +1 other test skip
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_fenced_exec_thrash@no-spare-fences.html

  * igt@gem_lmem_swapping@heavy-verify-multi-ccs:
    - shard-tglu:         NOTRUN -> [SKIP][81] ([i915#4613]) +1 other test skip
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_lmem_swapping@heavy-verify-multi-ccs.html

  * igt@gem_lmem_swapping@verify-ccs:
    - shard-glk:          NOTRUN -> [SKIP][82] ([fdo#109271] / [i915#4613]) +3 other tests skip
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@gem_lmem_swapping@verify-ccs.html

  * igt@gem_lmem_swapping@verify-ccs@lmem0:
    - shard-dg1:          NOTRUN -> [SKIP][83] ([i915#4565])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_lmem_swapping@verify-ccs@lmem0.html

  * igt@gem_lmem_swapping@verify-random-ccs:
    - shard-mtlp:         NOTRUN -> [SKIP][84] ([i915#4613])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_lmem_swapping@verify-random-ccs.html

  * igt@gem_mmap_gtt@basic-small-bo:
    - shard-dg2:          NOTRUN -> [SKIP][85] ([i915#4077]) +4 other tests skip
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_mmap_gtt@basic-small-bo.html

  * igt@gem_mmap_gtt@cpuset-medium-copy-odd:
    - shard-dg1:          NOTRUN -> [SKIP][86] ([i915#4077])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_mmap_gtt@cpuset-medium-copy-odd.html

  * igt@gem_mmap_gtt@ptrace:
    - shard-mtlp:         NOTRUN -> [SKIP][87] ([i915#4077]) +1 other test skip
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_mmap_gtt@ptrace.html

  * igt@gem_mmap_wc@fault-concurrent:
    - shard-dg2:          NOTRUN -> [SKIP][88] ([i915#4083]) +3 other tests skip
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_mmap_wc@fault-concurrent.html

  * igt@gem_partial_pwrite_pread@writes-after-reads-display:
    - shard-dg2:          NOTRUN -> [SKIP][89] ([i915#3282]) +6 other tests skip
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_partial_pwrite_pread@writes-after-reads-display.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-tglu:         NOTRUN -> [WARN][90] ([i915#2658])
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_pxp@protected-raw-src-copy-not-readible:
    - shard-mtlp:         NOTRUN -> [SKIP][91] ([i915#4270])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_pxp@protected-raw-src-copy-not-readible.html

  * igt@gem_pxp@verify-pxp-execution-after-suspend-resume:
    - shard-dg1:          NOTRUN -> [SKIP][92] ([i915#4270]) +1 other test skip
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_pxp@verify-pxp-execution-after-suspend-resume.html

  * igt@gem_readwrite@read-write:
    - shard-dg1:          NOTRUN -> [SKIP][93] ([i915#3282])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_readwrite@read-write.html

  * igt@gem_render_copy@mixed-tiled-to-y-tiled-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][94] ([i915#5190]) +5 other tests skip
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_render_copy@mixed-tiled-to-y-tiled-ccs.html

  * igt@gem_render_copy@y-tiled-ccs-to-y-tiled-mc-ccs:
    - shard-mtlp:         NOTRUN -> [SKIP][95] ([i915#8428])
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_render_copy@y-tiled-ccs-to-y-tiled-mc-ccs.html

  * igt@gem_render_tiled_blits@basic:
    - shard-dg2:          NOTRUN -> [SKIP][96] ([i915#4079])
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_render_tiled_blits@basic.html

  * igt@gem_set_tiling_vs_blt@tiled-to-untiled:
    - shard-mtlp:         NOTRUN -> [SKIP][97] ([i915#4079])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_set_tiling_vs_blt@tiled-to-untiled.html

  * igt@gem_softpin@evict-snoop-interruptible:
    - shard-dg2:          NOTRUN -> [SKIP][98] ([i915#4885])
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_softpin@evict-snoop-interruptible.html

  * igt@gem_userptr_blits@coherency-unsync:
    - shard-dg2:          NOTRUN -> [SKIP][99] ([i915#3297])
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_userptr_blits@coherency-unsync.html
    - shard-dg1:          NOTRUN -> [SKIP][100] ([i915#3297])
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_userptr_blits@coherency-unsync.html

  * igt@gem_userptr_blits@dmabuf-sync:
    - shard-mtlp:         NOTRUN -> [SKIP][101] ([i915#3297])
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_userptr_blits@dmabuf-sync.html

  * igt@gen7_exec_parse@basic-allowed:
    - shard-tglu:         NOTRUN -> [SKIP][102] ([fdo#109289]) +3 other tests skip
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gen7_exec_parse@basic-allowed.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [PASS][103] -> [ABORT][104] ([i915#5566])
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/igt@gen9_exec_parse@allowed-all.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/igt@gen9_exec_parse@allowed-all.html

  * igt@gen9_exec_parse@bb-start-far:
    - shard-dg2:          NOTRUN -> [SKIP][105] ([i915#2856]) +1 other test skip
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gen9_exec_parse@bb-start-far.html

  * igt@gen9_exec_parse@bb-start-param:
    - shard-mtlp:         NOTRUN -> [SKIP][106] ([i915#2856])
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gen9_exec_parse@bb-start-param.html

  * igt@i915_pm_freq_api@freq-basic-api:
    - shard-tglu:         NOTRUN -> [SKIP][107] ([i915#8399])
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@i915_pm_freq_api@freq-basic-api.html

  * igt@i915_pm_rps@min-max-config-loaded:
    - shard-dg2:          NOTRUN -> [SKIP][108] ([i915#6621])
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@i915_pm_rps@min-max-config-loaded.html

  * igt@intel_hwmon@hwmon-write:
    - shard-mtlp:         NOTRUN -> [SKIP][109] ([i915#7707])
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@intel_hwmon@hwmon-write.html

  * igt@kms_addfb_basic@basic-y-tiled-legacy:
    - shard-dg2:          NOTRUN -> [SKIP][110] ([i915#4215] / [i915#5190])
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_addfb_basic@basic-y-tiled-legacy.html

  * igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-2-y-rc-ccs-cc:
    - shard-rkl:          NOTRUN -> [SKIP][111] ([i915#8709]) +3 other tests skip
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-2-y-rc-ccs-cc.html

  * igt@kms_big_fb@4-tiled-16bpp-rotate-90:
    - shard-dg1:          NOTRUN -> [SKIP][112] ([i915#4538] / [i915#5286]) +1 other test skip
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_big_fb@4-tiled-16bpp-rotate-90.html

  * igt@kms_big_fb@4-tiled-8bpp-rotate-90:
    - shard-tglu:         NOTRUN -> [SKIP][113] ([fdo#111615] / [i915#5286]) +1 other test skip
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@4-tiled-8bpp-rotate-90.html

  * igt@kms_big_fb@linear-8bpp-rotate-90:
    - shard-dg2:          NOTRUN -> [SKIP][114] ([fdo#111614]) +4 other tests skip
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_big_fb@linear-8bpp-rotate-90.html

  * igt@kms_big_fb@x-tiled-8bpp-rotate-270:
    - shard-mtlp:         NOTRUN -> [SKIP][115] ([fdo#111614]) +2 other tests skip
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_big_fb@x-tiled-8bpp-rotate-270.html

  * igt@kms_big_fb@y-tiled-64bpp-rotate-90:
    - shard-tglu:         NOTRUN -> [SKIP][116] ([fdo#111614])
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@y-tiled-64bpp-rotate-90.html

  * igt@kms_big_fb@y-tiled-8bpp-rotate-270:
    - shard-dg1:          NOTRUN -> [SKIP][117] ([i915#3638]) +1 other test skip
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_big_fb@y-tiled-8bpp-rotate-270.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
    - shard-mtlp:         NOTRUN -> [SKIP][118] ([fdo#111615]) +2 other tests skip
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip:
    - shard-dg2:          NOTRUN -> [SKIP][119] ([i915#4538] / [i915#5190]) +6 other tests skip
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip:
    - shard-tglu:         [PASS][120] -> [FAIL][121] ([i915#3743]) +1 other test fail
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-5/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-7/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-180:
    - shard-tglu:         NOTRUN -> [SKIP][122] ([fdo#111615])
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@yf-tiled-32bpp-rotate-180.html

  * igt@kms_big_fb@yf-tiled-8bpp-rotate-90:
    - shard-dg1:          NOTRUN -> [SKIP][123] ([i915#4538])
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_big_fb@yf-tiled-8bpp-rotate-90.html

  * igt@kms_cdclk@mode-transition:
    - shard-dg1:          NOTRUN -> [SKIP][124] ([i915#3742])
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_cdclk@mode-transition.html

  * igt@kms_cdclk@mode-transition-all-outputs:
    - shard-mtlp:         NOTRUN -> [SKIP][125] ([i915#7213] / [i915#9010])
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cdclk@mode-transition-all-outputs.html

  * igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][126] ([i915#4087]) +3 other tests skip
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-6/igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3.html

  * igt@kms_chamelium_audio@dp-audio:
    - shard-tglu:         NOTRUN -> [SKIP][127] ([i915#7828]) +2 other tests skip
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_chamelium_audio@dp-audio.html

  * igt@kms_chamelium_color@ctm-0-50:
    - shard-dg2:          NOTRUN -> [SKIP][128] ([fdo#111827])
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_chamelium_color@ctm-0-50.html

  * igt@kms_chamelium_color@ctm-red-to-blue:
    - shard-dg1:          NOTRUN -> [SKIP][129] ([fdo#111827])
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_chamelium_color@ctm-red-to-blue.html

  * igt@kms_chamelium_frames@hdmi-crc-fast:
    - shard-dg2:          NOTRUN -> [SKIP][130] ([i915#7828]) +6 other tests skip
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_chamelium_frames@hdmi-crc-fast.html

  * igt@kms_chamelium_hpd@hdmi-hpd-storm-disable:
    - shard-mtlp:         NOTRUN -> [SKIP][131] ([i915#7828]) +1 other test skip
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_chamelium_hpd@hdmi-hpd-storm-disable.html

  * igt@kms_chamelium_hpd@vga-hpd-after-suspend:
    - shard-dg1:          NOTRUN -> [SKIP][132] ([i915#7828]) +2 other tests skip
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_chamelium_hpd@vga-hpd-after-suspend.html

  * igt@kms_content_protection@dp-mst-lic-type-0:
    - shard-mtlp:         NOTRUN -> [SKIP][133] ([i915#3299])
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_content_protection@dp-mst-lic-type-0.html

  * igt@kms_content_protection@lic-type-0:
    - shard-dg2:          NOTRUN -> [SKIP][134] ([i915#9424])
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_content_protection@lic-type-0.html

  * igt@kms_content_protection@type1:
    - shard-dg2:          NOTRUN -> [SKIP][135] ([i915#7118] / [i915#9424]) +1 other test skip
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_content_protection@type1.html

  * igt@kms_cursor_crc@cursor-offscreen-512x170:
    - shard-dg2:          NOTRUN -> [SKIP][136] ([i915#3359]) +1 other test skip
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_cursor_crc@cursor-offscreen-512x170.html

  * igt@kms_cursor_crc@cursor-onscreen-512x512:
    - shard-mtlp:         NOTRUN -> [SKIP][137] ([i915#3359])
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-onscreen-512x512.html

  * igt@kms_cursor_crc@cursor-rapid-movement-256x85:
    - shard-mtlp:         NOTRUN -> [SKIP][138] ([i915#8814])
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-rapid-movement-256x85.html

  * igt@kms_cursor_crc@cursor-sliding-max-size:
    - shard-mtlp:         NOTRUN -> [SKIP][139] ([i915#3555] / [i915#8814])
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-sliding-max-size.html

  * igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
    - shard-dg2:          NOTRUN -> [SKIP][140] ([fdo#109274] / [i915#5354]) +2 other tests skip
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - shard-mtlp:         NOTRUN -> [SKIP][141] ([i915#4213])
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size:
    - shard-snb:          [PASS][142] -> [SKIP][143] ([fdo#109271]) +3 other tests skip
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html

  * igt@kms_cursor_legacy@cursorb-vs-flipa-legacy:
    - shard-mtlp:         NOTRUN -> [SKIP][144] ([i915#9809]) +1 other test skip
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_legacy@cursorb-vs-flipa-legacy.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions:
    - shard-tglu:         NOTRUN -> [SKIP][145] ([fdo#109274] / [fdo#111767])
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions-varying-size:
    - shard-tglu:         NOTRUN -> [SKIP][146] ([fdo#109274])
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions-varying-size.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][147] ([fdo#110189] / [i915#9723])
   [147]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-3/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-2.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-3:
    - shard-dg1:          NOTRUN -> [SKIP][148] ([fdo#110189] / [i915#9723])
   [148]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-12/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-3.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-vga-1:
    - shard-snb:          NOTRUN -> [SKIP][149] ([fdo#109271] / [fdo#110189])
   [149]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-vga-1.html

  * igt@kms_dither@fb-8bpc-vs-panel-6bpc:
    - shard-dg1:          NOTRUN -> [SKIP][150] ([i915#3555]) +1 other test skip
   [150]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_dither@fb-8bpc-vs-panel-6bpc.html

  * igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-1:
    - shard-rkl:          NOTRUN -> [SKIP][151] ([i915#3804])
   [151]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-1.html

  * igt@kms_draw_crc@draw-method-mmap-gtt:
    - shard-mtlp:         NOTRUN -> [SKIP][152] ([i915#3555] / [i915#8812])
   [152]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_draw_crc@draw-method-mmap-gtt.html

  * igt@kms_dsc@dsc-fractional-bpp:
    - shard-mtlp:         NOTRUN -> [SKIP][153] ([i915#3840] / [i915#9688])
   [153]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_dsc@dsc-fractional-bpp.html

  * igt@kms_dsc@dsc-with-output-formats-with-bpc:
    - shard-dg2:          NOTRUN -> [SKIP][154] ([i915#3840] / [i915#9053])
   [154]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_dsc@dsc-with-output-formats-with-bpc.html

  * igt@kms_feature_discovery@chamelium:
    - shard-dg2:          NOTRUN -> [SKIP][155] ([i915#4854])
   [155]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_feature_discovery@chamelium.html

  * igt@kms_flip@2x-flip-vs-expired-vblank:
    - shard-mtlp:         NOTRUN -> [SKIP][156] ([i915#3637])
   [156]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_flip@2x-flip-vs-expired-vblank.html

  * igt@kms_flip@2x-flip-vs-fences-interruptible:
    - shard-dg2:          NOTRUN -> [SKIP][157] ([i915#8381])
   [157]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_flip@2x-flip-vs-fences-interruptible.html

  * igt@kms_flip@2x-flip-vs-modeset:
    - shard-tglu:         NOTRUN -> [SKIP][158] ([fdo#109274] / [i915#3637] / [i915#3966]) +1 other test skip
   [158]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip@2x-flip-vs-modeset.html

  * igt@kms_flip@2x-flip-vs-modeset-vs-hang:
    - shard-dg2:          NOTRUN -> [SKIP][159] ([fdo#109274]) +5 other tests skip
   [159]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_flip@2x-flip-vs-modeset-vs-hang.html

  * igt@kms_flip@2x-flip-vs-panning-vs-hang:
    - shard-dg1:          NOTRUN -> [SKIP][160] ([fdo#111825] / [i915#9934]) +2 other tests skip
   [160]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_flip@2x-flip-vs-panning-vs-hang.html

  * igt@kms_flip@2x-flip-vs-suspend-interruptible:
    - shard-tglu:         NOTRUN -> [SKIP][161] ([fdo#109274] / [i915#3637])
   [161]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip@2x-flip-vs-suspend-interruptible.html

  * igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling@pipe-a-valid-mode:
    - shard-tglu:         NOTRUN -> [SKIP][162] ([i915#2587] / [i915#2672])
   [162]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling@pipe-a-valid-mode:
    - shard-dg1:          NOTRUN -> [SKIP][163] ([i915#2587] / [i915#2672]) +1 other test skip
   [163]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling@pipe-a-valid-mode:
    - shard-dg2:          NOTRUN -> [SKIP][164] ([i915#2672]) +3 other tests skip
   [164]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling@pipe-a-valid-mode.html

  * igt@kms_force_connector_basic@force-load-detect:
    - shard-dg2:          NOTRUN -> [SKIP][165] ([fdo#109285])
   [165]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move:
    - shard-mtlp:         NOTRUN -> [SKIP][166] ([i915#1825]) +7 other tests skip
   [166]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][167] ([fdo#111767] / [i915#5354])
   [167]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render:
    - shard-tglu:         NOTRUN -> [SKIP][168] ([fdo#109280]) +8 other tests skip
   [168]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][169] ([i915#5354]) +21 other tests skip
   [169]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render:
    - shard-dg1:          NOTRUN -> [SKIP][170] ([fdo#111825]) +6 other tests skip
   [170]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt:
    - shard-mtlp:         NOTRUN -> [SKIP][171] ([i915#8708]) +3 other tests skip
   [171]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite:
    - shard-dg2:          NOTRUN -> [SKIP][172] ([i915#3458]) +14 other tests skip
   [172]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move:
    - shard-dg1:          NOTRUN -> [SKIP][173] ([i915#3458]) +4 other tests skip
   [173]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move.html

  * igt@kms_frontbuffer_tracking@plane-fbc-rte:
    - shard-glk:          NOTRUN -> [SKIP][174] ([fdo#109271]) +104 other tests skip
   [174]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_frontbuffer_tracking@plane-fbc-rte.html
    - shard-dg1:          NOTRUN -> [SKIP][175] ([i915#10070])
   [175]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@plane-fbc-rte.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt:
    - shard-dg2:          NOTRUN -> [SKIP][176] ([i915#8708]) +6 other tests skip
   [176]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc:
    - shard-dg1:          NOTRUN -> [SKIP][177] ([i915#8708]) +4 other tests skip
   [177]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc.html

  * igt@kms_getfb@getfb-reject-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][178] ([i915#6118])
   [178]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_getfb@getfb-reject-ccs.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-dg2:          NOTRUN -> [SKIP][179] ([i915#3555] / [i915#8228]) +1 other test skip
   [179]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c:
    - shard-dg2:          NOTRUN -> [SKIP][180] ([fdo#109289]) +2 other tests skip
   [180]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c.html

  * igt@kms_plane_scaling@2x-scaler-multi-pipe:
    - shard-dg2:          NOTRUN -> [SKIP][181] ([fdo#109274] / [i915#5354] / [i915#9423])
   [181]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_plane_scaling@2x-scaler-multi-pipe.html

  * igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-3:
    - shard-dg1:          NOTRUN -> [FAIL][182] ([i915#8292])
   [182]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-3.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format@pipe-b-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][183] ([i915#9423]) +7 other tests skip
   [183]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format@pipe-b-hdmi-a-3.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-a-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][184] ([i915#9423]) +11 other tests skip
   [184]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-19/igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-a-hdmi-a-4.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-1:
    - shard-rkl:          NOTRUN -> [SKIP][185] ([i915#5176] / [i915#9423]) +1 other test skip
   [185]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-1.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][186] ([i915#5176] / [i915#9423]) +3 other tests skip
   [186]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-16/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4.html

  * igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][187] ([i915#9423]) +5 other tests skip
   [187]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-a-hdmi-a-2.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20@pipe-b-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][188] ([i915#5235]) +11 other tests skip
   [188]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-6/igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20@pipe-b-hdmi-a-2.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][189] ([i915#5235]) +15 other tests skip
   [189]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-16/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-hdmi-a-4.html

  * igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-d-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][190] ([i915#5235] / [i915#9423]) +3 other tests skip
   [190]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-6/igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-d-hdmi-a-3.html

  * igt@kms_pm_dc@dc3co-vpb-simulation:
    - shard-dg2:          NOTRUN -> [SKIP][191] ([i915#9685])
   [191]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_pm_dc@dc3co-vpb-simulation.html

  * igt@kms_pm_dc@dc5-psr:
    - shard-tglu:         NOTRUN -> [SKIP][192] ([i915#9685])
   [192]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_pm_dc@dc5-psr.html

  * igt@kms_pm_rpm@i2c:
    - shard-dg2:          [PASS][193] -> [FAIL][194] ([i915#8717])
   [193]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@i2c.html
   [194]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@i2c.html

  * igt@kms_pm_rpm@modeset-lpsp:
    - shard-dg2:          NOTRUN -> [SKIP][195] ([i915#9519])
   [195]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_pm_rpm@modeset-lpsp.html

  * igt@kms_pm_rpm@modeset-lpsp-stress:
    - shard-dg2:          [PASS][196] -> [SKIP][197] ([i915#9519])
   [196]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@modeset-lpsp-stress.html
   [197]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@modeset-lpsp-stress.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait:
    - shard-rkl:          [PASS][198] -> [SKIP][199] ([i915#9519]) +1 other test skip
   [198]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-3/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html
   [199]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html

  * igt@kms_prime@basic-modeset-hybrid:
    - shard-dg2:          NOTRUN -> [SKIP][200] ([i915#6524] / [i915#6805])
   [200]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_prime@basic-modeset-hybrid.html

  * igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf:
    - shard-glk:          NOTRUN -> [SKIP][201] ([fdo#109271] / [fdo#110189]) +1 other test skip
   [201]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf.html

  * igt@kms_psr2_sf@fbc-primary-plane-update-sf-dmg-area:
    - shard-tglu:         NOTRUN -> [SKIP][202] ([fdo#110189]) +7 other tests skip
   [202]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_psr2_sf@fbc-primary-plane-update-sf-dmg-area.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf:
    - shard-dg2:          NOTRUN -> [SKIP][203] ([fdo#110189]) +2 other tests skip
   [203]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf:
    - shard-dg1:          NOTRUN -> [SKIP][204] ([fdo#110189])
   [204]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-mtlp:         NOTRUN -> [SKIP][205] ([i915#4348])
   [205]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_psr@fbc-psr-primary-mmap-gtt@edp-1:
    - shard-mtlp:         NOTRUN -> [SKIP][206] ([i915#9688]) +2 other tests skip
   [206]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_psr@fbc-psr-primary-mmap-gtt@edp-1.html

  * igt@kms_psr@psr-cursor-render:
    - shard-dg2:          NOTRUN -> [SKIP][207] ([i915#9732]) +15 other tests skip
   [207]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_psr@psr-cursor-render.html

  * igt@kms_psr@psr2-primary-mmap-cpu:
    - shard-dg1:          NOTRUN -> [SKIP][208] ([i915#9732]) +4 other tests skip
   [208]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_psr@psr2-primary-mmap-cpu.html

  * igt@kms_psr@psr2-sprite-mmap-gtt:
    - shard-tglu:         NOTRUN -> [SKIP][209] ([i915#9732]) +3 other tests skip
   [209]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_psr@psr2-sprite-mmap-gtt.html

  * igt@kms_rotation_crc@primary-y-tiled-reflect-x-180:
    - shard-rkl:          [PASS][210] -> [INCOMPLETE][211] ([i915#8875] / [i915#9569])
   [210]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@kms_rotation_crc@primary-y-tiled-reflect-x-180.html
   [211]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_rotation_crc@primary-y-tiled-reflect-x-180.html

  * igt@kms_rotation_crc@sprite-rotation-90:
    - shard-dg2:          NOTRUN -> [SKIP][212] ([i915#4235]) +2 other tests skip
   [212]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_rotation_crc@sprite-rotation-90.html

  * igt@kms_rotation_crc@sprite-rotation-90-pos-100-0:
    - shard-mtlp:         NOTRUN -> [SKIP][213] ([i915#4235]) +1 other test skip
   [213]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.html

  * igt@kms_scaling_modes@scaling-mode-center:
    - shard-tglu:         NOTRUN -> [SKIP][214] ([i915#3555]) +1 other test skip
   [214]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_scaling_modes@scaling-mode-center.html

  * igt@kms_setmode@invalid-clone-single-crtc-stealing:
    - shard-dg2:          NOTRUN -> [SKIP][215] ([i915#3555]) +3 other tests skip
   [215]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_setmode@invalid-clone-single-crtc-stealing.html

  * igt@kms_tiled_display@basic-test-pattern-with-chamelium:
    - shard-mtlp:         NOTRUN -> [SKIP][216] ([i915#8623])
   [216]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html

  * igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1:
    - shard-rkl:          [PASS][217] -> [FAIL][218] ([i915#9196])
   [217]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-2/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
   [218]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-5/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html

  * igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1:
    - shard-tglu:         [PASS][219] -> [FAIL][220] ([i915#9196])
   [219]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-7/igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1.html
   [220]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-9/igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1.html

  * igt@kms_vrr@seamless-rr-switch-vrr:
    - shard-dg2:          NOTRUN -> [SKIP][221] ([i915#9906])
   [221]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_vrr@seamless-rr-switch-vrr.html

  * igt@kms_writeback@writeback-fb-id-xrgb2101010:
    - shard-dg2:          NOTRUN -> [SKIP][222] ([i915#2437] / [i915#9412])
   [222]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_writeback@writeback-fb-id-xrgb2101010.html

  * igt@kms_writeback@writeback-pixel-formats:
    - shard-glk:          NOTRUN -> [SKIP][223] ([fdo#109271] / [i915#2437])
   [223]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_writeback@writeback-pixel-formats.html
    - shard-dg1:          NOTRUN -> [SKIP][224] ([i915#2437] / [i915#9412])
   [224]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_writeback@writeback-pixel-formats.html

  * igt@perf@mi-rpc:
    - shard-dg2:          NOTRUN -> [SKIP][225] ([i915#2434] / [i915#7387])
   [225]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@perf@mi-rpc.html

  * igt@perf_pmu@event-wait@rcs0:
    - shard-tglu:         NOTRUN -> [SKIP][226] ([fdo#112283])
   [226]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@perf_pmu@event-wait@rcs0.html

  * igt@perf_pmu@frequency@gt0:
    - shard-dg2:          NOTRUN -> [FAIL][227] ([i915#6806])
   [227]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@perf_pmu@frequency@gt0.html
    - shard-dg1:          NOTRUN -> [FAIL][228] ([i915#6806])
   [228]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@perf_pmu@frequency@gt0.html

  * igt@perf_pmu@rc6@other-idle-gt0:
    - shard-tglu:         NOTRUN -> [SKIP][229] ([i915#8516])
   [229]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@perf_pmu@rc6@other-idle-gt0.html

  * igt@prime_udl:
    - shard-dg2:          NOTRUN -> [SKIP][230] ([fdo#109291])
   [230]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@prime_udl.html

  * igt@prime_vgem@basic-write:
    - shard-dg2:          NOTRUN -> [SKIP][231] ([i915#3291] / [i915#3708])
   [231]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@prime_vgem@basic-write.html

  * igt@prime_vgem@fence-read-hang:
    - shard-tglu:         NOTRUN -> [SKIP][232] ([fdo#109295])
   [232]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@prime_vgem@fence-read-hang.html

  * igt@prime_vgem@fence-write-hang:
    - shard-dg1:          NOTRUN -> [SKIP][233] ([i915#3708]) +1 other test skip
   [233]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@prime_vgem@fence-write-hang.html

  * igt@sriov_basic@enable-vfs-autoprobe-on:
    - shard-dg1:          NOTRUN -> [SKIP][234] ([i915#9917])
   [234]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@sriov_basic@enable-vfs-autoprobe-on.html

  * igt@sriov_basic@enable-vfs-bind-unbind-each:
    - shard-mtlp:         NOTRUN -> [SKIP][235] ([i915#9917])
   [235]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@sriov_basic@enable-vfs-bind-unbind-each.html

  * igt@syncobj_wait@invalid-wait-zero-handles:
    - shard-dg1:          NOTRUN -> [FAIL][236] ([i915#9779])
   [236]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@syncobj_wait@invalid-wait-zero-handles.html

  * igt@v3d/v3d_perfmon@create-two-perfmon:
    - shard-dg1:          NOTRUN -> [SKIP][237] ([i915#2575]) +2 other tests skip
   [237]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@v3d/v3d_perfmon@create-two-perfmon.html

  * igt@v3d/v3d_submit_cl@single-out-sync:
    - shard-tglu:         NOTRUN -> [SKIP][238] ([fdo#109315] / [i915#2575]) +2 other tests skip
   [238]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@v3d/v3d_submit_cl@single-out-sync.html

  * igt@v3d/v3d_submit_csd@bad-extension:
    - shard-mtlp:         NOTRUN -> [SKIP][239] ([i915#2575]) +1 other test skip
   [239]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@v3d/v3d_submit_csd@bad-extension.html

  * igt@v3d/v3d_submit_csd@single-out-sync:
    - shard-dg2:          NOTRUN -> [SKIP][240] ([i915#2575]) +9 other tests skip
   [240]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@v3d/v3d_submit_csd@single-out-sync.html

  * igt@vc4/vc4_label_bo@set-bad-name:
    - shard-mtlp:         NOTRUN -> [SKIP][241] ([i915#7711]) +1 other test skip
   [241]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@vc4/vc4_label_bo@set-bad-name.html

  * igt@vc4/vc4_perfmon@create-perfmon-0:
    - shard-tglu:         NOTRUN -> [SKIP][242] ([i915#2575])
   [242]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@vc4/vc4_perfmon@create-perfmon-0.html

  * igt@vc4/vc4_tiling@set-bad-modifier:
    - shard-dg1:          NOTRUN -> [SKIP][243] ([i915#7711]) +1 other test skip
   [243]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@vc4/vc4_tiling@set-bad-modifier.html

  * igt@vc4/vc4_wait_bo@bad-bo:
    - shard-dg2:          NOTRUN -> [SKIP][244] ([i915#7711]) +4 other tests skip
   [244]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@vc4/vc4_wait_bo@bad-bo.html

  
#### Possible fixes ####

  * igt@drm_fdinfo@most-busy-idle-check-all@rcs0:
    - shard-rkl:          [FAIL][245] ([i915#7742]) -> [PASS][246]
   [245]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html
   [246]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-5/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html

  * igt@gem_ctx_exec@basic-nohangcheck:
    - shard-tglu:         [FAIL][247] ([i915#6268]) -> [PASS][248]
   [247]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-4/igt@gem_ctx_exec@basic-nohangcheck.html
   [248]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-3/igt@gem_ctx_exec@basic-nohangcheck.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-rkl:          [FAIL][249] ([i915#2842]) -> [PASS][250]
   [249]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@gem_exec_fair@basic-none@vecs0.html
   [250]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [FAIL][251] ([i915#2842]) -> [PASS][252]
   [251]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/igt@gem_exec_fair@basic-throttle@rcs0.html
   [252]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_lmem_swapping@smem-oom@lmem0:
    - shard-dg1:          [TIMEOUT][253] ([i915#5493]) -> [PASS][254]
   [253]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-17/igt@gem_lmem_swapping@smem-oom@lmem0.html
   [254]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-15/igt@gem_lmem_swapping@smem-oom@lmem0.html

  * igt@i915_module_load@reload-with-fault-injection:
    - shard-dg1:          [INCOMPLETE][255] ([i915#10137] / [i915#9820] / [i915#9849]) -> [PASS][256]
   [255]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-16/igt@i915_module_load@reload-with-fault-injection.html
   [256]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@i915_module_load@reload-with-fault-injection.html

  * igt@i915_suspend@basic-s3-without-i915:
    - shard-rkl:          [FAIL][257] ([i915#10031]) -> [PASS][258]
   [257]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-4/igt@i915_suspend@basic-s3-without-i915.html
   [258]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-2/igt@i915_suspend@basic-s3-without-i915.html

  * igt@kms_big_fb@4-tiled-64bpp-rotate-180:
    - shard-mtlp:         [FAIL][259] ([i915#3763] / [i915#5138]) -> [PASS][260]
   [259]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-mtlp-4/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html
   [260]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-8/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
    - shard-tglu:         [FAIL][261] ([i915#3743]) -> [PASS][262]
   [261]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-9/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
   [262]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-6/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html

  * igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic:
    - shard-snb:          [SKIP][263] ([fdo#109271] / [fdo#111767]) -> [PASS][264]
   [263]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html
   [264]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-varying-size:
    - shard-snb:          [SKIP][265] ([fdo#109271]) -> [PASS][266] +3 other tests pass
   [265]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_cursor_legacy@cursora-vs-flipb-varying-size.html
   [266]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_cursor_legacy@cursora-vs-flipb-varying-size.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-glk:          [FAIL][267] ([i915#2346]) -> [PASS][268]
   [267]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [268]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_pm_rpm@modeset-non-lpsp:
    - shard-dg2:          [SKIP][269] ([i915#9519]) -> [PASS][270]
   [269]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@modeset-non-lpsp.html
   [270]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@modeset-non-lpsp.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress:
    - shard-rkl:          [SKIP][271] ([i915#9519]) -> [PASS][272] +2 other tests pass
   [271]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
   [272]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-3/igt@kms_pm_rpm@modeset-non-lpsp-stress.html

  * igt@perf@non-zero-reason@0-rcs0:
    - shard-dg2:          [FAIL][273] ([i915#7484]) -> [PASS][274]
   [273]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@perf@non-zero-reason@0-rcs0.html
   [274]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@perf@non-zero-reason@0-rcs0.html

  
#### Warnings ####

  * igt@kms_content_protection@atomic:
    - shard-snb:          [INCOMPLETE][275] ([i915#8816]) -> [SKIP][276] ([fdo#109271])
   [275]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_content_protection@atomic.html
   [276]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@mei-interface:
    - shard-dg1:          [SKIP][277] ([i915#9424]) -> [SKIP][278] ([i915#9433])
   [277]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-15/igt@kms_content_protection@mei-interface.html
   [278]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-12/igt@kms_content_protection@mei-interface.html
    - shard-snb:          [SKIP][279] ([fdo#109271]) -> [INCOMPLETE][280] ([i915#9878])
   [279]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_content_protection@mei-interface.html
   [280]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_content_protection@mei-interface.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc:
    - shard-snb:          [SKIP][281] ([fdo#109271] / [fdo#111767]) -> [SKIP][282] ([fdo#109271])
   [281]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc.html
   [282]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render:
    - shard-snb:          [SKIP][283] ([fdo#109271]) -> [SKIP][284] ([fdo#109271] / [fdo#111767])
   [283]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html
   [284]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
    - shard-rkl:          [SKIP][285] ([i915#4070] / [i915#4816]) -> [SKIP][286] ([i915#4816])
   [285]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
   [286]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html

  * igt@kms_pm_dc@dc6-dpms:
    - shard-rkl:          [FAIL][287] ([i915#9295]) -> [SKIP][288] ([i915#3361])
   [287]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@kms_pm_dc@dc6-dpms.html
   [288]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@kms_pm_dc@dc6-dpms.html

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

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111767]: https://bugs.freedesktop.org/show_bug.cgi?id=111767
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
  [i915#10031]: https://gitlab.freedesktop.org/drm/intel/issues/10031
  [i915#10070]: https://gitlab.freedesktop.org/drm/intel/issues/10070
  [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
  [i915#10307]: https://gitlab.freedesktop.org/drm/intel/issues/10307
  [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2434]: https://gitlab.freedesktop.org/drm/intel/issues/2434
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#280]: https://gitlab.freedesktop.org/drm/intel/issues/280
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
  [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
  [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3299]: https://gitlab.freedesktop.org/drm/intel/issues/3299
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3361]: https://gitlab.freedesktop.org/drm/intel/issues/3361
  [i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
  [i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#3742]: https://gitlab.freedesktop.org/drm/intel/issues/3742
  [i915#3743]: https://gitlab.freedesktop.org/drm/intel/issues/3743
  [i915#3763]: https://gitlab.freedesktop.org/drm/intel/issues/3763
  [i915#3804]: https://gitlab.freedesktop.org/drm/intel/issues/3804
  [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
  [i915#3966]: https://gitlab.freedesktop.org/drm/intel/issues/3966
  [i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4087]: https://gitlab.freedesktop.org/drm/intel/issues/4087
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#4235]: https://gitlab.freedesktop.org/drm/intel/issues/4235
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4348]: https://gitlab.freedesktop.org/drm/intel/issues/4348
  [i915#4473]: https://gitlab.freedesktop.org/drm/intel/issues/4473
  [i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
  [i915#4565]: https://gitlab.freedesktop.org/drm/intel/issues/4565
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4771]: https://gitlab.freedesktop.org/drm/intel/issues/4771
  [i915#4812]: https://gitlab.freedesktop.org/drm/intel/issues/4812
  [i915#4816]: https://gitlab.freedesktop.org/drm/intel/issues/4816
  [i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
  [i915#4854]: https://gitlab.freedesktop.org/drm/intel/issues/4854
  [i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
  [i915#4885]: https://gitlab.freedesktop.org/drm/intel/issues/4885
  [i915#5107]: https://gitlab.freedesktop.org/drm/intel/issues/5107
  [i915#5138]: https://gitlab.freedesktop.org/drm/intel/issues/5138
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
  [i915#5493]: https://gitlab.freedesktop.org/drm/intel/issues/5493
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
  [i915#6118]: https://gitlab.freedesktop.org/drm/intel/issues/6118
  [i915#6268]: https://gitlab.freedesktop.org/drm/intel/issues/6268
  [i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
  [i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
  [i915#6805]: https://gitlab.freedesktop.org/drm/intel/issues/6805
  [i915#6806]: https://gitlab.freedesktop.org/drm/intel/issues/6806
  [i915#7118]: https://gitlab.freedesktop.org/drm/intel/issues/7118
  [i915#7213]: https://gitlab.freedesktop.org/drm/intel/issues/7213
  [i915#7387]: https://gitlab.freedesktop.org/drm/intel/issues/7387
  [i915#7484]: https://gitlab.freedesktop.org/drm/intel/issues/7484
  [i915#7701]: https://gitlab.freedesktop.org/drm/intel/issues/7701
  [i915#7707]: https://gitlab.freedesktop.org/drm/intel/issues/7707
  [i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
  [i915#7742]: https://gitlab.freedesktop.org/drm/intel/issues/7742
  [i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
  [i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
  [i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
  [i915#8228]: https://gitlab.freedesktop.org/drm/intel/issues/8228
  [i915#8292]: https://gitlab.freedesktop.org/drm/intel/issues/8292
  [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293
  [i915#8381]: https://gitlab.freedesktop.org/drm/intel/issues/8381
  [i915#8399]: https://gitlab.freedesktop.org/drm/intel/issues/8399
  [i915#8411]: https://gitlab.freedesktop.org/drm/intel/issues/8411
  [i915#8414]: https://gitlab.freedesktop.org/drm/intel/issues/8414
  [i915#8428]: https://gitlab.freedesktop.org/drm/intel/issues/8428
  [i915#8516]: https://gitlab.freedesktop.org/drm/intel/issues/8516
  [i915#8555]: https://gitlab.freedesktop.org/drm/intel/issues/8555
  [i915#8623]: https://gitlab.freedesktop.org/drm/intel/issues/8623
  [i915#8708]: https://gitlab.freedesktop.org/drm/intel/issues/8708
  [i915#8709]: https://gitlab.freedesktop.org/drm/intel/issues/8709
  [i915#8717]: https://gitlab.freedesktop.org/drm/intel/issues/8717
  [i915#8812]: https://gitlab.freedesktop.org/drm/intel/issues/8812
  [i915#8814]: https://gitlab.freedesktop.org/drm/intel/issues/8814
  [i915#8816]: https://gitlab.freedesktop.org/drm/intel/issues/8816
  [i915#8875]: https://gitlab.freedesktop.org/drm/intel/issues/8875
  [i915#9010]: https://gitlab.freedesktop.org/drm/intel/issues/9010
  [i915#9053]: https://gitlab.freedesktop.org/drm/intel/issues/9053
  [i915#9196]: https://gitlab.freedesktop.org/drm/intel/issues/9196
  [i915#9275]: https://gitlab.freedesktop.org/drm/intel/issues/9275
  [i915#9295]: https://gitlab.freedesktop.org/drm/intel/issues/9295
  [i915#9412]: https://gitlab.freedesktop.org/drm/intel/issues/9412
  [i915#9423]: https://gitlab.freedesktop.org/drm/intel/issues/9423
  [i915#9424]: https://gitlab.freedesktop.org/drm/intel/issues/9424
  [i915#9433]: https://gitlab.freedesktop.org/drm/intel/issues/9433
  [i915#9519]: https://gitlab.freedesktop.org/drm/intel/issues/9519
  [i915#9569]: https://gitlab.freedesktop.org/drm/intel/issues/9569
  [i915#9685]: https://gitlab.freedesktop.org/drm/intel/issues/9685
  [i915#9688]: https://gitlab.freedesktop.org/drm/intel/issues/9688
  [i915#9723]: https://gitlab.freedesktop.org/drm/intel/issues/9723
  [i915#9732]: https://gitlab.freedesktop.org/drm/intel/issues/9732
  [i915#9779]: https://gitlab.freedesktop.org/drm/intel/issues/9779
  [i915#9809]: https://gitlab.freedesktop.org/drm/intel/issues/9809
  [i915#9820]: https://gitlab.freedesktop.org/drm/intel/issues/9820
  [i915#9849]: https://gitlab.freedesktop.org/drm/intel/issues/9849
  [i915#9878]: https://gitlab.freedesktop.org/drm/intel/issues/9878
  [i915#9906]: https://gitlab.freedesktop.org/drm/intel/issues/9906
  [i915#9917]: https://gitlab.freedesktop.org/drm/intel/issues/9917
  [i915#9934]: https://gitlab.freedesktop.org/drm/intel/issues/9934


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

  * Linux: CI_DRM_14345 -> Patchwork_129082v6

  CI-20190529: 20190529
  CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

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

* Re: ✗ Fi.CI.IGT: failure for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-27 14:21 ` ✗ Fi.CI.IGT: failure " Patchwork
@ 2024-02-27 15:51   ` Imre Deak
  0 siblings, 0 replies; 61+ messages in thread
From: Imre Deak @ 2024-02-27 15:51 UTC (permalink / raw)
  To: Jouni Hogander, Uma Shankar, Ville Syrjälä,
	Jani Nikula, Maxime Ripard
  Cc: intel-gfx, dri-devel

On Tue, Feb 27, 2024 at 02:21:29PM +0000, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
> URL   : https://patchwork.freedesktop.org/series/129082/
> State : failure

Thanks for the reviews,acks, patchset is pushed to drm-intel-next. The
failure is unrelated see below.

> 
> == Summary ==
> 
> CI Bug Log - changes from CI_DRM_14345_full -> Patchwork_129082v6_full
> ====================================================
> 
> Summary
> -------
> 
>   **FAILURE**
> 
>   Serious unknown changes coming with Patchwork_129082v6_full absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_129082v6_full, 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.
> 
>   
> 
> Participating hosts (8 -> 8)
> ------------------------------
> 
>   No changes in participating hosts
> 
> Possible new issues
> -------------------
> 
>   Here are the unknown changes that may have been introduced in Patchwork_129082v6_full:
> 
> ### IGT changes ###
> 
> #### Possible regressions ####
> 
>   * igt@kms_fbcon_fbt@fbc-suspend:
>     - shard-snb:          [PASS][1] -> [DMESG-WARN][2]
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_fbcon_fbt@fbc-suspend.html
>    [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_fbcon_fbt@fbc-suspend.html

No TBT/DP tunnels on the above machine, an unrelated system/suspend
resume problem in the EPB driver:

<7>[  554.320951] Calling intel_epb_restore+0x0/0xb0
<4>[  554.320956] unchecked MSR access error: RDMSR from 0x1b0 at rIP: 0xffffffff8104d4d3 (intel_epb_restore+0x13/0xb0)

The same was already reported at:
https://gitlab.freedesktop.org/drm/intel/-/issues/10007

> #### Warnings ####
> 
>   * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move:
>     - shard-snb:          [SKIP][3] ([fdo#109271]) -> [FAIL][4]
>    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb5/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html
>    [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb4/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html
> 
>   
> Known issues
> ------------
> 
>   Here are the changes found in Patchwork_129082v6_full that come from known issues:
> 
> ### CI changes ###
> 
> #### Possible fixes ####
> 
>   * boot:
>     - shard-glk:          ([PASS][5], [PASS][6], [PASS][7], [PASS][8], [PASS][9], [PASS][10], [PASS][11], [PASS][12], [PASS][13], [FAIL][14], [PASS][15], [PASS][16], [PASS][17], [PASS][18], [PASS][19], [PASS][20], [PASS][21], [PASS][22], [PASS][23], [PASS][24], [PASS][25], [PASS][26], [PASS][27], [PASS][28], [FAIL][29]) ([i915#8293]) -> ([PASS][30], [PASS][31], [PASS][32], [PASS][33], [PASS][34], [PASS][35], [PASS][36], [PASS][37], [PASS][38], [PASS][39], [PASS][40], [PASS][41], [PASS][42], [PASS][43], [PASS][44], [PASS][45], [PASS][46], [PASS][47], [PASS][48], [PASS][49], [PASS][50], [PASS][51], [PASS][52], [PASS][53])
>    [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
>    [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
>    [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
>    [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
>    [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
>    [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
>    [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
>    [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
>    [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
>    [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
>    [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
>    [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
>    [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
>    [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
>    [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
>    [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
>    [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
>    [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
>    [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
>    [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
>    [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
>    [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
>    [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
>    [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
>    [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
>    [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
>    [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
>    [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
>    [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
>    [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
>    [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
>    [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
>    [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
>    [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
>    [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
>    [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
>    [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
>    [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
>    [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
>    [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
>    [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
>    [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
>    [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
>    [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
>    [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk8/boot.html
>    [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk8/boot.html
>    [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
>    [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
>    [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
> 
>   
> 
> ### IGT changes ###
> 
> #### Issues hit ####
> 
>   * igt@api_intel_bb@object-reloc-purge-cache:
>     - shard-dg2:          NOTRUN -> [SKIP][54] ([i915#8411]) +2 other tests skip
>    [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@api_intel_bb@object-reloc-purge-cache.html
> 
>   * igt@device_reset@unbind-cold-reset-rebind:
>     - shard-mtlp:         NOTRUN -> [SKIP][55] ([i915#7701])
>    [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@device_reset@unbind-cold-reset-rebind.html
> 
>   * igt@drm_fdinfo@virtual-busy-idle-all:
>     - shard-dg2:          NOTRUN -> [SKIP][56] ([i915#8414]) +1 other test skip
>    [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@drm_fdinfo@virtual-busy-idle-all.html
> 
>   * igt@gem_ctx_persistence@heartbeat-stop:
>     - shard-dg1:          NOTRUN -> [SKIP][57] ([i915#8555])
>    [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_ctx_persistence@heartbeat-stop.html
> 
>   * igt@gem_ctx_sseu@invalid-args:
>     - shard-tglu:         NOTRUN -> [SKIP][58] ([i915#280])
>    [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_ctx_sseu@invalid-args.html
> 
>   * igt@gem_eio@kms:
>     - shard-dg1:          NOTRUN -> [FAIL][59] ([i915#5784])
>    [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_eio@kms.html
> 
>   * igt@gem_eio@unwedge-stress:
>     - shard-dg1:          [PASS][60] -> [FAIL][61] ([i915#5784])
>    [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-18/igt@gem_eio@unwedge-stress.html
>    [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-19/igt@gem_eio@unwedge-stress.html
> 
>   * igt@gem_exec_balancer@bonded-true-hang:
>     - shard-mtlp:         NOTRUN -> [SKIP][62] ([i915#4812])
>    [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_balancer@bonded-true-hang.html
> 
>   * igt@gem_exec_fair@basic-deadline:
>     - shard-glk:          NOTRUN -> [FAIL][63] ([i915#2846])
>    [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@gem_exec_fair@basic-deadline.html
> 
>   * igt@gem_exec_fair@basic-flow:
>     - shard-mtlp:         NOTRUN -> [SKIP][64] ([i915#4473] / [i915#4771]) +1 other test skip
>    [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_fair@basic-flow.html
> 
>   * igt@gem_exec_fair@basic-none-rrul@rcs0:
>     - shard-tglu:         NOTRUN -> [FAIL][65] ([i915#2842])
>    [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_exec_fair@basic-none-rrul@rcs0.html
> 
>   * igt@gem_exec_fair@basic-pace-share@rcs0:
>     - shard-glk:          NOTRUN -> [FAIL][66] ([i915#2842])
>    [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/igt@gem_exec_fair@basic-pace-share@rcs0.html
> 
>   * igt@gem_exec_fair@basic-pace@vecs0:
>     - shard-rkl:          [PASS][67] -> [FAIL][68] ([i915#2842]) +4 other tests fail
>    [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@gem_exec_fair@basic-pace@vecs0.html
>    [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@gem_exec_fair@basic-pace@vecs0.html
> 
>   * igt@gem_exec_flush@basic-batch-kernel-default-uc:
>     - shard-dg1:          NOTRUN -> [SKIP][69] ([i915#3539] / [i915#4852])
>    [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_exec_flush@basic-batch-kernel-default-uc.html
> 
>   * igt@gem_exec_flush@basic-uc-ro-default:
>     - shard-dg2:          NOTRUN -> [SKIP][70] ([i915#3539] / [i915#4852]) +1 other test skip
>    [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_exec_flush@basic-uc-ro-default.html
> 
>   * igt@gem_exec_params@rsvd2-dirt:
>     - shard-mtlp:         NOTRUN -> [SKIP][71] ([i915#5107])
>    [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_params@rsvd2-dirt.html
> 
>   * igt@gem_exec_params@secure-non-master:
>     - shard-mtlp:         NOTRUN -> [SKIP][72] ([fdo#112283]) +1 other test skip
>    [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_params@secure-non-master.html
> 
>   * igt@gem_exec_reloc@basic-concurrent0:
>     - shard-dg1:          NOTRUN -> [SKIP][73] ([i915#3281]) +4 other tests skip
>    [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_exec_reloc@basic-concurrent0.html
> 
>   * igt@gem_exec_reloc@basic-cpu-wc-noreloc:
>     - shard-mtlp:         NOTRUN -> [SKIP][74] ([i915#3281]) +3 other tests skip
>    [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_reloc@basic-cpu-wc-noreloc.html
> 
>   * igt@gem_exec_reloc@basic-write-gtt:
>     - shard-dg2:          NOTRUN -> [SKIP][75] ([i915#3281]) +7 other tests skip
>    [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_exec_reloc@basic-write-gtt.html
> 
>   * igt@gem_exec_suspend@basic-s0@lmem0:
>     - shard-dg2:          [PASS][76] -> [INCOMPLETE][77] ([i915#9275])
>    [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-5/igt@gem_exec_suspend@basic-s0@lmem0.html
>    [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_exec_suspend@basic-s0@lmem0.html
> 
>   * igt@gem_exec_suspend@basic-s4-devices@lmem0:
>     - shard-dg2:          NOTRUN -> [ABORT][78] ([i915#7975] / [i915#8213])
>    [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_exec_suspend@basic-s4-devices@lmem0.html
> 
>   * igt@gem_fence_thrash@bo-copy:
>     - shard-dg2:          NOTRUN -> [SKIP][79] ([i915#4860]) +1 other test skip
>    [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_fence_thrash@bo-copy.html
> 
>   * igt@gem_fenced_exec_thrash@no-spare-fences:
>     - shard-dg1:          NOTRUN -> [SKIP][80] ([i915#4860]) +1 other test skip
>    [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_fenced_exec_thrash@no-spare-fences.html
> 
>   * igt@gem_lmem_swapping@heavy-verify-multi-ccs:
>     - shard-tglu:         NOTRUN -> [SKIP][81] ([i915#4613]) +1 other test skip
>    [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_lmem_swapping@heavy-verify-multi-ccs.html
> 
>   * igt@gem_lmem_swapping@verify-ccs:
>     - shard-glk:          NOTRUN -> [SKIP][82] ([fdo#109271] / [i915#4613]) +3 other tests skip
>    [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@gem_lmem_swapping@verify-ccs.html
> 
>   * igt@gem_lmem_swapping@verify-ccs@lmem0:
>     - shard-dg1:          NOTRUN -> [SKIP][83] ([i915#4565])
>    [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_lmem_swapping@verify-ccs@lmem0.html
> 
>   * igt@gem_lmem_swapping@verify-random-ccs:
>     - shard-mtlp:         NOTRUN -> [SKIP][84] ([i915#4613])
>    [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_lmem_swapping@verify-random-ccs.html
> 
>   * igt@gem_mmap_gtt@basic-small-bo:
>     - shard-dg2:          NOTRUN -> [SKIP][85] ([i915#4077]) +4 other tests skip
>    [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_mmap_gtt@basic-small-bo.html
> 
>   * igt@gem_mmap_gtt@cpuset-medium-copy-odd:
>     - shard-dg1:          NOTRUN -> [SKIP][86] ([i915#4077])
>    [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_mmap_gtt@cpuset-medium-copy-odd.html
> 
>   * igt@gem_mmap_gtt@ptrace:
>     - shard-mtlp:         NOTRUN -> [SKIP][87] ([i915#4077]) +1 other test skip
>    [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_mmap_gtt@ptrace.html
> 
>   * igt@gem_mmap_wc@fault-concurrent:
>     - shard-dg2:          NOTRUN -> [SKIP][88] ([i915#4083]) +3 other tests skip
>    [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_mmap_wc@fault-concurrent.html
> 
>   * igt@gem_partial_pwrite_pread@writes-after-reads-display:
>     - shard-dg2:          NOTRUN -> [SKIP][89] ([i915#3282]) +6 other tests skip
>    [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_partial_pwrite_pread@writes-after-reads-display.html
> 
>   * igt@gem_pwrite@basic-exhaustion:
>     - shard-tglu:         NOTRUN -> [WARN][90] ([i915#2658])
>    [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_pwrite@basic-exhaustion.html
> 
>   * igt@gem_pxp@protected-raw-src-copy-not-readible:
>     - shard-mtlp:         NOTRUN -> [SKIP][91] ([i915#4270])
>    [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_pxp@protected-raw-src-copy-not-readible.html
> 
>   * igt@gem_pxp@verify-pxp-execution-after-suspend-resume:
>     - shard-dg1:          NOTRUN -> [SKIP][92] ([i915#4270]) +1 other test skip
>    [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_pxp@verify-pxp-execution-after-suspend-resume.html
> 
>   * igt@gem_readwrite@read-write:
>     - shard-dg1:          NOTRUN -> [SKIP][93] ([i915#3282])
>    [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_readwrite@read-write.html
> 
>   * igt@gem_render_copy@mixed-tiled-to-y-tiled-ccs:
>     - shard-dg2:          NOTRUN -> [SKIP][94] ([i915#5190]) +5 other tests skip
>    [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_render_copy@mixed-tiled-to-y-tiled-ccs.html
> 
>   * igt@gem_render_copy@y-tiled-ccs-to-y-tiled-mc-ccs:
>     - shard-mtlp:         NOTRUN -> [SKIP][95] ([i915#8428])
>    [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_render_copy@y-tiled-ccs-to-y-tiled-mc-ccs.html
> 
>   * igt@gem_render_tiled_blits@basic:
>     - shard-dg2:          NOTRUN -> [SKIP][96] ([i915#4079])
>    [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_render_tiled_blits@basic.html
> 
>   * igt@gem_set_tiling_vs_blt@tiled-to-untiled:
>     - shard-mtlp:         NOTRUN -> [SKIP][97] ([i915#4079])
>    [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_set_tiling_vs_blt@tiled-to-untiled.html
> 
>   * igt@gem_softpin@evict-snoop-interruptible:
>     - shard-dg2:          NOTRUN -> [SKIP][98] ([i915#4885])
>    [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_softpin@evict-snoop-interruptible.html
> 
>   * igt@gem_userptr_blits@coherency-unsync:
>     - shard-dg2:          NOTRUN -> [SKIP][99] ([i915#3297])
>    [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_userptr_blits@coherency-unsync.html
>     - shard-dg1:          NOTRUN -> [SKIP][100] ([i915#3297])
>    [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_userptr_blits@coherency-unsync.html
> 
>   * igt@gem_userptr_blits@dmabuf-sync:
>     - shard-mtlp:         NOTRUN -> [SKIP][101] ([i915#3297])
>    [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_userptr_blits@dmabuf-sync.html
> 
>   * igt@gen7_exec_parse@basic-allowed:
>     - shard-tglu:         NOTRUN -> [SKIP][102] ([fdo#109289]) +3 other tests skip
>    [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gen7_exec_parse@basic-allowed.html
> 
>   * igt@gen9_exec_parse@allowed-all:
>     - shard-glk:          [PASS][103] -> [ABORT][104] ([i915#5566])
>    [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/igt@gen9_exec_parse@allowed-all.html
>    [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/igt@gen9_exec_parse@allowed-all.html
> 
>   * igt@gen9_exec_parse@bb-start-far:
>     - shard-dg2:          NOTRUN -> [SKIP][105] ([i915#2856]) +1 other test skip
>    [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gen9_exec_parse@bb-start-far.html
> 
>   * igt@gen9_exec_parse@bb-start-param:
>     - shard-mtlp:         NOTRUN -> [SKIP][106] ([i915#2856])
>    [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gen9_exec_parse@bb-start-param.html
> 
>   * igt@i915_pm_freq_api@freq-basic-api:
>     - shard-tglu:         NOTRUN -> [SKIP][107] ([i915#8399])
>    [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@i915_pm_freq_api@freq-basic-api.html
> 
>   * igt@i915_pm_rps@min-max-config-loaded:
>     - shard-dg2:          NOTRUN -> [SKIP][108] ([i915#6621])
>    [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@i915_pm_rps@min-max-config-loaded.html
> 
>   * igt@intel_hwmon@hwmon-write:
>     - shard-mtlp:         NOTRUN -> [SKIP][109] ([i915#7707])
>    [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@intel_hwmon@hwmon-write.html
> 
>   * igt@kms_addfb_basic@basic-y-tiled-legacy:
>     - shard-dg2:          NOTRUN -> [SKIP][110] ([i915#4215] / [i915#5190])
>    [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_addfb_basic@basic-y-tiled-legacy.html
> 
>   * igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-2-y-rc-ccs-cc:
>     - shard-rkl:          NOTRUN -> [SKIP][111] ([i915#8709]) +3 other tests skip
>    [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-2-y-rc-ccs-cc.html
> 
>   * igt@kms_big_fb@4-tiled-16bpp-rotate-90:
>     - shard-dg1:          NOTRUN -> [SKIP][112] ([i915#4538] / [i915#5286]) +1 other test skip
>    [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_big_fb@4-tiled-16bpp-rotate-90.html
> 
>   * igt@kms_big_fb@4-tiled-8bpp-rotate-90:
>     - shard-tglu:         NOTRUN -> [SKIP][113] ([fdo#111615] / [i915#5286]) +1 other test skip
>    [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@4-tiled-8bpp-rotate-90.html
> 
>   * igt@kms_big_fb@linear-8bpp-rotate-90:
>     - shard-dg2:          NOTRUN -> [SKIP][114] ([fdo#111614]) +4 other tests skip
>    [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_big_fb@linear-8bpp-rotate-90.html
> 
>   * igt@kms_big_fb@x-tiled-8bpp-rotate-270:
>     - shard-mtlp:         NOTRUN -> [SKIP][115] ([fdo#111614]) +2 other tests skip
>    [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_big_fb@x-tiled-8bpp-rotate-270.html
> 
>   * igt@kms_big_fb@y-tiled-64bpp-rotate-90:
>     - shard-tglu:         NOTRUN -> [SKIP][116] ([fdo#111614])
>    [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@y-tiled-64bpp-rotate-90.html
> 
>   * igt@kms_big_fb@y-tiled-8bpp-rotate-270:
>     - shard-dg1:          NOTRUN -> [SKIP][117] ([i915#3638]) +1 other test skip
>    [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_big_fb@y-tiled-8bpp-rotate-270.html
> 
>   * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
>     - shard-mtlp:         NOTRUN -> [SKIP][118] ([fdo#111615]) +2 other tests skip
>    [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html
> 
>   * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip:
>     - shard-dg2:          NOTRUN -> [SKIP][119] ([i915#4538] / [i915#5190]) +6 other tests skip
>    [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip.html
> 
>   * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip:
>     - shard-tglu:         [PASS][120] -> [FAIL][121] ([i915#3743]) +1 other test fail
>    [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-5/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
>    [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-7/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
> 
>   * igt@kms_big_fb@yf-tiled-32bpp-rotate-180:
>     - shard-tglu:         NOTRUN -> [SKIP][122] ([fdo#111615])
>    [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@yf-tiled-32bpp-rotate-180.html
> 
>   * igt@kms_big_fb@yf-tiled-8bpp-rotate-90:
>     - shard-dg1:          NOTRUN -> [SKIP][123] ([i915#4538])
>    [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_big_fb@yf-tiled-8bpp-rotate-90.html
> 
>   * igt@kms_cdclk@mode-transition:
>     - shard-dg1:          NOTRUN -> [SKIP][124] ([i915#3742])
>    [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_cdclk@mode-transition.html
> 
>   * igt@kms_cdclk@mode-transition-all-outputs:
>     - shard-mtlp:         NOTRUN -> [SKIP][125] ([i915#7213] / [i915#9010])
>    [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cdclk@mode-transition-all-outputs.html
> 
>   * igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3:
>     - shard-dg2:          NOTRUN -> [SKIP][126] ([i915#4087]) +3 other tests skip
>    [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-6/igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3.html
> 
>   * igt@kms_chamelium_audio@dp-audio:
>     - shard-tglu:         NOTRUN -> [SKIP][127] ([i915#7828]) +2 other tests skip
>    [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_chamelium_audio@dp-audio.html
> 
>   * igt@kms_chamelium_color@ctm-0-50:
>     - shard-dg2:          NOTRUN -> [SKIP][128] ([fdo#111827])
>    [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_chamelium_color@ctm-0-50.html
> 
>   * igt@kms_chamelium_color@ctm-red-to-blue:
>     - shard-dg1:          NOTRUN -> [SKIP][129] ([fdo#111827])
>    [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_chamelium_color@ctm-red-to-blue.html
> 
>   * igt@kms_chamelium_frames@hdmi-crc-fast:
>     - shard-dg2:          NOTRUN -> [SKIP][130] ([i915#7828]) +6 other tests skip
>    [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_chamelium_frames@hdmi-crc-fast.html
> 
>   * igt@kms_chamelium_hpd@hdmi-hpd-storm-disable:
>     - shard-mtlp:         NOTRUN -> [SKIP][131] ([i915#7828]) +1 other test skip
>    [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_chamelium_hpd@hdmi-hpd-storm-disable.html
> 
>   * igt@kms_chamelium_hpd@vga-hpd-after-suspend:
>     - shard-dg1:          NOTRUN -> [SKIP][132] ([i915#7828]) +2 other tests skip
>    [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_chamelium_hpd@vga-hpd-after-suspend.html
> 
>   * igt@kms_content_protection@dp-mst-lic-type-0:
>     - shard-mtlp:         NOTRUN -> [SKIP][133] ([i915#3299])
>    [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_content_protection@dp-mst-lic-type-0.html
> 
>   * igt@kms_content_protection@lic-type-0:
>     - shard-dg2:          NOTRUN -> [SKIP][134] ([i915#9424])
>    [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_content_protection@lic-type-0.html
> 
>   * igt@kms_content_protection@type1:
>     - shard-dg2:          NOTRUN -> [SKIP][135] ([i915#7118] / [i915#9424]) +1 other test skip
>    [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_content_protection@type1.html
> 
>   * igt@kms_cursor_crc@cursor-offscreen-512x170:
>     - shard-dg2:          NOTRUN -> [SKIP][136] ([i915#3359]) +1 other test skip
>    [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_cursor_crc@cursor-offscreen-512x170.html
> 
>   * igt@kms_cursor_crc@cursor-onscreen-512x512:
>     - shard-mtlp:         NOTRUN -> [SKIP][137] ([i915#3359])
>    [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-onscreen-512x512.html
> 
>   * igt@kms_cursor_crc@cursor-rapid-movement-256x85:
>     - shard-mtlp:         NOTRUN -> [SKIP][138] ([i915#8814])
>    [138]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-rapid-movement-256x85.html
> 
>   * igt@kms_cursor_crc@cursor-sliding-max-size:
>     - shard-mtlp:         NOTRUN -> [SKIP][139] ([i915#3555] / [i915#8814])
>    [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-sliding-max-size.html
> 
>   * igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
>     - shard-dg2:          NOTRUN -> [SKIP][140] ([fdo#109274] / [i915#5354]) +2 other tests skip
>    [140]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html
> 
>   * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
>     - shard-mtlp:         NOTRUN -> [SKIP][141] ([i915#4213])
>    [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
> 
>   * igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size:
>     - shard-snb:          [PASS][142] -> [SKIP][143] ([fdo#109271]) +3 other tests skip
>    [142]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html
>    [143]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html
> 
>   * igt@kms_cursor_legacy@cursorb-vs-flipa-legacy:
>     - shard-mtlp:         NOTRUN -> [SKIP][144] ([i915#9809]) +1 other test skip
>    [144]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_legacy@cursorb-vs-flipa-legacy.html
> 
>   * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions:
>     - shard-tglu:         NOTRUN -> [SKIP][145] ([fdo#109274] / [fdo#111767])
>    [145]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions.html
> 
>   * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions-varying-size:
>     - shard-tglu:         NOTRUN -> [SKIP][146] ([fdo#109274])
>    [146]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions-varying-size.html
> 
>   * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-2:
>     - shard-rkl:          NOTRUN -> [SKIP][147] ([fdo#110189] / [i915#9723])
>    [147]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-3/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-2.html
> 
>   * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-3:
>     - shard-dg1:          NOTRUN -> [SKIP][148] ([fdo#110189] / [i915#9723])
>    [148]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-12/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-3.html
> 
>   * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-vga-1:
>     - shard-snb:          NOTRUN -> [SKIP][149] ([fdo#109271] / [fdo#110189])
>    [149]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-vga-1.html
> 
>   * igt@kms_dither@fb-8bpc-vs-panel-6bpc:
>     - shard-dg1:          NOTRUN -> [SKIP][150] ([i915#3555]) +1 other test skip
>    [150]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_dither@fb-8bpc-vs-panel-6bpc.html
> 
>   * igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-1:
>     - shard-rkl:          NOTRUN -> [SKIP][151] ([i915#3804])
>    [151]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-1.html
> 
>   * igt@kms_draw_crc@draw-method-mmap-gtt:
>     - shard-mtlp:         NOTRUN -> [SKIP][152] ([i915#3555] / [i915#8812])
>    [152]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_draw_crc@draw-method-mmap-gtt.html
> 
>   * igt@kms_dsc@dsc-fractional-bpp:
>     - shard-mtlp:         NOTRUN -> [SKIP][153] ([i915#3840] / [i915#9688])
>    [153]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_dsc@dsc-fractional-bpp.html
> 
>   * igt@kms_dsc@dsc-with-output-formats-with-bpc:
>     - shard-dg2:          NOTRUN -> [SKIP][154] ([i915#3840] / [i915#9053])
>    [154]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_dsc@dsc-with-output-formats-with-bpc.html
> 
>   * igt@kms_feature_discovery@chamelium:
>     - shard-dg2:          NOTRUN -> [SKIP][155] ([i915#4854])
>    [155]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_feature_discovery@chamelium.html
> 
>   * igt@kms_flip@2x-flip-vs-expired-vblank:
>     - shard-mtlp:         NOTRUN -> [SKIP][156] ([i915#3637])
>    [156]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_flip@2x-flip-vs-expired-vblank.html
> 
>   * igt@kms_flip@2x-flip-vs-fences-interruptible:
>     - shard-dg2:          NOTRUN -> [SKIP][157] ([i915#8381])
>    [157]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_flip@2x-flip-vs-fences-interruptible.html
> 
>   * igt@kms_flip@2x-flip-vs-modeset:
>     - shard-tglu:         NOTRUN -> [SKIP][158] ([fdo#109274] / [i915#3637] / [i915#3966]) +1 other test skip
>    [158]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip@2x-flip-vs-modeset.html
> 
>   * igt@kms_flip@2x-flip-vs-modeset-vs-hang:
>     - shard-dg2:          NOTRUN -> [SKIP][159] ([fdo#109274]) +5 other tests skip
>    [159]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_flip@2x-flip-vs-modeset-vs-hang.html
> 
>   * igt@kms_flip@2x-flip-vs-panning-vs-hang:
>     - shard-dg1:          NOTRUN -> [SKIP][160] ([fdo#111825] / [i915#9934]) +2 other tests skip
>    [160]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_flip@2x-flip-vs-panning-vs-hang.html
> 
>   * igt@kms_flip@2x-flip-vs-suspend-interruptible:
>     - shard-tglu:         NOTRUN -> [SKIP][161] ([fdo#109274] / [i915#3637])
>    [161]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip@2x-flip-vs-suspend-interruptible.html
> 
>   * igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling@pipe-a-valid-mode:
>     - shard-tglu:         NOTRUN -> [SKIP][162] ([i915#2587] / [i915#2672])
>    [162]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling@pipe-a-valid-mode.html
> 
>   * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling@pipe-a-valid-mode:
>     - shard-dg1:          NOTRUN -> [SKIP][163] ([i915#2587] / [i915#2672]) +1 other test skip
>    [163]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling@pipe-a-valid-mode.html
> 
>   * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling@pipe-a-valid-mode:
>     - shard-dg2:          NOTRUN -> [SKIP][164] ([i915#2672]) +3 other tests skip
>    [164]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling@pipe-a-valid-mode.html
> 
>   * igt@kms_force_connector_basic@force-load-detect:
>     - shard-dg2:          NOTRUN -> [SKIP][165] ([fdo#109285])
>    [165]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_force_connector_basic@force-load-detect.html
> 
>   * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move:
>     - shard-mtlp:         NOTRUN -> [SKIP][166] ([i915#1825]) +7 other tests skip
>    [166]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move.html
> 
>   * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt:
>     - shard-dg2:          NOTRUN -> [SKIP][167] ([fdo#111767] / [i915#5354])
>    [167]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt.html
> 
>   * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render:
>     - shard-tglu:         NOTRUN -> [SKIP][168] ([fdo#109280]) +8 other tests skip
>    [168]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render.html
> 
>   * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt:
>     - shard-dg2:          NOTRUN -> [SKIP][169] ([i915#5354]) +21 other tests skip
>    [169]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt.html
> 
>   * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render:
>     - shard-dg1:          NOTRUN -> [SKIP][170] ([fdo#111825]) +6 other tests skip
>    [170]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render.html
> 
>   * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt:
>     - shard-mtlp:         NOTRUN -> [SKIP][171] ([i915#8708]) +3 other tests skip
>    [171]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt.html
> 
>   * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite:
>     - shard-dg2:          NOTRUN -> [SKIP][172] ([i915#3458]) +14 other tests skip
>    [172]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite.html
> 
>   * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move:
>     - shard-dg1:          NOTRUN -> [SKIP][173] ([i915#3458]) +4 other tests skip
>    [173]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move.html
> 
>   * igt@kms_frontbuffer_tracking@plane-fbc-rte:
>     - shard-glk:          NOTRUN -> [SKIP][174] ([fdo#109271]) +104 other tests skip
>    [174]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_frontbuffer_tracking@plane-fbc-rte.html
>     - shard-dg1:          NOTRUN -> [SKIP][175] ([i915#10070])
>    [175]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@plane-fbc-rte.html
> 
>   * igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt:
>     - shard-dg2:          NOTRUN -> [SKIP][176] ([i915#8708]) +6 other tests skip
>    [176]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt.html
> 
>   * igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc:
>     - shard-dg1:          NOTRUN -> [SKIP][177] ([i915#8708]) +4 other tests skip
>    [177]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc.html
> 
>   * igt@kms_getfb@getfb-reject-ccs:
>     - shard-dg2:          NOTRUN -> [SKIP][178] ([i915#6118])
>    [178]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_getfb@getfb-reject-ccs.html
> 
>   * igt@kms_hdr@bpc-switch-suspend:
>     - shard-dg2:          NOTRUN -> [SKIP][179] ([i915#3555] / [i915#8228]) +1 other test skip
>    [179]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_hdr@bpc-switch-suspend.html
> 
>   * igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c:
>     - shard-dg2:          NOTRUN -> [SKIP][180] ([fdo#109289]) +2 other tests skip
>    [180]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c.html
> 
>   * igt@kms_plane_scaling@2x-scaler-multi-pipe:
>     - shard-dg2:          NOTRUN -> [SKIP][181] ([fdo#109274] / [i915#5354] / [i915#9423])
>    [181]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_plane_scaling@2x-scaler-multi-pipe.html
> 
>   * igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-3:
>     - shard-dg1:          NOTRUN -> [FAIL][182] ([i915#8292])
>    [182]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-3.html
> 
>   * igt@kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format@pipe-b-hdmi-a-3:
>     - shard-dg2:          NOTRUN -> [SKIP][183] ([i915#9423]) +7 other tests skip
>    [183]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format@pipe-b-hdmi-a-3.html
> 
>   * igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-a-hdmi-a-4:
>     - shard-dg1:          NOTRUN -> [SKIP][184] ([i915#9423]) +11 other tests skip
>    [184]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-19/igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-a-hdmi-a-4.html
> 
>   * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-1:
>     - shard-rkl:          NOTRUN -> [SKIP][185] ([i915#5176] / [i915#9423]) +1 other test skip
>    [185]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-1.html
> 
>   * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4:
>     - shard-dg1:          NOTRUN -> [SKIP][186] ([i915#5176] / [i915#9423]) +3 other tests skip
>    [186]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-16/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4.html
> 
>   * igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-a-hdmi-a-2:
>     - shard-rkl:          NOTRUN -> [SKIP][187] ([i915#9423]) +5 other tests skip
>    [187]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-a-hdmi-a-2.html
> 
>   * igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20@pipe-b-hdmi-a-2:
>     - shard-rkl:          NOTRUN -> [SKIP][188] ([i915#5235]) +11 other tests skip
>    [188]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-6/igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20@pipe-b-hdmi-a-2.html
> 
>   * igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-hdmi-a-4:
>     - shard-dg1:          NOTRUN -> [SKIP][189] ([i915#5235]) +15 other tests skip
>    [189]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-16/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-hdmi-a-4.html
> 
>   * igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-d-hdmi-a-3:
>     - shard-dg2:          NOTRUN -> [SKIP][190] ([i915#5235] / [i915#9423]) +3 other tests skip
>    [190]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-6/igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-d-hdmi-a-3.html
> 
>   * igt@kms_pm_dc@dc3co-vpb-simulation:
>     - shard-dg2:          NOTRUN -> [SKIP][191] ([i915#9685])
>    [191]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_pm_dc@dc3co-vpb-simulation.html
> 
>   * igt@kms_pm_dc@dc5-psr:
>     - shard-tglu:         NOTRUN -> [SKIP][192] ([i915#9685])
>    [192]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_pm_dc@dc5-psr.html
> 
>   * igt@kms_pm_rpm@i2c:
>     - shard-dg2:          [PASS][193] -> [FAIL][194] ([i915#8717])
>    [193]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@i2c.html
>    [194]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@i2c.html
> 
>   * igt@kms_pm_rpm@modeset-lpsp:
>     - shard-dg2:          NOTRUN -> [SKIP][195] ([i915#9519])
>    [195]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_pm_rpm@modeset-lpsp.html
> 
>   * igt@kms_pm_rpm@modeset-lpsp-stress:
>     - shard-dg2:          [PASS][196] -> [SKIP][197] ([i915#9519])
>    [196]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@modeset-lpsp-stress.html
>    [197]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@modeset-lpsp-stress.html
> 
>   * igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait:
>     - shard-rkl:          [PASS][198] -> [SKIP][199] ([i915#9519]) +1 other test skip
>    [198]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-3/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html
>    [199]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html
> 
>   * igt@kms_prime@basic-modeset-hybrid:
>     - shard-dg2:          NOTRUN -> [SKIP][200] ([i915#6524] / [i915#6805])
>    [200]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_prime@basic-modeset-hybrid.html
> 
>   * igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf:
>     - shard-glk:          NOTRUN -> [SKIP][201] ([fdo#109271] / [fdo#110189]) +1 other test skip
>    [201]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf.html
> 
>   * igt@kms_psr2_sf@fbc-primary-plane-update-sf-dmg-area:
>     - shard-tglu:         NOTRUN -> [SKIP][202] ([fdo#110189]) +7 other tests skip
>    [202]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_psr2_sf@fbc-primary-plane-update-sf-dmg-area.html
> 
>   * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf:
>     - shard-dg2:          NOTRUN -> [SKIP][203] ([fdo#110189]) +2 other tests skip
>    [203]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf.html
> 
>   * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf:
>     - shard-dg1:          NOTRUN -> [SKIP][204] ([fdo#110189])
>    [204]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf.html
> 
>   * igt@kms_psr2_su@page_flip-p010:
>     - shard-mtlp:         NOTRUN -> [SKIP][205] ([i915#4348])
>    [205]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_psr2_su@page_flip-p010.html
> 
>   * igt@kms_psr@fbc-psr-primary-mmap-gtt@edp-1:
>     - shard-mtlp:         NOTRUN -> [SKIP][206] ([i915#9688]) +2 other tests skip
>    [206]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_psr@fbc-psr-primary-mmap-gtt@edp-1.html
> 
>   * igt@kms_psr@psr-cursor-render:
>     - shard-dg2:          NOTRUN -> [SKIP][207] ([i915#9732]) +15 other tests skip
>    [207]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_psr@psr-cursor-render.html
> 
>   * igt@kms_psr@psr2-primary-mmap-cpu:
>     - shard-dg1:          NOTRUN -> [SKIP][208] ([i915#9732]) +4 other tests skip
>    [208]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_psr@psr2-primary-mmap-cpu.html
> 
>   * igt@kms_psr@psr2-sprite-mmap-gtt:
>     - shard-tglu:         NOTRUN -> [SKIP][209] ([i915#9732]) +3 other tests skip
>    [209]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_psr@psr2-sprite-mmap-gtt.html
> 
>   * igt@kms_rotation_crc@primary-y-tiled-reflect-x-180:
>     - shard-rkl:          [PASS][210] -> [INCOMPLETE][211] ([i915#8875] / [i915#9569])
>    [210]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@kms_rotation_crc@primary-y-tiled-reflect-x-180.html
>    [211]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_rotation_crc@primary-y-tiled-reflect-x-180.html
> 
>   * igt@kms_rotation_crc@sprite-rotation-90:
>     - shard-dg2:          NOTRUN -> [SKIP][212] ([i915#4235]) +2 other tests skip
>    [212]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_rotation_crc@sprite-rotation-90.html
> 
>   * igt@kms_rotation_crc@sprite-rotation-90-pos-100-0:
>     - shard-mtlp:         NOTRUN -> [SKIP][213] ([i915#4235]) +1 other test skip
>    [213]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.html
> 
>   * igt@kms_scaling_modes@scaling-mode-center:
>     - shard-tglu:         NOTRUN -> [SKIP][214] ([i915#3555]) +1 other test skip
>    [214]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_scaling_modes@scaling-mode-center.html
> 
>   * igt@kms_setmode@invalid-clone-single-crtc-stealing:
>     - shard-dg2:          NOTRUN -> [SKIP][215] ([i915#3555]) +3 other tests skip
>    [215]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_setmode@invalid-clone-single-crtc-stealing.html
> 
>   * igt@kms_tiled_display@basic-test-pattern-with-chamelium:
>     - shard-mtlp:         NOTRUN -> [SKIP][216] ([i915#8623])
>    [216]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html
> 
>   * igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1:
>     - shard-rkl:          [PASS][217] -> [FAIL][218] ([i915#9196])
>    [217]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-2/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
>    [218]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-5/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
> 
>   * igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1:
>     - shard-tglu:         [PASS][219] -> [FAIL][220] ([i915#9196])
>    [219]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-7/igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1.html
>    [220]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-9/igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1.html
> 
>   * igt@kms_vrr@seamless-rr-switch-vrr:
>     - shard-dg2:          NOTRUN -> [SKIP][221] ([i915#9906])
>    [221]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_vrr@seamless-rr-switch-vrr.html
> 
>   * igt@kms_writeback@writeback-fb-id-xrgb2101010:
>     - shard-dg2:          NOTRUN -> [SKIP][222] ([i915#2437] / [i915#9412])
>    [222]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_writeback@writeback-fb-id-xrgb2101010.html
> 
>   * igt@kms_writeback@writeback-pixel-formats:
>     - shard-glk:          NOTRUN -> [SKIP][223] ([fdo#109271] / [i915#2437])
>    [223]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_writeback@writeback-pixel-formats.html
>     - shard-dg1:          NOTRUN -> [SKIP][224] ([i915#2437] / [i915#9412])
>    [224]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_writeback@writeback-pixel-formats.html
> 
>   * igt@perf@mi-rpc:
>     - shard-dg2:          NOTRUN -> [SKIP][225] ([i915#2434] / [i915#7387])
>    [225]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@perf@mi-rpc.html
> 
>   * igt@perf_pmu@event-wait@rcs0:
>     - shard-tglu:         NOTRUN -> [SKIP][226] ([fdo#112283])
>    [226]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@perf_pmu@event-wait@rcs0.html
> 
>   * igt@perf_pmu@frequency@gt0:
>     - shard-dg2:          NOTRUN -> [FAIL][227] ([i915#6806])
>    [227]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@perf_pmu@frequency@gt0.html
>     - shard-dg1:          NOTRUN -> [FAIL][228] ([i915#6806])
>    [228]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@perf_pmu@frequency@gt0.html
> 
>   * igt@perf_pmu@rc6@other-idle-gt0:
>     - shard-tglu:         NOTRUN -> [SKIP][229] ([i915#8516])
>    [229]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@perf_pmu@rc6@other-idle-gt0.html
> 
>   * igt@prime_udl:
>     - shard-dg2:          NOTRUN -> [SKIP][230] ([fdo#109291])
>    [230]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@prime_udl.html
> 
>   * igt@prime_vgem@basic-write:
>     - shard-dg2:          NOTRUN -> [SKIP][231] ([i915#3291] / [i915#3708])
>    [231]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@prime_vgem@basic-write.html
> 
>   * igt@prime_vgem@fence-read-hang:
>     - shard-tglu:         NOTRUN -> [SKIP][232] ([fdo#109295])
>    [232]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@prime_vgem@fence-read-hang.html
> 
>   * igt@prime_vgem@fence-write-hang:
>     - shard-dg1:          NOTRUN -> [SKIP][233] ([i915#3708]) +1 other test skip
>    [233]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@prime_vgem@fence-write-hang.html
> 
>   * igt@sriov_basic@enable-vfs-autoprobe-on:
>     - shard-dg1:          NOTRUN -> [SKIP][234] ([i915#9917])
>    [234]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@sriov_basic@enable-vfs-autoprobe-on.html
> 
>   * igt@sriov_basic@enable-vfs-bind-unbind-each:
>     - shard-mtlp:         NOTRUN -> [SKIP][235] ([i915#9917])
>    [235]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@sriov_basic@enable-vfs-bind-unbind-each.html
> 
>   * igt@syncobj_wait@invalid-wait-zero-handles:
>     - shard-dg1:          NOTRUN -> [FAIL][236] ([i915#9779])
>    [236]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@syncobj_wait@invalid-wait-zero-handles.html
> 
>   * igt@v3d/v3d_perfmon@create-two-perfmon:
>     - shard-dg1:          NOTRUN -> [SKIP][237] ([i915#2575]) +2 other tests skip
>    [237]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@v3d/v3d_perfmon@create-two-perfmon.html
> 
>   * igt@v3d/v3d_submit_cl@single-out-sync:
>     - shard-tglu:         NOTRUN -> [SKIP][238] ([fdo#109315] / [i915#2575]) +2 other tests skip
>    [238]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@v3d/v3d_submit_cl@single-out-sync.html
> 
>   * igt@v3d/v3d_submit_csd@bad-extension:
>     - shard-mtlp:         NOTRUN -> [SKIP][239] ([i915#2575]) +1 other test skip
>    [239]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@v3d/v3d_submit_csd@bad-extension.html
> 
>   * igt@v3d/v3d_submit_csd@single-out-sync:
>     - shard-dg2:          NOTRUN -> [SKIP][240] ([i915#2575]) +9 other tests skip
>    [240]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@v3d/v3d_submit_csd@single-out-sync.html
> 
>   * igt@vc4/vc4_label_bo@set-bad-name:
>     - shard-mtlp:         NOTRUN -> [SKIP][241] ([i915#7711]) +1 other test skip
>    [241]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@vc4/vc4_label_bo@set-bad-name.html
> 
>   * igt@vc4/vc4_perfmon@create-perfmon-0:
>     - shard-tglu:         NOTRUN -> [SKIP][242] ([i915#2575])
>    [242]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@vc4/vc4_perfmon@create-perfmon-0.html
> 
>   * igt@vc4/vc4_tiling@set-bad-modifier:
>     - shard-dg1:          NOTRUN -> [SKIP][243] ([i915#7711]) +1 other test skip
>    [243]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@vc4/vc4_tiling@set-bad-modifier.html
> 
>   * igt@vc4/vc4_wait_bo@bad-bo:
>     - shard-dg2:          NOTRUN -> [SKIP][244] ([i915#7711]) +4 other tests skip
>    [244]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@vc4/vc4_wait_bo@bad-bo.html
> 
>   
> #### Possible fixes ####
> 
>   * igt@drm_fdinfo@most-busy-idle-check-all@rcs0:
>     - shard-rkl:          [FAIL][245] ([i915#7742]) -> [PASS][246]
>    [245]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html
>    [246]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-5/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html
> 
>   * igt@gem_ctx_exec@basic-nohangcheck:
>     - shard-tglu:         [FAIL][247] ([i915#6268]) -> [PASS][248]
>    [247]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-4/igt@gem_ctx_exec@basic-nohangcheck.html
>    [248]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-3/igt@gem_ctx_exec@basic-nohangcheck.html
> 
>   * igt@gem_exec_fair@basic-none@vecs0:
>     - shard-rkl:          [FAIL][249] ([i915#2842]) -> [PASS][250]
>    [249]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@gem_exec_fair@basic-none@vecs0.html
>    [250]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@gem_exec_fair@basic-none@vecs0.html
> 
>   * igt@gem_exec_fair@basic-throttle@rcs0:
>     - shard-glk:          [FAIL][251] ([i915#2842]) -> [PASS][252]
>    [251]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/igt@gem_exec_fair@basic-throttle@rcs0.html
>    [252]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/igt@gem_exec_fair@basic-throttle@rcs0.html
> 
>   * igt@gem_lmem_swapping@smem-oom@lmem0:
>     - shard-dg1:          [TIMEOUT][253] ([i915#5493]) -> [PASS][254]
>    [253]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-17/igt@gem_lmem_swapping@smem-oom@lmem0.html
>    [254]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-15/igt@gem_lmem_swapping@smem-oom@lmem0.html
> 
>   * igt@i915_module_load@reload-with-fault-injection:
>     - shard-dg1:          [INCOMPLETE][255] ([i915#10137] / [i915#9820] / [i915#9849]) -> [PASS][256]
>    [255]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-16/igt@i915_module_load@reload-with-fault-injection.html
>    [256]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@i915_module_load@reload-with-fault-injection.html
> 
>   * igt@i915_suspend@basic-s3-without-i915:
>     - shard-rkl:          [FAIL][257] ([i915#10031]) -> [PASS][258]
>    [257]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-4/igt@i915_suspend@basic-s3-without-i915.html
>    [258]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-2/igt@i915_suspend@basic-s3-without-i915.html
> 
>   * igt@kms_big_fb@4-tiled-64bpp-rotate-180:
>     - shard-mtlp:         [FAIL][259] ([i915#3763] / [i915#5138]) -> [PASS][260]
>    [259]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-mtlp-4/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html
>    [260]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-8/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html
> 
>   * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
>     - shard-tglu:         [FAIL][261] ([i915#3743]) -> [PASS][262]
>    [261]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-9/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
>    [262]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-6/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
> 
>   * igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic:
>     - shard-snb:          [SKIP][263] ([fdo#109271] / [fdo#111767]) -> [PASS][264]
>    [263]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html
>    [264]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html
> 
>   * igt@kms_cursor_legacy@cursora-vs-flipb-varying-size:
>     - shard-snb:          [SKIP][265] ([fdo#109271]) -> [PASS][266] +3 other tests pass
>    [265]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_cursor_legacy@cursora-vs-flipb-varying-size.html
>    [266]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_cursor_legacy@cursora-vs-flipb-varying-size.html
> 
>   * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
>     - shard-glk:          [FAIL][267] ([i915#2346]) -> [PASS][268]
>    [267]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
>    [268]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
> 
>   * igt@kms_pm_rpm@modeset-non-lpsp:
>     - shard-dg2:          [SKIP][269] ([i915#9519]) -> [PASS][270]
>    [269]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@modeset-non-lpsp.html
>    [270]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@modeset-non-lpsp.html
> 
>   * igt@kms_pm_rpm@modeset-non-lpsp-stress:
>     - shard-rkl:          [SKIP][271] ([i915#9519]) -> [PASS][272] +2 other tests pass
>    [271]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
>    [272]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-3/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
> 
>   * igt@perf@non-zero-reason@0-rcs0:
>     - shard-dg2:          [FAIL][273] ([i915#7484]) -> [PASS][274]
>    [273]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@perf@non-zero-reason@0-rcs0.html
>    [274]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@perf@non-zero-reason@0-rcs0.html
> 
>   
> #### Warnings ####
> 
>   * igt@kms_content_protection@atomic:
>     - shard-snb:          [INCOMPLETE][275] ([i915#8816]) -> [SKIP][276] ([fdo#109271])
>    [275]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_content_protection@atomic.html
>    [276]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_content_protection@atomic.html
> 
>   * igt@kms_content_protection@mei-interface:
>     - shard-dg1:          [SKIP][277] ([i915#9424]) -> [SKIP][278] ([i915#9433])
>    [277]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-15/igt@kms_content_protection@mei-interface.html
>    [278]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-12/igt@kms_content_protection@mei-interface.html
>     - shard-snb:          [SKIP][279] ([fdo#109271]) -> [INCOMPLETE][280] ([i915#9878])
>    [279]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_content_protection@mei-interface.html
>    [280]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_content_protection@mei-interface.html
> 
>   * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc:
>     - shard-snb:          [SKIP][281] ([fdo#109271] / [fdo#111767]) -> [SKIP][282] ([fdo#109271])
>    [281]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc.html
>    [282]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc.html
> 
>   * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render:
>     - shard-snb:          [SKIP][283] ([fdo#109271]) -> [SKIP][284] ([fdo#109271] / [fdo#111767])
>    [283]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html
>    [284]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html
> 
>   * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
>     - shard-rkl:          [SKIP][285] ([i915#4070] / [i915#4816]) -> [SKIP][286] ([i915#4816])
>    [285]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
>    [286]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
> 
>   * igt@kms_pm_dc@dc6-dpms:
>     - shard-rkl:          [FAIL][287] ([i915#9295]) -> [SKIP][288] ([i915#3361])
>    [287]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@kms_pm_dc@dc6-dpms.html
>    [288]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@kms_pm_dc@dc6-dpms.html
> 
>   
>   {name}: This element is suppressed. This means it is ignored when computing
>           the status of the difference (SUCCESS, WARNING, or FAILURE).
> 
>   [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
>   [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
>   [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
>   [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
>   [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
>   [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
>   [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
>   [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
>   [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
>   [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
>   [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
>   [fdo#111767]: https://bugs.freedesktop.org/show_bug.cgi?id=111767
>   [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
>   [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
>   [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
>   [i915#10031]: https://gitlab.freedesktop.org/drm/intel/issues/10031
>   [i915#10070]: https://gitlab.freedesktop.org/drm/intel/issues/10070
>   [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
>   [i915#10307]: https://gitlab.freedesktop.org/drm/intel/issues/10307
>   [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
>   [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
>   [i915#2434]: https://gitlab.freedesktop.org/drm/intel/issues/2434
>   [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
>   [i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
>   [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
>   [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
>   [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
>   [i915#280]: https://gitlab.freedesktop.org/drm/intel/issues/280
>   [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
>   [i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
>   [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
>   [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
>   [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
>   [i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
>   [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
>   [i915#3299]: https://gitlab.freedesktop.org/drm/intel/issues/3299
>   [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
>   [i915#3361]: https://gitlab.freedesktop.org/drm/intel/issues/3361
>   [i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
>   [i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
>   [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
>   [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
>   [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
>   [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
>   [i915#3742]: https://gitlab.freedesktop.org/drm/intel/issues/3742
>   [i915#3743]: https://gitlab.freedesktop.org/drm/intel/issues/3743
>   [i915#3763]: https://gitlab.freedesktop.org/drm/intel/issues/3763
>   [i915#3804]: https://gitlab.freedesktop.org/drm/intel/issues/3804
>   [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
>   [i915#3966]: https://gitlab.freedesktop.org/drm/intel/issues/3966
>   [i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
>   [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
>   [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
>   [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
>   [i915#4087]: https://gitlab.freedesktop.org/drm/intel/issues/4087
>   [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
>   [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
>   [i915#4235]: https://gitlab.freedesktop.org/drm/intel/issues/4235
>   [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
>   [i915#4348]: https://gitlab.freedesktop.org/drm/intel/issues/4348
>   [i915#4473]: https://gitlab.freedesktop.org/drm/intel/issues/4473
>   [i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
>   [i915#4565]: https://gitlab.freedesktop.org/drm/intel/issues/4565
>   [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
>   [i915#4771]: https://gitlab.freedesktop.org/drm/intel/issues/4771
>   [i915#4812]: https://gitlab.freedesktop.org/drm/intel/issues/4812
>   [i915#4816]: https://gitlab.freedesktop.org/drm/intel/issues/4816
>   [i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
>   [i915#4854]: https://gitlab.freedesktop.org/drm/intel/issues/4854
>   [i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
>   [i915#4885]: https://gitlab.freedesktop.org/drm/intel/issues/4885
>   [i915#5107]: https://gitlab.freedesktop.org/drm/intel/issues/5107
>   [i915#5138]: https://gitlab.freedesktop.org/drm/intel/issues/5138
>   [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
>   [i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
>   [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
>   [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
>   [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
>   [i915#5493]: https://gitlab.freedesktop.org/drm/intel/issues/5493
>   [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
>   [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
>   [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
>   [i915#6118]: https://gitlab.freedesktop.org/drm/intel/issues/6118
>   [i915#6268]: https://gitlab.freedesktop.org/drm/intel/issues/6268
>   [i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
>   [i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
>   [i915#6805]: https://gitlab.freedesktop.org/drm/intel/issues/6805
>   [i915#6806]: https://gitlab.freedesktop.org/drm/intel/issues/6806
>   [i915#7118]: https://gitlab.freedesktop.org/drm/intel/issues/7118
>   [i915#7213]: https://gitlab.freedesktop.org/drm/intel/issues/7213
>   [i915#7387]: https://gitlab.freedesktop.org/drm/intel/issues/7387
>   [i915#7484]: https://gitlab.freedesktop.org/drm/intel/issues/7484
>   [i915#7701]: https://gitlab.freedesktop.org/drm/intel/issues/7701
>   [i915#7707]: https://gitlab.freedesktop.org/drm/intel/issues/7707
>   [i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
>   [i915#7742]: https://gitlab.freedesktop.org/drm/intel/issues/7742
>   [i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
>   [i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
>   [i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
>   [i915#8228]: https://gitlab.freedesktop.org/drm/intel/issues/8228
>   [i915#8292]: https://gitlab.freedesktop.org/drm/intel/issues/8292
>   [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293
>   [i915#8381]: https://gitlab.freedesktop.org/drm/intel/issues/8381
>   [i915#8399]: https://gitlab.freedesktop.org/drm/intel/issues/8399
>   [i915#8411]: https://gitlab.freedesktop.org/drm/intel/issues/8411
>   [i915#8414]: https://gitlab.freedesktop.org/drm/intel/issues/8414
>   [i915#8428]: https://gitlab.freedesktop.org/drm/intel/issues/8428
>   [i915#8516]: https://gitlab.freedesktop.org/drm/intel/issues/8516
>   [i915#8555]: https://gitlab.freedesktop.org/drm/intel/issues/8555
>   [i915#8623]: https://gitlab.freedesktop.org/drm/intel/issues/8623
>   [i915#8708]: https://gitlab.freedesktop.org/drm/intel/issues/8708
>   [i915#8709]: https://gitlab.freedesktop.org/drm/intel/issues/8709
>   [i915#8717]: https://gitlab.freedesktop.org/drm/intel/issues/8717
>   [i915#8812]: https://gitlab.freedesktop.org/drm/intel/issues/8812
>   [i915#8814]: https://gitlab.freedesktop.org/drm/intel/issues/8814
>   [i915#8816]: https://gitlab.freedesktop.org/drm/intel/issues/8816
>   [i915#8875]: https://gitlab.freedesktop.org/drm/intel/issues/8875
>   [i915#9010]: https://gitlab.freedesktop.org/drm/intel/issues/9010
>   [i915#9053]: https://gitlab.freedesktop.org/drm/intel/issues/9053
>   [i915#9196]: https://gitlab.freedesktop.org/drm/intel/issues/9196
>   [i915#9275]: https://gitlab.freedesktop.org/drm/intel/issues/9275
>   [i915#9295]: https://gitlab.freedesktop.org/drm/intel/issues/9295
>   [i915#9412]: https://gitlab.freedesktop.org/drm/intel/issues/9412
>   [i915#9423]: https://gitlab.freedesktop.org/drm/intel/issues/9423
>   [i915#9424]: https://gitlab.freedesktop.org/drm/intel/issues/9424
>   [i915#9433]: https://gitlab.freedesktop.org/drm/intel/issues/9433
>   [i915#9519]: https://gitlab.freedesktop.org/drm/intel/issues/9519
>   [i915#9569]: https://gitlab.freedesktop.org/drm/intel/issues/9569
>   [i915#9685]: https://gitlab.freedesktop.org/drm/intel/issues/9685
>   [i915#9688]: https://gitlab.freedesktop.org/drm/intel/issues/9688
>   [i915#9723]: https://gitlab.freedesktop.org/drm/intel/issues/9723
>   [i915#9732]: https://gitlab.freedesktop.org/drm/intel/issues/9732
>   [i915#9779]: https://gitlab.freedesktop.org/drm/intel/issues/9779
>   [i915#9809]: https://gitlab.freedesktop.org/drm/intel/issues/9809
>   [i915#9820]: https://gitlab.freedesktop.org/drm/intel/issues/9820
>   [i915#9849]: https://gitlab.freedesktop.org/drm/intel/issues/9849
>   [i915#9878]: https://gitlab.freedesktop.org/drm/intel/issues/9878
>   [i915#9906]: https://gitlab.freedesktop.org/drm/intel/issues/9906
>   [i915#9917]: https://gitlab.freedesktop.org/drm/intel/issues/9917
>   [i915#9934]: https://gitlab.freedesktop.org/drm/intel/issues/9934
> 
> 
> Build changes
> -------------
> 
>   * Linux: CI_DRM_14345 -> Patchwork_129082v6
> 
>   CI-20190529: 20190529
>   CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
>   Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
>   piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
> 
> == Logs ==
> 
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/index.html

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

* ✓ Fi.CI.IGT: success for drm/i915: Add Display Port tunnel BW allocation support (rev6)
  2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
                   ` (31 preceding siblings ...)
  2024-02-27 14:21 ` ✗ Fi.CI.IGT: failure " Patchwork
@ 2024-02-28  5:55 ` Patchwork
  32 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2024-02-28  5:55 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

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

== Series Details ==

Series: drm/i915: Add Display Port tunnel BW allocation support (rev6)
URL   : https://patchwork.freedesktop.org/series/129082/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_14345_full -> Patchwork_129082v6_full
====================================================

Summary
-------

  **WARNING**

  Minor unknown changes coming with Patchwork_129082v6_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_129082v6_full, 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.

  

Participating hosts (8 -> 8)
------------------------------

  No changes in participating hosts

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

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

### IGT changes ###

#### Warnings ####

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move:
    - shard-snb:          [SKIP][1] ([fdo#109271]) -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb5/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb4/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move.html

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

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

### CI changes ###

#### Possible fixes ####

  * boot:
    - shard-glk:          ([PASS][3], [PASS][4], [PASS][5], [PASS][6], [PASS][7], [PASS][8], [PASS][9], [PASS][10], [PASS][11], [FAIL][12], [PASS][13], [PASS][14], [PASS][15], [PASS][16], [PASS][17], [PASS][18], [PASS][19], [PASS][20], [PASS][21], [PASS][22], [PASS][23], [PASS][24], [PASS][25], [PASS][26], [FAIL][27]) ([i915#8293]) -> ([PASS][28], [PASS][29], [PASS][30], [PASS][31], [PASS][32], [PASS][33], [PASS][34], [PASS][35], [PASS][36], [PASS][37], [PASS][38], [PASS][39], [PASS][40], [PASS][41], [PASS][42], [PASS][43], [PASS][44], [PASS][45], [PASS][46], [PASS][47], [PASS][48], [PASS][49], [PASS][50], [PASS][51])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk9/boot.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk8/boot.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk7/boot.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk5/boot.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk4/boot.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/boot.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk2/boot.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/boot.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/boot.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk2/boot.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk3/boot.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk4/boot.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/boot.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/boot.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk8/boot.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk8/boot.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/boot.html

  

### IGT changes ###

#### Issues hit ####

  * igt@api_intel_bb@object-reloc-purge-cache:
    - shard-dg2:          NOTRUN -> [SKIP][52] ([i915#8411]) +2 other tests skip
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@api_intel_bb@object-reloc-purge-cache.html

  * igt@device_reset@unbind-cold-reset-rebind:
    - shard-mtlp:         NOTRUN -> [SKIP][53] ([i915#7701])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@device_reset@unbind-cold-reset-rebind.html

  * igt@drm_fdinfo@virtual-busy-idle-all:
    - shard-dg2:          NOTRUN -> [SKIP][54] ([i915#8414]) +1 other test skip
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@drm_fdinfo@virtual-busy-idle-all.html

  * igt@gem_ctx_persistence@heartbeat-stop:
    - shard-dg1:          NOTRUN -> [SKIP][55] ([i915#8555])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_ctx_persistence@heartbeat-stop.html

  * igt@gem_ctx_sseu@invalid-args:
    - shard-tglu:         NOTRUN -> [SKIP][56] ([i915#280])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_ctx_sseu@invalid-args.html

  * igt@gem_eio@kms:
    - shard-dg1:          NOTRUN -> [FAIL][57] ([i915#5784])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_eio@kms.html

  * igt@gem_eio@unwedge-stress:
    - shard-dg1:          [PASS][58] -> [FAIL][59] ([i915#5784])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-18/igt@gem_eio@unwedge-stress.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-19/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_balancer@bonded-true-hang:
    - shard-mtlp:         NOTRUN -> [SKIP][60] ([i915#4812])
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_balancer@bonded-true-hang.html

  * igt@gem_exec_fair@basic-deadline:
    - shard-glk:          NOTRUN -> [FAIL][61] ([i915#2846])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-flow:
    - shard-mtlp:         NOTRUN -> [SKIP][62] ([i915#4473] / [i915#4771]) +1 other test skip
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_fair@basic-flow.html

  * igt@gem_exec_fair@basic-none-rrul@rcs0:
    - shard-tglu:         NOTRUN -> [FAIL][63] ([i915#2842])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_exec_fair@basic-none-rrul@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-glk:          NOTRUN -> [FAIL][64] ([i915#2842])
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@vecs0:
    - shard-rkl:          [PASS][65] -> [FAIL][66] ([i915#2842]) +4 other tests fail
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@gem_exec_fair@basic-pace@vecs0.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@gem_exec_fair@basic-pace@vecs0.html

  * igt@gem_exec_flush@basic-batch-kernel-default-uc:
    - shard-dg1:          NOTRUN -> [SKIP][67] ([i915#3539] / [i915#4852])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_exec_flush@basic-batch-kernel-default-uc.html

  * igt@gem_exec_flush@basic-uc-ro-default:
    - shard-dg2:          NOTRUN -> [SKIP][68] ([i915#3539] / [i915#4852]) +1 other test skip
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_exec_flush@basic-uc-ro-default.html

  * igt@gem_exec_params@rsvd2-dirt:
    - shard-mtlp:         NOTRUN -> [SKIP][69] ([i915#5107])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_params@rsvd2-dirt.html

  * igt@gem_exec_params@secure-non-master:
    - shard-mtlp:         NOTRUN -> [SKIP][70] ([fdo#112283]) +1 other test skip
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_params@secure-non-master.html

  * igt@gem_exec_reloc@basic-concurrent0:
    - shard-dg1:          NOTRUN -> [SKIP][71] ([i915#3281]) +4 other tests skip
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@gem_exec_reloc@basic-cpu-wc-noreloc:
    - shard-mtlp:         NOTRUN -> [SKIP][72] ([i915#3281]) +3 other tests skip
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_exec_reloc@basic-cpu-wc-noreloc.html

  * igt@gem_exec_reloc@basic-write-gtt:
    - shard-dg2:          NOTRUN -> [SKIP][73] ([i915#3281]) +7 other tests skip
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_exec_reloc@basic-write-gtt.html

  * igt@gem_exec_suspend@basic-s0@lmem0:
    - shard-dg2:          [PASS][74] -> [INCOMPLETE][75] ([i915#9275])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-5/igt@gem_exec_suspend@basic-s0@lmem0.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_exec_suspend@basic-s0@lmem0.html

  * igt@gem_exec_suspend@basic-s4-devices@lmem0:
    - shard-dg2:          NOTRUN -> [ABORT][76] ([i915#7975] / [i915#8213])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_exec_suspend@basic-s4-devices@lmem0.html

  * igt@gem_fence_thrash@bo-copy:
    - shard-dg2:          NOTRUN -> [SKIP][77] ([i915#4860]) +1 other test skip
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_fence_thrash@bo-copy.html

  * igt@gem_fenced_exec_thrash@no-spare-fences:
    - shard-dg1:          NOTRUN -> [SKIP][78] ([i915#4860]) +1 other test skip
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_fenced_exec_thrash@no-spare-fences.html

  * igt@gem_lmem_swapping@heavy-verify-multi-ccs:
    - shard-tglu:         NOTRUN -> [SKIP][79] ([i915#4613]) +1 other test skip
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_lmem_swapping@heavy-verify-multi-ccs.html

  * igt@gem_lmem_swapping@verify-ccs:
    - shard-glk:          NOTRUN -> [SKIP][80] ([fdo#109271] / [i915#4613]) +3 other tests skip
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@gem_lmem_swapping@verify-ccs.html

  * igt@gem_lmem_swapping@verify-ccs@lmem0:
    - shard-dg1:          NOTRUN -> [SKIP][81] ([i915#4565])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_lmem_swapping@verify-ccs@lmem0.html

  * igt@gem_lmem_swapping@verify-random-ccs:
    - shard-mtlp:         NOTRUN -> [SKIP][82] ([i915#4613])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_lmem_swapping@verify-random-ccs.html

  * igt@gem_mmap_gtt@basic-small-bo:
    - shard-dg2:          NOTRUN -> [SKIP][83] ([i915#4077]) +4 other tests skip
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_mmap_gtt@basic-small-bo.html

  * igt@gem_mmap_gtt@cpuset-medium-copy-odd:
    - shard-dg1:          NOTRUN -> [SKIP][84] ([i915#4077])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_mmap_gtt@cpuset-medium-copy-odd.html

  * igt@gem_mmap_gtt@ptrace:
    - shard-mtlp:         NOTRUN -> [SKIP][85] ([i915#4077]) +1 other test skip
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_mmap_gtt@ptrace.html

  * igt@gem_mmap_wc@fault-concurrent:
    - shard-dg2:          NOTRUN -> [SKIP][86] ([i915#4083]) +3 other tests skip
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_mmap_wc@fault-concurrent.html

  * igt@gem_partial_pwrite_pread@writes-after-reads-display:
    - shard-dg2:          NOTRUN -> [SKIP][87] ([i915#3282]) +6 other tests skip
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_partial_pwrite_pread@writes-after-reads-display.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-tglu:         NOTRUN -> [WARN][88] ([i915#2658])
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_pxp@protected-raw-src-copy-not-readible:
    - shard-mtlp:         NOTRUN -> [SKIP][89] ([i915#4270])
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_pxp@protected-raw-src-copy-not-readible.html

  * igt@gem_pxp@verify-pxp-execution-after-suspend-resume:
    - shard-dg1:          NOTRUN -> [SKIP][90] ([i915#4270]) +1 other test skip
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@gem_pxp@verify-pxp-execution-after-suspend-resume.html

  * igt@gem_readwrite@read-write:
    - shard-dg1:          NOTRUN -> [SKIP][91] ([i915#3282])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_readwrite@read-write.html

  * igt@gem_render_copy@mixed-tiled-to-y-tiled-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][92] ([i915#5190]) +5 other tests skip
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_render_copy@mixed-tiled-to-y-tiled-ccs.html

  * igt@gem_render_copy@y-tiled-ccs-to-y-tiled-mc-ccs:
    - shard-mtlp:         NOTRUN -> [SKIP][93] ([i915#8428])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_render_copy@y-tiled-ccs-to-y-tiled-mc-ccs.html

  * igt@gem_render_tiled_blits@basic:
    - shard-dg2:          NOTRUN -> [SKIP][94] ([i915#4079])
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@gem_render_tiled_blits@basic.html

  * igt@gem_set_tiling_vs_blt@tiled-to-untiled:
    - shard-mtlp:         NOTRUN -> [SKIP][95] ([i915#4079])
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_set_tiling_vs_blt@tiled-to-untiled.html

  * igt@gem_softpin@evict-snoop-interruptible:
    - shard-dg2:          NOTRUN -> [SKIP][96] ([i915#4885])
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gem_softpin@evict-snoop-interruptible.html

  * igt@gem_userptr_blits@coherency-unsync:
    - shard-dg2:          NOTRUN -> [SKIP][97] ([i915#3297])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@gem_userptr_blits@coherency-unsync.html
    - shard-dg1:          NOTRUN -> [SKIP][98] ([i915#3297])
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@gem_userptr_blits@coherency-unsync.html

  * igt@gem_userptr_blits@dmabuf-sync:
    - shard-mtlp:         NOTRUN -> [SKIP][99] ([i915#3297])
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gem_userptr_blits@dmabuf-sync.html

  * igt@gen7_exec_parse@basic-allowed:
    - shard-tglu:         NOTRUN -> [SKIP][100] ([fdo#109289]) +3 other tests skip
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@gen7_exec_parse@basic-allowed.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [PASS][101] -> [ABORT][102] ([i915#5566])
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/igt@gen9_exec_parse@allowed-all.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk1/igt@gen9_exec_parse@allowed-all.html

  * igt@gen9_exec_parse@bb-start-far:
    - shard-dg2:          NOTRUN -> [SKIP][103] ([i915#2856]) +1 other test skip
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@gen9_exec_parse@bb-start-far.html

  * igt@gen9_exec_parse@bb-start-param:
    - shard-mtlp:         NOTRUN -> [SKIP][104] ([i915#2856])
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@gen9_exec_parse@bb-start-param.html

  * igt@i915_pm_freq_api@freq-basic-api:
    - shard-tglu:         NOTRUN -> [SKIP][105] ([i915#8399])
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@i915_pm_freq_api@freq-basic-api.html

  * igt@i915_pm_rps@min-max-config-loaded:
    - shard-dg2:          NOTRUN -> [SKIP][106] ([i915#6621])
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@i915_pm_rps@min-max-config-loaded.html

  * igt@intel_hwmon@hwmon-write:
    - shard-mtlp:         NOTRUN -> [SKIP][107] ([i915#7707])
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@intel_hwmon@hwmon-write.html

  * igt@kms_addfb_basic@basic-y-tiled-legacy:
    - shard-dg2:          NOTRUN -> [SKIP][108] ([i915#4215] / [i915#5190])
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_addfb_basic@basic-y-tiled-legacy.html

  * igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-2-y-rc-ccs-cc:
    - shard-rkl:          NOTRUN -> [SKIP][109] ([i915#8709]) +3 other tests skip
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-2-y-rc-ccs-cc.html

  * igt@kms_big_fb@4-tiled-16bpp-rotate-90:
    - shard-dg1:          NOTRUN -> [SKIP][110] ([i915#4538] / [i915#5286]) +1 other test skip
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_big_fb@4-tiled-16bpp-rotate-90.html

  * igt@kms_big_fb@4-tiled-8bpp-rotate-90:
    - shard-tglu:         NOTRUN -> [SKIP][111] ([fdo#111615] / [i915#5286]) +1 other test skip
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@4-tiled-8bpp-rotate-90.html

  * igt@kms_big_fb@linear-8bpp-rotate-90:
    - shard-dg2:          NOTRUN -> [SKIP][112] ([fdo#111614]) +4 other tests skip
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_big_fb@linear-8bpp-rotate-90.html

  * igt@kms_big_fb@x-tiled-8bpp-rotate-270:
    - shard-mtlp:         NOTRUN -> [SKIP][113] ([fdo#111614]) +2 other tests skip
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_big_fb@x-tiled-8bpp-rotate-270.html

  * igt@kms_big_fb@y-tiled-64bpp-rotate-90:
    - shard-tglu:         NOTRUN -> [SKIP][114] ([fdo#111614])
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@y-tiled-64bpp-rotate-90.html

  * igt@kms_big_fb@y-tiled-8bpp-rotate-270:
    - shard-dg1:          NOTRUN -> [SKIP][115] ([i915#3638]) +1 other test skip
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_big_fb@y-tiled-8bpp-rotate-270.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
    - shard-mtlp:         NOTRUN -> [SKIP][116] ([fdo#111615]) +2 other tests skip
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip:
    - shard-dg2:          NOTRUN -> [SKIP][117] ([i915#4538] / [i915#5190]) +6 other tests skip
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip:
    - shard-tglu:         [PASS][118] -> [FAIL][119] ([i915#3743]) +1 other test fail
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-5/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-7/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-180:
    - shard-tglu:         NOTRUN -> [SKIP][120] ([fdo#111615])
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_big_fb@yf-tiled-32bpp-rotate-180.html

  * igt@kms_big_fb@yf-tiled-8bpp-rotate-90:
    - shard-dg1:          NOTRUN -> [SKIP][121] ([i915#4538])
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_big_fb@yf-tiled-8bpp-rotate-90.html

  * igt@kms_cdclk@mode-transition:
    - shard-dg1:          NOTRUN -> [SKIP][122] ([i915#3742])
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_cdclk@mode-transition.html

  * igt@kms_cdclk@mode-transition-all-outputs:
    - shard-mtlp:         NOTRUN -> [SKIP][123] ([i915#7213] / [i915#9010])
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cdclk@mode-transition-all-outputs.html

  * igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][124] ([i915#4087]) +3 other tests skip
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-6/igt@kms_cdclk@plane-scaling@pipe-b-hdmi-a-3.html

  * igt@kms_chamelium_audio@dp-audio:
    - shard-tglu:         NOTRUN -> [SKIP][125] ([i915#7828]) +2 other tests skip
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_chamelium_audio@dp-audio.html

  * igt@kms_chamelium_color@ctm-0-50:
    - shard-dg2:          NOTRUN -> [SKIP][126] ([fdo#111827])
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_chamelium_color@ctm-0-50.html

  * igt@kms_chamelium_color@ctm-red-to-blue:
    - shard-dg1:          NOTRUN -> [SKIP][127] ([fdo#111827])
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_chamelium_color@ctm-red-to-blue.html

  * igt@kms_chamelium_frames@hdmi-crc-fast:
    - shard-dg2:          NOTRUN -> [SKIP][128] ([i915#7828]) +6 other tests skip
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_chamelium_frames@hdmi-crc-fast.html

  * igt@kms_chamelium_hpd@hdmi-hpd-storm-disable:
    - shard-mtlp:         NOTRUN -> [SKIP][129] ([i915#7828]) +1 other test skip
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_chamelium_hpd@hdmi-hpd-storm-disable.html

  * igt@kms_chamelium_hpd@vga-hpd-after-suspend:
    - shard-dg1:          NOTRUN -> [SKIP][130] ([i915#7828]) +2 other tests skip
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_chamelium_hpd@vga-hpd-after-suspend.html

  * igt@kms_content_protection@dp-mst-lic-type-0:
    - shard-mtlp:         NOTRUN -> [SKIP][131] ([i915#3299])
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_content_protection@dp-mst-lic-type-0.html

  * igt@kms_content_protection@lic-type-0:
    - shard-dg2:          NOTRUN -> [SKIP][132] ([i915#9424])
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_content_protection@lic-type-0.html

  * igt@kms_content_protection@type1:
    - shard-dg2:          NOTRUN -> [SKIP][133] ([i915#7118] / [i915#9424]) +1 other test skip
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_content_protection@type1.html

  * igt@kms_cursor_crc@cursor-offscreen-512x170:
    - shard-dg2:          NOTRUN -> [SKIP][134] ([i915#3359]) +1 other test skip
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_cursor_crc@cursor-offscreen-512x170.html

  * igt@kms_cursor_crc@cursor-onscreen-512x512:
    - shard-mtlp:         NOTRUN -> [SKIP][135] ([i915#3359])
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-onscreen-512x512.html

  * igt@kms_cursor_crc@cursor-rapid-movement-256x85:
    - shard-mtlp:         NOTRUN -> [SKIP][136] ([i915#8814])
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-rapid-movement-256x85.html

  * igt@kms_cursor_crc@cursor-sliding-max-size:
    - shard-mtlp:         NOTRUN -> [SKIP][137] ([i915#3555] / [i915#8814])
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_crc@cursor-sliding-max-size.html

  * igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
    - shard-dg2:          NOTRUN -> [SKIP][138] ([fdo#109274] / [i915#5354]) +2 other tests skip
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - shard-mtlp:         NOTRUN -> [SKIP][139] ([i915#4213])
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size:
    - shard-snb:          [PASS][140] -> [SKIP][141] ([fdo#109271]) +3 other tests skip
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_cursor_legacy@cursora-vs-flipb-atomic-transitions-varying-size.html

  * igt@kms_cursor_legacy@cursorb-vs-flipa-legacy:
    - shard-mtlp:         NOTRUN -> [SKIP][142] ([i915#9809]) +1 other test skip
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_cursor_legacy@cursorb-vs-flipa-legacy.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions:
    - shard-tglu:         NOTRUN -> [SKIP][143] ([fdo#109274] / [fdo#111767])
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions-varying-size:
    - shard-tglu:         NOTRUN -> [SKIP][144] ([fdo#109274])
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic-transitions-varying-size.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][145] ([fdo#110189] / [i915#9723])
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-3/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-2.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-3:
    - shard-dg1:          NOTRUN -> [SKIP][146] ([fdo#110189] / [i915#9723])
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-12/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-hdmi-a-3.html

  * igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-vga-1:
    - shard-snb:          NOTRUN -> [SKIP][147] ([fdo#109271] / [fdo#110189])
   [147]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_dirtyfb@fbc-dirtyfb-ioctl@a-vga-1.html

  * igt@kms_dither@fb-8bpc-vs-panel-6bpc:
    - shard-dg1:          NOTRUN -> [SKIP][148] ([i915#3555]) +1 other test skip
   [148]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_dither@fb-8bpc-vs-panel-6bpc.html

  * igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-1:
    - shard-rkl:          NOTRUN -> [SKIP][149] ([i915#3804])
   [149]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-1.html

  * igt@kms_draw_crc@draw-method-mmap-gtt:
    - shard-mtlp:         NOTRUN -> [SKIP][150] ([i915#3555] / [i915#8812])
   [150]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_draw_crc@draw-method-mmap-gtt.html

  * igt@kms_dsc@dsc-fractional-bpp:
    - shard-mtlp:         NOTRUN -> [SKIP][151] ([i915#3840] / [i915#9688])
   [151]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_dsc@dsc-fractional-bpp.html

  * igt@kms_dsc@dsc-with-output-formats-with-bpc:
    - shard-dg2:          NOTRUN -> [SKIP][152] ([i915#3840] / [i915#9053])
   [152]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_dsc@dsc-with-output-formats-with-bpc.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-snb:          [PASS][153] -> [DMESG-WARN][154] ([i915#10007])
   [153]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_fbcon_fbt@fbc-suspend.html
   [154]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_feature_discovery@chamelium:
    - shard-dg2:          NOTRUN -> [SKIP][155] ([i915#4854])
   [155]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_feature_discovery@chamelium.html

  * igt@kms_flip@2x-flip-vs-expired-vblank:
    - shard-mtlp:         NOTRUN -> [SKIP][156] ([i915#3637])
   [156]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_flip@2x-flip-vs-expired-vblank.html

  * igt@kms_flip@2x-flip-vs-fences-interruptible:
    - shard-dg2:          NOTRUN -> [SKIP][157] ([i915#8381])
   [157]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_flip@2x-flip-vs-fences-interruptible.html

  * igt@kms_flip@2x-flip-vs-modeset:
    - shard-tglu:         NOTRUN -> [SKIP][158] ([fdo#109274] / [i915#3637] / [i915#3966]) +1 other test skip
   [158]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip@2x-flip-vs-modeset.html

  * igt@kms_flip@2x-flip-vs-modeset-vs-hang:
    - shard-dg2:          NOTRUN -> [SKIP][159] ([fdo#109274]) +5 other tests skip
   [159]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_flip@2x-flip-vs-modeset-vs-hang.html

  * igt@kms_flip@2x-flip-vs-panning-vs-hang:
    - shard-dg1:          NOTRUN -> [SKIP][160] ([fdo#111825] / [i915#9934]) +2 other tests skip
   [160]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_flip@2x-flip-vs-panning-vs-hang.html

  * igt@kms_flip@2x-flip-vs-suspend-interruptible:
    - shard-tglu:         NOTRUN -> [SKIP][161] ([fdo#109274] / [i915#3637])
   [161]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip@2x-flip-vs-suspend-interruptible.html

  * igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling@pipe-a-valid-mode:
    - shard-tglu:         NOTRUN -> [SKIP][162] ([i915#2587] / [i915#2672])
   [162]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling@pipe-a-valid-mode:
    - shard-dg1:          NOTRUN -> [SKIP][163] ([i915#2587] / [i915#2672]) +1 other test skip
   [163]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling@pipe-a-valid-mode:
    - shard-dg2:          NOTRUN -> [SKIP][164] ([i915#2672]) +3 other tests skip
   [164]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling@pipe-a-valid-mode.html

  * igt@kms_force_connector_basic@force-load-detect:
    - shard-dg2:          NOTRUN -> [SKIP][165] ([fdo#109285])
   [165]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move:
    - shard-mtlp:         NOTRUN -> [SKIP][166] ([i915#1825]) +7 other tests skip
   [166]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][167] ([fdo#111767] / [i915#5354])
   [167]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render:
    - shard-tglu:         NOTRUN -> [SKIP][168] ([fdo#109280]) +8 other tests skip
   [168]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt:
    - shard-dg2:          NOTRUN -> [SKIP][169] ([i915#5354]) +21 other tests skip
   [169]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render:
    - shard-dg1:          NOTRUN -> [SKIP][170] ([fdo#111825]) +6 other tests skip
   [170]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt:
    - shard-mtlp:         NOTRUN -> [SKIP][171] ([i915#8708]) +3 other tests skip
   [171]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite:
    - shard-dg2:          NOTRUN -> [SKIP][172] ([i915#3458]) +14 other tests skip
   [172]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move:
    - shard-dg1:          NOTRUN -> [SKIP][173] ([i915#3458]) +4 other tests skip
   [173]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move.html

  * igt@kms_frontbuffer_tracking@plane-fbc-rte:
    - shard-glk:          NOTRUN -> [SKIP][174] ([fdo#109271]) +104 other tests skip
   [174]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_frontbuffer_tracking@plane-fbc-rte.html
    - shard-dg1:          NOTRUN -> [SKIP][175] ([i915#10070])
   [175]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@plane-fbc-rte.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt:
    - shard-dg2:          NOTRUN -> [SKIP][176] ([i915#8708]) +6 other tests skip
   [176]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc:
    - shard-dg1:          NOTRUN -> [SKIP][177] ([i915#8708]) +4 other tests skip
   [177]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc.html

  * igt@kms_getfb@getfb-reject-ccs:
    - shard-dg2:          NOTRUN -> [SKIP][178] ([i915#6118])
   [178]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_getfb@getfb-reject-ccs.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-dg2:          NOTRUN -> [SKIP][179] ([i915#3555] / [i915#8228]) +1 other test skip
   [179]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c:
    - shard-dg2:          NOTRUN -> [SKIP][180] ([fdo#109289]) +2 other tests skip
   [180]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c.html

  * igt@kms_plane_scaling@2x-scaler-multi-pipe:
    - shard-dg2:          NOTRUN -> [SKIP][181] ([fdo#109274] / [i915#5354] / [i915#9423])
   [181]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_plane_scaling@2x-scaler-multi-pipe.html

  * igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-3:
    - shard-dg1:          NOTRUN -> [FAIL][182] ([i915#8292])
   [182]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-3.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format@pipe-b-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][183] ([i915#9423]) +7 other tests skip
   [183]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format@pipe-b-hdmi-a-3.html

  * igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-a-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][184] ([i915#9423]) +11 other tests skip
   [184]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-19/igt@kms_plane_scaling@plane-downscale-factor-0-5-with-rotation@pipe-a-hdmi-a-4.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-1:
    - shard-rkl:          NOTRUN -> [SKIP][185] ([i915#5176] / [i915#9423]) +1 other test skip
   [185]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-1.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][186] ([i915#5176] / [i915#9423]) +3 other tests skip
   [186]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-16/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-c-hdmi-a-4.html

  * igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-a-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][187] ([i915#9423]) +5 other tests skip
   [187]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_plane_scaling@plane-upscale-factor-0-25-with-rotation@pipe-a-hdmi-a-2.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20@pipe-b-hdmi-a-2:
    - shard-rkl:          NOTRUN -> [SKIP][188] ([i915#5235]) +11 other tests skip
   [188]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-6/igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20@pipe-b-hdmi-a-2.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-hdmi-a-4:
    - shard-dg1:          NOTRUN -> [SKIP][189] ([i915#5235]) +15 other tests skip
   [189]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-16/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-hdmi-a-4.html

  * igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-d-hdmi-a-3:
    - shard-dg2:          NOTRUN -> [SKIP][190] ([i915#5235] / [i915#9423]) +3 other tests skip
   [190]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-6/igt@kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25@pipe-d-hdmi-a-3.html

  * igt@kms_pm_dc@dc3co-vpb-simulation:
    - shard-dg2:          NOTRUN -> [SKIP][191] ([i915#9685])
   [191]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_pm_dc@dc3co-vpb-simulation.html

  * igt@kms_pm_dc@dc5-psr:
    - shard-tglu:         NOTRUN -> [SKIP][192] ([i915#9685])
   [192]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_pm_dc@dc5-psr.html

  * igt@kms_pm_rpm@i2c:
    - shard-dg2:          [PASS][193] -> [FAIL][194] ([i915#8717])
   [193]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@i2c.html
   [194]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@i2c.html

  * igt@kms_pm_rpm@modeset-lpsp:
    - shard-dg2:          NOTRUN -> [SKIP][195] ([i915#9519])
   [195]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_pm_rpm@modeset-lpsp.html

  * igt@kms_pm_rpm@modeset-lpsp-stress:
    - shard-dg2:          [PASS][196] -> [SKIP][197] ([i915#9519])
   [196]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@modeset-lpsp-stress.html
   [197]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@modeset-lpsp-stress.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait:
    - shard-rkl:          [PASS][198] -> [SKIP][199] ([i915#9519]) +1 other test skip
   [198]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-3/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html
   [199]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress-no-wait.html

  * igt@kms_prime@basic-modeset-hybrid:
    - shard-dg2:          NOTRUN -> [SKIP][200] ([i915#6524] / [i915#6805])
   [200]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_prime@basic-modeset-hybrid.html

  * igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf:
    - shard-glk:          NOTRUN -> [SKIP][201] ([fdo#109271] / [fdo#110189]) +1 other test skip
   [201]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk7/igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf.html

  * igt@kms_psr2_sf@fbc-primary-plane-update-sf-dmg-area:
    - shard-tglu:         NOTRUN -> [SKIP][202] ([fdo#110189]) +7 other tests skip
   [202]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_psr2_sf@fbc-primary-plane-update-sf-dmg-area.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf:
    - shard-dg2:          NOTRUN -> [SKIP][203] ([fdo#110189]) +2 other tests skip
   [203]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf:
    - shard-dg1:          NOTRUN -> [SKIP][204] ([fdo#110189])
   [204]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_psr2_sf@overlay-plane-move-continuous-exceed-sf.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-mtlp:         NOTRUN -> [SKIP][205] ([i915#4348])
   [205]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_psr@fbc-psr-primary-mmap-gtt@edp-1:
    - shard-mtlp:         NOTRUN -> [SKIP][206] ([i915#9688]) +2 other tests skip
   [206]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_psr@fbc-psr-primary-mmap-gtt@edp-1.html

  * igt@kms_psr@psr-cursor-render:
    - shard-dg2:          NOTRUN -> [SKIP][207] ([i915#9732]) +15 other tests skip
   [207]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_psr@psr-cursor-render.html

  * igt@kms_psr@psr2-primary-mmap-cpu:
    - shard-dg1:          NOTRUN -> [SKIP][208] ([i915#9732]) +4 other tests skip
   [208]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_psr@psr2-primary-mmap-cpu.html

  * igt@kms_psr@psr2-sprite-mmap-gtt:
    - shard-tglu:         NOTRUN -> [SKIP][209] ([i915#9732]) +3 other tests skip
   [209]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_psr@psr2-sprite-mmap-gtt.html

  * igt@kms_rotation_crc@primary-y-tiled-reflect-x-180:
    - shard-rkl:          [PASS][210] -> [INCOMPLETE][211] ([i915#8875] / [i915#9569])
   [210]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@kms_rotation_crc@primary-y-tiled-reflect-x-180.html
   [211]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-1/igt@kms_rotation_crc@primary-y-tiled-reflect-x-180.html

  * igt@kms_rotation_crc@sprite-rotation-90:
    - shard-dg2:          NOTRUN -> [SKIP][212] ([i915#4235]) +2 other tests skip
   [212]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@kms_rotation_crc@sprite-rotation-90.html

  * igt@kms_rotation_crc@sprite-rotation-90-pos-100-0:
    - shard-mtlp:         NOTRUN -> [SKIP][213] ([i915#4235]) +1 other test skip
   [213]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.html

  * igt@kms_scaling_modes@scaling-mode-center:
    - shard-tglu:         NOTRUN -> [SKIP][214] ([i915#3555]) +1 other test skip
   [214]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@kms_scaling_modes@scaling-mode-center.html

  * igt@kms_setmode@invalid-clone-single-crtc-stealing:
    - shard-dg2:          NOTRUN -> [SKIP][215] ([i915#3555]) +3 other tests skip
   [215]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_setmode@invalid-clone-single-crtc-stealing.html

  * igt@kms_tiled_display@basic-test-pattern-with-chamelium:
    - shard-mtlp:         NOTRUN -> [SKIP][216] ([i915#8623])
   [216]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html

  * igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1:
    - shard-rkl:          [PASS][217] -> [FAIL][218] ([i915#9196])
   [217]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-2/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html
   [218]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-5/igt@kms_universal_plane@cursor-fb-leak@pipe-a-hdmi-a-1.html

  * igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1:
    - shard-tglu:         [PASS][219] -> [FAIL][220] ([i915#9196])
   [219]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-7/igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1.html
   [220]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-9/igt@kms_universal_plane@cursor-fb-leak@pipe-d-hdmi-a-1.html

  * igt@kms_vrr@seamless-rr-switch-vrr:
    - shard-dg2:          NOTRUN -> [SKIP][221] ([i915#9906])
   [221]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@kms_vrr@seamless-rr-switch-vrr.html

  * igt@kms_writeback@writeback-fb-id-xrgb2101010:
    - shard-dg2:          NOTRUN -> [SKIP][222] ([i915#2437] / [i915#9412])
   [222]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@kms_writeback@writeback-fb-id-xrgb2101010.html

  * igt@kms_writeback@writeback-pixel-formats:
    - shard-glk:          NOTRUN -> [SKIP][223] ([fdo#109271] / [i915#2437])
   [223]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_writeback@writeback-pixel-formats.html
    - shard-dg1:          NOTRUN -> [SKIP][224] ([i915#2437] / [i915#9412])
   [224]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@kms_writeback@writeback-pixel-formats.html

  * igt@perf@mi-rpc:
    - shard-dg2:          NOTRUN -> [SKIP][225] ([i915#2434] / [i915#7387])
   [225]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@perf@mi-rpc.html

  * igt@perf_pmu@event-wait@rcs0:
    - shard-tglu:         NOTRUN -> [SKIP][226] ([fdo#112283])
   [226]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@perf_pmu@event-wait@rcs0.html

  * igt@perf_pmu@frequency@gt0:
    - shard-dg2:          NOTRUN -> [FAIL][227] ([i915#6806])
   [227]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@perf_pmu@frequency@gt0.html
    - shard-dg1:          NOTRUN -> [FAIL][228] ([i915#6806])
   [228]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-13/igt@perf_pmu@frequency@gt0.html

  * igt@perf_pmu@rc6@other-idle-gt0:
    - shard-tglu:         NOTRUN -> [SKIP][229] ([i915#8516])
   [229]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@perf_pmu@rc6@other-idle-gt0.html

  * igt@prime_udl:
    - shard-dg2:          NOTRUN -> [SKIP][230] ([fdo#109291])
   [230]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@prime_udl.html

  * igt@prime_vgem@basic-write:
    - shard-dg2:          NOTRUN -> [SKIP][231] ([i915#3291] / [i915#3708])
   [231]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@prime_vgem@basic-write.html

  * igt@prime_vgem@fence-read-hang:
    - shard-tglu:         NOTRUN -> [SKIP][232] ([fdo#109295])
   [232]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@prime_vgem@fence-read-hang.html

  * igt@prime_vgem@fence-write-hang:
    - shard-dg1:          NOTRUN -> [SKIP][233] ([i915#3708]) +1 other test skip
   [233]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@prime_vgem@fence-write-hang.html

  * igt@sriov_basic@enable-vfs-autoprobe-on:
    - shard-dg1:          NOTRUN -> [SKIP][234] ([i915#9917])
   [234]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@sriov_basic@enable-vfs-autoprobe-on.html

  * igt@sriov_basic@enable-vfs-bind-unbind-each:
    - shard-mtlp:         NOTRUN -> [SKIP][235] ([i915#9917])
   [235]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@sriov_basic@enable-vfs-bind-unbind-each.html

  * igt@syncobj_wait@invalid-wait-zero-handles:
    - shard-dg1:          NOTRUN -> [FAIL][236] ([i915#9779])
   [236]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@syncobj_wait@invalid-wait-zero-handles.html

  * igt@v3d/v3d_perfmon@create-two-perfmon:
    - shard-dg1:          NOTRUN -> [SKIP][237] ([i915#2575]) +2 other tests skip
   [237]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@v3d/v3d_perfmon@create-two-perfmon.html

  * igt@v3d/v3d_submit_cl@single-out-sync:
    - shard-tglu:         NOTRUN -> [SKIP][238] ([fdo#109315] / [i915#2575]) +2 other tests skip
   [238]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@v3d/v3d_submit_cl@single-out-sync.html

  * igt@v3d/v3d_submit_csd@bad-extension:
    - shard-mtlp:         NOTRUN -> [SKIP][239] ([i915#2575]) +1 other test skip
   [239]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@v3d/v3d_submit_csd@bad-extension.html

  * igt@v3d/v3d_submit_csd@single-out-sync:
    - shard-dg2:          NOTRUN -> [SKIP][240] ([i915#2575]) +9 other tests skip
   [240]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-5/igt@v3d/v3d_submit_csd@single-out-sync.html

  * igt@vc4/vc4_label_bo@set-bad-name:
    - shard-mtlp:         NOTRUN -> [SKIP][241] ([i915#7711]) +1 other test skip
   [241]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-3/igt@vc4/vc4_label_bo@set-bad-name.html

  * igt@vc4/vc4_perfmon@create-perfmon-0:
    - shard-tglu:         NOTRUN -> [SKIP][242] ([i915#2575])
   [242]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-4/igt@vc4/vc4_perfmon@create-perfmon-0.html

  * igt@vc4/vc4_tiling@set-bad-modifier:
    - shard-dg1:          NOTRUN -> [SKIP][243] ([i915#7711]) +1 other test skip
   [243]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@vc4/vc4_tiling@set-bad-modifier.html

  * igt@vc4/vc4_wait_bo@bad-bo:
    - shard-dg2:          NOTRUN -> [SKIP][244] ([i915#7711]) +4 other tests skip
   [244]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-1/igt@vc4/vc4_wait_bo@bad-bo.html

  
#### Possible fixes ####

  * igt@drm_fdinfo@most-busy-idle-check-all@rcs0:
    - shard-rkl:          [FAIL][245] ([i915#7742]) -> [PASS][246]
   [245]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html
   [246]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-5/igt@drm_fdinfo@most-busy-idle-check-all@rcs0.html

  * igt@gem_ctx_exec@basic-nohangcheck:
    - shard-tglu:         [FAIL][247] ([i915#6268]) -> [PASS][248]
   [247]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-4/igt@gem_ctx_exec@basic-nohangcheck.html
   [248]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-3/igt@gem_ctx_exec@basic-nohangcheck.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-rkl:          [FAIL][249] ([i915#2842]) -> [PASS][250]
   [249]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@gem_exec_fair@basic-none@vecs0.html
   [250]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [FAIL][251] ([i915#2842]) -> [PASS][252]
   [251]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk1/igt@gem_exec_fair@basic-throttle@rcs0.html
   [252]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk5/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_lmem_swapping@smem-oom@lmem0:
    - shard-dg1:          [TIMEOUT][253] ([i915#5493]) -> [PASS][254]
   [253]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-17/igt@gem_lmem_swapping@smem-oom@lmem0.html
   [254]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-15/igt@gem_lmem_swapping@smem-oom@lmem0.html

  * igt@i915_module_load@reload-with-fault-injection:
    - shard-dg1:          [INCOMPLETE][255] ([i915#10137] / [i915#9820] / [i915#9849]) -> [PASS][256]
   [255]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-16/igt@i915_module_load@reload-with-fault-injection.html
   [256]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-18/igt@i915_module_load@reload-with-fault-injection.html

  * igt@i915_suspend@basic-s3-without-i915:
    - shard-rkl:          [FAIL][257] ([i915#10031]) -> [PASS][258]
   [257]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-4/igt@i915_suspend@basic-s3-without-i915.html
   [258]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-2/igt@i915_suspend@basic-s3-without-i915.html

  * igt@kms_big_fb@4-tiled-64bpp-rotate-180:
    - shard-mtlp:         [FAIL][259] ([i915#3763] / [i915#5138]) -> [PASS][260]
   [259]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-mtlp-4/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html
   [260]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-mtlp-8/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
    - shard-tglu:         [FAIL][261] ([i915#3743]) -> [PASS][262]
   [261]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-tglu-9/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
   [262]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-tglu-6/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html

  * igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic:
    - shard-snb:          [SKIP][263] ([fdo#109271] / [fdo#111767]) -> [PASS][264]
   [263]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html
   [264]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-varying-size:
    - shard-snb:          [SKIP][265] ([fdo#109271]) -> [PASS][266] +3 other tests pass
   [265]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_cursor_legacy@cursora-vs-flipb-varying-size.html
   [266]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_cursor_legacy@cursora-vs-flipb-varying-size.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-glk:          [FAIL][267] ([i915#2346]) -> [PASS][268]
   [267]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-glk3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [268]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-glk9/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_pm_rpm@modeset-non-lpsp:
    - shard-dg2:          [SKIP][269] ([i915#9519]) -> [PASS][270]
   [269]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@kms_pm_rpm@modeset-non-lpsp.html
   [270]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-2/igt@kms_pm_rpm@modeset-non-lpsp.html

  * igt@kms_pm_rpm@modeset-non-lpsp-stress:
    - shard-rkl:          [SKIP][271] ([i915#9519]) -> [PASS][272] +2 other tests pass
   [271]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-7/igt@kms_pm_rpm@modeset-non-lpsp-stress.html
   [272]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-3/igt@kms_pm_rpm@modeset-non-lpsp-stress.html

  * igt@perf@non-zero-reason@0-rcs0:
    - shard-dg2:          [FAIL][273] ([i915#7484]) -> [PASS][274]
   [273]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg2-10/igt@perf@non-zero-reason@0-rcs0.html
   [274]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg2-10/igt@perf@non-zero-reason@0-rcs0.html

  
#### Warnings ####

  * igt@kms_content_protection@atomic:
    - shard-snb:          [INCOMPLETE][275] ([i915#8816]) -> [SKIP][276] ([fdo#109271])
   [275]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_content_protection@atomic.html
   [276]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@mei-interface:
    - shard-dg1:          [SKIP][277] ([i915#9424]) -> [SKIP][278] ([i915#9433])
   [277]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-dg1-15/igt@kms_content_protection@mei-interface.html
   [278]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-dg1-12/igt@kms_content_protection@mei-interface.html
    - shard-snb:          [SKIP][279] ([fdo#109271]) -> [INCOMPLETE][280] ([i915#9878])
   [279]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_content_protection@mei-interface.html
   [280]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_content_protection@mei-interface.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc:
    - shard-snb:          [SKIP][281] ([fdo#109271] / [fdo#111767]) -> [SKIP][282] ([fdo#109271])
   [281]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb6/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc.html
   [282]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb7/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render:
    - shard-snb:          [SKIP][283] ([fdo#109271]) -> [SKIP][284] ([fdo#109271] / [fdo#111767])
   [283]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-snb7/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html
   [284]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-snb2/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render.html

  * igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
    - shard-rkl:          [SKIP][285] ([i915#4070] / [i915#4816]) -> [SKIP][286] ([i915#4816])
   [285]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-1/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
   [286]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-7/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html

  * igt@kms_pm_dc@dc6-dpms:
    - shard-rkl:          [FAIL][287] ([i915#9295]) -> [SKIP][288] ([i915#3361])
   [287]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_14345/shard-rkl-5/igt@kms_pm_dc@dc6-dpms.html
   [288]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_129082v6/shard-rkl-4/igt@kms_pm_dc@dc6-dpms.html

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

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111767]: https://bugs.freedesktop.org/show_bug.cgi?id=111767
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
  [i915#10007]: https://gitlab.freedesktop.org/drm/intel/issues/10007
  [i915#10031]: https://gitlab.freedesktop.org/drm/intel/issues/10031
  [i915#10070]: https://gitlab.freedesktop.org/drm/intel/issues/10070
  [i915#10137]: https://gitlab.freedesktop.org/drm/intel/issues/10137
  [i915#10307]: https://gitlab.freedesktop.org/drm/intel/issues/10307
  [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2434]: https://gitlab.freedesktop.org/drm/intel/issues/2434
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#280]: https://gitlab.freedesktop.org/drm/intel/issues/280
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
  [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
  [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3299]: https://gitlab.freedesktop.org/drm/intel/issues/3299
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3361]: https://gitlab.freedesktop.org/drm/intel/issues/3361
  [i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
  [i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#3742]: https://gitlab.freedesktop.org/drm/intel/issues/3742
  [i915#3743]: https://gitlab.freedesktop.org/drm/intel/issues/3743
  [i915#3763]: https://gitlab.freedesktop.org/drm/intel/issues/3763
  [i915#3804]: https://gitlab.freedesktop.org/drm/intel/issues/3804
  [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
  [i915#3966]: https://gitlab.freedesktop.org/drm/intel/issues/3966
  [i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4087]: https://gitlab.freedesktop.org/drm/intel/issues/4087
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#4235]: https://gitlab.freedesktop.org/drm/intel/issues/4235
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4348]: https://gitlab.freedesktop.org/drm/intel/issues/4348
  [i915#4473]: https://gitlab.freedesktop.org/drm/intel/issues/4473
  [i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
  [i915#4565]: https://gitlab.freedesktop.org/drm/intel/issues/4565
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4771]: https://gitlab.freedesktop.org/drm/intel/issues/4771
  [i915#4812]: https://gitlab.freedesktop.org/drm/intel/issues/4812
  [i915#4816]: https://gitlab.freedesktop.org/drm/intel/issues/4816
  [i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
  [i915#4854]: https://gitlab.freedesktop.org/drm/intel/issues/4854
  [i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
  [i915#4885]: https://gitlab.freedesktop.org/drm/intel/issues/4885
  [i915#5107]: https://gitlab.freedesktop.org/drm/intel/issues/5107
  [i915#5138]: https://gitlab.freedesktop.org/drm/intel/issues/5138
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
  [i915#5493]: https://gitlab.freedesktop.org/drm/intel/issues/5493
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
  [i915#6118]: https://gitlab.freedesktop.org/drm/intel/issues/6118
  [i915#6268]: https://gitlab.freedesktop.org/drm/intel/issues/6268
  [i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
  [i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
  [i915#6805]: https://gitlab.freedesktop.org/drm/intel/issues/6805
  [i915#6806]: https://gitlab.freedesktop.org/drm/intel/issues/6806
  [i915#7118]: https://gitlab.freedesktop.org/drm/intel/issues/7118
  [i915#7213]: https://gitlab.freedesktop.org/drm/intel/issues/7213
  [i915#7387]: https://gitlab.freedesktop.org/drm/intel/issues/7387
  [i915#7484]: https://gitlab.freedesktop.org/drm/intel/issues/7484
  [i915#7701]: https://gitlab.freedesktop.org/drm/intel/issues/7701
  [i915#7707]: https://gitlab.freedesktop.org/drm/intel/issues/7707
  [i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
  [i915#7742]: https://gitlab.freedesktop.org/drm/intel/issues/7742
  [i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
  [i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
  [i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
  [i915#8228]: https://gitlab.freedesktop.org/drm/intel/issues/8228
  [i915#8292]: https://gitlab.freedesktop.org/drm/intel/issues/8292
  [i915#8293]: https://gitlab.freedesktop.org/drm/intel/issues/8293
  [i915#8381]: https://gitlab.freedesktop.org/drm/intel/issues/8381
  [i915#8399]: https://gitlab.freedesktop.org/drm/intel/issues/8399
  [i915#8411]: https://gitlab.freedesktop.org/drm/intel/issues/8411
  [i915#8414]: https://gitlab.freedesktop.org/drm/intel/issues/8414
  [i915#8428]: https://gitlab.freedesktop.org/drm/intel/issues/8428
  [i915#8516]: https://gitlab.freedesktop.org/drm/intel/issues/8516
  [i915#8555]: https://gitlab.freedesktop.org/drm/intel/issues/8555
  [i915#8623]: https://gitlab.freedesktop.org/drm/intel/issues/8623
  [i915#8708]: https://gitlab.freedesktop.org/drm/intel/issues/8708
  [i915#8709]: https://gitlab.freedesktop.org/drm/intel/issues/8709
  [i915#8717]: https://gitlab.freedesktop.org/drm/intel/issues/8717
  [i915#8812]: https://gitlab.freedesktop.org/drm/intel/issues/8812
  [i915#8814]: https://gitlab.freedesktop.org/drm/intel/issues/8814
  [i915#8816]: https://gitlab.freedesktop.org/drm/intel/issues/8816
  [i915#8875]: https://gitlab.freedesktop.org/drm/intel/issues/8875
  [i915#9010]: https://gitlab.freedesktop.org/drm/intel/issues/9010
  [i915#9053]: https://gitlab.freedesktop.org/drm/intel/issues/9053
  [i915#9196]: https://gitlab.freedesktop.org/drm/intel/issues/9196
  [i915#9275]: https://gitlab.freedesktop.org/drm/intel/issues/9275
  [i915#9295]: https://gitlab.freedesktop.org/drm/intel/issues/9295
  [i915#9412]: https://gitlab.freedesktop.org/drm/intel/issues/9412
  [i915#9423]: https://gitlab.freedesktop.org/drm/intel/issues/9423
  [i915#9424]: https://gitlab.freedesktop.org/drm/intel/issues/9424
  [i915#9433]: https://gitlab.freedesktop.org/drm/intel/issues/9433
  [i915#9519]: https://gitlab.freedesktop.org/drm/intel/issues/9519
  [i915#9569]: https://gitlab.freedesktop.org/drm/intel/issues/9569
  [i915#9685]: https://gitlab.freedesktop.org/drm/intel/issues/9685
  [i915#9688]: https://gitlab.freedesktop.org/drm/intel/issues/9688
  [i915#9723]: https://gitlab.freedesktop.org/drm/intel/issues/9723
  [i915#9732]: https://gitlab.freedesktop.org/drm/intel/issues/9732
  [i915#9779]: https://gitlab.freedesktop.org/drm/intel/issues/9779
  [i915#9809]: https://gitlab.freedesktop.org/drm/intel/issues/9809
  [i915#9820]: https://gitlab.freedesktop.org/drm/intel/issues/9820
  [i915#9849]: https://gitlab.freedesktop.org/drm/intel/issues/9849
  [i915#9878]: https://gitlab.freedesktop.org/drm/intel/issues/9878
  [i915#9906]: https://gitlab.freedesktop.org/drm/intel/issues/9906
  [i915#9917]: https://gitlab.freedesktop.org/drm/intel/issues/9917
  [i915#9934]: https://gitlab.freedesktop.org/drm/intel/issues/9934


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

  * Linux: CI_DRM_14345 -> Patchwork_129082v6

  CI-20190529: 20190529
  CI_DRM_14345: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7731: 17f897a81868fb35c6a7033a8b07256659742248 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_129082v6: b3552bf1e79de200a6ca49c518ead46a1256618c @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

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

end of thread, other threads:[~2024-02-28  5:55 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-20 21:18 [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Imre Deak
2024-02-20 21:18 ` [PATCH v2 01/21] drm/dp: Add drm_dp_max_dprx_data_rate() Imre Deak
2024-02-26 18:52   ` [PATCH v3 " Imre Deak
2024-02-20 21:18 ` [PATCH v2 02/21] drm/dp: Add support for DP tunneling Imre Deak
2024-02-23  6:25   ` Shankar, Uma
2024-02-23 14:33     ` Imre Deak
2024-02-23 21:32   ` Ville Syrjälä
2024-02-26 11:40     ` Imre Deak
2024-02-26 18:52   ` [PATCH v3 " Imre Deak
2024-02-20 21:18 ` [PATCH v2 03/21] drm/i915: Fix display bpp limit computation during system resume Imre Deak
2024-02-23  6:38   ` Shankar, Uma
2024-02-20 21:18 ` [PATCH v2 04/21] drm/i915/dp: Add support to notify MST connectors to retry modesets Imre Deak
2024-02-23  7:59   ` Shankar, Uma
2024-02-20 21:18 ` [PATCH v2 05/21] drm/i915/dp: Use drm_dp_max_dprx_data_rate() Imre Deak
2024-02-20 21:18 ` [PATCH v2 06/21] drm/i915/dp: Factor out intel_dp_config_required_rate() Imre Deak
2024-02-20 21:18 ` [PATCH v2 07/21] drm/i915/dp: Export intel_dp_max_common_rate/lane_count() Imre Deak
2024-02-20 21:18 ` [PATCH v2 08/21] drm/i915/dp: Factor out intel_dp_update_sink_caps() Imre Deak
2024-02-20 21:18 ` [PATCH v2 09/21] drm/i915/dp: Factor out intel_dp_read_dprx_caps() Imre Deak
2024-02-20 21:18 ` [PATCH v2 10/21] drm/i915/dp: Add intel_dp_max_link_data_rate() Imre Deak
2024-02-20 21:18 ` [PATCH v2 11/21] drm/i915/dp: Add way to get active pipes with syncing commits Imre Deak
2024-02-23  8:10   ` Shankar, Uma
2024-02-23 21:11   ` Ville Syrjälä
2024-02-23 22:09     ` Imre Deak
2024-02-23 22:13       ` Ville Syrjälä
2024-02-26 18:52   ` [PATCH v3 11/21] drm/i915/dp: Sync instead of try-sync commits when getting active pipes Imre Deak
2024-02-20 21:18 ` [PATCH v2 12/21] drm/i915/dp: Add support for DP tunnel BW allocation Imre Deak
2024-02-23 21:37   ` Ville Syrjälä
2024-02-26 11:42     ` Imre Deak
2024-02-26 10:47   ` Shankar, Uma
2024-02-26 18:52   ` [PATCH v3 " Imre Deak
2024-02-20 21:18 ` [PATCH v2 13/21] drm/i915/dp: Add DP tunnel atomic state and check BW limit Imre Deak
2024-02-23 10:13   ` Shankar, Uma
2024-02-20 21:18 ` [PATCH v2 14/21] drm/i915/dp: Account for tunnel BW limit in intel_dp_max_link_data_rate() Imre Deak
2024-02-20 21:18 ` [PATCH v2 15/21] drm/i915/dp: Compute DP tunnel BW during encoder state computation Imre Deak
2024-02-20 21:18 ` [PATCH v2 16/21] drm/i915/dp: Allocate/free DP tunnel BW in the encoder enable/disable hooks Imre Deak
2024-02-23 21:25   ` Ville Syrjälä
2024-02-20 21:18 ` [PATCH v2 17/21] drm/i915/dp: Handle DP tunnel IRQs Imre Deak
2024-02-23 10:19   ` Shankar, Uma
2024-02-20 21:18 ` [PATCH v2 18/21] drm/i915/dp: Call intel_dp_sync_state() always for DDI DP encoders Imre Deak
2024-02-20 21:18 ` [PATCH v2 19/21] drm/i915/dp: Suspend/resume DP tunnels Imre Deak
2024-02-23 10:23   ` Shankar, Uma
2024-02-20 21:18 ` [PATCH v2 20/21] drm/i915/dp: Read DPRX for all long HPD pulses Imre Deak
2024-02-23 10:33   ` Shankar, Uma
2024-02-20 21:18 ` [PATCH v2 21/21] drm/i915/dp: Enable DP tunnel BW allocation mode Imre Deak
2024-02-23 10:36   ` Shankar, Uma
2024-02-21  1:49 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev2) Patchwork
2024-02-21  1:49 ` ✗ Fi.CI.SPARSE: " Patchwork
2024-02-21  2:08 ` ✓ Fi.CI.BAT: success " Patchwork
2024-02-21  5:25 ` ✗ Fi.CI.IGT: failure " Patchwork
2024-02-23 22:14 ` [PATCH v2 00/21] drm/i915: Add Display Port tunnel BW allocation support Ville Syrjälä
2024-02-26 13:54 ` Jani Nikula
2024-02-26 13:59   ` Maxime Ripard
2024-02-27  1:02 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add Display Port tunnel BW allocation support (rev6) Patchwork
2024-02-27  1:02 ` ✗ Fi.CI.SPARSE: " Patchwork
2024-02-27  1:18 ` ✗ Fi.CI.BAT: failure " Patchwork
2024-02-27 10:59   ` Imre Deak
2024-02-27 11:34     ` Illipilli, TejasreeX
2024-02-27 11:32 ` ✓ Fi.CI.BAT: success " Patchwork
2024-02-27 14:21 ` ✗ Fi.CI.IGT: failure " Patchwork
2024-02-27 15:51   ` Imre Deak
2024-02-28  5:55 ` ✓ Fi.CI.IGT: success " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.