mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 06:41:39 -04:00
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 <sunpeng.li@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -95,6 +95,7 @@
|
||||
#include <drm/drm_utils.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_audio_component.h>
|
||||
#include <drm/drm_colorop.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
|
||||
#include <media/cec-notifier.h>
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user