summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2026-04-08 18:57:44 +0300
committerJani Nikula <jani.nikula@intel.com>2026-04-13 10:16:13 +0300
commitf49499e635c18ead4ba6b573c63955c02056b840 (patch)
tree219daec94179ca13c19dcae6515b4b88247581ef /drivers/gpu
parent482bcc7ee600dcb5fb937dc742d051977fb5983c (diff)
downloadlinux-next-f49499e635c18ead4ba6b573c63955c02056b840.tar.gz
linux-next-f49499e635c18ead4ba6b573c63955c02056b840.zip
drm/i915: Walk crtcs in pipe order
Currently our crtcs are registered in pipe order, and thus all the for_intel_crtc*() iterators walk the crtcs in pipe order. There are a bunch of places that more or less depend on that. Eg. during plane updates and such we want joined pipes to be processed back-to-back to give a better chance of an atomic update across the whole set. When we start to register crtcs in a different order we don't want to change the order in which the pipes get handled. Decouple the for_each_intel_crtc*() iterators from the crtc registration order by using a separate list which will be sorted by the pipe rather than the crtc index. We could probably use a simple array or something, but that would require some kind of extra iterator variable for the macros, and thus would require a lot more changes. Using a linked list keeps the fallout minimal. We can look at using a more optimal data structure later. I also added this extra junk to the atomic state iterators: "(__i) = drm_crtc_index(&(crtc)->base), (void)(__i)" even though the macro itself no longer needs the "__i" iterator. This in case the "__i" is used by the caller, and to avoid compiler warnings if it's completely unused now. v2: Flip the pipe comparison (Jani) Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patch.msgid.link/20260408155744.13326-3-ville.syrjala@linux.intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h90
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_core.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_driver.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h1
-rw-r--r--drivers/gpu/drm/xe/display/xe_display.c1
6 files changed, 64 insertions, 52 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index b8189cd5d864..c88a6810c49f 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -209,6 +209,8 @@ static struct intel_crtc *intel_crtc_alloc(void)
crtc->base.state = &crtc_state->uapi;
crtc->config = crtc_state;
+ INIT_LIST_HEAD(&crtc->pipe_head);
+
return crtc;
}
@@ -222,6 +224,8 @@ static void intel_crtc_destroy(struct drm_crtc *_crtc)
{
struct intel_crtc *crtc = to_intel_crtc(_crtc);
+ list_del(&crtc->pipe_head);
+
cpu_latency_qos_remove_request(&crtc->vblank_pm_qos);
drm_crtc_cleanup(&crtc->base);
@@ -308,6 +312,20 @@ static const struct drm_crtc_funcs i8xx_crtc_funcs = {
.get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
};
+static void add_crtc_to_pipe_list(struct intel_display *display, struct intel_crtc *crtc)
+{
+ struct intel_crtc *iter;
+
+ list_for_each_entry(iter, &display->pipe_list, pipe_head) {
+ if (crtc->pipe < iter->pipe) {
+ list_add_tail(&crtc->pipe_head, &iter->pipe_head);
+ return;
+ }
+ }
+
+ list_add_tail(&crtc->pipe_head, &display->pipe_list);
+}
+
static int __intel_crtc_init(struct intel_display *display, enum pipe pipe)
{
struct intel_plane *primary, *cursor;
@@ -398,6 +416,8 @@ static int __intel_crtc_init(struct intel_display *display, enum pipe pipe)
if (HAS_CASF(display) && crtc->num_scalers >= 2)
drm_crtc_create_sharpness_strength_property(&crtc->base);
+ add_crtc_to_pipe_list(display, crtc);
+
return 0;
fail:
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 552a59d19e0f..1e76a455d7c4 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -212,22 +212,23 @@ enum phy_fia {
base.head) \
for_each_if((intel_plane)->pipe == (intel_crtc)->pipe)
-#define for_each_intel_crtc(dev, intel_crtc) \
- list_for_each_entry(intel_crtc, \
- &(dev)->mode_config.crtc_list, \
- base.head)
+#define for_each_intel_crtc(dev, crtc) \
+ list_for_each_entry((crtc), \
+ &to_intel_display(dev)->pipe_list, \
+ pipe_head)
-#define for_each_intel_crtc_in_pipe_mask(dev, intel_crtc, pipe_mask) \
- list_for_each_entry(intel_crtc, \
- &(dev)->mode_config.crtc_list, \
- base.head) \
- for_each_if((pipe_mask) & BIT(intel_crtc->pipe))
+#define for_each_intel_crtc_reverse(dev, crtc) \
+ list_for_each_entry_reverse((crtc), \
+ &to_intel_display(dev)->pipe_list, \
+ pipe_head)
+
+#define for_each_intel_crtc_in_pipe_mask(dev, crtc, pipe_mask) \
+ for_each_intel_crtc((dev), (crtc)) \
+ for_each_if((pipe_mask) & BIT((crtc)->pipe))
-#define for_each_intel_crtc_in_pipe_mask_reverse(dev, intel_crtc, pipe_mask) \
- list_for_each_entry_reverse((intel_crtc), \
- &(dev)->mode_config.crtc_list, \
- base.head) \
- for_each_if((pipe_mask) & BIT((intel_crtc)->pipe))
+#define for_each_intel_crtc_in_pipe_mask_reverse(dev, crtc, pipe_mask) \
+ for_each_intel_crtc_reverse((dev), (crtc)) \
+ for_each_if((pipe_mask) & BIT((crtc)->pipe))
#define for_each_intel_encoder(dev, intel_encoder) \
list_for_each_entry(intel_encoder, \
@@ -269,14 +270,6 @@ enum phy_fia {
(__i)++) \
for_each_if(plane)
-#define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state, __i) \
- for ((__i) = 0; \
- (__i) < (__state)->base.dev->mode_config.num_crtc && \
- ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
- (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), 1); \
- (__i)++) \
- for_each_if(crtc)
-
#define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->base.dev->mode_config.num_total_plane && \
@@ -285,22 +278,6 @@ enum phy_fia {
(__i)++) \
for_each_if(plane)
-#define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state, __i) \
- for ((__i) = 0; \
- (__i) < (__state)->base.dev->mode_config.num_crtc && \
- ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
- (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
- (__i)++) \
- for_each_if(crtc)
-
-#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state, __i) \
- for ((__i) = (__state)->base.dev->mode_config.num_crtc - 1; \
- (__i) >= 0 && \
- ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
- (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
- (__i)--) \
- for_each_if(crtc)
-
#define for_each_oldnew_intel_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->base.dev->mode_config.num_total_plane && \
@@ -310,23 +287,32 @@ enum phy_fia {
(__i)++) \
for_each_if(plane)
+#define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state, __i) \
+ for_each_intel_crtc((__state)->base.dev, (crtc)) \
+ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
+ (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc))))
+
+#define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state, __i) \
+ for_each_intel_crtc((__state)->base.dev, (crtc)) \
+ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
+ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
+
+#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state, __i) \
+ for_each_intel_crtc_reverse((__state)->base.dev, (crtc)) \
+ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
+ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
+
#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
- for ((__i) = 0; \
- (__i) < (__state)->base.dev->mode_config.num_crtc && \
- ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
- (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
- (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
- (__i)++) \
- for_each_if(crtc)
+ for_each_intel_crtc((__state)->base.dev, (crtc)) \
+ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
+ (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \
+ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
#define for_each_oldnew_intel_crtc_in_state_reverse(__state, crtc, old_crtc_state, new_crtc_state, __i) \
- for ((__i) = (__state)->base.dev->mode_config.num_crtc - 1; \
- (__i) >= 0 && \
- ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
- (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \
- (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
- (__i)--) \
- for_each_if(crtc)
+ for_each_intel_crtc_reverse((__state)->base.dev, (crtc)) \
+ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
+ (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \
+ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
#define intel_atomic_crtc_state_for_each_plane_state( \
plane, plane_state, \
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index d708d322aa85..d9baca2d5aaf 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -294,6 +294,9 @@ struct intel_display {
/* Parent, or core, driver functions exposed to display */
const struct intel_display_parent_interface *parent;
+ /* list of all intel_crtcs sorted by pipe */
+ struct list_head pipe_list;
+
/* Display functions */
struct {
/* Top level crtc-ish functions */
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 23bfecc983e8..9c2f7ad6c7b7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -117,6 +117,7 @@ static void intel_mode_config_init(struct intel_display *display)
drm_mode_config_init(display->drm);
INIT_LIST_HEAD(&display->global.obj_list);
+ INIT_LIST_HEAD(&display->pipe_list);
mode_config->min_width = 0;
mode_config->min_height = 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e2496db1642a..f6cd0a062090 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1484,6 +1484,7 @@ struct intel_flipq {
struct intel_crtc {
struct drm_crtc base;
+ struct list_head pipe_head;
enum pipe pipe;
/*
* Whether the crtc and the connected output pipeline is active. Implies
diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
index a0a4ddf3bb46..00dfa68af29a 100644
--- a/drivers/gpu/drm/xe/display/xe_display.c
+++ b/drivers/gpu/drm/xe/display/xe_display.c
@@ -21,6 +21,7 @@
#include "intel_audio.h"
#include "intel_bw.h"
#include "intel_display.h"
+#include "intel_display_core.h"
#include "intel_display_device.h"
#include "intel_display_driver.h"
#include "intel_display_irq.h"