Skip to content

Commit 00c8e0d

Browse files
committed
drm/i915: Rework joiner and Y plane dependency handling
The current code tries to handle joiner vs. Y planes completely independently. That does not really work since each pipe selects its Y planes completely independently, and any plane pulled into the state by one of the secondary pipes needs to have the plane on the primary pipe also included in the state (for the uapi state copy). The current code sometimes forgets to pull in planes that we need, leading to weird things like the Y<->UV plane link only getting torn down from one side but not the other. Remedy the situation by pulling in the exact same set planes on all the joined pipes. To calculate the set we simply look through each joined crtc and any plane in the state gets added to the set. However due to the way the Y plane selection works we may not be able to determine the set in one go. One plane on one pipe may pull in a Y plane, which may have to pull in another plane because it's not acting in the same role on another pipe, etc. The simple approach taken here is to keep looping and adding planes to the set until it stops growing. I suppose if we tracked more of this Y plane stuff in the crtc state rather than the plane state we might be able to do it in one go. But this works, and it's not going to loop for long anyway since we only have so many pipes and Y planes to consider. Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250212164330.16891-4-ville.syrjala@linux.intel.com
1 parent 5845614 commit 00c8e0d

1 file changed

Lines changed: 53 additions & 51 deletions

File tree

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4405,31 +4405,6 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state,
44054405
return true;
44064406
}
44074407

4408-
static int icl_add_linked_planes(struct intel_atomic_state *state)
4409-
{
4410-
struct intel_plane *plane, *linked;
4411-
struct intel_plane_state *plane_state, *linked_plane_state;
4412-
int i;
4413-
4414-
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
4415-
linked = plane_state->planar_linked_plane;
4416-
4417-
if (!linked)
4418-
continue;
4419-
4420-
linked_plane_state = intel_atomic_get_plane_state(state, linked);
4421-
if (IS_ERR(linked_plane_state))
4422-
return PTR_ERR(linked_plane_state);
4423-
4424-
drm_WARN_ON(state->base.dev,
4425-
linked_plane_state->planar_linked_plane != plane);
4426-
drm_WARN_ON(state->base.dev,
4427-
linked_plane_state->planar_slave == plane_state->planar_slave);
4428-
}
4429-
4430-
return 0;
4431-
}
4432-
44334408
static int icl_check_nv12_planes(struct intel_atomic_state *state,
44344409
struct intel_crtc *crtc)
44354410
{
@@ -6180,44 +6155,75 @@ static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv)
61806155
IS_IVYBRIDGE(dev_priv);
61816156
}
61826157

6183-
static int intel_crtc_add_joiner_planes(struct intel_atomic_state *state,
6184-
struct intel_crtc *crtc,
6185-
struct intel_crtc *other)
6158+
static u8 intel_joiner_affected_planes(struct intel_atomic_state *state,
6159+
u8 joined_pipes)
61866160
{
6187-
const struct intel_plane_state __maybe_unused *plane_state;
6161+
const struct intel_plane_state *plane_state;
61886162
struct intel_plane *plane;
6189-
u8 plane_ids = 0;
6163+
u8 affected_planes = 0;
61906164
int i;
61916165

61926166
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
6193-
if (plane->pipe == crtc->pipe)
6194-
plane_ids |= BIT(plane->id);
6167+
struct intel_plane *linked = plane_state->planar_linked_plane;
6168+
6169+
if ((joined_pipes & BIT(plane->pipe)) == 0)
6170+
continue;
6171+
6172+
affected_planes |= BIT(plane->id);
6173+
if (linked)
6174+
affected_planes |= BIT(linked->id);
61956175
}
61966176

6197-
return intel_crtc_add_planes_to_state(state, other, plane_ids);
6177+
return affected_planes;
61986178
}
61996179

6200-
static int intel_joiner_add_affected_planes(struct intel_atomic_state *state)
6180+
static int intel_joiner_add_affected_planes(struct intel_atomic_state *state,
6181+
u8 joined_pipes)
62016182
{
6202-
struct drm_i915_private *i915 = to_i915(state->base.dev);
6203-
const struct intel_crtc_state *crtc_state;
6204-
struct intel_crtc *crtc;
6205-
int i;
6183+
u8 prev_affected_planes, affected_planes = 0;
62066184

6207-
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
6208-
struct intel_crtc *other;
6185+
/*
6186+
* We want all the joined pipes to have the same
6187+
* set of planes in the atomic state, to make sure
6188+
* state copying always works correctly, and the
6189+
* UV<->Y plane linkage is always up to date.
6190+
* Keep pulling planes in until we've determined
6191+
* the full set of affected planes. A bit complicated
6192+
* on account of each pipe being capable of selecting
6193+
* their own Y planes independently of the other pipes,
6194+
* and the selection being done from the set of
6195+
* inactive planes.
6196+
*/
6197+
do {
6198+
struct intel_crtc *crtc;
62096199

6210-
for_each_intel_crtc_in_pipe_mask(&i915->drm, other,
6211-
crtc_state->joiner_pipes) {
6200+
for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) {
62126201
int ret;
62136202

6214-
if (crtc == other)
6215-
continue;
6216-
6217-
ret = intel_crtc_add_joiner_planes(state, crtc, other);
6203+
ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes);
62186204
if (ret)
62196205
return ret;
62206206
}
6207+
6208+
prev_affected_planes = affected_planes;
6209+
affected_planes = intel_joiner_affected_planes(state, joined_pipes);
6210+
} while (affected_planes != prev_affected_planes);
6211+
6212+
return 0;
6213+
}
6214+
6215+
static int intel_add_affected_planes(struct intel_atomic_state *state)
6216+
{
6217+
const struct intel_crtc_state *crtc_state;
6218+
struct intel_crtc *crtc;
6219+
int i;
6220+
6221+
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
6222+
int ret;
6223+
6224+
ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state));
6225+
if (ret)
6226+
return ret;
62216227
}
62226228

62236229
return 0;
@@ -6232,11 +6238,7 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
62326238
struct intel_crtc *crtc;
62336239
int i, ret;
62346240

6235-
ret = icl_add_linked_planes(state);
6236-
if (ret)
6237-
return ret;
6238-
6239-
ret = intel_joiner_add_affected_planes(state);
6241+
ret = intel_add_affected_planes(state);
62406242
if (ret)
62416243
return ret;
62426244

0 commit comments

Comments
 (0)