xref: /linux/include/drm/drm_colorop.h (revision 5ea5880764cbb164afb17a62e76ca75dc371409d)
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 	/** @state: backpointer to global drm_atomic_state */
187 	struct drm_atomic_state *state;
188 };
189 
190 /**
191  * struct drm_colorop_funcs - driver colorop control functions
192  */
193 struct drm_colorop_funcs {
194 	/**
195 	 * @destroy:
196 	 *
197 	 * Clean up colorop resources. This is called at driver unload time
198 	 * through drm_mode_config_cleanup()
199 	 */
200 	void (*destroy)(struct drm_colorop *colorop);
201 };
202 
203 /**
204  * struct drm_colorop - DRM color operation control structure
205  *
206  * A colorop represents one color operation. They can be chained via
207  * the 'next' pointer to build a color pipeline.
208  *
209  * Since colorops cannot stand-alone and are used to describe colorop
210  * operations on a plane they don't have their own locking mechanism but
211  * are locked and programmed along with their associated &drm_plane.
212  *
213  */
214 struct drm_colorop {
215 	/** @dev: parent DRM device */
216 	struct drm_device *dev;
217 
218 	/**
219 	 * @head:
220 	 *
221 	 * List of all colorops on @dev, linked from &drm_mode_config.colorop_list.
222 	 * Invariant over the lifetime of @dev and therefore does not need
223 	 * locking.
224 	 */
225 	struct list_head head;
226 
227 	/**
228 	 * @index: Position inside the mode_config.list, can be used as an array
229 	 * index. It is invariant over the lifetime of the colorop.
230 	 */
231 	unsigned int index;
232 
233 	/** @base: base mode object */
234 	struct drm_mode_object base;
235 
236 	/**
237 	 * @plane:
238 	 *
239 	 * The plane on which the colorop sits. A drm_colorop is always unique
240 	 * to a plane.
241 	 */
242 	struct drm_plane *plane;
243 
244 	/**
245 	 * @state:
246 	 *
247 	 * Current atomic state for this colorop.
248 	 *
249 	 * This is protected by @mutex. Note that nonblocking atomic commits
250 	 * access the current colorop state without taking locks.
251 	 */
252 	struct drm_colorop_state *state;
253 
254 	/*
255 	 * Color properties
256 	 *
257 	 * The following fields are not always valid, their usage depends
258 	 * on the colorop type. See their associated comment for more
259 	 * information.
260 	 */
261 
262 	/** @properties: property tracking for this colorop */
263 	struct drm_object_properties properties;
264 
265 	/**
266 	 * @type:
267 	 *
268 	 * Read-only
269 	 * Type of color operation
270 	 */
271 	enum drm_colorop_type type;
272 
273 	/**
274 	 * @next:
275 	 *
276 	 * Read-only
277 	 * Pointer to next drm_colorop in pipeline
278 	 */
279 	struct drm_colorop *next;
280 
281 	/**
282 	 * @type_property:
283 	 *
284 	 * Read-only "TYPE" property for specifying the type of
285 	 * this color operation. The type is enum drm_colorop_type.
286 	 */
287 	struct drm_property *type_property;
288 
289 	/**
290 	 * @bypass_property:
291 	 *
292 	 * Boolean property to control enablement of the color
293 	 * operation. Only present if DRM_COLOROP_FLAG_ALLOW_BYPASS
294 	 * flag is set. When present, setting bypass to "true" shall
295 	 * always be supported to allow compositors to quickly fall
296 	 * back to alternate methods of color processing. This is
297 	 * important since setting color operations can fail due to
298 	 * unique HW constraints.
299 	 */
300 	struct drm_property *bypass_property;
301 
302 	/**
303 	 * @size:
304 	 *
305 	 * Number of entries of the custom LUT. This should be read-only.
306 	 */
307 	uint32_t size;
308 
309 	/**
310 	 * @lut1d_interpolation:
311 	 *
312 	 * Read-only
313 	 * Interpolation for DRM_COLOROP_1D_LUT
314 	 */
315 	enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
316 
317 	/**
318 	 * @lut3d_interpolation:
319 	 *
320 	 * Read-only
321 	 * Interpolation for DRM_COLOROP_3D_LUT
322 	 */
323 	enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
324 
325 	/**
326 	 * @lut1d_interpolation_property:
327 	 *
328 	 * Read-only property for DRM_COLOROP_1D_LUT interpolation
329 	 */
330 	struct drm_property *lut1d_interpolation_property;
331 
332 	/**
333 	 * @curve_1d_type_property:
334 	 *
335 	 * Sub-type for DRM_COLOROP_1D_CURVE type.
336 	 */
337 	struct drm_property *curve_1d_type_property;
338 
339 	/**
340 	 * @multiplier_property:
341 	 *
342 	 * Multiplier property for plane gain
343 	 */
344 	struct drm_property *multiplier_property;
345 
346 	/**
347 	 * @size_property:
348 	 *
349 	 * Size property for custom LUT from userspace.
350 	 */
351 	struct drm_property *size_property;
352 
353 	/**
354 	 * @lut3d_interpolation_property:
355 	 *
356 	 * Read-only property for DRM_COLOROP_3D_LUT interpolation
357 	 */
358 	struct drm_property *lut3d_interpolation_property;
359 
360 	/**
361 	 * @data_property:
362 	 *
363 	 * blob property for any TYPE that requires a blob of data,
364 	 * such as 1DLUT, CTM, 3DLUT, etc.
365 	 *
366 	 * The way this blob is interpreted depends on the TYPE of
367 	 * this
368 	 */
369 	struct drm_property *data_property;
370 
371 	/**
372 	 * @next_property:
373 	 *
374 	 * Read-only property to next colorop in the pipeline
375 	 */
376 	struct drm_property *next_property;
377 
378 	/** @funcs: colorop control functions */
379 	const struct drm_colorop_funcs *funcs;
380 };
381 
382 #define obj_to_colorop(x) container_of(x, struct drm_colorop, base)
383 
384 /**
385  * drm_colorop_find - look up a Colorop object from its ID
386  * @dev: DRM device
387  * @file_priv: drm file to check for lease against.
388  * @id: &drm_mode_object ID
389  *
390  * This can be used to look up a Colorop from its userspace ID. Only used by
391  * drivers for legacy IOCTLs and interface, nowadays extensions to the KMS
392  * userspace interface should be done using &drm_property.
393  */
394 static inline struct drm_colorop *drm_colorop_find(struct drm_device *dev,
395 						   struct drm_file *file_priv,
396 						   uint32_t id)
397 {
398 	struct drm_mode_object *mo;
399 
400 	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_COLOROP);
401 	return mo ? obj_to_colorop(mo) : NULL;
402 }
403 
404 void drm_colorop_pipeline_destroy(struct drm_device *dev);
405 void drm_colorop_cleanup(struct drm_colorop *colorop);
406 
407 int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop,
408 				    struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
409 				    u64 supported_tfs, uint32_t flags);
410 int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop,
411 					struct drm_plane *plane,
412 					const struct drm_colorop_funcs *funcs,
413 					uint32_t lut_size,
414 					enum drm_colorop_lut1d_interpolation_type interpolation,
415 					uint32_t flags);
416 int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop,
417 				   struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
418 				   uint32_t flags);
419 int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop,
420 				struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
421 				uint32_t flags);
422 int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop,
423 				 struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
424 				 uint32_t lut_size,
425 				 enum drm_colorop_lut3d_interpolation_type interpolation,
426 				 uint32_t flags);
427 
428 struct drm_colorop_state *
429 drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
430 
431 void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
432 				      struct drm_colorop_state *state);
433 
434 /**
435  * drm_colorop_reset - reset colorop atomic state
436  * @colorop: drm colorop
437  *
438  * Resets the atomic state for @colorop by freeing the state pointer (which might
439  * be NULL, e.g. at driver load time) and allocating a new empty state object.
440  */
441 void drm_colorop_reset(struct drm_colorop *colorop);
442 
443 void drm_colorop_destroy(struct drm_colorop *colorop);
444 
445 /**
446  * drm_colorop_index - find the index of a registered colorop
447  * @colorop: colorop to find index for
448  *
449  * Given a registered colorop, return the index of that colorop within a DRM
450  * device's list of colorops.
451  */
452 static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop)
453 {
454 	return colorop->index;
455 }
456 
457 #define drm_for_each_colorop(colorop, dev) \
458 	list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head)
459 
460 /**
461  * drm_get_colorop_type_name - return a string for colorop type
462  * @type: colorop type to compute name of
463  *
464  * In contrast to the other drm_get_*_name functions this one here returns a
465  * const pointer and hence is threadsafe.
466  */
467 const char *drm_get_colorop_type_name(enum drm_colorop_type type);
468 
469 /**
470  * drm_get_colorop_curve_1d_type_name - return a string for 1D curve type
471  * @type: 1d curve type to compute name of
472  *
473  * In contrast to the other drm_get_*_name functions this one here returns a
474  * const pointer and hence is threadsafe.
475  */
476 const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type);
477 
478 const char *
479 drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type);
480 
481 const char *
482 drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
483 
484 void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
485 
486 #endif /* __DRM_COLOROP_H__ */
487