From: Alex Hung Date: Wed, 25 Mar 2026 02:03:25 +0000 (-0600) Subject: drm/amd/display: Use overlay cursor when color pipeline is active X-Git-Tag: v7.1-rc1~24^2~3^2~20 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=d3a549f4df7864bca8612c8bcfce1ec72b2874fb;p=thirdparty%2Flinux.git drm/amd/display: Use overlay cursor when color pipeline is active Force overlay cursor mode when an underlying plane has a non-bypassed color pipeline to avoid incorrect cursor transformation. Reviewed-by: Sun peng (Leo) Li Signed-off-by: Alex Hung Signed-off-by: Aurabindo Pillai Tested-by: Dan Wheeler Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f4be2724471d..1ecac2174119 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -95,6 +95,7 @@ #include #include #include +#include #include #include @@ -12338,6 +12339,38 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm * available. */ +/** + * dm_plane_color_pipeline_active() - Check if a plane's color pipeline active. + * @state: DRM atomic state + * @plane: DRM plane to check + * @use_old: if true, inspect the old colorop states; otherwise the new ones + * + * A color pipeline may be selected (color_pipeline != NULL) but still is + * inactive if every colorop in the chain is bypassed. Only return + * true when at least one colorop has bypass == false, meaning the cursor + * would be subjected to the transformation in native mode. + * + * Return: true if the pipeline modifies pixels, false otherwise. + */ +static bool dm_plane_color_pipeline_active(struct drm_atomic_state *state, + struct drm_plane *plane, + bool use_old) +{ + struct drm_colorop *colorop; + struct drm_colorop_state *old_colorop_state, *new_colorop_state; + int i; + + for_each_oldnew_colorop_in_state(state, colorop, old_colorop_state, new_colorop_state, i) { + struct drm_colorop_state *cstate = use_old ? old_colorop_state : new_colorop_state; + + if (cstate->colorop->plane != plane) + continue; + if (!cstate->bypass) + return true; + } + return false; +} + /** * dm_crtc_get_cursor_mode() - Determine the required cursor mode on crtc * @adev: amdgpu device @@ -12349,8 +12382,8 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm * the dm_crtc_state. * * The cursor should be enabled in overlay mode if there exists an underlying - * plane - on which the cursor may be blended - that is either YUV formatted, or - * scaled differently from the cursor. + * plane - on which the cursor may be blended - that is either YUV formatted, + * scaled differently from the cursor, or has a color pipeline active. * * Since zpos info is required, drm_atomic_normalize_zpos must be called before * calling this function. @@ -12388,7 +12421,7 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, /* * Cursor mode can change if a plane's format changes, scale changes, is - * enabled/disabled, or z-order changes. + * enabled/disabled, z-order changes, or color management properties change. */ for_each_oldnew_plane_in_state(state, plane, old_plane_state, plane_state, i) { int new_scale_w, new_scale_h, old_scale_w, old_scale_h; @@ -12413,6 +12446,12 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, consider_mode_change = true; break; } + + if (dm_plane_color_pipeline_active(state, plane, true) != + dm_plane_color_pipeline_active(state, plane, false)) { + consider_mode_change = true; + break; + } } if (!consider_mode_change && !crtc_state->zpos_changed) @@ -12453,6 +12492,12 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, return 0; } + /* Underlying plane has an active color pipeline - cursor would be transformed */ + if (dm_plane_color_pipeline_active(state, plane, false)) { + *cursor_mode = DM_CURSOR_OVERLAY_MODE; + return 0; + } + dm_get_plane_scale(plane_state, &underlying_scale_w, &underlying_scale_h); dm_get_plane_scale(cursor_state, @@ -12832,7 +12877,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, goto fail; } else if (required_cursor_mode == DM_CURSOR_OVERLAY_MODE) { drm_dbg_driver(crtc->dev, - "[CRTC:%d:%s] Cannot enable native cursor due to scaling or YUV restrictions\n", + "[CRTC:%d:%s] Cannot enable native cursor due to scaling, YUV, or color pipeline restrictions\n", crtc->base.id, crtc->name); ret = -EINVAL; goto fail;