xref: /linux/include/drm/drm_colorop.h (revision 056a5087d87ead77dedbe9cf5bde53b7cd4b4651)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors: AMD
24  *
25  */
26 
27 #ifndef __DRM_COLOROP_H__
28 #define __DRM_COLOROP_H__
29 
30 #include <drm/drm_mode_object.h>
31 #include <drm/drm_mode.h>
32 #include <drm/drm_property.h>
33 
34 /* DRM colorop flags */
35 #define DRM_COLOROP_FLAG_ALLOW_BYPASS	(1<<0)	/* Allow bypass on the drm_colorop */
36 
37 /**
38  * enum drm_colorop_curve_1d_type - type of 1D curve
39  *
40  * Describes a 1D curve to be applied by the DRM_COLOROP_1D_CURVE colorop.
41  */
42 enum drm_colorop_curve_1d_type {
43 	/**
44 	 * @DRM_COLOROP_1D_CURVE_SRGB_EOTF:
45 	 *
46 	 * enum string "sRGB EOTF"
47 	 *
48 	 * sRGB piece-wise electro-optical transfer function. Transfer
49 	 * characteristics as defined by IEC 61966-2-1 sRGB. Equivalent
50 	 * to H.273 TransferCharacteristics code point 13 with
51 	 * MatrixCoefficients set to 0.
52 	 */
53 	DRM_COLOROP_1D_CURVE_SRGB_EOTF,
54 
55 	/**
56 	 * @DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF:
57 	 *
58 	 * enum string "sRGB Inverse EOTF"
59 	 *
60 	 * The inverse of &DRM_COLOROP_1D_CURVE_SRGB_EOTF
61 	 */
62 	DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF,
63 
64 	/**
65 	 * @DRM_COLOROP_1D_CURVE_PQ_125_EOTF:
66 	 *
67 	 * enum string "PQ 125 EOTF"
68 	 *
69 	 * The PQ transfer function, scaled by 125.0f, so that 10,000
70 	 * nits correspond to 125.0f.
71 	 *
72 	 * Transfer characteristics of the PQ function as defined by
73 	 * SMPTE ST 2084 (2014) for 10-, 12-, 14-, and 16-bit systems
74 	 * and Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system,
75 	 * represented by H.273 TransferCharacteristics code point 16.
76 	 */
77 	DRM_COLOROP_1D_CURVE_PQ_125_EOTF,
78 
79 	/**
80 	 * @DRM_COLOROP_1D_CURVE_PQ_125_INV_EOTF:
81 	 *
82 	 * enum string "PQ 125 Inverse EOTF"
83 	 *
84 	 * The inverse of DRM_COLOROP_1D_CURVE_PQ_125_EOTF.
85 	 */
86 	DRM_COLOROP_1D_CURVE_PQ_125_INV_EOTF,
87 
88 	/**
89 	 * @DRM_COLOROP_1D_CURVE_BT2020_INV_OETF:
90 	 *
91 	 * enum string "BT.2020 Inverse OETF"
92 	 *
93 	 * The inverse of &DRM_COLOROP_1D_CURVE_BT2020_OETF
94 	 */
95 	DRM_COLOROP_1D_CURVE_BT2020_INV_OETF,
96 
97 	/**
98 	 * @DRM_COLOROP_1D_CURVE_BT2020_OETF:
99 	 *
100 	 * enum string "BT.2020 OETF"
101 	 *
102 	 * The BT.2020/BT.709 transfer function. The BT.709 and BT.2020
103 	 * transfer functions are the same, the only difference is that
104 	 * BT.2020 is defined with more precision for 10 and 12-bit
105 	 * encodings.
106 	 *
107 	 *
108 	 */
109 	DRM_COLOROP_1D_CURVE_BT2020_OETF,
110 
111 	/**
112 	 * @DRM_COLOROP_1D_CURVE_GAMMA22:
113 	 *
114 	 * enum string "Gamma 2.2"
115 	 *
116 	 * A gamma 2.2 power function. This applies a power curve with
117 	 * gamma value of 2.2 to the input values.
118 	 */
119 	DRM_COLOROP_1D_CURVE_GAMMA22,
120 
121 	/**
122 	 * @DRM_COLOROP_1D_CURVE_GAMMA22_INV:
123 	 *
124 	 * enum string "Gamma 2.2 Inverse"
125 	 *
126 	 * The inverse of &DRM_COLOROP_1D_CURVE_GAMMA22
127 	 */
128 	DRM_COLOROP_1D_CURVE_GAMMA22_INV,
129 	/**
130 	 * @DRM_COLOROP_1D_CURVE_COUNT:
131 	 *
132 	 * enum value denoting the size of the enum
133 	 */
134 	DRM_COLOROP_1D_CURVE_COUNT
135 };
136 
137 /**
138  * struct drm_colorop_state - mutable colorop state
139  */
140 struct drm_colorop_state {
141 	/** @colorop: backpointer to the colorop */
142 	struct drm_colorop *colorop;
143 
144 	/*
145 	 * Color properties
146 	 *
147 	 * The following fields are not always valid, their usage depends
148 	 * on the colorop type. See their associated comment for more
149 	 * information.
150 	 */
151 
152 	/**
153 	 * @bypass:
154 	 *
155 	 * When the property BYPASS exists on this colorop, this stores
156 	 * the requested bypass state: true if colorop shall be bypassed,
157 	 * false if colorop is enabled.
158 	 */
159 	bool bypass;
160 
161 	/**
162 	 * @curve_1d_type:
163 	 *
164 	 * Type of 1D curve.
165 	 */
166 	enum drm_colorop_curve_1d_type curve_1d_type;
167 
168 	/**
169 	 * @multiplier:
170 	 *
171 	 * Multiplier to 'gain' the plane. Format is S31.32 sign-magnitude.
172 	 */
173 	uint64_t multiplier;
174 
175 	/**
176 	 * @data:
177 	 *
178 	 * Data blob for any TYPE that requires such a blob. The
179 	 * interpretation of the blob is TYPE-specific.
180 	 *
181 	 * See the &drm_colorop_type documentation for how blob is laid
182 	 * out.
183 	 */
184 	struct drm_property_blob *data;
185 
186 	/**
187 	 * @lut1d_interpolation:
188 	 *
189 	 * Interpolation for DRM_COLOROP_1D_LUT
190 	 */
191 	enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
192 
193 	/**
194 	 * @lut3d_interpolation:
195 	 *
196 	 * Interpolation for DRM_COLOROP_3D_LUT
197 	 */
198 	enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
199 
200 	/** @state: backpointer to global drm_atomic_state */
201 	struct drm_atomic_state *state;
202 };
203 
204 /**
205  * struct drm_colorop_funcs - driver colorop control functions
206  */
207 struct drm_colorop_funcs {
208 	/**
209 	 * @destroy:
210 	 *
211 	 * Clean up colorop resources. This is called at driver unload time
212 	 * through drm_mode_config_cleanup()
213 	 */
214 	void (*destroy)(struct drm_colorop *colorop);
215 };
216 
217 /**
218  * struct drm_colorop - DRM color operation control structure
219  *
220  * A colorop represents one color operation. They can be chained via
221  * the 'next' pointer to build a color pipeline.
222  *
223  * Since colorops cannot stand-alone and are used to describe colorop
224  * operations on a plane they don't have their own locking mechanism but
225  * are locked and programmed along with their associated &drm_plane.
226  *
227  */
228 struct drm_colorop {
229 	/** @dev: parent DRM device */
230 	struct drm_device *dev;
231 
232 	/**
233 	 * @head:
234 	 *
235 	 * List of all colorops on @dev, linked from &drm_mode_config.colorop_list.
236 	 * Invariant over the lifetime of @dev and therefore does not need
237 	 * locking.
238 	 */
239 	struct list_head head;
240 
241 	/**
242 	 * @index: Position inside the mode_config.list, can be used as an array
243 	 * index. It is invariant over the lifetime of the colorop.
244 	 */
245 	unsigned int index;
246 
247 	/** @base: base mode object */
248 	struct drm_mode_object base;
249 
250 	/**
251 	 * @plane:
252 	 *
253 	 * The plane on which the colorop sits. A drm_colorop is always unique
254 	 * to a plane.
255 	 */
256 	struct drm_plane *plane;
257 
258 	/**
259 	 * @state:
260 	 *
261 	 * Current atomic state for this colorop.
262 	 *
263 	 * This is protected by @mutex. Note that nonblocking atomic commits
264 	 * access the current colorop state without taking locks.
265 	 */
266 	struct drm_colorop_state *state;
267 
268 	/*
269 	 * Color properties
270 	 *
271 	 * The following fields are not always valid, their usage depends
272 	 * on the colorop type. See their associated comment for more
273 	 * information.
274 	 */
275 
276 	/** @properties: property tracking for this colorop */
277 	struct drm_object_properties properties;
278 
279 	/**
280 	 * @type:
281 	 *
282 	 * Read-only
283 	 * Type of color operation
284 	 */
285 	enum drm_colorop_type type;
286 
287 	/**
288 	 * @next:
289 	 *
290 	 * Read-only
291 	 * Pointer to next drm_colorop in pipeline
292 	 */
293 	struct drm_colorop *next;
294 
295 	/**
296 	 * @type_property:
297 	 *
298 	 * Read-only "TYPE" property for specifying the type of
299 	 * this color operation. The type is enum drm_colorop_type.
300 	 */
301 	struct drm_property *type_property;
302 
303 	/**
304 	 * @bypass_property:
305 	 *
306 	 * Boolean property to control enablement of the color
307 	 * operation. Only present if DRM_COLOROP_FLAG_ALLOW_BYPASS
308 	 * flag is set. When present, setting bypass to "true" shall
309 	 * always be supported to allow compositors to quickly fall
310 	 * back to alternate methods of color processing. This is
311 	 * important since setting color operations can fail due to
312 	 * unique HW constraints.
313 	 */
314 	struct drm_property *bypass_property;
315 
316 	/**
317 	 * @size:
318 	 *
319 	 * Number of entries of the custom LUT. This should be read-only.
320 	 */
321 	uint32_t size;
322 
323 	/**
324 	 * @lut1d_interpolation_property:
325 	 *
326 	 * Property for DRM_COLOROP_1D_LUT interpolation
327 	 */
328 	struct drm_property *lut1d_interpolation_property;
329 
330 	/**
331 	 * @curve_1d_type_property:
332 	 *
333 	 * Sub-type for DRM_COLOROP_1D_CURVE type.
334 	 */
335 	struct drm_property *curve_1d_type_property;
336 
337 	/**
338 	 * @multiplier_property:
339 	 *
340 	 * Multiplier property for plane gain
341 	 */
342 	struct drm_property *multiplier_property;
343 
344 	/**
345 	 * @size_property:
346 	 *
347 	 * Size property for custom LUT from userspace.
348 	 */
349 	struct drm_property *size_property;
350 
351 	/**
352 	 * @lut3d_interpolation_property:
353 	 *
354 	 * Property for DRM_COLOROP_3D_LUT interpolation
355 	 */
356 	struct drm_property *lut3d_interpolation_property;
357 
358 	/**
359 	 * @data_property:
360 	 *
361 	 * blob property for any TYPE that requires a blob of data,
362 	 * such as 1DLUT, CTM, 3DLUT, etc.
363 	 *
364 	 * The way this blob is interpreted depends on the TYPE of
365 	 * this
366 	 */
367 	struct drm_property *data_property;
368 
369 	/**
370 	 * @next_property:
371 	 *
372 	 * Read-only property to next colorop in the pipeline
373 	 */
374 	struct drm_property *next_property;
375 
376 	/** @funcs: colorop control functions */
377 	const struct drm_colorop_funcs *funcs;
378 };
379 
380 #define obj_to_colorop(x) container_of(x, struct drm_colorop, base)
381 
382 /**
383  * drm_colorop_find - look up a Colorop object from its ID
384  * @dev: DRM device
385  * @file_priv: drm file to check for lease against.
386  * @id: &drm_mode_object ID
387  *
388  * This can be used to look up a Colorop from its userspace ID. Only used by
389  * drivers for legacy IOCTLs and interface, nowadays extensions to the KMS
390  * userspace interface should be done using &drm_property.
391  */
392 static inline struct drm_colorop *drm_colorop_find(struct drm_device *dev,
393 						   struct drm_file *file_priv,
394 						   uint32_t id)
395 {
396 	struct drm_mode_object *mo;
397 
398 	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_COLOROP);
399 	return mo ? obj_to_colorop(mo) : NULL;
400 }
401 
402 void drm_colorop_pipeline_destroy(struct drm_device *dev);
403 void drm_colorop_cleanup(struct drm_colorop *colorop);
404 
405 int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop,
406 				    struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
407 				    u64 supported_tfs, uint32_t flags);
408 int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop,
409 					struct drm_plane *plane,
410 					const struct drm_colorop_funcs *funcs,
411 					uint32_t lut_size,
412 					enum drm_colorop_lut1d_interpolation_type interpolation,
413 					uint32_t flags);
414 int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop,
415 				   struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
416 				   uint32_t flags);
417 int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop,
418 				struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
419 				uint32_t flags);
420 int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop,
421 				 struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
422 				 uint32_t lut_size,
423 				 enum drm_colorop_lut3d_interpolation_type interpolation,
424 				 uint32_t flags);
425 
426 struct drm_colorop_state *
427 drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
428 
429 void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
430 				      struct drm_colorop_state *state);
431 
432 /**
433  * drm_colorop_reset - reset colorop atomic state
434  * @colorop: drm colorop
435  *
436  * Resets the atomic state for @colorop by freeing the state pointer (which might
437  * be NULL, e.g. at driver load time) and allocating a new empty state object.
438  */
439 void drm_colorop_reset(struct drm_colorop *colorop);
440 
441 void drm_colorop_destroy(struct drm_colorop *colorop);
442 
443 /**
444  * drm_colorop_index - find the index of a registered colorop
445  * @colorop: colorop to find index for
446  *
447  * Given a registered colorop, return the index of that colorop within a DRM
448  * device's list of colorops.
449  */
450 static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop)
451 {
452 	return colorop->index;
453 }
454 
455 #define drm_for_each_colorop(colorop, dev) \
456 	list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head)
457 
458 /**
459  * drm_get_colorop_type_name - return a string for colorop type
460  * @type: colorop type to compute name of
461  *
462  * In contrast to the other drm_get_*_name functions this one here returns a
463  * const pointer and hence is threadsafe.
464  */
465 const char *drm_get_colorop_type_name(enum drm_colorop_type type);
466 
467 /**
468  * drm_get_colorop_curve_1d_type_name - return a string for 1D curve type
469  * @type: 1d curve type to compute name of
470  *
471  * In contrast to the other drm_get_*_name functions this one here returns a
472  * const pointer and hence is threadsafe.
473  */
474 const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type);
475 
476 const char *
477 drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type);
478 
479 const char *
480 drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
481 
482 void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
483 
484 #endif /* __DRM_COLOROP_H__ */
485