mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
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: stable@vger.kernel.org Reported-by: Khaled Almahallawy <khaled.almahallawy@intel.com> Closes: https://lore.kernel.org/intel-gfx/20260212004852.1920270-1-khaled.almahallawy@intel.com/ Tested-by: Khaled Almahallawy <khaled.almahallawy@intel.com> Fixes:6a01df2f1b("drm/i915: Remove pointless visible check in unlink_nv12_plane()") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patch.msgid.link/20260316163953.12905-2-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com> (cherry picked from commit017ecd0498) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
This commit is contained in:
committed by
Joonas Lahtinen
parent
6ad2a661ff
commit
bfa71b7a9d
@@ -436,11 +436,16 @@ void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
|
||||
drm_framebuffer_get(plane_state->hw.fb);
|
||||
}
|
||||
|
||||
static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state);
|
||||
|
||||
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
|
||||
unlink_nv12_plane(crtc_state, plane_state);
|
||||
|
||||
crtc_state->active_planes &= ~BIT(plane->id);
|
||||
crtc_state->scaled_planes &= ~BIT(plane->id);
|
||||
crtc_state->nv12_planes &= ~BIT(plane->id);
|
||||
@@ -1513,6 +1518,9 @@ static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
|
||||
if (!plane_state->planar_linked_plane)
|
||||
return;
|
||||
|
||||
plane_state->planar_linked_plane = NULL;
|
||||
|
||||
if (!plane_state->is_y_plane)
|
||||
@@ -1550,8 +1558,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
|
||||
if (plane->pipe != crtc->pipe)
|
||||
continue;
|
||||
|
||||
if (plane_state->planar_linked_plane)
|
||||
unlink_nv12_plane(crtc_state, plane_state);
|
||||
unlink_nv12_plane(crtc_state, plane_state);
|
||||
}
|
||||
|
||||
if (!crtc_state->nv12_planes)
|
||||
|
||||
Reference in New Issue
Block a user