Add drm_plane_colorop_csc_init() helper function to initialize a CSC
(Color Space Conversion) colorop with COLOR_ENCODING and COLOR_RANGE
properties.

This function allows drivers to create CSC colorops with configurable
YUV encoding standards (BT.601, BT.709, BT.2020) and range types
(limited/full range), which control the YUV-to-RGB conversion matrix.

The colorop state structure is extended with color_encoding and
color_range fields to hold the current property values.

Co-developed by Claude Sonnet 4.5.

Signed-off-by: Harry Wentland <[email protected]>
---
 drivers/gpu/drm/drm_colorop.c | 89 +++++++++++++++++++++++++++++++++++
 include/drm/drm_colorop.h     | 39 +++++++++++++++
 2 files changed, 128 insertions(+)

diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 11b2f11db874..5329eeb0ae1b 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -621,6 +621,95 @@ const char *drm_get_colorop_lut3d_interpolation_name(enum 
drm_colorop_lut3d_inte
        return colorop_lu3d_interpolation_name[type];
 }
 
+/**
+ * drm_plane_colorop_csc_init - Initialize a CSC colorop
+ * @dev: DRM device
+ * @colorop: the color operation to initialize
+ * @plane: plane object that this colorop will belong to
+ * @supported_encodings: Bitmask of supported encodings 
(BIT(DRM_COLOR_YCBCR_*))
+ * @supported_ranges: Bitmask of supported ranges 
(BIT(DRM_COLOR_YCBCR_*_RANGE))
+ * @default_encoding: Default COLOR_ENCODING value
+ * @default_range: Default COLOR_RANGE value
+ * @flags: Flags for this colorop (DRM_COLOROP_FLAG_*)
+ *
+ * Initializes a CSC (Color Space Conversion) colorop suitable for YUV to RGB
+ * conversion. Creates COLOR_ENCODING and COLOR_RANGE properties that control
+ * which conversion matrix is used.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_plane_colorop_csc_init(struct drm_device *dev, struct drm_colorop 
*colorop,
+                              struct drm_plane *plane, const struct 
drm_colorop_funcs *funcs,
+                              u32 supported_encodings, u32 supported_ranges,
+                              enum drm_color_encoding default_encoding,
+                              enum drm_color_range default_range,
+                              uint32_t flags)
+{
+       struct drm_property *prop;
+       struct drm_prop_enum_list enum_list[max_t(int, DRM_COLOR_ENCODING_MAX,
+                                                      DRM_COLOR_RANGE_MAX)];
+       int i, len, ret;
+
+       ret = drm_plane_colorop_init(dev, colorop, plane, funcs, 
DRM_COLOROP_CSC, flags);
+       if (ret)
+               return ret;
+
+
+       if (WARN_ON(supported_encodings == 0 ||
+                   (supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
+                   (supported_encodings & BIT(default_encoding)) == 0))
+               return -EINVAL;
+
+       if (WARN_ON(supported_ranges == 0 ||
+                   (supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
+                   (supported_ranges & BIT(default_range)) == 0))
+               return -EINVAL;
+
+       len = 0;
+       for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
+               if ((supported_encodings & BIT(i)) == 0)
+                       continue;
+
+               enum_list[len].type = i;
+               enum_list[len].name = drm_get_color_encoding_name(i);
+               len++;
+       }
+
+       prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
+                                       enum_list, len);
+       if (!prop)
+               return -ENOMEM;
+       colorop->color_encoding_property = prop;
+       drm_object_attach_property(&colorop->base, prop, default_encoding);
+       if (colorop->state)
+               colorop->state->color_encoding = default_encoding;
+
+       len = 0;
+       for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
+               if ((supported_ranges & BIT(i)) == 0)
+                       continue;
+
+               enum_list[len].type = i;
+               enum_list[len].name = drm_get_color_range_name(i);
+               len++;
+       }
+
+       prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
+                                       enum_list, len);
+       if (!prop)
+               return -ENOMEM;
+       colorop->color_range_property = prop;
+       drm_object_attach_property(&colorop->base, prop, default_range);
+       if (colorop->state)
+               colorop->state->color_range = default_range;
+
+       drm_colorop_reset(colorop);
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_plane_colorop_csc_init);
+
 /**
  * drm_colorop_set_next_property - sets the next pointer
  * @colorop: drm colorop
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index bd082854ca74..09844e8885e2 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -30,6 +30,8 @@
 #include <drm/drm_mode_object.h>
 #include <drm/drm_mode.h>
 #include <drm/drm_property.h>
+#include <drm/drm_color_mgmt.h>
+
 
 /* DRM colorop flags */
 #define DRM_COLOROP_FLAG_ALLOW_BYPASS  (1<<0)  /* Allow bypass on the 
drm_colorop */
@@ -183,6 +185,20 @@ struct drm_colorop_state {
         */
        struct drm_property_blob *data;
 
+       /**
+        * @color_encoding:
+        *
+        * Color encoding for YUV-to-RGB conversion
+        */
+       enum drm_color_encoding color_encoding;
+
+       /**
+        * @color_range:
+        *
+        * Color range
+        */
+       enum drm_color_range color_range;
+
        /** @state: backpointer to global drm_atomic_state */
        struct drm_atomic_state *state;
 };
@@ -357,6 +373,23 @@ struct drm_colorop {
         */
        struct drm_property *lut3d_interpolation_property;
 
+       /**
+        * @color_encoding_property:
+        *
+        * "COLOR_ENCODING" enum property for specifying the YUV-to-RGB
+        * conversion matrix on a DRM_COLOROP_CSC.
+        */
+
+       struct drm_property *color_encoding_property;
+
+       /**
+        * @color_range_property:
+        *
+        * "COLOR_RANGE" enum property for specifying color range
+        * for a YUV-to-RGB conversion matrix on DRM_COLOROP_CSC.
+        */
+       struct drm_property *color_range_property;
+
        /**
         * @data_property:
         *
@@ -424,6 +457,12 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, 
struct drm_colorop *col
                                 uint32_t lut_size,
                                 enum drm_colorop_lut3d_interpolation_type 
interpolation,
                                 uint32_t flags);
+int drm_plane_colorop_csc_init(struct drm_device *dev, struct drm_colorop 
*colorop,
+                              struct drm_plane *plane, const struct 
drm_colorop_funcs *funcs,
+                              u32 supported_encodings, u32 supported_ranges,
+                              enum drm_color_encoding default_encoding,
+                              enum drm_color_range default_range,
+                              uint32_t flags);
 
 struct drm_colorop_state *
 drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
-- 
2.53.0

Reply via email to