Skip to content

Commit bfa71b7

Browse files
vsyrjalajlahtine-intel
authored andcommitted
drm/i915: Unlink NV12 planes earlier
unlink_nv12_plane() will clobber parts of the plane state potentially already set up by plane_atomic_check(), so we must make sure not to call the two in the wrong order. The problem happens when a plane previously selected as a Y plane is now configured as a normal plane by user space. plane_atomic_check() will first compute the proper plane state based on the userspace request, and unlink_nv12_plane() later clears some of the state. This used to work on account of unlink_nv12_plane() skipping the state clearing based on the plane visibility. But I removed that check, thinking it was an impossible situation. Now when that situation happens unlink_nv12_plane() will just WARN and proceed to clobber the state. Rather than reverting to the old way of doing things, I think it's more clear if we unlink the NV12 planes before we even compute the new plane state. Cc: [email protected] Reported-by: Khaled Almahallawy <[email protected]> Closes: https://lore.kernel.org/intel-gfx/[email protected]/ Tested-by: Khaled Almahallawy <[email protected]> Fixes: 6a01df2 ("drm/i915: Remove pointless visible check in unlink_nv12_plane()") Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patch.msgid.link/[email protected] Reviewed-by: Uma Shankar <[email protected]> (cherry picked from commit 017ecd0) Signed-off-by: Joonas Lahtinen <[email protected]>
1 parent 6ad2a66 commit bfa71b7

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,11 +436,16 @@ void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
436436
drm_framebuffer_get(plane_state->hw.fb);
437437
}
438438

439+
static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
440+
struct intel_plane_state *plane_state);
441+
439442
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
440443
struct intel_plane_state *plane_state)
441444
{
442445
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
443446

447+
unlink_nv12_plane(crtc_state, plane_state);
448+
444449
crtc_state->active_planes &= ~BIT(plane->id);
445450
crtc_state->scaled_planes &= ~BIT(plane->id);
446451
crtc_state->nv12_planes &= ~BIT(plane->id);
@@ -1513,6 +1518,9 @@ static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
15131518
struct intel_display *display = to_intel_display(plane_state);
15141519
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
15151520

1521+
if (!plane_state->planar_linked_plane)
1522+
return;
1523+
15161524
plane_state->planar_linked_plane = NULL;
15171525

15181526
if (!plane_state->is_y_plane)
@@ -1550,8 +1558,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
15501558
if (plane->pipe != crtc->pipe)
15511559
continue;
15521560

1553-
if (plane_state->planar_linked_plane)
1554-
unlink_nv12_plane(crtc_state, plane_state);
1561+
unlink_nv12_plane(crtc_state, plane_state);
15551562
}
15561563

15571564
if (!crtc_state->nv12_planes)

0 commit comments

Comments
 (0)