Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/colorop: Add 3x4 CTM type

This type is used to support a 3x4 matrix in colorops. A 3x4
matrix uses the last column as a "bias" column. Some HW exposes
support for 3x4. The calculation looks like:

out matrix in
|R| |0 1 2 3 | | R |
|G| = |4 5 6 7 | x | G |
|B| |8 9 10 11| | B |
|1.0|

This is also the first colorop where we need a blob property to
program the property. For that we'll introduce a new DATA
property that can be used by all colorop TYPEs requiring a
blob. The way a DATA blob is read depends on the TYPE of
the colorop.

We only create the DATA property for property types that
need it.

Reviewed-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Sebastian Wick <sebastian.wick@redhat.com>
Signed-off-by: Simon Ser <contact@emersion.fr>
Link: https://patch.msgid.link/20251115000237.3561250-19-alex.hung@amd.com

authored by

Harry Wentland and committed by
Simon Ser
e5719e7f cb500b4c

+136 -10
+3
drivers/gpu/drm/drm_atomic.c
··· 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_CTM_3X4: 798 + drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0); 799 + break; 797 800 default: 798 801 break; 799 802 }
+31
drivers/gpu/drm/drm_atomic_uapi.c
··· 689 689 return 0; 690 690 } 691 691 692 + static int drm_atomic_color_set_data_property(struct drm_colorop *colorop, 693 + struct drm_colorop_state *state, 694 + struct drm_property *property, 695 + uint64_t val) 696 + { 697 + ssize_t elem_size = -1; 698 + ssize_t size = -1; 699 + bool replaced = false; 700 + 701 + switch (colorop->type) { 702 + case DRM_COLOROP_CTM_3X4: 703 + size = sizeof(struct drm_color_ctm_3x4); 704 + break; 705 + default: 706 + /* should never get here */ 707 + return -EINVAL; 708 + } 709 + 710 + return drm_property_replace_blob_from_id(colorop->dev, 711 + &state->data, 712 + val, 713 + size, 714 + elem_size, 715 + &replaced); 716 + } 717 + 692 718 static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, 693 719 struct drm_colorop_state *state, 694 720 struct drm_file *file_priv, ··· 725 699 state->bypass = val; 726 700 } else if (property == colorop->curve_1d_type_property) { 727 701 state->curve_1d_type = val; 702 + } else if (property == colorop->data_property) { 703 + return drm_atomic_color_set_data_property(colorop, state, 704 + property, val); 728 705 } else { 729 706 drm_dbg_atomic(colorop->dev, 730 707 "[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n", ··· 750 721 *val = state->bypass; 751 722 else if (property == colorop->curve_1d_type_property) 752 723 *val = state->curve_1d_type; 724 + else if (property == colorop->data_property) 725 + *val = (state->data) ? state->data->base.id : 0; 753 726 else 754 727 return -EINVAL; 755 728
+47
drivers/gpu/drm/drm_colorop.c
··· 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_CTM_3X4, "3x4 Matrix"}, 67 68 }; 68 69 69 70 static const char * const colorop_curve_1d_type_names[] = { ··· 147 146 148 147 list_del(&colorop->head); 149 148 config->num_colorop--; 149 + 150 + if (colorop->state && colorop->state->data) { 151 + drm_property_blob_put(colorop->state->data); 152 + colorop->state->data = NULL; 153 + } 150 154 151 155 kfree(colorop->state); 152 156 } ··· 242 236 } 243 237 EXPORT_SYMBOL(drm_plane_colorop_curve_1d_init); 244 238 239 + static int drm_colorop_create_data_prop(struct drm_device *dev, struct drm_colorop *colorop) 240 + { 241 + struct drm_property *prop; 242 + 243 + /* data */ 244 + prop = drm_property_create(dev, DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB, 245 + "DATA", 0); 246 + if (!prop) 247 + return -ENOMEM; 248 + 249 + colorop->data_property = prop; 250 + drm_object_attach_property(&colorop->base, 251 + colorop->data_property, 252 + 0); 253 + 254 + return 0; 255 + } 256 + 257 + int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, 258 + struct drm_plane *plane) 259 + { 260 + int ret; 261 + 262 + ret = drm_plane_colorop_init(dev, colorop, plane, DRM_COLOROP_CTM_3X4); 263 + if (ret) 264 + return ret; 265 + 266 + ret = drm_colorop_create_data_prop(dev, colorop); 267 + if (ret) 268 + return ret; 269 + 270 + drm_colorop_reset(colorop); 271 + 272 + return 0; 273 + } 274 + EXPORT_SYMBOL(drm_plane_colorop_ctm_3x4_init); 275 + 245 276 static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop, 246 277 struct drm_colorop_state *state) 247 278 { 248 279 memcpy(state, colorop->state, sizeof(*state)); 280 + 281 + if (state->data) 282 + drm_property_blob_get(state->data); 249 283 250 284 state->bypass = true; 251 285 } ··· 367 321 368 322 static const char * const colorop_type_name[] = { 369 323 [DRM_COLOROP_1D_CURVE] = "1D Curve", 324 + [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", 370 325 }; 371 326 372 327 const char *drm_get_colorop_type_name(enum drm_colorop_type type)
+24
include/drm/drm_colorop.h
··· 97 97 */ 98 98 enum drm_colorop_curve_1d_type curve_1d_type; 99 99 100 + /** 101 + * @data: 102 + * 103 + * Data blob for any TYPE that requires such a blob. The 104 + * interpretation of the blob is TYPE-specific. 105 + * 106 + * See the &drm_colorop_type documentation for how blob is laid 107 + * out. 108 + */ 109 + struct drm_property_blob *data; 110 + 100 111 /** @state: backpointer to global drm_atomic_state */ 101 112 struct drm_atomic_state *state; 102 113 }; ··· 218 207 struct drm_property *curve_1d_type_property; 219 208 220 209 /** 210 + * @data_property: 211 + * 212 + * blob property for any TYPE that requires a blob of data, 213 + * such as 1DLUT, CTM, 3DLUT, etc. 214 + * 215 + * The way this blob is interpreted depends on the TYPE of 216 + * this 217 + */ 218 + struct drm_property *data_property; 219 + 220 + /** 221 221 * @next_property: 222 222 * 223 223 * Read-only property to next colorop in the pipeline ··· 264 242 265 243 int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, 266 244 struct drm_plane *plane, u64 supported_tfs); 245 + int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, 246 + struct drm_plane *plane); 267 247 268 248 struct drm_colorop_state * 269 249 drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
-9
include/uapi/drm/amdgpu_drm.h
··· 1656 1656 #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ 1657 1657 #define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ 1658 1658 1659 - /* FIXME wrong namespace! */ 1660 - struct drm_color_ctm_3x4 { 1661 - /* 1662 - * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude 1663 - * (not two's complement!) format. 1664 - */ 1665 - __u64 matrix[12]; 1666 - }; 1667 - 1668 1659 #if defined(__cplusplus) 1669 1660 } 1670 1661 #endif
+31 -1
include/uapi/drm/drm_mode.h
··· 847 847 __u64 matrix[9]; 848 848 }; 849 849 850 + struct drm_color_ctm_3x4 { 851 + /* 852 + * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude 853 + * (not two's complement!) format. 854 + * 855 + * out matrix in 856 + * |R| |0 1 2 3 | | R | 857 + * |G| = |4 5 6 7 | x | G | 858 + * |B| |8 9 10 11| | B | 859 + * |1.0| 860 + */ 861 + __u64 matrix[12]; 862 + }; 863 + 850 864 struct drm_color_lut { 851 865 /* 852 866 * Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and ··· 888 874 * A 1D curve that is being applied to all color channels. The 889 875 * curve is specified via the CURVE_1D_TYPE colorop property. 890 876 */ 891 - DRM_COLOROP_1D_CURVE 877 + DRM_COLOROP_1D_CURVE, 878 + 879 + /** 880 + * @DRM_COLOROP_CTM_3X4: 881 + * 882 + * enum string "3x4 Matrix" 883 + * 884 + * A 3x4 matrix. Its values are specified via the 885 + * &drm_color_ctm_3x4 struct provided via the DATA property. 886 + * 887 + * The DATA blob is a float[12]: 888 + * out matrix in 889 + * | R | | 0 1 2 3 | | R | 890 + * | G | = | 4 5 6 7 | x | G | 891 + * | B | | 8 9 10 12 | | B | 892 + */ 893 + DRM_COLOROP_CTM_3X4, 892 894 }; 893 895 894 896 /**