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