Commit f49499e6 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Jani Nikula
Browse files

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: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260408155744.13326-3-ville.syrjala@linux.intel.com


Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 482bcc7e
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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:
+38 −52
Original line number Diff line number Diff line
@@ -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_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(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, 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, \
+3 −0
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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
Loading