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 | drm_printf(p, "\tcurve_1d_type=%s\n", | 794 | drm_printf(p, "\tcurve_1d_type=%s\n", |
| 795 | drm_get_colorop_curve_1d_type_name(state->curve_1d_type)); | 795 | drm_get_colorop_curve_1d_type_name(state->curve_1d_type)); |
| 796 | break; | 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 | case DRM_COLOROP_CTM_3X4: | 801 | case DRM_COLOROP_CTM_3X4: |
| 798 | drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0); | 802 | drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0); |
| 799 | break; | 803 | break; |
| @@ -699,6 +699,9 @@ static int drm_atomic_color_set_data_property(struct drm_colorop *colorop, · 698 unmodified lines | |||
| 699 | bool replaced = false; | 699 | bool replaced = false; |
| 700 | 700 | ||
| 701 | switch (colorop->type) { | 701 | switch (colorop->type) { |
| 702 | case DRM_COLOROP_1D_LUT: | ||
| 703 | size = colorop->size * sizeof(struct drm_color_lut32); | ||
| 704 | break; | ||
| 702 | case DRM_COLOROP_CTM_3X4: | 705 | case DRM_COLOROP_CTM_3X4: |
| 703 | size = sizeof(struct drm_color_ctm_3x4); | 706 | size = sizeof(struct drm_color_ctm_3x4); |
| 704 | break; | 707 | break; |
| @@ -750,6 +753,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, · 45 unmodified lines | |||
| 750 | *val = state->bypass; | 753 | *val = state->bypass; |
| 751 | else if (property == colorop->curve_1d_type_property) | 754 | else if (property == colorop->curve_1d_type_property) |
| 752 | *val = state->curve_1d_type; | 755 | *val = state->curve_1d_type; |
| 756 | else if (property == colorop->size_property) | ||
| 757 | *val = colorop->size; | ||
| 753 | else if (property == colorop->data_property) | 758 | else if (property == colorop->data_property) |
| 754 | *val = (state->data) ? state->data->base.id : 0; | 759 | *val = (state->data) ? state->data->base.id : 0; |
| 755 | else | 760 | else |
| @@ -64,6 +64,7 @@ · 63 unmodified lines | |||
| 64 | 64 | ||
| 65 | static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { | 65 | static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { |
| 66 | { DRM_COLOROP_1D_CURVE, "1D Curve" }, | 66 | { DRM_COLOROP_1D_CURVE, "1D Curve" }, |
| 67 | { DRM_COLOROP_1D_LUT, "1D LUT" }, | ||
| 67 | { DRM_COLOROP_CTM_3X4, "3x4 Matrix"}, | 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 | return 0; | 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 | int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, | 309 | int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 268 | struct drm_plane *plane) | 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 | static const char * const colorop_type_name[] = { | 414 | static const char * const colorop_type_name[] = { |
| 373 | [DRM_COLOROP_1D_CURVE] = "1D Curve", | 415 | [DRM_COLOROP_1D_CURVE] = "1D Curve", |
| 416 | [DRM_COLOROP_1D_LUT] = "1D LUT", | ||
| 374 | [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", | 417 | [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", |
| 375 | }; | 418 | }; |
| 376 | 419 | ||
| @@ -257,6 +257,13 @@ struct drm_colorop { · 256 unmodified lines | |||
| 257 | */ | 257 | */ |
| 258 | struct drm_property *bypass_property; | 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 | * @curve_1d_type_property: | 268 | * @curve_1d_type_property: |
| 262 | * | 269 | * |
| @@ -264,6 +271,13 @@ struct drm_colorop { · 1 unmodified line | |||
| 264 | */ | 271 | */ |
| 265 | struct drm_property *curve_1d_type_property; | 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 | * @data_property: | 282 | * @data_property: |
| 269 | * | 283 | * |
| @@ -311,6 +325,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop); · 41 unmodified lines | |||
| 311 | 325 | ||
| 312 | int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, | 326 | int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 313 | struct drm_plane *plane, u64 supported_tfs); | 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 | int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, | 330 | int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 315 | struct drm_plane *plane); | 331 | struct drm_plane *plane); |
| 316 | 332 | ||
| @@ -902,6 +902,20 @@ enum drm_colorop_type { · 901 unmodified lines | |||
| 902 | */ | 902 | */ |
| 903 | DRM_COLOROP_1D_CURVE, | 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 | * @DRM_COLOROP_CTM_3X4: | 920 | * @DRM_COLOROP_CTM_3X4: |
| 907 | * | 921 | * |