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
