Existing LUT precision structure is having only 16 bit precision. This is not enough for upcoming enhanced hardwares and advance usecases like HDR processing. Hence added a new structure with 32 bit precision values. Signed-off-by: Uma Shankar <uma.shankar@xxxxxxxxx> Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@xxxxxxxxx> --- drivers/gpu/drm/drm_color_mgmt.c | 43 ++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 13 ++++++++++ include/uapi/drm/drm_mode.h | 18 +++++++++++++ 3 files changed, 74 insertions(+) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 3969dc548cff..83dc850d3b54 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -630,3 +630,46 @@ int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests) return 0; } EXPORT_SYMBOL(drm_color_lut_check); + +/** + * drm_color_lut_32_check - check validity of extended lookup table + * @lut: property blob containing extended LUT to check + * @tests: bitmask of tests to run + * + * Helper to check whether a userspace-provided extended lookup table is valid and + * satisfies hardware requirements. Drivers pass a bitmask indicating which of + * the tests in &drm_color_lut_tests should be performed. + * + * Returns 0 on success, -EINVAL on failure. + */ +int drm_color_lut_32_check(const struct drm_property_blob *lut, u32 tests) +{ + const struct drm_color_lut_32 *entry; + int i; + + if (!lut || !tests) + return 0; + + entry = lut->data; + for (i = 0; i < drm_color_lut_32_size(lut); i++) { + if (tests & DRM_COLOR_LUT_EQUAL_CHANNELS) { + if (entry[i].red != entry[i].blue || + entry[i].red != entry[i].green) { + DRM_DEBUG_KMS("All LUT entries must have equal r/g/b\n"); + return -EINVAL; + } + } + + if (i > 0 && tests & DRM_COLOR_LUT_NON_DECREASING) { + if (entry[i].red < entry[i - 1].red || + entry[i].green < entry[i - 1].green || + entry[i].blue < entry[i - 1].blue) { + DRM_DEBUG_KMS("LUT entries must never decrease.\n"); + return -EINVAL; + } + } + } + + return 0; +} +EXPORT_SYMBOL(drm_color_lut_32_check); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index ed81741036d7..882253a82bf1 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -72,6 +72,18 @@ static inline int drm_color_lut_size(const struct drm_property_blob *blob) return blob->length / sizeof(struct drm_color_lut); } +/** + * drm_color_lut_32_size - calculate the number of entries in the extended LUT + * @blob: blob containing the LUT + * + * Returns: + * The number of entries in the color LUT stored in @blob. + */ +static inline int drm_color_lut_32_size(const struct drm_property_blob *blob) +{ + return blob->length / sizeof(struct drm_color_lut_32); +} + enum drm_color_encoding { DRM_COLOR_YCBCR_BT601, DRM_COLOR_YCBCR_BT709, @@ -118,4 +130,5 @@ enum drm_color_lut_tests { }; int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests); +int drm_color_lut_32_check(const struct drm_property_blob *lut, u32 tests); #endif diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index a4a7ab689631..e5090416c1ae 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -872,6 +872,23 @@ struct drm_color_lut { __u16 reserved; }; +/** + * struct drm_color_lut_32 - Represents high precision lut values + * + * Creating 32 bit palette entries for better data + * precision. This will be required for HDR and + * similar color processing usecases. + */ +struct drm_color_lut_32 { + /* + * Data for high precision LUTs + */ + __u32 red; + __u32 green; + __u32 blue; + __u32 reserved; +}; + /** * enum drm_colorop_type - Type of color operation * @@ -879,6 +896,7 @@ struct drm_color_lut { * and defines a different set of properties. This enum defines all types and * gives a high-level description. */ + enum drm_colorop_type { /** * @DRM_COLOROP_1D_CURVE: -- 2.42.0