We've previously introduced DRM_COLOROP_1D_CURVE for pre-defined 1D curves. But we also have HW that supports custom curves and userspace needs the ability to pass custom curves, aka LUTs. This patch introduces a new colorop type, called DRM_COLOROP_1D_LUT that provides a SIZE property which is used by a driver to advertise the supported SIZE of the LUT, as well as a DATA property which userspace uses to set the LUT. DATA and size function in the same way as current drm_crtc GAMMA and DEGAMMA LUTs.
Unified · Split
| @@ -794,6 +794,10 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p, · 793 unmodified lines | ||
| 794 | 794 | drm_printf(p, "\tcurve_1d_type=%s\n", |
| 795 | 795 | drm_get_colorop_curve_1d_type_name(state->curve_1d_type)); |
| 796 | 796 | break; |
| 797 | + case DRM_COLOROP_1D_LUT: | |
| 798 | + drm_printf(p, "\tsize=%d\n", colorop->size); | |
| 799 | + drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0); | |
| 800 | + break; | |
| 797 | 801 | case DRM_COLOROP_CTM_3X4: |
| 798 | 802 | drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0); |
| 799 | 803 | break; |
| @@ -699,6 +699,9 @@ static int drm_atomic_color_set_data_property(struct drm_colorop *colorop, · 698 unmodified lines | ||
| 699 | 699 | bool replaced = false; |
| 700 | 700 | |
| 701 | 701 | switch (colorop->type) { |
| 702 | + case DRM_COLOROP_1D_LUT: | |
| 703 | + size = colorop->size * sizeof(struct drm_color_lut32); | |
| 704 | + break; | |
| 702 | 705 | case DRM_COLOROP_CTM_3X4: |
| 703 | 706 | size = sizeof(struct drm_color_ctm_3x4); |
| 704 | 707 | break; |
| @@ -750,6 +753,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, · 45 unmodified lines | ||
| 750 | 753 | *val = state->bypass; |
| 751 | 754 | else if (property == colorop->curve_1d_type_property) |
| 752 | 755 | *val = state->curve_1d_type; |
| 756 | + else if (property == colorop->size_property) | |
| 757 | + *val = colorop->size; | |
| 753 | 758 | else if (property == colorop->data_property) |
| 754 | 759 | *val = (state->data) ? state->data->base.id : 0; |
| 755 | 760 | else |
| @@ -64,6 +64,7 @@ · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { |
| 66 | 66 | { DRM_COLOROP_1D_CURVE, "1D Curve" }, |
| 67 | + { DRM_COLOROP_1D_LUT, "1D LUT" }, | |
| 67 | 68 | { DRM_COLOROP_CTM_3X4, "3x4 Matrix"}, |
| 68 | 69 | }; |
| 69 | 70 | |
| @@ -264,6 +265,47 @@ static int drm_colorop_create_data_prop(struct drm_device *dev, struct drm_color · 194 unmodified lines | ||
| 264 | 265 | return 0; |
| 265 | 266 | } |
| 266 | 267 | |
| 268 | +/** | |
| 269 | + * drm_plane_colorop_curve_1d_lut_init - Initialize a DRM_COLOROP_1D_LUT | |
| 270 | + * | |
| 271 | + * @dev: DRM device | |
| 272 | + * @colorop: The drm_colorop object to initialize | |
| 273 | + * @plane: The associated drm_plane | |
| 274 | + * @lut_size: LUT size supported by driver | |
| 275 | + * @return zero on success, -E value on failure | |
| 276 | + */ | |
| 277 | +int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, | |
| 278 | + struct drm_plane *plane, uint32_t lut_size) | |
| 279 | +{ | |
| 280 | + struct drm_property *prop; | |
| 281 | + int ret; | |
| 282 | + | |
| 283 | + ret = drm_plane_colorop_init(dev, colorop, plane, DRM_COLOROP_1D_LUT); | |
| 284 | + if (ret) | |
| 285 | + return ret; | |
| 286 | + | |
| 287 | + /* initialize 1D LUT only attribute */ | |
| 288 | + /* LUT size */ | |
| 289 | + prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ATOMIC, | |
| 290 | + "SIZE", 0, UINT_MAX); | |
| 291 | + if (!prop) | |
| 292 | + return -ENOMEM; | |
| 293 | + | |
| 294 | + colorop->size_property = prop; | |
| 295 | + drm_object_attach_property(&colorop->base, colorop->size_property, lut_size); | |
| 296 | + colorop->size = lut_size; | |
| 297 | + | |
| 298 | + /* data */ | |
| 299 | + ret = drm_colorop_create_data_prop(dev, colorop); | |
| 300 | + if (ret) | |
| 301 | + return ret; | |
| 302 | + | |
| 303 | + drm_colorop_reset(colorop); | |
| 304 | + | |
| 305 | + return 0; | |
| 306 | +} | |
| 307 | +EXPORT_SYMBOL(drm_plane_colorop_curve_1d_lut_init); | |
| 308 | + | |
| 267 | 309 | int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 268 | 310 | struct drm_plane *plane) |
| 269 | 311 | { |
| @@ -371,6 +413,7 @@ void drm_colorop_reset(struct drm_colorop *colorop) · 101 unmodified lines | ||
| 371 | 413 | |
| 372 | 414 | static const char * const colorop_type_name[] = { |
| 373 | 415 | [DRM_COLOROP_1D_CURVE] = "1D Curve", |
| 416 | + [DRM_COLOROP_1D_LUT] = "1D LUT", | |
| 374 | 417 | [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", |
| 375 | 418 | }; |
| 376 | 419 | |
| @@ -257,6 +257,13 @@ struct drm_colorop { · 256 unmodified lines | ||
| 257 | 257 | */ |
| 258 | 258 | struct drm_property *bypass_property; |
| 259 | 259 | |
| 260 | + /** | |
| 261 | + * @size: | |
| 262 | + * | |
| 263 | + * Number of entries of the custom LUT. This should be read-only. | |
| 264 | + */ | |
| 265 | + uint32_t size; | |
| 266 | + | |
| 260 | 267 | /** |
| 261 | 268 | * @curve_1d_type_property: |
| 262 | 269 | * |
| @@ -264,6 +271,13 @@ struct drm_colorop { · 1 unmodified line | ||
| 264 | 271 | */ |
| 265 | 272 | struct drm_property *curve_1d_type_property; |
| 266 | 273 | |
| 274 | + /** | |
| 275 | + * @size_property: | |
| 276 | + * | |
| 277 | + * Size property for custom LUT from userspace. | |
| 278 | + */ | |
| 279 | + struct drm_property *size_property; | |
| 280 | + | |
| 267 | 281 | /** |
| 268 | 282 | * @data_property: |
| 269 | 283 | * |
| @@ -311,6 +325,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop); · 41 unmodified lines | ||
| 311 | 325 | |
| 312 | 326 | int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 313 | 327 | struct drm_plane *plane, u64 supported_tfs); |
| 328 | +int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, | |
| 329 | + struct drm_plane *plane, uint32_t lut_size); | |
| 314 | 330 | int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 315 | 331 | struct drm_plane *plane); |
| 316 | 332 | |
| @@ -902,6 +902,20 @@ enum drm_colorop_type { · 901 unmodified lines | ||
| 902 | 902 | */ |
| 903 | 903 | DRM_COLOROP_1D_CURVE, |
| 904 | 904 | |
| 905 | + /** | |
| 906 | + * @DRM_COLOROP_1D_LUT: | |
| 907 | + * | |
| 908 | + * enum string "1D LUT" | |
| 909 | + * | |
| 910 | + * A simple 1D LUT of uniformly spaced &drm_color_lut32 entries, | |
| 911 | + * packed into a blob via the DATA property. The driver's | |
| 912 | + * expected LUT size is advertised via the SIZE property. | |
| 913 | + * | |
| 914 | + * The DATA blob is an array of struct drm_color_lut32 with size | |
| 915 | + * of "size". | |
| 916 | + */ | |
| 917 | + DRM_COLOROP_1D_LUT, | |
| 918 | + | |
| 905 | 919 | /** |
| 906 | 920 | * @DRM_COLOROP_CTM_3X4: |
| 907 | 921 | * |