From: Alex Hung <alex.hung@amd.com>
To: <dri-devel@lists.freedesktop.org>, <amd-gfx@lists.freedesktop.org>
Cc: <wayland-devel@lists.freedesktop.org>, <harry.wentland@amd.com>,
<alex.hung@amd.com>, <leo.liu@amd.com>,
<ville.syrjala@linux.intel.com>, <pekka.paalanen@collabora.com>,
<contact@emersion.fr>, <mwen@igalia.com>, <jadahl@redhat.com>,
<sebastian.wick@redhat.com>, <shashank.sharma@amd.com>,
<agoins@nvidia.com>, <joshua@froggi.es>, <mdaenzer@redhat.com>,
<aleixpol@kde.org>, <xaver.hugl@gmail.com>,
<victoria@system76.com>, <daniel@ffwll.ch>,
<uma.shankar@intel.com>, <quic_naseer@quicinc.com>,
<quic_cbraga@quicinc.com>, <quic_abhinavk@quicinc.com>,
<marcan@marcan.st>, <Liviu.Dudau@arm.com>,
<sashamcintosh@google.com>, <chaitanya.kumar.borah@intel.com>,
<louis.chauvet@bootlin.com>
Subject: [PATCH V8 04/43] drm/colorop: Introduce new drm_colorop mode object
Date: Wed, 26 Mar 2025 17:46:45 -0600 [thread overview]
Message-ID: <20250326234748.2982010-5-alex.hung@amd.com> (raw)
In-Reply-To: <20250326234748.2982010-1-alex.hung@amd.com>
From: Harry Wentland <harry.wentland@amd.com>
This patches introduces a new drm_colorop mode object. This
object represents color transformations and can be used to
define color pipelines.
We also introduce the drm_colorop_state here, as well as
various helpers and state tracking bits.
Reviewed-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
v8:
- Remove drm_atomic_get_existing_colorop_state (Louis Chauvet)
v7:
- Fix checkpatch warnings and errors
- Add a tab to for_each_oldnew_colorop_in_state definition
- Change unsigned index to unsigned int index
- Fix a checkpatch warning - a new line after variable declaration
v6:
- Comment that properties validity depends on type (Louis Chauvet)
v5:
- Add comment to drm_atomic_state.colorops
- Replace a misplaced 'plane' with 'colorop' in comment
- Fix colorop_list kernel doc
- Add kernel doc for color_pipeline
- drop unused drm_colorop_destroy_state
- drop drm_colorop_init, to be introduced in later patch
when used
- Add kernel docs
- Drop TODOs
v4:
- Drop IOCTL definitions (Pekka)
- add missing declaration (Chaitanya Kumar Borah)
v3:
- Drop TODO for lock (it's handled in drm_modeset_drop_locks)
(Melissa)
- Don't get plane state when getting colorop state
- Make some functions static (kernel test robot)
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/drm_atomic.c | 70 ++++++++++++
drivers/gpu/drm/drm_atomic_helper.c | 12 ++
drivers/gpu/drm/drm_atomic_uapi.c | 48 ++++++++
drivers/gpu/drm/drm_colorop.c | 104 +++++++++++++++++
drivers/gpu/drm/drm_mode_config.c | 7 ++
include/drm/drm_atomic.h | 70 ++++++++++++
include/drm/drm_atomic_uapi.h | 1 +
include/drm/drm_colorop.h | 171 ++++++++++++++++++++++++++++
include/drm/drm_mode_config.h | 18 +++
include/drm/drm_plane.h | 8 ++
include/uapi/drm/drm_mode.h | 1 +
12 files changed, 511 insertions(+)
create mode 100644 drivers/gpu/drm/drm_colorop.c
create mode 100644 include/drm/drm_colorop.h
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index ed54a546bbe2..50bb6be2cad1 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -41,6 +41,7 @@ drm-y := \
drm_bridge.o \
drm_cache.o \
drm_color_mgmt.o \
+ drm_colorop.o \
drm_connector.o \
drm_crtc.o \
drm_displayid.o \
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 9ea2611770f4..85d492a1f3d4 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -42,6 +42,7 @@
#include <drm/drm_mode.h>
#include <drm/drm_print.h>
#include <drm/drm_writeback.h>
+#include <drm/drm_colorop.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
@@ -107,6 +108,7 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
kfree(state->connectors);
kfree(state->crtcs);
kfree(state->planes);
+ kfree(state->colorops);
kfree(state->private_objs);
}
EXPORT_SYMBOL(drm_atomic_state_default_release);
@@ -138,6 +140,10 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
sizeof(*state->planes), GFP_KERNEL);
if (!state->planes)
goto fail;
+ state->colorops = kcalloc(dev->mode_config.num_colorop,
+ sizeof(*state->colorops), GFP_KERNEL);
+ if (!state->colorops)
+ goto fail;
/*
* Because drm_atomic_state can be committed asynchronously we need our
@@ -249,6 +255,20 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
state->planes[i].new_state = NULL;
}
+ for (i = 0; i < config->num_colorop; i++) {
+ struct drm_colorop *colorop = state->colorops[i].ptr;
+
+ if (!colorop)
+ continue;
+
+ drm_colorop_atomic_destroy_state(colorop,
+ state->colorops[i].state);
+ state->colorops[i].ptr = NULL;
+ state->colorops[i].state = NULL;
+ state->colorops[i].old_state = NULL;
+ state->colorops[i].new_state = NULL;
+ }
+
for (i = 0; i < state->num_private_objs; i++) {
struct drm_private_obj *obj = state->private_objs[i].ptr;
@@ -568,6 +588,56 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
}
EXPORT_SYMBOL(drm_atomic_get_plane_state);
+
+/**
+ * drm_atomic_get_colorop_state - get colorop state
+ * @state: global atomic state object
+ * @colorop: colorop to get state object for
+ *
+ * This function returns the colorop state for the given colorop, allocating it
+ * if needed. It will also grab the relevant plane lock to make sure that the
+ * state is consistent.
+ *
+ * Returns:
+ *
+ * Either the allocated state or the error code encoded into the pointer. When
+ * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
+ * entire atomic sequence must be restarted. All other errors are fatal.
+ */
+struct drm_colorop_state *
+drm_atomic_get_colorop_state(struct drm_atomic_state *state,
+ struct drm_colorop *colorop)
+{
+ int ret, index = drm_colorop_index(colorop);
+ struct drm_colorop_state *colorop_state;
+
+ WARN_ON(!state->acquire_ctx);
+
+ colorop_state = drm_atomic_get_new_colorop_state(state, colorop);
+ if (colorop_state)
+ return colorop_state;
+
+ ret = drm_modeset_lock(&colorop->plane->mutex, state->acquire_ctx);
+ if (ret)
+ return ERR_PTR(ret);
+
+ colorop_state = drm_atomic_helper_colorop_duplicate_state(colorop);
+ if (!colorop_state)
+ return ERR_PTR(-ENOMEM);
+
+ state->colorops[index].state = colorop_state;
+ state->colorops[index].ptr = colorop;
+ state->colorops[index].old_state = colorop->state;
+ state->colorops[index].new_state = colorop_state;
+ colorop_state->state = state;
+
+ drm_dbg_atomic(colorop->dev, "Added [COLOROP:%d] %p state to %p\n",
+ colorop->base.id, colorop_state, state);
+
+ return colorop_state;
+}
+EXPORT_SYMBOL(drm_atomic_get_colorop_state);
+
static bool
plane_switching_crtc(const struct drm_plane_state *old_plane_state,
const struct drm_plane_state *new_plane_state)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 5302ab324898..65db840f8b20 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3060,6 +3060,8 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_plane *plane;
struct drm_plane_state *old_plane_state, *new_plane_state;
+ struct drm_colorop *colorop;
+ struct drm_colorop_state *old_colorop_state, *new_colorop_state;
struct drm_crtc_commit *commit;
struct drm_private_obj *obj;
struct drm_private_state *old_obj_state, *new_obj_state;
@@ -3137,6 +3139,16 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
}
}
+ for_each_oldnew_colorop_in_state(state, colorop, old_colorop_state, new_colorop_state, i) {
+ WARN_ON(colorop->state != old_colorop_state);
+
+ old_colorop_state->state = state;
+ new_colorop_state->state = NULL;
+
+ state->colorops[i].state = old_colorop_state;
+ colorop->state = new_colorop_state;
+ }
+
drm_panic_lock(state->dev, flags);
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
WARN_ON(plane->state != old_plane_state);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 2765ba90ad8f..cf1772118895 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -35,6 +35,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_writeback.h>
#include <drm/drm_vblank.h>
+#include <drm/drm_colorop.h>
#include <linux/dma-fence.h>
#include <linux/uaccess.h>
@@ -643,6 +644,26 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
return 0;
}
+
+static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
+ struct drm_colorop_state *state, struct drm_file *file_priv,
+ struct drm_property *property, uint64_t val)
+{
+ drm_dbg_atomic(colorop->dev,
+ "[COLOROP:%d] unknown property [PROP:%d:%s]]\n",
+ colorop->base.id,
+ property->base.id, property->name);
+ return -EINVAL;
+}
+
+static int
+drm_atomic_colorop_get_property(struct drm_colorop *colorop,
+ const struct drm_colorop_state *state,
+ struct drm_property *property, uint64_t *val)
+{
+ return -EINVAL;
+}
+
static int drm_atomic_set_writeback_fb_for_connector(
struct drm_connector_state *conn_state,
struct drm_framebuffer *fb)
@@ -909,6 +930,16 @@ int drm_atomic_get_property(struct drm_mode_object *obj,
plane->state, property, val);
break;
}
+ case DRM_MODE_OBJECT_COLOROP: {
+ struct drm_colorop *colorop = obj_to_colorop(obj);
+
+ if (colorop->plane)
+ WARN_ON(!drm_modeset_is_locked(&colorop->plane->mutex));
+
+ ret = drm_atomic_colorop_get_property(colorop,
+ colorop->state, property, val);
+ break;
+ }
default:
drm_dbg_atomic(dev, "[OBJECT:%d] has no properties\n", obj->id);
ret = -EINVAL;
@@ -1101,6 +1132,23 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
ret = drm_atomic_plane_set_property(plane,
plane_state, file_priv,
prop, prop_value);
+
+ break;
+ }
+ case DRM_MODE_OBJECT_COLOROP: {
+ struct drm_colorop *colorop = obj_to_colorop(obj);
+ struct drm_colorop_state *colorop_state;
+
+ colorop_state = drm_atomic_get_colorop_state(state, colorop);
+ if (IS_ERR(colorop_state)) {
+ ret = PTR_ERR(colorop_state);
+ break;
+ }
+
+ ret = drm_atomic_colorop_set_property(colorop,
+ colorop_state, file_priv,
+ prop, prop_value);
+
break;
}
default:
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
new file mode 100644
index 000000000000..d215e22c9d20
--- /dev/null
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include <drm/drm_colorop.h>
+#include <drm/drm_print.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_plane.h>
+
+#include "drm_crtc_internal.h"
+
+static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop,
+ struct drm_colorop_state *state)
+{
+ memcpy(state, colorop->state, sizeof(*state));
+}
+
+struct drm_colorop_state *
+drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop)
+{
+ struct drm_colorop_state *state;
+
+ if (WARN_ON(!colorop->state))
+ return NULL;
+
+ state = kmalloc(sizeof(*state), GFP_KERNEL);
+ if (state)
+ __drm_atomic_helper_colorop_duplicate_state(colorop, state);
+
+ return state;
+}
+
+
+void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
+ struct drm_colorop_state *state)
+{
+ kfree(state);
+}
+
+/**
+ * __drm_colorop_state_reset - resets colorop state to default values
+ * @colorop_state: atomic colorop state, must not be NULL
+ * @colorop: colorop object, must not be NULL
+ *
+ * Initializes the newly allocated @colorop_state with default
+ * values. This is useful for drivers that subclass the CRTC state.
+ */
+static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
+ struct drm_colorop *colorop)
+{
+ colorop_state->colorop = colorop;
+}
+
+/**
+ * __drm_colorop_reset - reset state on colorop
+ * @colorop: drm colorop
+ * @colorop_state: colorop state to assign
+ *
+ * Initializes the newly allocated @colorop_state and assigns it to
+ * the &drm_crtc->state pointer of @colorop, usually required when
+ * initializing the drivers or when called from the &drm_colorop_funcs.reset
+ * hook.
+ *
+ * This is useful for drivers that subclass the colorop state.
+ */
+static void __drm_colorop_reset(struct drm_colorop *colorop,
+ struct drm_colorop_state *colorop_state)
+{
+ if (colorop_state)
+ __drm_colorop_state_reset(colorop_state, colorop);
+
+ colorop->state = colorop_state;
+}
+
+void drm_colorop_reset(struct drm_colorop *colorop)
+{
+ kfree(colorop->state);
+ colorop->state = kzalloc(sizeof(*colorop->state), GFP_KERNEL);
+
+ if (colorop->state)
+ __drm_colorop_reset(colorop, colorop->state);
+}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 8642a2fb25a9..369a66bad9da 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -29,6 +29,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_mode_config.h>
#include <drm/drm_print.h>
+#include <drm/drm_colorop.h>
#include <linux/dma-resv.h>
#include "drm_crtc_internal.h"
@@ -191,11 +192,15 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
void drm_mode_config_reset(struct drm_device *dev)
{
struct drm_crtc *crtc;
+ struct drm_colorop *colorop;
struct drm_plane *plane;
struct drm_encoder *encoder;
struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
+ drm_for_each_colorop(colorop, dev)
+ drm_colorop_reset(colorop);
+
drm_for_each_plane(plane, dev)
if (plane->funcs->reset)
plane->funcs->reset(plane);
@@ -429,6 +434,7 @@ int drmm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(&dev->mode_config.property_list);
INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
INIT_LIST_HEAD(&dev->mode_config.plane_list);
+ INIT_LIST_HEAD(&dev->mode_config.colorop_list);
INIT_LIST_HEAD(&dev->mode_config.privobj_list);
idr_init_base(&dev->mode_config.object_idr, 1);
idr_init_base(&dev->mode_config.tile_idr, 1);
@@ -450,6 +456,7 @@ int drmm_mode_config_init(struct drm_device *dev)
dev->mode_config.num_crtc = 0;
dev->mode_config.num_encoder = 0;
dev->mode_config.num_total_plane = 0;
+ dev->mode_config.num_colorop = 0;
if (IS_ENABLED(CONFIG_LOCKDEP)) {
struct drm_modeset_acquire_ctx modeset_ctx;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 4c673f0698fe..b294f5ee11da 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,6 +30,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_util.h>
+#include <drm/drm_colorop.h>
/**
* struct drm_crtc_commit - track modeset commits on a CRTC
@@ -157,6 +158,11 @@ struct drm_crtc_commit {
bool abort_completion;
};
+struct __drm_colorops_state {
+ struct drm_colorop *ptr;
+ struct drm_colorop_state *state, *old_state, *new_state;
+};
+
struct __drm_planes_state {
struct drm_plane *ptr;
struct drm_plane_state *state, *old_state, *new_state;
@@ -458,6 +464,14 @@ struct drm_atomic_state {
*/
bool duplicated : 1;
+ /**
+ * @colorops:
+ *
+ * Pointer to array of @drm_colorop and @drm_colorop_state part of this
+ * update.
+ */
+ struct __drm_colorops_state *colorops;
+
/**
* @planes:
*
@@ -599,6 +613,9 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_plane_state * __must_check
drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane);
+struct drm_colorop_state *
+drm_atomic_get_colorop_state(struct drm_atomic_state *state,
+ struct drm_colorop *colorop);
struct drm_connector_state * __must_check
drm_atomic_get_connector_state(struct drm_atomic_state *state,
struct drm_connector *connector);
@@ -728,6 +745,36 @@ drm_atomic_get_new_plane_state(const struct drm_atomic_state *state,
return state->planes[drm_plane_index(plane)].new_state;
}
+/**
+ * drm_atomic_get_old_colorop_state - get colorop state, if it exists
+ * @state: global atomic state object
+ * @colorop: colorop to grab
+ *
+ * This function returns the old colorop state for the given colorop, or
+ * NULL if the colorop is not part of the global atomic state.
+ */
+static inline struct drm_colorop_state *
+drm_atomic_get_old_colorop_state(struct drm_atomic_state *state,
+ struct drm_colorop *colorop)
+{
+ return state->colorops[drm_colorop_index(colorop)].old_state;
+}
+
+/**
+ * drm_atomic_get_new_colorop_state - get colorop state, if it exists
+ * @state: global atomic state object
+ * @colorop: colorop to grab
+ *
+ * This function returns the new colorop state for the given colorop, or
+ * NULL if the colorop is not part of the global atomic state.
+ */
+static inline struct drm_colorop_state *
+drm_atomic_get_new_colorop_state(struct drm_atomic_state *state,
+ struct drm_colorop *colorop)
+{
+ return state->colorops[drm_colorop_index(colorop)].new_state;
+}
+
/**
* drm_atomic_get_existing_connector_state - get connector state, if it exists
* @state: global atomic state object
@@ -975,6 +1022,29 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(new_crtc_state) = (__state)->crtcs[__i].new_state, \
(void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1))
+/**
+ * for_each_oldnew_colorop_in_state - iterate over all colorops in an atomic update
+ * @__state: &struct drm_atomic_state pointer
+ * @colorop: &struct drm_colorop iteration cursor
+ * @old_colorop_state: &struct drm_colorop_state iteration cursor for the old state
+ * @new_colorop_state: &struct drm_colorop_state iteration cursor for the new state
+ * @__i: int iteration cursor, for macro-internal use
+ *
+ * This iterates over all colorops in an atomic update, tracking both old and
+ * new state. This is useful in places where the state delta needs to be
+ * considered, for example in atomic check functions.
+ */
+#define for_each_oldnew_colorop_in_state(__state, colorop, old_colorop_state, new_colorop_state, __i) \
+ for ((__i) = 0; \
+ (__i) < (__state)->dev->mode_config.num_colorop; \
+ (__i)++) \
+ for_each_if ((__state)->colorops[__i].ptr && \
+ ((colorop) = (__state)->colorops[__i].ptr, \
+ (void)(colorop) /* Only to avoid unused-but-set-variable warning */, \
+ (old_colorop_state) = (__state)->colorops[__i].old_state,\
+ (new_colorop_state) = (__state)->colorops[__i].new_state, 1))
+
+
/**
* for_each_oldnew_plane_in_state - iterate over all planes in an atomic update
* @__state: &struct drm_atomic_state pointer
diff --git a/include/drm/drm_atomic_uapi.h b/include/drm/drm_atomic_uapi.h
index 4c6d39d7bdb2..70a115d523cd 100644
--- a/include/drm/drm_atomic_uapi.h
+++ b/include/drm/drm_atomic_uapi.h
@@ -37,6 +37,7 @@ struct drm_crtc;
struct drm_connector_state;
struct dma_fence;
struct drm_framebuffer;
+struct drm_colorop;
int __must_check
drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
new file mode 100644
index 000000000000..008665d2d960
--- /dev/null
+++ b/include/drm/drm_colorop.h
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DRM_COLOROP_H__
+#define __DRM_COLOROP_H__
+
+#include <drm/drm_mode_object.h>
+#include <drm/drm_mode.h>
+#include <drm/drm_property.h>
+
+/**
+ * struct drm_colorop_state - mutable colorop state
+ */
+struct drm_colorop_state {
+ /** @colorop: backpointer to the colorop */
+ struct drm_colorop *colorop;
+
+ /*
+ * Color properties
+ *
+ * The following fields are not always valid, their usage depends
+ * on the colorop type. See their associated comment for more
+ * information.
+ */
+
+ /** @state: backpointer to global drm_atomic_state */
+ struct drm_atomic_state *state;
+};
+
+/**
+ * struct drm_colorop - DRM color operation control structure
+ *
+ * A colorop represents one color operation. They can be chained via
+ * the 'next' pointer to build a color pipeline.
+ *
+ * Since colorops cannot stand-alone and are used to describe colorop
+ * operations on a plane they don't have their own locking mechanism but
+ * are locked and programmed along with their associated &drm_plane.
+ *
+ */
+struct drm_colorop {
+ /** @dev: parent DRM device */
+ struct drm_device *dev;
+
+ /**
+ * @head:
+ *
+ * List of all colorops on @dev, linked from &drm_mode_config.colorop_list.
+ * Invariant over the lifetime of @dev and therefore does not need
+ * locking.
+ */
+ struct list_head head;
+
+ /**
+ * @index: Position inside the mode_config.list, can be used as an array
+ * index. It is invariant over the lifetime of the colorop.
+ */
+ unsigned int index;
+
+ /** @base: base mode object */
+ struct drm_mode_object base;
+
+ /**
+ * @plane:
+ *
+ * The plane on which the colorop sits. A drm_colorop is always unique
+ * to a plane.
+ */
+ struct drm_plane *plane;
+
+ /**
+ * @state:
+ *
+ * Current atomic state for this colorop.
+ *
+ * This is protected by @mutex. Note that nonblocking atomic commits
+ * access the current colorop state without taking locks.
+ */
+ struct drm_colorop_state *state;
+
+ /*
+ * Color properties
+ *
+ * The following fields are not always valid, their usage depends
+ * on the colorop type. See their associated comment for more
+ * information.
+ */
+
+ /** @properties: property tracking for this colorop */
+ struct drm_object_properties properties;
+
+};
+
+#define obj_to_colorop(x) container_of(x, struct drm_colorop, base)
+
+/**
+ * drm_colorop_find - look up a Colorop object from its ID
+ * @dev: DRM device
+ * @file_priv: drm file to check for lease against.
+ * @id: &drm_mode_object ID
+ *
+ * This can be used to look up a Colorop from its userspace ID. Only used by
+ * drivers for legacy IOCTLs and interface, nowadays extensions to the KMS
+ * userspace interface should be done using &drm_property.
+ */
+static inline struct drm_colorop *drm_colorop_find(struct drm_device *dev,
+ struct drm_file *file_priv,
+ uint32_t id)
+{
+ struct drm_mode_object *mo;
+
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_COLOROP);
+ return mo ? obj_to_colorop(mo) : NULL;
+}
+
+struct drm_colorop_state *
+drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
+
+void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
+ struct drm_colorop_state *state);
+
+/**
+ * drm_colorop_reset - reset colorop atomic state
+ * @colorop: drm colorop
+ *
+ * Resets the atomic state for @colorop by freeing the state pointer (which might
+ * be NULL, e.g. at driver load time) and allocating a new empty state object.
+ */
+void drm_colorop_reset(struct drm_colorop *colorop);
+
+/**
+ * drm_colorop_index - find the index of a registered colorop
+ * @colorop: colorop to find index for
+ *
+ * Given a registered colorop, return the index of that colorop within a DRM
+ * device's list of colorops.
+ */
+static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop)
+{
+ return colorop->index;
+}
+
+
+#define drm_for_each_colorop(colorop, dev) \
+ list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head)
+
+
+#endif /* __DRM_COLOROP_H__ */
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 271765e2e9f2..d4661d4431dc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -499,6 +499,24 @@ struct drm_mode_config {
*/
struct raw_spinlock panic_lock;
+ /**
+ * @num_colorop:
+ *
+ * Number of colorop objects on this device.
+ * This is invariant over the lifetime of a device and hence doesn't
+ * need any locks.
+ */
+ int num_colorop;
+
+ /**
+ * @colorop_list:
+ *
+ * List of colorop objects linked with &drm_colorop.head. This is
+ * invariant over the lifetime of a device and hence doesn't need any
+ * locks.
+ */
+ struct list_head colorop_list;
+
/**
* @num_crtc:
*
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index dd718c62ac31..2a9b902623c0 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -243,6 +243,14 @@ struct drm_plane_state {
*/
enum drm_scaling_filter scaling_filter;
+ /**
+ * @color_pipeline:
+ *
+ * The first colorop of the active color pipeline, or NULL, if no
+ * color pipeline is active.
+ */
+ struct drm_colorop *color_pipeline;
+
/**
* @commit: Tracks the pending commit to prevent use-after-free conditions,
* and for async plane updates.
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index c082810c08a8..d49cded6c568 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -629,6 +629,7 @@ struct drm_mode_connector_set_property {
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
+#define DRM_MODE_OBJECT_COLOROP 0xfafafafa
#define DRM_MODE_OBJECT_ANY 0
struct drm_mode_obj_get_properties {
--
2.43.0
next prev parent reply other threads:[~2025-03-26 23:49 UTC|newest]
Thread overview: 128+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-26 23:46 [PATCH V8 00/43] Color Pipeline API w/ VKMS Alex Hung
2025-03-26 23:46 ` [PATCH V8 01/43] drm: Add helper for conversion from signed-magnitude Alex Hung
2025-03-26 23:46 ` [PATCH V8 02/43] drm/vkms: Add kunit tests for VKMS LUT handling Alex Hung
2025-03-26 23:46 ` [PATCH V8 03/43] drm/doc/rfc: Describe why prescriptive color pipeline is needed Alex Hung
2025-03-29 15:26 ` Simon Ser
2025-04-01 0:10 ` Alex Hung
2025-04-01 7:26 ` Simon Ser
2025-03-31 16:24 ` Shengyu Qu
2025-03-31 16:41 ` Alex Hung
2025-03-31 16:54 ` Shengyu Qu
2025-03-26 23:46 ` Alex Hung [this message]
2025-03-26 23:46 ` [PATCH V8 05/43] drm/colorop: Add TYPE property Alex Hung
2025-03-26 23:46 ` [PATCH V8 06/43] drm/colorop: Add 1D Curve subtype Alex Hung
2025-04-01 15:14 ` Daniel Stone
2025-04-01 19:53 ` Simon Ser
2025-04-01 21:02 ` Harry Wentland
2025-04-08 16:40 ` Daniel Stone
2025-04-08 17:30 ` Harry Wentland
2025-04-08 18:28 ` Daniel Stone
2025-04-10 7:53 ` Pipeline vs. no pipeline (Re: [PATCH V8 06/43] drm/colorop: Add 1D Curve subtype) Pekka Paalanen
2025-04-15 15:29 ` Harry Wentland
2025-04-16 14:39 ` Xaver Hugl
2025-04-17 8:28 ` Pekka Paalanen
2025-04-10 10:05 ` [PATCH V8 06/43] drm/colorop: Add 1D Curve subtype Simon Ser
2025-04-15 11:12 ` Borah, Chaitanya Kumar
2025-04-17 15:13 ` Simon Ser
2025-03-26 23:46 ` [PATCH V8 07/43] drm/colorop: Add BYPASS property Alex Hung
2025-03-26 23:46 ` [PATCH V8 08/43] drm/colorop: Add NEXT property Alex Hung
2025-03-27 23:26 ` Simon Ser
2025-03-26 23:46 ` [PATCH V8 09/43] drm/colorop: Add atomic state print for drm_colorop Alex Hung
2025-03-27 23:29 ` Simon Ser
2025-03-26 23:46 ` [PATCH V8 10/43] drm/plane: Add COLOR PIPELINE property Alex Hung
2025-03-29 14:33 ` Simon Ser
2025-03-26 23:46 ` [PATCH V8 11/43] drm/colorop: Introduce DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE Alex Hung
2025-03-29 14:37 ` Simon Ser
2025-04-01 1:42 ` Shengyu Qu
2025-03-26 23:46 ` [PATCH V8 12/43] Documentation/gpu: document drm_colorop Alex Hung
2025-03-29 14:40 ` Simon Ser
2025-03-26 23:46 ` [PATCH V8 13/43] drm/vkms: Add enumerated 1D curve colorop Alex Hung
2025-03-26 23:46 ` [PATCH V8 14/43] drm/vkms: Add kunit tests for linear and sRGB LUTs Alex Hung
2025-03-26 23:46 ` [PATCH V8 15/43] drm/colorop: Add 3x4 CTM type Alex Hung
2025-03-26 23:46 ` [PATCH V8 16/43] drm/vkms: Use s32 for internal color pipeline precision Alex Hung
2025-03-26 23:46 ` [PATCH V8 17/43] drm/vkms: add 3x4 matrix in color pipeline Alex Hung
2025-03-26 23:46 ` [PATCH V8 18/43] drm/tests: Add a few tests around drm_fixed.h Alex Hung
2025-03-26 23:47 ` [PATCH V8 19/43] drm/vkms: Add tests for CTM handling Alex Hung
2025-03-26 23:47 ` [PATCH V8 20/43] drm/colorop: pass plane_color_pipeline client cap to atomic check Alex Hung
2025-03-29 15:32 ` Simon Ser
2025-03-26 23:47 ` [PATCH V8 21/43] drm/colorop: define a new macro for_each_new_colorop_in_state Alex Hung
2025-03-26 23:47 ` [PATCH V8 22/43] drm/amd/display: Ignore deprecated props when plane_color_pipeline set Alex Hung
2025-03-26 23:47 ` [PATCH V8 23/43] drm/amd/display: Add bypass COLOR PIPELINE Alex Hung
2025-03-26 23:47 ` [PATCH V8 24/43] drm/amd/display: Skip color pipeline initialization for cursor plane Alex Hung
2025-03-30 9:48 ` Shengyu Qu
2025-03-30 12:59 ` Shengyu Qu
2025-03-31 14:28 ` Alex Hung
2025-03-31 15:43 ` Shengyu Qu
2025-03-31 16:06 ` Alex Hung
2025-03-31 16:12 ` Shengyu Qu
2025-03-31 16:26 ` Alex Hung
2025-03-31 16:31 ` Shengyu Qu
2025-03-31 16:34 ` Alex Hung
2025-03-31 16:50 ` Shengyu Qu
2025-03-31 17:04 ` Shengyu Qu
2025-03-31 17:42 ` Alex Hung
2025-03-31 18:53 ` Xaver Hugl
2025-04-01 0:28 ` Alex Hung
2025-04-01 15:04 ` Xaver Hugl
2025-04-01 15:45 ` Melissa Wen
2025-04-01 19:39 ` Harry Wentland
2025-04-01 1:04 ` Shengyu Qu
2025-04-01 1:24 ` Alex Hung
2025-04-01 9:56 ` Michel Dänzer
2025-04-01 12:32 ` Shengyu Qu
2025-04-01 14:11 ` Michel Dänzer
2025-04-01 15:45 ` Shengyu Qu
2025-04-01 19:45 ` Harry Wentland
2025-04-02 3:47 ` Qu Shengyu
2025-04-01 16:24 ` Shengyu Qu
2025-03-26 23:47 ` [PATCH V8 25/43] drm/amd/display: Add support for sRGB EOTF in DEGAM block Alex Hung
2025-03-26 23:47 ` [PATCH V8 26/43] drm/amd/display: Add support for sRGB Inverse EOTF in SHAPER block Alex Hung
2025-03-26 23:47 ` [PATCH V8 27/43] drm/amd/display: Add support for sRGB EOTF in BLND block Alex Hung
2025-03-26 23:47 ` [PATCH V8 28/43] drm/colorop: Add PQ 125 EOTF and its inverse Alex Hung
2025-03-29 14:48 ` Simon Ser
2025-03-26 23:47 ` [PATCH V8 29/43] drm/amd/display: Enable support for PQ 125 EOTF and Inverse Alex Hung
2025-03-26 23:47 ` [PATCH V8 30/43] drm/colorop: add BT2020/BT709 OETF and Inverse OETF Alex Hung
2025-03-29 14:53 ` Simon Ser
2025-03-26 23:47 ` [PATCH V8 31/43] drm/amd/display: Add support for BT.709 and BT.2020 TFs Alex Hung
2025-03-26 23:47 ` [PATCH V8 32/43] drm/colorop: Add 1D Curve Custom LUT type Alex Hung
2025-03-29 14:55 ` Simon Ser
2025-04-15 6:09 ` Shankar, Uma
2025-04-15 6:16 ` Simon Ser
2025-04-15 6:40 ` Shankar, Uma
2025-04-15 15:05 ` Harry Wentland
2025-04-15 16:25 ` Simon Ser
2025-05-22 11:33 ` Shankar, Uma
2025-05-30 13:58 ` Pekka Paalanen
2025-06-03 8:30 ` Shankar, Uma
2025-06-03 10:51 ` Pekka Paalanen
2025-06-03 20:26 ` Harry Wentland
2025-06-04 18:59 ` Shankar, Uma
2025-06-05 7:30 ` Pekka Paalanen
2025-03-26 23:47 ` [PATCH V8 33/43] drm/amd/display: add shaper and blend colorops for 1D Curve Custom LUT Alex Hung
2025-03-26 23:47 ` [PATCH V8 34/43] drm/amd/display: add 3x4 matrix colorop Alex Hung
2025-03-26 23:47 ` [PATCH V8 35/43] drm/colorop: Add mutliplier type Alex Hung
2025-03-26 23:47 ` [PATCH V8 36/43] drm/amd/display: add multiplier colorop Alex Hung
2025-03-26 23:47 ` [PATCH V8 37/43] drm/amd/display: Swap matrix and multiplier Alex Hung
2025-03-26 23:47 ` [PATCH V8 38/43] drm/colorop: Define LUT_1D interpolation Alex Hung
2025-03-26 23:47 ` [PATCH V8 39/43] drm/colorop: allow non-bypass colorops Alex Hung
2025-03-29 15:41 ` Simon Ser
2025-03-26 23:47 ` [PATCH V8 40/43] drm/colorop: Add 3D LUT support to color pipeline Alex Hung
2025-03-29 14:57 ` Simon Ser
2025-04-25 13:50 ` Leandro Ribeiro
2025-05-13 3:39 ` Alex Hung
2025-05-17 1:22 ` Xaver Hugl
2025-05-17 11:53 ` Simon Ser
2025-05-17 22:32 ` Xaver Hugl
2025-05-19 23:43 ` Simon Ser
2025-05-20 20:13 ` Harry Wentland
2025-05-21 19:18 ` Harry Wentland
2025-05-22 10:14 ` Simon Ser
2025-05-22 11:46 ` Shankar, Uma
2025-05-17 17:36 ` Autumn Ashton
2025-03-26 23:47 ` [PATCH V8 41/43] drm/amd/display: add 3D LUT colorop Alex Hung
2025-03-26 23:47 ` [PATCH V8 42/43] drm/amd/display: Add AMD color pipeline doc Alex Hung
2025-03-26 23:47 ` [PATCH V8 43/43] drm/colorop: Add destroy functions for color pipeline Alex Hung
2025-03-29 15:48 ` Simon Ser
2025-04-01 2:42 ` Alex Hung
2025-04-10 16:18 ` Simon Ser
2025-03-29 15:51 ` [PATCH V8 00/43] Color Pipeline API w/ VKMS Simon Ser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250326234748.2982010-5-alex.hung@amd.com \
--to=alex.hung@amd.com \
--cc=Liviu.Dudau@arm.com \
--cc=agoins@nvidia.com \
--cc=aleixpol@kde.org \
--cc=amd-gfx@lists.freedesktop.org \
--cc=chaitanya.kumar.borah@intel.com \
--cc=contact@emersion.fr \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=harry.wentland@amd.com \
--cc=jadahl@redhat.com \
--cc=joshua@froggi.es \
--cc=leo.liu@amd.com \
--cc=louis.chauvet@bootlin.com \
--cc=marcan@marcan.st \
--cc=mdaenzer@redhat.com \
--cc=mwen@igalia.com \
--cc=pekka.paalanen@collabora.com \
--cc=quic_abhinavk@quicinc.com \
--cc=quic_cbraga@quicinc.com \
--cc=quic_naseer@quicinc.com \
--cc=sashamcintosh@google.com \
--cc=sebastian.wick@redhat.com \
--cc=shashank.sharma@amd.com \
--cc=uma.shankar@intel.com \
--cc=victoria@system76.com \
--cc=ville.syrjala@linux.intel.com \
--cc=wayland-devel@lists.freedesktop.org \
--cc=xaver.hugl@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.