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