mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 19:14:35 -04:00
The KMS framework uses two slightly different definitions for the state concept. For a given object (plane, CRTC, encoder, etc., so drm_$OBJECT_state), the state is the entire state of that object. However, at the device level, drm_atomic_state refers to a state update for a limited number of objects. Thus, drm_atomic_state isn't the entire device state, but only the full state of some objects in that device. This has been an endless source of confusion and thus bugs. We can rename the drm_atomic_state structure to drm_atomic_commit to make it less confusing. This patch was created using: rg -l drm_atomic_state | \ xargs sed -i 's/drm_atomic_state/drm_atomic_commit/g; s/drm_atomic_commit_helper/drm_atomic_state_helper/g' mv drivers/gpu/drm/tests/drm_atomic_state_test.c drivers/gpu/drm/tests/drm_atomic_commit_test.c Acked-by: Simona Vetter <simona.vetter@ffwll.ch> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Signed-off-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patch.msgid.link/20260427-drm-drm-atomic-update-v4-1-c0e713bfdf25@kernel.org
129 lines
3.4 KiB
C
129 lines
3.4 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright © 2023 Intel Corporation
|
|
*/
|
|
|
|
#include "intel_crtc.h"
|
|
#include "intel_display_core.h"
|
|
#include "intel_display_types.h"
|
|
#include "intel_sprite_uapi.h"
|
|
|
|
static bool has_dst_key_in_primary_plane(struct intel_display *display)
|
|
{
|
|
return DISPLAY_VER(display) >= 9;
|
|
}
|
|
|
|
static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
|
|
const struct drm_intel_sprite_colorkey *set)
|
|
{
|
|
struct intel_display *display = to_intel_display(plane_state);
|
|
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
|
struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
|
|
|
|
*key = *set;
|
|
|
|
/*
|
|
* We want src key enabled on the
|
|
* sprite and not on the primary.
|
|
*/
|
|
if (plane->id == PLANE_PRIMARY &&
|
|
set->flags & I915_SET_COLORKEY_SOURCE)
|
|
key->flags = 0;
|
|
|
|
/*
|
|
* On SKL+ we want dst key enabled on
|
|
* the primary and not on the sprite.
|
|
*/
|
|
if (DISPLAY_VER(display) >= 9 && plane->id != PLANE_PRIMARY &&
|
|
set->flags & I915_SET_COLORKEY_DESTINATION)
|
|
key->flags = 0;
|
|
}
|
|
|
|
int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
|
|
struct drm_file *file_priv)
|
|
{
|
|
struct intel_display *display = to_intel_display(dev);
|
|
struct drm_intel_sprite_colorkey *set = data;
|
|
struct drm_plane *plane;
|
|
struct drm_plane_state *plane_state;
|
|
struct drm_atomic_commit *state;
|
|
struct drm_modeset_acquire_ctx ctx;
|
|
int ret = 0;
|
|
|
|
/* ignore the pointless "none" flag */
|
|
set->flags &= ~I915_SET_COLORKEY_NONE;
|
|
|
|
if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
|
|
return -EINVAL;
|
|
|
|
/* Make sure we don't try to enable both src & dest simultaneously */
|
|
if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
|
|
return -EINVAL;
|
|
|
|
if ((display->platform.valleyview || display->platform.cherryview) &&
|
|
set->flags & I915_SET_COLORKEY_DESTINATION)
|
|
return -EINVAL;
|
|
|
|
plane = drm_plane_find(dev, file_priv, set->plane_id);
|
|
if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
|
|
return -ENOENT;
|
|
|
|
/*
|
|
* SKL+ only plane 2 can do destination keying against plane 1.
|
|
* Also multiple planes can't do destination keying on the same
|
|
* pipe simultaneously.
|
|
*/
|
|
if (DISPLAY_VER(display) >= 9 &&
|
|
to_intel_plane(plane)->id >= PLANE_3 &&
|
|
set->flags & I915_SET_COLORKEY_DESTINATION)
|
|
return -EINVAL;
|
|
|
|
drm_modeset_acquire_init(&ctx, 0);
|
|
|
|
state = drm_atomic_commit_alloc(plane->dev);
|
|
if (!state) {
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
state->acquire_ctx = &ctx;
|
|
to_intel_atomic_state(state)->internal = true;
|
|
|
|
while (1) {
|
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
|
ret = PTR_ERR_OR_ZERO(plane_state);
|
|
if (!ret)
|
|
intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
|
|
|
|
/*
|
|
* On some platforms we have to configure
|
|
* the dst colorkey on the primary plane.
|
|
*/
|
|
if (!ret && has_dst_key_in_primary_plane(display)) {
|
|
struct intel_crtc *crtc =
|
|
intel_crtc_for_pipe(display,
|
|
to_intel_plane(plane)->pipe);
|
|
|
|
plane_state = drm_atomic_get_plane_state(state,
|
|
crtc->base.primary);
|
|
ret = PTR_ERR_OR_ZERO(plane_state);
|
|
if (!ret)
|
|
intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
|
|
}
|
|
|
|
if (!ret)
|
|
ret = drm_atomic_commit(state);
|
|
|
|
if (ret != -EDEADLK)
|
|
break;
|
|
|
|
drm_atomic_commit_clear(state);
|
|
drm_modeset_backoff(&ctx);
|
|
}
|
|
|
|
drm_atomic_commit_put(state);
|
|
out:
|
|
drm_modeset_drop_locks(&ctx);
|
|
drm_modeset_acquire_fini(&ctx);
|
|
return ret;
|
|
}
|