1 /* $NetBSD: intel_color.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $ */
2
3 /*
4 * Copyright © 2016 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: intel_color.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $");
29
30 #include "intel_color.h"
31 #include "intel_display_types.h"
32
33 #define CTM_COEFF_SIGN (1ULL << 63)
34
35 #define CTM_COEFF_1_0 (1ULL << 32)
36 #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1)
37 #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1)
38 #define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1)
39 #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1)
40 #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1)
41 #define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1)
42
43 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
44
45 #define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
46 #define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
47
48 #define LEGACY_LUT_LENGTH 256
49
50 /*
51 * ILK+ csc matrix:
52 *
53 * |R/Cr| | c0 c1 c2 | ( |R/Cr| |preoff0| ) |postoff0|
54 * |G/Y | = | c3 c4 c5 | x ( |G/Y | + |preoff1| ) + |postoff1|
55 * |B/Cb| | c6 c7 c8 | ( |B/Cb| |preoff2| ) |postoff2|
56 *
57 * ILK/SNB don't have explicit post offsets, and instead
58 * CSC_MODE_YUV_TO_RGB and CSC_BLACK_SCREEN_OFFSET are used:
59 * CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=0 -> 1/2, 0, 1/2
60 * CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/2, 1/16, 1/2
61 * CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=0 -> 0, 0, 0
62 * CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/16, 1/16, 1/16
63 */
64
65 /*
66 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
67 * format). This macro takes the coefficient we want transformed and the
68 * number of fractional bits.
69 *
70 * We only have a 9 bits precision window which slides depending on the value
71 * of the CTM coefficient and we write the value from bit 3. We also round the
72 * value.
73 */
74 #define ILK_CSC_COEFF_FP(coeff, fbits) \
75 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
76
77 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
78 #define ILK_CSC_COEFF_1_0 0x7800
79
80 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
81
82 /* Nop pre/post offsets */
83 static const u16 ilk_csc_off_zero[3] = {};
84
85 /* Identity matrix */
86 static const u16 ilk_csc_coeff_identity[9] = {
87 ILK_CSC_COEFF_1_0, 0, 0,
88 0, ILK_CSC_COEFF_1_0, 0,
89 0, 0, ILK_CSC_COEFF_1_0,
90 };
91
92 /* Limited range RGB post offsets */
93 static const u16 ilk_csc_postoff_limited_range[3] = {
94 ILK_CSC_POSTOFF_LIMITED_RANGE,
95 ILK_CSC_POSTOFF_LIMITED_RANGE,
96 ILK_CSC_POSTOFF_LIMITED_RANGE,
97 };
98
99 /* Full range RGB -> limited range RGB matrix */
100 static const u16 ilk_csc_coeff_limited_range[9] = {
101 ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
102 0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
103 0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
104 };
105
106 /* BT.709 full range RGB -> limited range YCbCr matrix */
107 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
108 0x1e08, 0x9cc0, 0xb528,
109 0x2ba8, 0x09d8, 0x37e8,
110 0xbce8, 0x9ad8, 0x1e08,
111 };
112
113 /* Limited range YCbCr post offsets */
114 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
115 0x0800, 0x0100, 0x0800,
116 };
117
lut_is_legacy(const struct drm_property_blob * lut)118 static bool lut_is_legacy(const struct drm_property_blob *lut)
119 {
120 return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
121 }
122
crtc_state_is_legacy_gamma(const struct intel_crtc_state * crtc_state)123 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
124 {
125 return !crtc_state->hw.degamma_lut &&
126 !crtc_state->hw.ctm &&
127 crtc_state->hw.gamma_lut &&
128 lut_is_legacy(crtc_state->hw.gamma_lut);
129 }
130
131 /*
132 * When using limited range, multiply the matrix given by userspace by
133 * the matrix that we would use for the limited range.
134 */
ctm_mult_by_limited(u64 * result,const u64 * input)135 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
136 {
137 int i;
138
139 for (i = 0; i < 9; i++) {
140 u64 user_coeff = input[i];
141 u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
142 u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
143 CTM_COEFF_4_0 - 1) >> 2;
144
145 /*
146 * By scaling every co-efficient with limited range (16-235)
147 * vs full range (0-255) the final o/p will be scaled down to
148 * fit in the limited range supported by the panel.
149 */
150 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
151 result[i] |= user_coeff & CTM_COEFF_SIGN;
152 }
153
154 return result;
155 }
156
ilk_update_pipe_csc(struct intel_crtc * crtc,const u16 preoff[3],const u16 coeff[9],const u16 postoff[3])157 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
158 const u16 preoff[3],
159 const u16 coeff[9],
160 const u16 postoff[3])
161 {
162 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
163 enum pipe pipe = crtc->pipe;
164
165 I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
166 I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
167 I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
168
169 I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
170 I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
171
172 I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
173 I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
174
175 I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
176 I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
177
178 if (INTEL_GEN(dev_priv) >= 7) {
179 I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff[0]);
180 I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff[1]);
181 I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff[2]);
182 }
183 }
184
icl_update_output_csc(struct intel_crtc * crtc,const u16 preoff[3],const u16 coeff[9],const u16 postoff[3])185 static void icl_update_output_csc(struct intel_crtc *crtc,
186 const u16 preoff[3],
187 const u16 coeff[9],
188 const u16 postoff[3])
189 {
190 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
191 enum pipe pipe = crtc->pipe;
192
193 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
194 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
195 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
196
197 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
198 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2] << 16);
199
200 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
201 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5] << 16);
202
203 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
204 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8] << 16);
205
206 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
207 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
208 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
209 }
210
ilk_csc_limited_range(const struct intel_crtc_state * crtc_state)211 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
212 {
213 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
214
215 /*
216 * FIXME if there's a gamma LUT after the CSC, we should
217 * do the range compression using the gamma LUT instead.
218 */
219 return crtc_state->limited_color_range &&
220 (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
221 IS_GEN_RANGE(dev_priv, 9, 10));
222 }
223
ilk_csc_convert_ctm(const struct intel_crtc_state * crtc_state,u16 coeffs[9])224 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
225 u16 coeffs[9])
226 {
227 const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
228 const u64 *input;
229 u64 temp[9];
230 int i;
231
232 if (ilk_csc_limited_range(crtc_state))
233 input = ctm_mult_by_limited(temp, ctm->matrix);
234 else
235 input = ctm->matrix;
236
237 /*
238 * Convert fixed point S31.32 input to format supported by the
239 * hardware.
240 */
241 for (i = 0; i < 9; i++) {
242 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
243
244 /*
245 * Clamp input value to min/max supported by
246 * hardware.
247 */
248 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
249
250 coeffs[i] = 0;
251
252 /* sign bit */
253 if (CTM_COEFF_NEGATIVE(input[i]))
254 coeffs[i] |= 1 << 15;
255
256 if (abs_coeff < CTM_COEFF_0_125)
257 coeffs[i] |= (3 << 12) |
258 ILK_CSC_COEFF_FP(abs_coeff, 12);
259 else if (abs_coeff < CTM_COEFF_0_25)
260 coeffs[i] |= (2 << 12) |
261 ILK_CSC_COEFF_FP(abs_coeff, 11);
262 else if (abs_coeff < CTM_COEFF_0_5)
263 coeffs[i] |= (1 << 12) |
264 ILK_CSC_COEFF_FP(abs_coeff, 10);
265 else if (abs_coeff < CTM_COEFF_1_0)
266 coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
267 else if (abs_coeff < CTM_COEFF_2_0)
268 coeffs[i] |= (7 << 12) |
269 ILK_CSC_COEFF_FP(abs_coeff, 8);
270 else
271 coeffs[i] |= (6 << 12) |
272 ILK_CSC_COEFF_FP(abs_coeff, 7);
273 }
274 }
275
ilk_load_csc_matrix(const struct intel_crtc_state * crtc_state)276 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
277 {
278 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
279 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
280 bool limited_color_range = ilk_csc_limited_range(crtc_state);
281
282 if (crtc_state->hw.ctm) {
283 u16 coeff[9];
284
285 ilk_csc_convert_ctm(crtc_state, coeff);
286 ilk_update_pipe_csc(crtc, ilk_csc_off_zero, coeff,
287 limited_color_range ?
288 ilk_csc_postoff_limited_range :
289 ilk_csc_off_zero);
290 } else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
291 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
292 ilk_csc_coeff_rgb_to_ycbcr,
293 ilk_csc_postoff_rgb_to_ycbcr);
294 } else if (limited_color_range) {
295 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
296 ilk_csc_coeff_limited_range,
297 ilk_csc_postoff_limited_range);
298 } else if (crtc_state->csc_enable) {
299 /*
300 * On GLK+ both pipe CSC and degamma LUT are controlled
301 * by csc_enable. Hence for the cases where the degama
302 * LUT is needed but CSC is not we need to load an
303 * identity matrix.
304 */
305 WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
306
307 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
308 ilk_csc_coeff_identity,
309 ilk_csc_off_zero);
310 }
311
312 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
313 }
314
icl_load_csc_matrix(const struct intel_crtc_state * crtc_state)315 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
316 {
317 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
318 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
319
320 if (crtc_state->hw.ctm) {
321 u16 coeff[9];
322
323 ilk_csc_convert_ctm(crtc_state, coeff);
324 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
325 coeff, ilk_csc_off_zero);
326 }
327
328 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
329 icl_update_output_csc(crtc, ilk_csc_off_zero,
330 ilk_csc_coeff_rgb_to_ycbcr,
331 ilk_csc_postoff_rgb_to_ycbcr);
332 } else if (crtc_state->limited_color_range) {
333 icl_update_output_csc(crtc, ilk_csc_off_zero,
334 ilk_csc_coeff_limited_range,
335 ilk_csc_postoff_limited_range);
336 }
337
338 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
339 }
340
341 /*
342 * Set up the pipe CSC unit on CherryView.
343 */
cherryview_load_csc_matrix(const struct intel_crtc_state * crtc_state)344 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
345 {
346 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
347 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
348 enum pipe pipe = crtc->pipe;
349
350 if (crtc_state->hw.ctm) {
351 const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
352 u16 coeffs[9] = {};
353 int i;
354
355 for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
356 u64 abs_coeff =
357 ((1ULL << 63) - 1) & ctm->matrix[i];
358
359 /* Round coefficient. */
360 abs_coeff += 1 << (32 - 13);
361 /* Clamp to hardware limits. */
362 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
363
364 /* Write coefficients in S3.12 format. */
365 if (ctm->matrix[i] & (1ULL << 63))
366 coeffs[i] = 1 << 15;
367 coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
368 coeffs[i] |= (abs_coeff >> 20) & 0xfff;
369 }
370
371 I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe),
372 coeffs[1] << 16 | coeffs[0]);
373 I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe),
374 coeffs[3] << 16 | coeffs[2]);
375 I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe),
376 coeffs[5] << 16 | coeffs[4]);
377 I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe),
378 coeffs[7] << 16 | coeffs[6]);
379 I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]);
380 }
381
382 I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
383 }
384
385 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
i965_lut_10p6_ldw(const struct drm_color_lut * color)386 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
387 {
388 return (color->red & 0xff) << 16 |
389 (color->green & 0xff) << 8 |
390 (color->blue & 0xff);
391 }
392
393 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
i965_lut_10p6_udw(const struct drm_color_lut * color)394 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
395 {
396 return (color->red >> 8) << 16 |
397 (color->green >> 8) << 8 |
398 (color->blue >> 8);
399 }
400
ilk_lut_10(const struct drm_color_lut * color)401 static u32 ilk_lut_10(const struct drm_color_lut *color)
402 {
403 return drm_color_lut_extract(color->red, 10) << 20 |
404 drm_color_lut_extract(color->green, 10) << 10 |
405 drm_color_lut_extract(color->blue, 10);
406 }
407
408 /* Loads the legacy palette/gamma unit for the CRTC. */
i9xx_load_luts_internal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob)409 static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
410 const struct drm_property_blob *blob)
411 {
412 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
413 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
414 enum pipe pipe = crtc->pipe;
415 int i;
416
417 if (HAS_GMCH(dev_priv)) {
418 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
419 assert_dsi_pll_enabled(dev_priv);
420 else
421 assert_pll_enabled(dev_priv, pipe);
422 }
423
424 if (blob) {
425 const struct drm_color_lut *lut = blob->data;
426
427 for (i = 0; i < 256; i++) {
428 u32 word =
429 (drm_color_lut_extract(lut[i].red, 8) << 16) |
430 (drm_color_lut_extract(lut[i].green, 8) << 8) |
431 drm_color_lut_extract(lut[i].blue, 8);
432
433 if (HAS_GMCH(dev_priv))
434 I915_WRITE(PALETTE(pipe, i), word);
435 else
436 I915_WRITE(LGC_PALETTE(pipe, i), word);
437 }
438 }
439 }
440
i9xx_load_luts(const struct intel_crtc_state * crtc_state)441 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
442 {
443 i9xx_load_luts_internal(crtc_state, crtc_state->hw.gamma_lut);
444 }
445
i9xx_color_commit(const struct intel_crtc_state * crtc_state)446 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
447 {
448 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
449 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
450 enum pipe pipe = crtc->pipe;
451 u32 val;
452
453 val = I915_READ(PIPECONF(pipe));
454 val &= ~PIPECONF_GAMMA_MODE_MASK_I9XX;
455 val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
456 I915_WRITE(PIPECONF(pipe), val);
457 }
458
ilk_color_commit(const struct intel_crtc_state * crtc_state)459 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
460 {
461 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
462 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
463 enum pipe pipe = crtc->pipe;
464 u32 val;
465
466 val = I915_READ(PIPECONF(pipe));
467 val &= ~PIPECONF_GAMMA_MODE_MASK_ILK;
468 val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
469 I915_WRITE(PIPECONF(pipe), val);
470
471 ilk_load_csc_matrix(crtc_state);
472 }
473
hsw_color_commit(const struct intel_crtc_state * crtc_state)474 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
475 {
476 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
477 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
478
479 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
480
481 ilk_load_csc_matrix(crtc_state);
482 }
483
skl_color_commit(const struct intel_crtc_state * crtc_state)484 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
485 {
486 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
487 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
488 enum pipe pipe = crtc->pipe;
489 u32 val = 0;
490
491 /*
492 * We don't (yet) allow userspace to control the pipe background color,
493 * so force it to black, but apply pipe gamma and CSC appropriately
494 * so that its handling will match how we program our planes.
495 */
496 if (crtc_state->gamma_enable)
497 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
498 if (crtc_state->csc_enable)
499 val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
500 I915_WRITE(SKL_BOTTOM_COLOR(pipe), val);
501
502 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
503
504 if (INTEL_GEN(dev_priv) >= 11)
505 icl_load_csc_matrix(crtc_state);
506 else
507 ilk_load_csc_matrix(crtc_state);
508 }
509
i965_load_lut_10p6(struct intel_crtc * crtc,const struct drm_property_blob * blob)510 static void i965_load_lut_10p6(struct intel_crtc *crtc,
511 const struct drm_property_blob *blob)
512 {
513 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
514 const struct drm_color_lut *lut = blob->data;
515 int i, lut_size = drm_color_lut_size(blob);
516 enum pipe pipe = crtc->pipe;
517
518 for (i = 0; i < lut_size - 1; i++) {
519 I915_WRITE(PALETTE(pipe, 2 * i + 0),
520 i965_lut_10p6_ldw(&lut[i]));
521 I915_WRITE(PALETTE(pipe, 2 * i + 1),
522 i965_lut_10p6_udw(&lut[i]));
523 }
524
525 I915_WRITE(PIPEGCMAX(pipe, 0), lut[i].red);
526 I915_WRITE(PIPEGCMAX(pipe, 1), lut[i].green);
527 I915_WRITE(PIPEGCMAX(pipe, 2), lut[i].blue);
528 }
529
i965_load_luts(const struct intel_crtc_state * crtc_state)530 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
531 {
532 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
533 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
534
535 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
536 i9xx_load_luts(crtc_state);
537 else
538 i965_load_lut_10p6(crtc, gamma_lut);
539 }
540
ilk_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob)541 static void ilk_load_lut_10(struct intel_crtc *crtc,
542 const struct drm_property_blob *blob)
543 {
544 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
545 const struct drm_color_lut *lut = blob->data;
546 int i, lut_size = drm_color_lut_size(blob);
547 enum pipe pipe = crtc->pipe;
548
549 for (i = 0; i < lut_size; i++)
550 I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
551 }
552
ilk_load_luts(const struct intel_crtc_state * crtc_state)553 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
554 {
555 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
556 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
557
558 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
559 i9xx_load_luts(crtc_state);
560 else
561 ilk_load_lut_10(crtc, gamma_lut);
562 }
563
ivb_lut_10_size(u32 prec_index)564 static int ivb_lut_10_size(u32 prec_index)
565 {
566 if (prec_index & PAL_PREC_SPLIT_MODE)
567 return 512;
568 else
569 return 1024;
570 }
571
572 /*
573 * IVB/HSW Bspec / PAL_PREC_INDEX:
574 * "Restriction : Index auto increment mode is not
575 * supported and must not be enabled."
576 */
ivb_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob,u32 prec_index)577 static void ivb_load_lut_10(struct intel_crtc *crtc,
578 const struct drm_property_blob *blob,
579 u32 prec_index)
580 {
581 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
582 int hw_lut_size = ivb_lut_10_size(prec_index);
583 const struct drm_color_lut *lut = blob->data;
584 int i, lut_size = drm_color_lut_size(blob);
585 enum pipe pipe = crtc->pipe;
586
587 for (i = 0; i < hw_lut_size; i++) {
588 /* We discard half the user entries in split gamma mode */
589 const struct drm_color_lut *entry =
590 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
591
592 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
593 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
594 }
595
596 /*
597 * Reset the index, otherwise it prevents the legacy palette to be
598 * written properly.
599 */
600 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
601 }
602
603 /* On BDW+ the index auto increment mode actually works */
bdw_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob,u32 prec_index)604 static void bdw_load_lut_10(struct intel_crtc *crtc,
605 const struct drm_property_blob *blob,
606 u32 prec_index)
607 {
608 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
609 int hw_lut_size = ivb_lut_10_size(prec_index);
610 const struct drm_color_lut *lut = blob->data;
611 int i, lut_size = drm_color_lut_size(blob);
612 enum pipe pipe = crtc->pipe;
613
614 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
615 PAL_PREC_AUTO_INCREMENT);
616
617 for (i = 0; i < hw_lut_size; i++) {
618 /* We discard half the user entries in split gamma mode */
619 const struct drm_color_lut *entry =
620 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
621
622 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
623 }
624
625 /*
626 * Reset the index, otherwise it prevents the legacy palette to be
627 * written properly.
628 */
629 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
630 }
631
ivb_load_lut_ext_max(struct intel_crtc * crtc)632 static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
633 {
634 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
635 struct intel_dsb *dsb = intel_dsb_get(crtc);
636 enum pipe pipe = crtc->pipe;
637
638 /* Program the max register to clamp values > 1.0. */
639 intel_dsb_reg_write(dsb, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
640 intel_dsb_reg_write(dsb, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
641 intel_dsb_reg_write(dsb, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
642
643 /*
644 * Program the gc max 2 register to clamp values > 1.0.
645 * ToDo: Extend the ABI to be able to program values
646 * from 3.0 to 7.0
647 */
648 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
649 intel_dsb_reg_write(dsb, PREC_PAL_EXT2_GC_MAX(pipe, 0),
650 1 << 16);
651 intel_dsb_reg_write(dsb, PREC_PAL_EXT2_GC_MAX(pipe, 1),
652 1 << 16);
653 intel_dsb_reg_write(dsb, PREC_PAL_EXT2_GC_MAX(pipe, 2),
654 1 << 16);
655 }
656
657 intel_dsb_put(dsb);
658 }
659
ivb_load_luts(const struct intel_crtc_state * crtc_state)660 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
661 {
662 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
663 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
664 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
665
666 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
667 i9xx_load_luts(crtc_state);
668 } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
669 ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
670 PAL_PREC_INDEX_VALUE(0));
671 ivb_load_lut_ext_max(crtc);
672 ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
673 PAL_PREC_INDEX_VALUE(512));
674 } else {
675 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
676
677 ivb_load_lut_10(crtc, blob,
678 PAL_PREC_INDEX_VALUE(0));
679 ivb_load_lut_ext_max(crtc);
680 }
681 }
682
bdw_load_luts(const struct intel_crtc_state * crtc_state)683 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
684 {
685 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
686 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
687 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
688
689 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
690 i9xx_load_luts(crtc_state);
691 } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
692 bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
693 PAL_PREC_INDEX_VALUE(0));
694 ivb_load_lut_ext_max(crtc);
695 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
696 PAL_PREC_INDEX_VALUE(512));
697 } else {
698 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
699
700 bdw_load_lut_10(crtc, blob,
701 PAL_PREC_INDEX_VALUE(0));
702 ivb_load_lut_ext_max(crtc);
703 }
704 }
705
glk_load_degamma_lut(const struct intel_crtc_state * crtc_state)706 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
707 {
708 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
709 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
710 enum pipe pipe = crtc->pipe;
711 const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
712 const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
713 u32 i;
714
715 /*
716 * When setting the auto-increment bit, the hardware seems to
717 * ignore the index bits, so we need to reset it to index 0
718 * separately.
719 */
720 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
721 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
722
723 for (i = 0; i < lut_size; i++) {
724 /*
725 * First 33 entries represent range from 0 to 1.0
726 * 34th and 35th entry will represent extended range
727 * inputs 3.0 and 7.0 respectively, currently clamped
728 * at 1.0. Since the precision is 16bit, the user
729 * value can be directly filled to register.
730 * The pipe degamma table in GLK+ onwards doesn't
731 * support different values per channel, so this just
732 * programs green value which will be equal to Red and
733 * Blue into the lut registers.
734 * ToDo: Extend to max 7.0. Enable 32 bit input value
735 * as compared to just 16 to achieve this.
736 */
737 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
738 }
739
740 /* Clamp values > 1.0. */
741 while (i++ < 35)
742 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
743 }
744
glk_load_degamma_lut_linear(const struct intel_crtc_state * crtc_state)745 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
746 {
747 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
748 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
749 enum pipe pipe = crtc->pipe;
750 const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
751 u32 i;
752
753 /*
754 * When setting the auto-increment bit, the hardware seems to
755 * ignore the index bits, so we need to reset it to index 0
756 * separately.
757 */
758 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
759 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
760
761 for (i = 0; i < lut_size; i++) {
762 u32 v = (i << 16) / (lut_size - 1);
763
764 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
765 }
766
767 /* Clamp values > 1.0. */
768 while (i++ < 35)
769 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
770 }
771
glk_load_luts(const struct intel_crtc_state * crtc_state)772 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
773 {
774 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
775 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
776
777 /*
778 * On GLK+ both pipe CSC and degamma LUT are controlled
779 * by csc_enable. Hence for the cases where the CSC is
780 * needed but degamma LUT is not we need to load a
781 * linear degamma LUT. In fact we'll just always load
782 * the degama LUT so that we don't have to reload
783 * it every time the pipe CSC is being enabled.
784 */
785 if (crtc_state->hw.degamma_lut)
786 glk_load_degamma_lut(crtc_state);
787 else
788 glk_load_degamma_lut_linear(crtc_state);
789
790 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
791 i9xx_load_luts(crtc_state);
792 } else {
793 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
794 ivb_load_lut_ext_max(crtc);
795 }
796 }
797
798 /* ilk+ "12.4" interpolated format (high 10 bits) */
ilk_lut_12p4_udw(const struct drm_color_lut * color)799 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
800 {
801 return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
802 (color->blue >> 6);
803 }
804
805 /* ilk+ "12.4" interpolated format (low 6 bits) */
ilk_lut_12p4_ldw(const struct drm_color_lut * color)806 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
807 {
808 return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
809 (color->blue & 0x3f) << 4;
810 }
811
812 static void
icl_load_gcmax(const struct intel_crtc_state * crtc_state,const struct drm_color_lut * color)813 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
814 const struct drm_color_lut *color)
815 {
816 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
817 struct intel_dsb *dsb = intel_dsb_get(crtc);
818 enum pipe pipe = crtc->pipe;
819
820 /* Fixme: LUT entries are 16 bit only, so we can prog 0xFFFF max */
821 intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 0), color->red);
822 intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 1), color->green);
823 intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 2), color->blue);
824 intel_dsb_put(dsb);
825 }
826
827 static void
icl_program_gamma_superfine_segment(const struct intel_crtc_state * crtc_state)828 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
829 {
830 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
831 const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
832 const struct drm_color_lut *lut = blob->data;
833 struct intel_dsb *dsb = intel_dsb_get(crtc);
834 enum pipe pipe = crtc->pipe;
835 u32 i;
836
837 /*
838 * Program Super Fine segment (let's call it seg1)...
839 *
840 * Super Fine segment's step is 1/(8 * 128 * 256) and it has
841 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256),
842 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256).
843 */
844 intel_dsb_reg_write(dsb, PREC_PAL_MULTI_SEG_INDEX(pipe),
845 PAL_PREC_AUTO_INCREMENT);
846
847 for (i = 0; i < 9; i++) {
848 const struct drm_color_lut *entry = &lut[i];
849
850 intel_dsb_indexed_reg_write(dsb, PREC_PAL_MULTI_SEG_DATA(pipe),
851 ilk_lut_12p4_ldw(entry));
852 intel_dsb_indexed_reg_write(dsb, PREC_PAL_MULTI_SEG_DATA(pipe),
853 ilk_lut_12p4_udw(entry));
854 }
855
856 intel_dsb_put(dsb);
857 }
858
859 static void
icl_program_gamma_multi_segment(const struct intel_crtc_state * crtc_state)860 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
861 {
862 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
863 const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
864 const struct drm_color_lut *lut = blob->data;
865 const struct drm_color_lut *entry;
866 struct intel_dsb *dsb = intel_dsb_get(crtc);
867 enum pipe pipe = crtc->pipe;
868 u32 i;
869
870 /*
871 * Program Fine segment (let's call it seg2)...
872 *
873 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256)
874 * ... 256/(128 * 256). So in order to program fine segment of LUT we
875 * need to pick every 8th entry in the LUT, and program 256 indexes.
876 *
877 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
878 * seg2[0] being unused by the hardware.
879 */
880 intel_dsb_reg_write(dsb, PREC_PAL_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
881 for (i = 1; i < 257; i++) {
882 entry = &lut[i * 8];
883 intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
884 ilk_lut_12p4_ldw(entry));
885 intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
886 ilk_lut_12p4_udw(entry));
887 }
888
889 /*
890 * Program Coarse segment (let's call it seg3)...
891 *
892 * Coarse segment starts from index 0 and it's step is 1/256 ie 0,
893 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT
894 * above, we need to pick every (8 * 128)th entry in LUT, and
895 * program 256 of those.
896 *
897 * Spec is not very clear about if entries seg3[0] and seg3[1] are
898 * being used or not, but we still need to program these to advance
899 * the index.
900 */
901 for (i = 0; i < 256; i++) {
902 entry = &lut[i * 8 * 128];
903 intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
904 ilk_lut_12p4_ldw(entry));
905 intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
906 ilk_lut_12p4_udw(entry));
907 }
908
909 /* The last entry in the LUT is to be programmed in GCMAX */
910 entry = &lut[256 * 8 * 128];
911 icl_load_gcmax(crtc_state, entry);
912 ivb_load_lut_ext_max(crtc);
913 intel_dsb_put(dsb);
914 }
915
icl_load_luts(const struct intel_crtc_state * crtc_state)916 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
917 {
918 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
919 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
920 struct intel_dsb *dsb = intel_dsb_get(crtc);
921
922 if (crtc_state->hw.degamma_lut)
923 glk_load_degamma_lut(crtc_state);
924
925 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
926 case GAMMA_MODE_MODE_8BIT:
927 i9xx_load_luts(crtc_state);
928 break;
929 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
930 icl_program_gamma_superfine_segment(crtc_state);
931 icl_program_gamma_multi_segment(crtc_state);
932 break;
933 default:
934 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
935 ivb_load_lut_ext_max(crtc);
936 }
937
938 intel_dsb_commit(dsb);
939 intel_dsb_put(dsb);
940 }
941
chv_cgm_degamma_ldw(const struct drm_color_lut * color)942 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
943 {
944 return drm_color_lut_extract(color->green, 14) << 16 |
945 drm_color_lut_extract(color->blue, 14);
946 }
947
chv_cgm_degamma_udw(const struct drm_color_lut * color)948 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
949 {
950 return drm_color_lut_extract(color->red, 14);
951 }
952
chv_load_cgm_degamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)953 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
954 const struct drm_property_blob *blob)
955 {
956 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
957 const struct drm_color_lut *lut = blob->data;
958 int i, lut_size = drm_color_lut_size(blob);
959 enum pipe pipe = crtc->pipe;
960
961 for (i = 0; i < lut_size; i++) {
962 I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0),
963 chv_cgm_degamma_ldw(&lut[i]));
964 I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1),
965 chv_cgm_degamma_udw(&lut[i]));
966 }
967 }
968
chv_cgm_gamma_ldw(const struct drm_color_lut * color)969 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
970 {
971 return drm_color_lut_extract(color->green, 10) << 16 |
972 drm_color_lut_extract(color->blue, 10);
973 }
974
chv_cgm_gamma_udw(const struct drm_color_lut * color)975 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
976 {
977 return drm_color_lut_extract(color->red, 10);
978 }
979
chv_load_cgm_gamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)980 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
981 const struct drm_property_blob *blob)
982 {
983 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
984 const struct drm_color_lut *lut = blob->data;
985 int i, lut_size = drm_color_lut_size(blob);
986 enum pipe pipe = crtc->pipe;
987
988 for (i = 0; i < lut_size; i++) {
989 I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0),
990 chv_cgm_gamma_ldw(&lut[i]));
991 I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1),
992 chv_cgm_gamma_udw(&lut[i]));
993 }
994 }
995
chv_load_luts(const struct intel_crtc_state * crtc_state)996 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
997 {
998 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
999 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1000 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
1001
1002 cherryview_load_csc_matrix(crtc_state);
1003
1004 if (crtc_state_is_legacy_gamma(crtc_state)) {
1005 i9xx_load_luts(crtc_state);
1006 return;
1007 }
1008
1009 if (degamma_lut)
1010 chv_load_cgm_degamma(crtc, degamma_lut);
1011
1012 if (gamma_lut)
1013 chv_load_cgm_gamma(crtc, gamma_lut);
1014 }
1015
intel_color_load_luts(const struct intel_crtc_state * crtc_state)1016 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
1017 {
1018 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1019
1020 dev_priv->display.load_luts(crtc_state);
1021 }
1022
intel_color_commit(const struct intel_crtc_state * crtc_state)1023 void intel_color_commit(const struct intel_crtc_state *crtc_state)
1024 {
1025 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1026
1027 dev_priv->display.color_commit(crtc_state);
1028 }
1029
intel_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1030 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1031 {
1032 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1033 struct intel_atomic_state *state =
1034 to_intel_atomic_state(new_crtc_state->uapi.state);
1035 const struct intel_crtc_state *old_crtc_state =
1036 intel_atomic_get_old_crtc_state(state, crtc);
1037
1038 return !old_crtc_state->hw.gamma_lut &&
1039 !old_crtc_state->hw.degamma_lut;
1040 }
1041
chv_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1042 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1043 {
1044 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1045 struct intel_atomic_state *state =
1046 to_intel_atomic_state(new_crtc_state->uapi.state);
1047 const struct intel_crtc_state *old_crtc_state =
1048 intel_atomic_get_old_crtc_state(state, crtc);
1049
1050 /*
1051 * CGM_PIPE_MODE is itself single buffered. We'd have to
1052 * somehow split it out from chv_load_luts() if we wanted
1053 * the ability to preload the CGM LUTs/CSC without tearing.
1054 */
1055 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1056 return false;
1057
1058 return !old_crtc_state->hw.gamma_lut;
1059 }
1060
glk_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1061 static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1062 {
1063 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1064 struct intel_atomic_state *state =
1065 to_intel_atomic_state(new_crtc_state->uapi.state);
1066 const struct intel_crtc_state *old_crtc_state =
1067 intel_atomic_get_old_crtc_state(state, crtc);
1068
1069 /*
1070 * The hardware degamma is active whenever the pipe
1071 * CSC is active. Thus even if the old state has no
1072 * software degamma we need to avoid clobbering the
1073 * linear hardware degamma mid scanout.
1074 */
1075 return !old_crtc_state->csc_enable &&
1076 !old_crtc_state->hw.gamma_lut;
1077 }
1078
intel_color_check(struct intel_crtc_state * crtc_state)1079 int intel_color_check(struct intel_crtc_state *crtc_state)
1080 {
1081 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1082
1083 return dev_priv->display.color_check(crtc_state);
1084 }
1085
intel_color_get_config(struct intel_crtc_state * crtc_state)1086 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1087 {
1088 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1089
1090 if (dev_priv->display.read_luts)
1091 dev_priv->display.read_luts(crtc_state);
1092 }
1093
need_plane_update(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)1094 static bool need_plane_update(struct intel_plane *plane,
1095 const struct intel_crtc_state *crtc_state)
1096 {
1097 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1098
1099 /*
1100 * On pre-SKL the pipe gamma enable and pipe csc enable for
1101 * the pipe bottom color are configured via the primary plane.
1102 * We have to reconfigure that even if the plane is inactive.
1103 */
1104 return crtc_state->active_planes & BIT(plane->id) ||
1105 (INTEL_GEN(dev_priv) < 9 &&
1106 plane->id == PLANE_PRIMARY);
1107 }
1108
1109 static int
intel_color_add_affected_planes(struct intel_crtc_state * new_crtc_state)1110 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1111 {
1112 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1113 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1114 struct intel_atomic_state *state =
1115 to_intel_atomic_state(new_crtc_state->uapi.state);
1116 const struct intel_crtc_state *old_crtc_state =
1117 intel_atomic_get_old_crtc_state(state, crtc);
1118 struct intel_plane *plane;
1119
1120 if (!new_crtc_state->hw.active ||
1121 drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
1122 return 0;
1123
1124 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1125 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1126 return 0;
1127
1128 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
1129 struct intel_plane_state *plane_state;
1130
1131 if (!need_plane_update(plane, new_crtc_state))
1132 continue;
1133
1134 plane_state = intel_atomic_get_plane_state(state, plane);
1135 if (IS_ERR(plane_state))
1136 return PTR_ERR(plane_state);
1137
1138 new_crtc_state->update_planes |= BIT(plane->id);
1139 }
1140
1141 return 0;
1142 }
1143
check_lut_size(const struct drm_property_blob * lut,int expected)1144 static int check_lut_size(const struct drm_property_blob *lut, int expected)
1145 {
1146 int len;
1147
1148 if (!lut)
1149 return 0;
1150
1151 len = drm_color_lut_size(lut);
1152 if (len != expected) {
1153 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1154 len, expected);
1155 return -EINVAL;
1156 }
1157
1158 return 0;
1159 }
1160
check_luts(const struct intel_crtc_state * crtc_state)1161 static int check_luts(const struct intel_crtc_state *crtc_state)
1162 {
1163 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1164 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1165 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
1166 int gamma_length, degamma_length;
1167 u32 gamma_tests, degamma_tests;
1168
1169 /* Always allow legacy gamma LUT with no further checking. */
1170 if (crtc_state_is_legacy_gamma(crtc_state))
1171 return 0;
1172
1173 /* C8 relies on its palette being stored in the legacy LUT */
1174 if (crtc_state->c8_planes) {
1175 DRM_DEBUG_KMS("C8 pixelformat requires the legacy LUT\n");
1176 return -EINVAL;
1177 }
1178
1179 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
1180 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1181 degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
1182 gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
1183
1184 if (check_lut_size(degamma_lut, degamma_length) ||
1185 check_lut_size(gamma_lut, gamma_length))
1186 return -EINVAL;
1187
1188 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
1189 drm_color_lut_check(gamma_lut, gamma_tests))
1190 return -EINVAL;
1191
1192 return 0;
1193 }
1194
i9xx_gamma_mode(struct intel_crtc_state * crtc_state)1195 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
1196 {
1197 if (!crtc_state->gamma_enable ||
1198 crtc_state_is_legacy_gamma(crtc_state))
1199 return GAMMA_MODE_MODE_8BIT;
1200 else
1201 return GAMMA_MODE_MODE_10BIT; /* i965+ only */
1202 }
1203
i9xx_color_check(struct intel_crtc_state * crtc_state)1204 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1205 {
1206 int ret;
1207
1208 ret = check_luts(crtc_state);
1209 if (ret)
1210 return ret;
1211
1212 crtc_state->gamma_enable =
1213 crtc_state->hw.gamma_lut &&
1214 !crtc_state->c8_planes;
1215
1216 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1217
1218 ret = intel_color_add_affected_planes(crtc_state);
1219 if (ret)
1220 return ret;
1221
1222 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1223
1224 return 0;
1225 }
1226
chv_cgm_mode(const struct intel_crtc_state * crtc_state)1227 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1228 {
1229 u32 cgm_mode = 0;
1230
1231 if (crtc_state_is_legacy_gamma(crtc_state))
1232 return 0;
1233
1234 if (crtc_state->hw.degamma_lut)
1235 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1236 if (crtc_state->hw.ctm)
1237 cgm_mode |= CGM_PIPE_MODE_CSC;
1238 if (crtc_state->hw.gamma_lut)
1239 cgm_mode |= CGM_PIPE_MODE_GAMMA;
1240
1241 return cgm_mode;
1242 }
1243
1244 /*
1245 * CHV color pipeline:
1246 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
1247 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
1248 *
1249 * We always bypass the WGC csc and use the CGM csc
1250 * instead since it has degamma and better precision.
1251 */
chv_color_check(struct intel_crtc_state * crtc_state)1252 static int chv_color_check(struct intel_crtc_state *crtc_state)
1253 {
1254 int ret;
1255
1256 ret = check_luts(crtc_state);
1257 if (ret)
1258 return ret;
1259
1260 /*
1261 * Pipe gamma will be used only for the legacy LUT.
1262 * Otherwise we bypass it and use the CGM gamma instead.
1263 */
1264 crtc_state->gamma_enable =
1265 crtc_state_is_legacy_gamma(crtc_state) &&
1266 !crtc_state->c8_planes;
1267
1268 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1269
1270 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1271
1272 ret = intel_color_add_affected_planes(crtc_state);
1273 if (ret)
1274 return ret;
1275
1276 crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
1277
1278 return 0;
1279 }
1280
ilk_gamma_mode(const struct intel_crtc_state * crtc_state)1281 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1282 {
1283 if (!crtc_state->gamma_enable ||
1284 crtc_state_is_legacy_gamma(crtc_state))
1285 return GAMMA_MODE_MODE_8BIT;
1286 else
1287 return GAMMA_MODE_MODE_10BIT;
1288 }
1289
ilk_csc_mode(const struct intel_crtc_state * crtc_state)1290 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
1291 {
1292 /*
1293 * CSC comes after the LUT in RGB->YCbCr mode.
1294 * RGB->YCbCr needs the limited range offsets added to
1295 * the output. RGB limited range output is handled by
1296 * the hw automagically elsewhere.
1297 */
1298 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
1299 return CSC_BLACK_SCREEN_OFFSET;
1300
1301 return CSC_MODE_YUV_TO_RGB |
1302 CSC_POSITION_BEFORE_GAMMA;
1303 }
1304
ilk_color_check(struct intel_crtc_state * crtc_state)1305 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1306 {
1307 int ret;
1308
1309 ret = check_luts(crtc_state);
1310 if (ret)
1311 return ret;
1312
1313 crtc_state->gamma_enable =
1314 crtc_state->hw.gamma_lut &&
1315 !crtc_state->c8_planes;
1316
1317 /*
1318 * We don't expose the ctm on ilk/snb currently, also RGB
1319 * limited range output is handled by the hw automagically.
1320 */
1321 crtc_state->csc_enable =
1322 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
1323
1324 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1325
1326 crtc_state->csc_mode = ilk_csc_mode(crtc_state);
1327
1328 ret = intel_color_add_affected_planes(crtc_state);
1329 if (ret)
1330 return ret;
1331
1332 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1333
1334 return 0;
1335 }
1336
ivb_gamma_mode(const struct intel_crtc_state * crtc_state)1337 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1338 {
1339 if (!crtc_state->gamma_enable ||
1340 crtc_state_is_legacy_gamma(crtc_state))
1341 return GAMMA_MODE_MODE_8BIT;
1342 else if (crtc_state->hw.gamma_lut &&
1343 crtc_state->hw.degamma_lut)
1344 return GAMMA_MODE_MODE_SPLIT;
1345 else
1346 return GAMMA_MODE_MODE_10BIT;
1347 }
1348
ivb_csc_mode(const struct intel_crtc_state * crtc_state)1349 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1350 {
1351 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1352
1353 /*
1354 * CSC comes after the LUT in degamma, RGB->YCbCr,
1355 * and RGB full->limited range mode.
1356 */
1357 if (crtc_state->hw.degamma_lut ||
1358 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1359 limited_color_range)
1360 return 0;
1361
1362 return CSC_POSITION_BEFORE_GAMMA;
1363 }
1364
ivb_color_check(struct intel_crtc_state * crtc_state)1365 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1366 {
1367 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1368 int ret;
1369
1370 ret = check_luts(crtc_state);
1371 if (ret)
1372 return ret;
1373
1374 crtc_state->gamma_enable =
1375 (crtc_state->hw.gamma_lut ||
1376 crtc_state->hw.degamma_lut) &&
1377 !crtc_state->c8_planes;
1378
1379 crtc_state->csc_enable =
1380 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1381 crtc_state->hw.ctm || limited_color_range;
1382
1383 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1384
1385 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1386
1387 ret = intel_color_add_affected_planes(crtc_state);
1388 if (ret)
1389 return ret;
1390
1391 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1392
1393 return 0;
1394 }
1395
glk_gamma_mode(const struct intel_crtc_state * crtc_state)1396 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1397 {
1398 if (!crtc_state->gamma_enable ||
1399 crtc_state_is_legacy_gamma(crtc_state))
1400 return GAMMA_MODE_MODE_8BIT;
1401 else
1402 return GAMMA_MODE_MODE_10BIT;
1403 }
1404
glk_color_check(struct intel_crtc_state * crtc_state)1405 static int glk_color_check(struct intel_crtc_state *crtc_state)
1406 {
1407 int ret;
1408
1409 ret = check_luts(crtc_state);
1410 if (ret)
1411 return ret;
1412
1413 crtc_state->gamma_enable =
1414 crtc_state->hw.gamma_lut &&
1415 !crtc_state->c8_planes;
1416
1417 /* On GLK+ degamma LUT is controlled by csc_enable */
1418 crtc_state->csc_enable =
1419 crtc_state->hw.degamma_lut ||
1420 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1421 crtc_state->hw.ctm || crtc_state->limited_color_range;
1422
1423 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1424
1425 crtc_state->csc_mode = 0;
1426
1427 ret = intel_color_add_affected_planes(crtc_state);
1428 if (ret)
1429 return ret;
1430
1431 crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
1432
1433 return 0;
1434 }
1435
icl_gamma_mode(const struct intel_crtc_state * crtc_state)1436 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1437 {
1438 u32 gamma_mode = 0;
1439
1440 if (crtc_state->hw.degamma_lut)
1441 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1442
1443 if (crtc_state->hw.gamma_lut &&
1444 !crtc_state->c8_planes)
1445 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1446
1447 if (!crtc_state->hw.gamma_lut ||
1448 crtc_state_is_legacy_gamma(crtc_state))
1449 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1450 else
1451 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
1452
1453 return gamma_mode;
1454 }
1455
icl_csc_mode(const struct intel_crtc_state * crtc_state)1456 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1457 {
1458 u32 csc_mode = 0;
1459
1460 if (crtc_state->hw.ctm)
1461 csc_mode |= ICL_CSC_ENABLE;
1462
1463 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1464 crtc_state->limited_color_range)
1465 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1466
1467 return csc_mode;
1468 }
1469
icl_color_check(struct intel_crtc_state * crtc_state)1470 static int icl_color_check(struct intel_crtc_state *crtc_state)
1471 {
1472 int ret;
1473
1474 ret = check_luts(crtc_state);
1475 if (ret)
1476 return ret;
1477
1478 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1479
1480 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1481
1482 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1483
1484 return 0;
1485 }
1486
i9xx_gamma_precision(const struct intel_crtc_state * crtc_state)1487 static int i9xx_gamma_precision(const struct intel_crtc_state *crtc_state)
1488 {
1489 if (!crtc_state->gamma_enable)
1490 return 0;
1491
1492 switch (crtc_state->gamma_mode) {
1493 case GAMMA_MODE_MODE_8BIT:
1494 return 8;
1495 case GAMMA_MODE_MODE_10BIT:
1496 return 16;
1497 default:
1498 MISSING_CASE(crtc_state->gamma_mode);
1499 return 0;
1500 }
1501 }
1502
ilk_gamma_precision(const struct intel_crtc_state * crtc_state)1503 static int ilk_gamma_precision(const struct intel_crtc_state *crtc_state)
1504 {
1505 if (!crtc_state->gamma_enable)
1506 return 0;
1507
1508 if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
1509 return 0;
1510
1511 switch (crtc_state->gamma_mode) {
1512 case GAMMA_MODE_MODE_8BIT:
1513 return 8;
1514 case GAMMA_MODE_MODE_10BIT:
1515 return 10;
1516 default:
1517 MISSING_CASE(crtc_state->gamma_mode);
1518 return 0;
1519 }
1520 }
1521
chv_gamma_precision(const struct intel_crtc_state * crtc_state)1522 static int chv_gamma_precision(const struct intel_crtc_state *crtc_state)
1523 {
1524 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1525 return 10;
1526 else
1527 return i9xx_gamma_precision(crtc_state);
1528 }
1529
glk_gamma_precision(const struct intel_crtc_state * crtc_state)1530 static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
1531 {
1532 if (!crtc_state->gamma_enable)
1533 return 0;
1534
1535 switch (crtc_state->gamma_mode) {
1536 case GAMMA_MODE_MODE_8BIT:
1537 return 8;
1538 case GAMMA_MODE_MODE_10BIT:
1539 return 10;
1540 default:
1541 MISSING_CASE(crtc_state->gamma_mode);
1542 return 0;
1543 }
1544 }
1545
intel_color_get_gamma_bit_precision(const struct intel_crtc_state * crtc_state)1546 int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
1547 {
1548 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1549 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1550
1551 if (HAS_GMCH(dev_priv)) {
1552 if (IS_CHERRYVIEW(dev_priv))
1553 return chv_gamma_precision(crtc_state);
1554 else
1555 return i9xx_gamma_precision(crtc_state);
1556 } else {
1557 if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
1558 return glk_gamma_precision(crtc_state);
1559 else if (IS_IRONLAKE(dev_priv))
1560 return ilk_gamma_precision(crtc_state);
1561 }
1562
1563 return 0;
1564 }
1565
err_check(struct drm_color_lut * lut1,struct drm_color_lut * lut2,u32 err)1566 static bool err_check(struct drm_color_lut *lut1,
1567 struct drm_color_lut *lut2, u32 err)
1568 {
1569 return ((abs((long)lut2->red - lut1->red)) <= err) &&
1570 ((abs((long)lut2->blue - lut1->blue)) <= err) &&
1571 ((abs((long)lut2->green - lut1->green)) <= err);
1572 }
1573
intel_color_lut_entry_equal(struct drm_color_lut * lut1,struct drm_color_lut * lut2,int lut_size,u32 err)1574 static bool intel_color_lut_entry_equal(struct drm_color_lut *lut1,
1575 struct drm_color_lut *lut2,
1576 int lut_size, u32 err)
1577 {
1578 int i;
1579
1580 for (i = 0; i < lut_size; i++) {
1581 if (!err_check(&lut1[i], &lut2[i], err))
1582 return false;
1583 }
1584
1585 return true;
1586 }
1587
intel_color_lut_equal(struct drm_property_blob * blob1,struct drm_property_blob * blob2,u32 gamma_mode,u32 bit_precision)1588 bool intel_color_lut_equal(struct drm_property_blob *blob1,
1589 struct drm_property_blob *blob2,
1590 u32 gamma_mode, u32 bit_precision)
1591 {
1592 struct drm_color_lut *lut1, *lut2;
1593 int lut_size1, lut_size2;
1594 u32 err;
1595
1596 if (!blob1 != !blob2)
1597 return false;
1598
1599 if (!blob1)
1600 return true;
1601
1602 lut_size1 = drm_color_lut_size(blob1);
1603 lut_size2 = drm_color_lut_size(blob2);
1604
1605 /* check sw and hw lut size */
1606 switch (gamma_mode) {
1607 case GAMMA_MODE_MODE_8BIT:
1608 case GAMMA_MODE_MODE_10BIT:
1609 if (lut_size1 != lut_size2)
1610 return false;
1611 break;
1612 default:
1613 MISSING_CASE(gamma_mode);
1614 return false;
1615 }
1616
1617 lut1 = blob1->data;
1618 lut2 = blob2->data;
1619
1620 err = 0xffff >> bit_precision;
1621
1622 /* check sw and hw lut entry to be equal */
1623 switch (gamma_mode) {
1624 case GAMMA_MODE_MODE_8BIT:
1625 case GAMMA_MODE_MODE_10BIT:
1626 if (!intel_color_lut_entry_equal(lut1, lut2,
1627 lut_size2, err))
1628 return false;
1629 break;
1630 default:
1631 MISSING_CASE(gamma_mode);
1632 return false;
1633 }
1634
1635 return true;
1636 }
1637
1638 /* convert hw value with given bit_precision to lut property val */
intel_color_lut_pack(u32 val,u32 bit_precision)1639 static u32 intel_color_lut_pack(u32 val, u32 bit_precision)
1640 {
1641 u32 max = 0xffff >> (16 - bit_precision);
1642
1643 val = clamp_val(val, 0, max);
1644
1645 if (bit_precision < 16)
1646 val <<= 16 - bit_precision;
1647
1648 return val;
1649 }
1650
1651 static struct drm_property_blob *
i9xx_read_lut_8(const struct intel_crtc_state * crtc_state)1652 i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
1653 {
1654 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1655 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1656 enum pipe pipe = crtc->pipe;
1657 struct drm_property_blob *blob;
1658 struct drm_color_lut *blob_data;
1659 u32 i, val;
1660
1661 blob = drm_property_create_blob(&dev_priv->drm,
1662 sizeof(struct drm_color_lut) * LEGACY_LUT_LENGTH,
1663 NULL);
1664 if (IS_ERR(blob))
1665 return NULL;
1666
1667 blob_data = blob->data;
1668
1669 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
1670 if (HAS_GMCH(dev_priv))
1671 val = I915_READ(PALETTE(pipe, i));
1672 else
1673 val = I915_READ(LGC_PALETTE(pipe, i));
1674
1675 blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
1676 LGC_PALETTE_RED_MASK, val), 8);
1677 blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
1678 LGC_PALETTE_GREEN_MASK, val), 8);
1679 blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
1680 LGC_PALETTE_BLUE_MASK, val), 8);
1681 }
1682
1683 return blob;
1684 }
1685
i9xx_read_luts(struct intel_crtc_state * crtc_state)1686 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
1687 {
1688 if (!crtc_state->gamma_enable)
1689 return;
1690
1691 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
1692 }
1693
1694 static struct drm_property_blob *
i965_read_lut_10p6(const struct intel_crtc_state * crtc_state)1695 i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
1696 {
1697 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1698 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1699 u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1700 enum pipe pipe = crtc->pipe;
1701 struct drm_property_blob *blob;
1702 struct drm_color_lut *blob_data;
1703 u32 i, val1, val2;
1704
1705 blob = drm_property_create_blob(&dev_priv->drm,
1706 sizeof(struct drm_color_lut) * lut_size,
1707 NULL);
1708 if (IS_ERR(blob))
1709 return NULL;
1710
1711 blob_data = blob->data;
1712
1713 for (i = 0; i < lut_size - 1; i++) {
1714 val1 = I915_READ(PALETTE(pipe, 2 * i + 0));
1715 val2 = I915_READ(PALETTE(pipe, 2 * i + 1));
1716
1717 blob_data[i].red = REG_FIELD_GET(PALETTE_RED_MASK, val2) << 8 |
1718 REG_FIELD_GET(PALETTE_RED_MASK, val1);
1719 blob_data[i].green = REG_FIELD_GET(PALETTE_GREEN_MASK, val2) << 8 |
1720 REG_FIELD_GET(PALETTE_GREEN_MASK, val1);
1721 blob_data[i].blue = REG_FIELD_GET(PALETTE_BLUE_MASK, val2) << 8 |
1722 REG_FIELD_GET(PALETTE_BLUE_MASK, val1);
1723 }
1724
1725 blob_data[i].red = REG_FIELD_GET(PIPEGCMAX_RGB_MASK,
1726 I915_READ(PIPEGCMAX(pipe, 0)));
1727 blob_data[i].green = REG_FIELD_GET(PIPEGCMAX_RGB_MASK,
1728 I915_READ(PIPEGCMAX(pipe, 1)));
1729 blob_data[i].blue = REG_FIELD_GET(PIPEGCMAX_RGB_MASK,
1730 I915_READ(PIPEGCMAX(pipe, 2)));
1731
1732 return blob;
1733 }
1734
i965_read_luts(struct intel_crtc_state * crtc_state)1735 static void i965_read_luts(struct intel_crtc_state *crtc_state)
1736 {
1737 if (!crtc_state->gamma_enable)
1738 return;
1739
1740 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
1741 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
1742 else
1743 crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc_state);
1744 }
1745
1746 static struct drm_property_blob *
chv_read_cgm_lut(const struct intel_crtc_state * crtc_state)1747 chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
1748 {
1749 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1750 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1751 u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1752 enum pipe pipe = crtc->pipe;
1753 struct drm_property_blob *blob;
1754 struct drm_color_lut *blob_data;
1755 u32 i, val;
1756
1757 blob = drm_property_create_blob(&dev_priv->drm,
1758 sizeof(struct drm_color_lut) * lut_size,
1759 NULL);
1760 if (IS_ERR(blob))
1761 return NULL;
1762
1763 blob_data = blob->data;
1764
1765 for (i = 0; i < lut_size; i++) {
1766 val = I915_READ(CGM_PIPE_GAMMA(pipe, i, 0));
1767 blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
1768 CGM_PIPE_GAMMA_GREEN_MASK, val), 10);
1769 blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
1770 CGM_PIPE_GAMMA_BLUE_MASK, val), 10);
1771
1772 val = I915_READ(CGM_PIPE_GAMMA(pipe, i, 1));
1773 blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
1774 CGM_PIPE_GAMMA_RED_MASK, val), 10);
1775 }
1776
1777 return blob;
1778 }
1779
chv_read_luts(struct intel_crtc_state * crtc_state)1780 static void chv_read_luts(struct intel_crtc_state *crtc_state)
1781 {
1782 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1783 crtc_state->hw.gamma_lut = chv_read_cgm_lut(crtc_state);
1784 else
1785 i965_read_luts(crtc_state);
1786 }
1787
1788 static struct drm_property_blob *
ilk_read_lut_10(const struct intel_crtc_state * crtc_state)1789 ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
1790 {
1791 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1792 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1793 u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1794 enum pipe pipe = crtc->pipe;
1795 struct drm_property_blob *blob;
1796 struct drm_color_lut *blob_data;
1797 u32 i, val;
1798
1799 blob = drm_property_create_blob(&dev_priv->drm,
1800 sizeof(struct drm_color_lut) * lut_size,
1801 NULL);
1802 if (IS_ERR(blob))
1803 return NULL;
1804
1805 blob_data = blob->data;
1806
1807 for (i = 0; i < lut_size; i++) {
1808 val = I915_READ(PREC_PALETTE(pipe, i));
1809
1810 blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
1811 PREC_PALETTE_RED_MASK, val), 10);
1812 blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
1813 PREC_PALETTE_GREEN_MASK, val), 10);
1814 blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
1815 PREC_PALETTE_BLUE_MASK, val), 10);
1816 }
1817
1818 return blob;
1819 }
1820
ilk_read_luts(struct intel_crtc_state * crtc_state)1821 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
1822 {
1823 if (!crtc_state->gamma_enable)
1824 return;
1825
1826 if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
1827 return;
1828
1829 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
1830 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
1831 else
1832 crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc_state);
1833 }
1834
1835 static struct drm_property_blob *
glk_read_lut_10(const struct intel_crtc_state * crtc_state,u32 prec_index)1836 glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
1837 {
1838 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1839 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1840 int hw_lut_size = ivb_lut_10_size(prec_index);
1841 enum pipe pipe = crtc->pipe;
1842 struct drm_property_blob *blob;
1843 struct drm_color_lut *blob_data;
1844 u32 i, val;
1845
1846 blob = drm_property_create_blob(&dev_priv->drm,
1847 sizeof(struct drm_color_lut) * hw_lut_size,
1848 NULL);
1849 if (IS_ERR(blob))
1850 return NULL;
1851
1852 blob_data = blob->data;
1853
1854 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
1855 PAL_PREC_AUTO_INCREMENT);
1856
1857 for (i = 0; i < hw_lut_size; i++) {
1858 val = I915_READ(PREC_PAL_DATA(pipe));
1859
1860 blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
1861 PREC_PAL_DATA_RED_MASK, val), 10);
1862 blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
1863 PREC_PAL_DATA_GREEN_MASK, val), 10);
1864 blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
1865 PREC_PAL_DATA_BLUE_MASK, val), 10);
1866 }
1867
1868 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
1869
1870 return blob;
1871 }
1872
glk_read_luts(struct intel_crtc_state * crtc_state)1873 static void glk_read_luts(struct intel_crtc_state *crtc_state)
1874 {
1875 if (!crtc_state->gamma_enable)
1876 return;
1877
1878 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
1879 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
1880 else
1881 crtc_state->hw.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
1882 }
1883
intel_color_init(struct intel_crtc * crtc)1884 void intel_color_init(struct intel_crtc *crtc)
1885 {
1886 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1887 bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0;
1888
1889 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
1890
1891 if (HAS_GMCH(dev_priv)) {
1892 if (IS_CHERRYVIEW(dev_priv)) {
1893 dev_priv->display.color_check = chv_color_check;
1894 dev_priv->display.color_commit = i9xx_color_commit;
1895 dev_priv->display.load_luts = chv_load_luts;
1896 dev_priv->display.read_luts = chv_read_luts;
1897 } else if (INTEL_GEN(dev_priv) >= 4) {
1898 dev_priv->display.color_check = i9xx_color_check;
1899 dev_priv->display.color_commit = i9xx_color_commit;
1900 dev_priv->display.load_luts = i965_load_luts;
1901 dev_priv->display.read_luts = i965_read_luts;
1902 } else {
1903 dev_priv->display.color_check = i9xx_color_check;
1904 dev_priv->display.color_commit = i9xx_color_commit;
1905 dev_priv->display.load_luts = i9xx_load_luts;
1906 dev_priv->display.read_luts = i9xx_read_luts;
1907 }
1908 } else {
1909 if (INTEL_GEN(dev_priv) >= 11)
1910 dev_priv->display.color_check = icl_color_check;
1911 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1912 dev_priv->display.color_check = glk_color_check;
1913 else if (INTEL_GEN(dev_priv) >= 7)
1914 dev_priv->display.color_check = ivb_color_check;
1915 else
1916 dev_priv->display.color_check = ilk_color_check;
1917
1918 if (INTEL_GEN(dev_priv) >= 9)
1919 dev_priv->display.color_commit = skl_color_commit;
1920 else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
1921 dev_priv->display.color_commit = hsw_color_commit;
1922 else
1923 dev_priv->display.color_commit = ilk_color_commit;
1924
1925 if (INTEL_GEN(dev_priv) >= 11) {
1926 dev_priv->display.load_luts = icl_load_luts;
1927 } else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) {
1928 dev_priv->display.load_luts = glk_load_luts;
1929 dev_priv->display.read_luts = glk_read_luts;
1930 } else if (INTEL_GEN(dev_priv) >= 8) {
1931 dev_priv->display.load_luts = bdw_load_luts;
1932 } else if (INTEL_GEN(dev_priv) >= 7) {
1933 dev_priv->display.load_luts = ivb_load_luts;
1934 } else {
1935 dev_priv->display.load_luts = ilk_load_luts;
1936 dev_priv->display.read_luts = ilk_read_luts;
1937 }
1938 }
1939
1940 drm_crtc_enable_color_mgmt(&crtc->base,
1941 INTEL_INFO(dev_priv)->color.degamma_lut_size,
1942 has_ctm,
1943 INTEL_INFO(dev_priv)->color.gamma_lut_size);
1944 }
1945