2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 #include "intel_color.h"
26 #include "intel_drv.h"
28 #define CTM_COEFF_SIGN (1ULL << 63)
30 #define CTM_COEFF_1_0 (1ULL << 32)
31 #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1)
32 #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1)
33 #define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1)
34 #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1)
35 #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1)
36 #define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1)
38 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
40 #define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
41 #define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
43 #define LEGACY_LUT_LENGTH 256
46 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
47 * format). This macro takes the coefficient we want transformed and the
48 * number of fractional bits.
50 * We only have a 9 bits precision window which slides depending on the value
51 * of the CTM coefficient and we write the value from bit 3. We also round the
54 #define ILK_CSC_COEFF_FP(coeff, fbits) \
55 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
57 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
58 #define ILK_CSC_COEFF_1_0 0x7800
60 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
62 static const u16 ilk_csc_off_zero[3] = {};
64 static const u16 ilk_csc_coeff_identity[9] = {
65 ILK_CSC_COEFF_1_0, 0, 0,
66 0, ILK_CSC_COEFF_1_0, 0,
67 0, 0, ILK_CSC_COEFF_1_0,
70 static const u16 ilk_csc_postoff_limited_range[3] = {
71 ILK_CSC_POSTOFF_LIMITED_RANGE,
72 ILK_CSC_POSTOFF_LIMITED_RANGE,
73 ILK_CSC_POSTOFF_LIMITED_RANGE,
76 static const u16 ilk_csc_coeff_limited_range[9] = {
77 ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
78 0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
79 0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
83 * These values are direct register values specified in the Bspec,
84 * for RGB->YUV conversion matrix (colorspace BT709)
86 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
87 0x1e08, 0x9cc0, 0xb528,
88 0x2ba8, 0x09d8, 0x37e8,
89 0xbce8, 0x9ad8, 0x1e08,
92 /* Post offset values for RGB->YCBCR conversion */
93 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
94 0x0800, 0x0100, 0x0800,
97 static bool lut_is_legacy(const struct drm_property_blob *lut)
99 return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
102 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
104 return !crtc_state->base.degamma_lut &&
105 !crtc_state->base.ctm &&
106 crtc_state->base.gamma_lut &&
107 lut_is_legacy(crtc_state->base.gamma_lut);
111 * When using limited range, multiply the matrix given by userspace by
112 * the matrix that we would use for the limited range.
114 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
118 for (i = 0; i < 9; i++) {
119 u64 user_coeff = input[i];
120 u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
121 u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
122 CTM_COEFF_4_0 - 1) >> 2;
125 * By scaling every co-efficient with limited range (16-235)
126 * vs full range (0-255) the final o/p will be scaled down to
127 * fit in the limited range supported by the panel.
129 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
130 result[i] |= user_coeff & CTM_COEFF_SIGN;
136 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
139 const u16 postoff[3])
141 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
142 enum pipe pipe = crtc->pipe;
144 I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
145 I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
146 I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
148 I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
149 I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
151 I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
152 I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
154 I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
155 I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
157 if (INTEL_GEN(dev_priv) >= 7) {
158 I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff[0]);
159 I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff[1]);
160 I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff[2]);
164 static void icl_update_output_csc(struct intel_crtc *crtc,
167 const u16 postoff[3])
169 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
170 enum pipe pipe = crtc->pipe;
172 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
173 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
174 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
176 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
177 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2] << 16);
179 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
180 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5] << 16);
182 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
183 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8] << 16);
185 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
186 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
187 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
190 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
192 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
195 * FIXME if there's a gamma LUT after the CSC, we should
196 * do the range compression using the gamma LUT instead.
198 return crtc_state->limited_color_range &&
199 (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
200 IS_GEN_RANGE(dev_priv, 9, 10));
203 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
206 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
211 if (ilk_csc_limited_range(crtc_state))
212 input = ctm_mult_by_limited(temp, ctm->matrix);
217 * Convert fixed point S31.32 input to format supported by the
220 for (i = 0; i < 9; i++) {
221 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
224 * Clamp input value to min/max supported by
227 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
232 if (CTM_COEFF_NEGATIVE(input[i]))
233 coeffs[i] |= 1 << 15;
235 if (abs_coeff < CTM_COEFF_0_125)
236 coeffs[i] |= (3 << 12) |
237 ILK_CSC_COEFF_FP(abs_coeff, 12);
238 else if (abs_coeff < CTM_COEFF_0_25)
239 coeffs[i] |= (2 << 12) |
240 ILK_CSC_COEFF_FP(abs_coeff, 11);
241 else if (abs_coeff < CTM_COEFF_0_5)
242 coeffs[i] |= (1 << 12) |
243 ILK_CSC_COEFF_FP(abs_coeff, 10);
244 else if (abs_coeff < CTM_COEFF_1_0)
245 coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
246 else if (abs_coeff < CTM_COEFF_2_0)
247 coeffs[i] |= (7 << 12) |
248 ILK_CSC_COEFF_FP(abs_coeff, 8);
250 coeffs[i] |= (6 << 12) |
251 ILK_CSC_COEFF_FP(abs_coeff, 7);
255 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
257 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
258 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
259 bool limited_color_range = ilk_csc_limited_range(crtc_state);
261 if (crtc_state->base.ctm) {
264 ilk_csc_convert_ctm(crtc_state, coeff);
265 ilk_update_pipe_csc(crtc, ilk_csc_off_zero, coeff,
266 limited_color_range ?
267 ilk_csc_postoff_limited_range :
269 } else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
270 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
271 ilk_csc_coeff_rgb_to_ycbcr,
272 ilk_csc_postoff_rgb_to_ycbcr);
273 } else if (limited_color_range) {
274 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
275 ilk_csc_coeff_limited_range,
276 ilk_csc_postoff_limited_range);
277 } else if (crtc_state->csc_enable) {
279 * On GLK+ both pipe CSC and degamma LUT are controlled
280 * by csc_enable. Hence for the cases where the degama
281 * LUT is needed but CSC is not we need to load an
284 WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
286 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
287 ilk_csc_coeff_identity,
291 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
294 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
296 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
297 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
299 if (crtc_state->base.ctm) {
302 ilk_csc_convert_ctm(crtc_state, coeff);
303 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
304 coeff, ilk_csc_off_zero);
307 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
308 icl_update_output_csc(crtc, ilk_csc_off_zero,
309 ilk_csc_coeff_rgb_to_ycbcr,
310 ilk_csc_postoff_rgb_to_ycbcr);
311 } else if (crtc_state->limited_color_range) {
312 icl_update_output_csc(crtc, ilk_csc_off_zero,
313 ilk_csc_coeff_limited_range,
314 ilk_csc_postoff_limited_range);
317 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
321 * Set up the pipe CSC unit on CherryView.
323 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
325 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
326 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
327 enum pipe pipe = crtc->pipe;
329 if (crtc_state->base.ctm) {
330 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
334 for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
336 ((1ULL << 63) - 1) & ctm->matrix[i];
338 /* Round coefficient. */
339 abs_coeff += 1 << (32 - 13);
340 /* Clamp to hardware limits. */
341 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
343 /* Write coefficients in S3.12 format. */
344 if (ctm->matrix[i] & (1ULL << 63))
346 coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
347 coeffs[i] |= (abs_coeff >> 20) & 0xfff;
350 I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe),
351 coeffs[1] << 16 | coeffs[0]);
352 I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe),
353 coeffs[3] << 16 | coeffs[2]);
354 I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe),
355 coeffs[5] << 16 | coeffs[4]);
356 I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe),
357 coeffs[7] << 16 | coeffs[6]);
358 I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]);
361 I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
364 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
365 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
367 return (color->red & 0xff) << 16 |
368 (color->green & 0xff) << 8 |
369 (color->blue & 0xff);
372 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
373 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
375 return (color->red >> 8) << 16 |
376 (color->green >> 8) << 8 |
380 static u32 ilk_lut_10(const struct drm_color_lut *color)
382 return drm_color_lut_extract(color->red, 10) << 20 |
383 drm_color_lut_extract(color->green, 10) << 10 |
384 drm_color_lut_extract(color->blue, 10);
387 /* Loads the legacy palette/gamma unit for the CRTC. */
388 static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
389 const struct drm_property_blob *blob)
391 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
392 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
393 enum pipe pipe = crtc->pipe;
396 if (HAS_GMCH(dev_priv)) {
397 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
398 assert_dsi_pll_enabled(dev_priv);
400 assert_pll_enabled(dev_priv, pipe);
404 const struct drm_color_lut *lut = blob->data;
406 for (i = 0; i < 256; i++) {
408 (drm_color_lut_extract(lut[i].red, 8) << 16) |
409 (drm_color_lut_extract(lut[i].green, 8) << 8) |
410 drm_color_lut_extract(lut[i].blue, 8);
412 if (HAS_GMCH(dev_priv))
413 I915_WRITE(PALETTE(pipe, i), word);
415 I915_WRITE(LGC_PALETTE(pipe, i), word);
420 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
422 i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
425 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
427 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
428 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
429 enum pipe pipe = crtc->pipe;
432 val = I915_READ(PIPECONF(pipe));
433 val &= ~PIPECONF_GAMMA_MODE_MASK_I9XX;
434 val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
435 I915_WRITE(PIPECONF(pipe), val);
438 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
440 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
441 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
442 enum pipe pipe = crtc->pipe;
445 val = I915_READ(PIPECONF(pipe));
446 val &= ~PIPECONF_GAMMA_MODE_MASK_ILK;
447 val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
448 I915_WRITE(PIPECONF(pipe), val);
450 ilk_load_csc_matrix(crtc_state);
453 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
455 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
456 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
458 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
460 ilk_load_csc_matrix(crtc_state);
463 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
465 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
466 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
467 enum pipe pipe = crtc->pipe;
471 * We don't (yet) allow userspace to control the pipe background color,
472 * so force it to black, but apply pipe gamma and CSC appropriately
473 * so that its handling will match how we program our planes.
475 if (crtc_state->gamma_enable)
476 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
477 if (crtc_state->csc_enable)
478 val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
479 I915_WRITE(SKL_BOTTOM_COLOR(pipe), val);
481 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
483 if (INTEL_GEN(dev_priv) >= 11)
484 icl_load_csc_matrix(crtc_state);
486 ilk_load_csc_matrix(crtc_state);
489 static void i965_load_lut_10p6(struct intel_crtc *crtc,
490 const struct drm_property_blob *blob)
492 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
493 const struct drm_color_lut *lut = blob->data;
494 int i, lut_size = drm_color_lut_size(blob);
495 enum pipe pipe = crtc->pipe;
497 for (i = 0; i < lut_size - 1; i++) {
498 I915_WRITE(PALETTE(pipe, 2 * i + 0),
499 i965_lut_10p6_ldw(&lut[i]));
500 I915_WRITE(PALETTE(pipe, 2 * i + 1),
501 i965_lut_10p6_udw(&lut[i]));
504 I915_WRITE(PIPEGCMAX(pipe, 0), lut[i].red);
505 I915_WRITE(PIPEGCMAX(pipe, 1), lut[i].green);
506 I915_WRITE(PIPEGCMAX(pipe, 2), lut[i].blue);
509 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
511 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
512 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
514 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
515 i9xx_load_luts(crtc_state);
517 i965_load_lut_10p6(crtc, gamma_lut);
520 static void ilk_load_lut_10(struct intel_crtc *crtc,
521 const struct drm_property_blob *blob)
523 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
524 const struct drm_color_lut *lut = blob->data;
525 int i, lut_size = drm_color_lut_size(blob);
526 enum pipe pipe = crtc->pipe;
528 for (i = 0; i < lut_size; i++)
529 I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
532 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
534 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
535 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
537 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
538 i9xx_load_luts(crtc_state);
540 ilk_load_lut_10(crtc, gamma_lut);
543 static int ivb_lut_10_size(u32 prec_index)
545 if (prec_index & PAL_PREC_SPLIT_MODE)
552 * IVB/HSW Bspec / PAL_PREC_INDEX:
553 * "Restriction : Index auto increment mode is not
554 * supported and must not be enabled."
556 static void ivb_load_lut_10(struct intel_crtc *crtc,
557 const struct drm_property_blob *blob,
560 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
561 int hw_lut_size = ivb_lut_10_size(prec_index);
562 const struct drm_color_lut *lut = blob->data;
563 int i, lut_size = drm_color_lut_size(blob);
564 enum pipe pipe = crtc->pipe;
566 for (i = 0; i < hw_lut_size; i++) {
567 /* We discard half the user entries in split gamma mode */
568 const struct drm_color_lut *entry =
569 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
571 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
572 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
576 * Reset the index, otherwise it prevents the legacy palette to be
579 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
582 /* On BDW+ the index auto increment mode actually works */
583 static void bdw_load_lut_10(struct intel_crtc *crtc,
584 const struct drm_property_blob *blob,
587 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
588 int hw_lut_size = ivb_lut_10_size(prec_index);
589 const struct drm_color_lut *lut = blob->data;
590 int i, lut_size = drm_color_lut_size(blob);
591 enum pipe pipe = crtc->pipe;
593 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
594 PAL_PREC_AUTO_INCREMENT);
596 for (i = 0; i < hw_lut_size; i++) {
597 /* We discard half the user entries in split gamma mode */
598 const struct drm_color_lut *entry =
599 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
601 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
605 * Reset the index, otherwise it prevents the legacy palette to be
608 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
611 static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
613 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
614 enum pipe pipe = crtc->pipe;
616 /* Program the max register to clamp values > 1.0. */
617 I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
618 I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
619 I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
622 * Program the gc max 2 register to clamp values > 1.0.
623 * ToDo: Extend the ABI to be able to program values
626 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
627 I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16);
628 I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16);
629 I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16);
633 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
635 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
636 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
637 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
639 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
640 i9xx_load_luts(crtc_state);
641 } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
642 ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
643 PAL_PREC_INDEX_VALUE(0));
644 ivb_load_lut_ext_max(crtc);
645 ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
646 PAL_PREC_INDEX_VALUE(512));
648 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
650 ivb_load_lut_10(crtc, blob,
651 PAL_PREC_INDEX_VALUE(0));
652 ivb_load_lut_ext_max(crtc);
656 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
658 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
659 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
660 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
662 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
663 i9xx_load_luts(crtc_state);
664 } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
665 bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
666 PAL_PREC_INDEX_VALUE(0));
667 ivb_load_lut_ext_max(crtc);
668 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
669 PAL_PREC_INDEX_VALUE(512));
671 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
673 bdw_load_lut_10(crtc, blob,
674 PAL_PREC_INDEX_VALUE(0));
675 ivb_load_lut_ext_max(crtc);
679 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
681 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
682 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
683 enum pipe pipe = crtc->pipe;
684 const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
685 const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data;
689 * When setting the auto-increment bit, the hardware seems to
690 * ignore the index bits, so we need to reset it to index 0
693 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
694 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
696 for (i = 0; i < lut_size; i++) {
698 * First 33 entries represent range from 0 to 1.0
699 * 34th and 35th entry will represent extended range
700 * inputs 3.0 and 7.0 respectively, currently clamped
701 * at 1.0. Since the precision is 16bit, the user
702 * value can be directly filled to register.
703 * The pipe degamma table in GLK+ onwards doesn't
704 * support different values per channel, so this just
705 * programs green value which will be equal to Red and
706 * Blue into the lut registers.
707 * ToDo: Extend to max 7.0. Enable 32 bit input value
708 * as compared to just 16 to achieve this.
710 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
713 /* Clamp values > 1.0. */
715 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
718 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
720 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
721 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
722 enum pipe pipe = crtc->pipe;
723 const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
727 * When setting the auto-increment bit, the hardware seems to
728 * ignore the index bits, so we need to reset it to index 0
731 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
732 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
734 for (i = 0; i < lut_size; i++) {
735 u32 v = (i << 16) / (lut_size - 1);
737 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
740 /* Clamp values > 1.0. */
742 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
745 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
747 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
748 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
751 * On GLK+ both pipe CSC and degamma LUT are controlled
752 * by csc_enable. Hence for the cases where the CSC is
753 * needed but degamma LUT is not we need to load a
754 * linear degamma LUT. In fact we'll just always load
755 * the degama LUT so that we don't have to reload
756 * it every time the pipe CSC is being enabled.
758 if (crtc_state->base.degamma_lut)
759 glk_load_degamma_lut(crtc_state);
761 glk_load_degamma_lut_linear(crtc_state);
763 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
764 i9xx_load_luts(crtc_state);
766 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
767 ivb_load_lut_ext_max(crtc);
771 /* ilk+ "12.4" interpolated format (high 10 bits) */
772 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
774 return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
778 /* ilk+ "12.4" interpolated format (low 6 bits) */
779 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
781 return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
782 (color->blue & 0x3f) << 4;
786 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
787 const struct drm_color_lut *color)
789 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
790 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
791 enum pipe pipe = crtc->pipe;
793 /* Fixme: LUT entries are 16 bit only, so we can prog 0xFFFF max */
794 I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), color->red);
795 I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), color->green);
796 I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), color->blue);
800 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
802 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
803 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
804 const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
805 const struct drm_color_lut *lut = blob->data;
806 enum pipe pipe = crtc->pipe;
810 * Every entry in the multi-segment LUT is corresponding to a superfine
811 * segment step which is 1/(8 * 128 * 256).
813 * Superfine segment has 9 entries, corresponding to values
814 * 0, 1/(8 * 128 * 256), 2/(8 * 128 * 256) .... 8/(8 * 128 * 256).
816 I915_WRITE(PREC_PAL_MULTI_SEG_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
818 for (i = 0; i < 9; i++) {
819 const struct drm_color_lut *entry = &lut[i];
821 I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe),
822 ilk_lut_12p4_ldw(entry));
823 I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe),
824 ilk_lut_12p4_udw(entry));
829 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
831 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
832 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
833 const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
834 const struct drm_color_lut *lut = blob->data;
835 const struct drm_color_lut *entry;
836 enum pipe pipe = crtc->pipe;
841 * Program Fine segment (let's call it seg2)...
843 * Fine segment's step is 1/(128 * 256) ie 1/(128 * 256), 2/(128*256)
844 * ... 256/(128*256). So in order to program fine segment of LUT we
845 * need to pick every 8'th entry in LUT, and program 256 indexes.
847 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
848 * with seg2[0] being unused by the hardware.
850 I915_WRITE(PREC_PAL_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
851 for (i = 1; i < 257; i++) {
853 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_ldw(entry));
854 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_udw(entry));
858 * Program Coarse segment (let's call it seg3)...
860 * Coarse segment's starts from index 0 and it's step is 1/256 ie 0,
861 * 1/256, 2/256 ...256/256. As per the description of each entry in LUT
862 * above, we need to pick every (8 * 128)th entry in LUT, and
863 * program 256 of those.
865 * Spec is not very clear about if entries seg3[0] and seg3[1] are
866 * being used or not, but we still need to program these to advance
869 for (i = 0; i < 256; i++) {
870 entry = &lut[i * 8 * 128];
871 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_ldw(entry));
872 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_udw(entry));
875 /* The last entry in the LUT is to be programmed in GCMAX */
876 entry = &lut[256 * 8 * 128];
877 icl_load_gcmax(crtc_state, entry);
878 ivb_load_lut_ext_max(crtc);
881 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
883 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
884 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
886 if (crtc_state->base.degamma_lut)
887 glk_load_degamma_lut(crtc_state);
889 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
890 case GAMMA_MODE_MODE_8BIT:
891 i9xx_load_luts(crtc_state);
894 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
895 icl_program_gamma_superfine_segment(crtc_state);
896 icl_program_gamma_multi_segment(crtc_state);
900 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
901 ivb_load_lut_ext_max(crtc);
905 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
907 return drm_color_lut_extract(color->green, 14) << 16 |
908 drm_color_lut_extract(color->blue, 14);
911 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
913 return drm_color_lut_extract(color->red, 14);
916 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
917 const struct drm_property_blob *blob)
919 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
920 const struct drm_color_lut *lut = blob->data;
921 int i, lut_size = drm_color_lut_size(blob);
922 enum pipe pipe = crtc->pipe;
924 for (i = 0; i < lut_size; i++) {
925 I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0),
926 chv_cgm_degamma_ldw(&lut[i]));
927 I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1),
928 chv_cgm_degamma_udw(&lut[i]));
932 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
934 return drm_color_lut_extract(color->green, 10) << 16 |
935 drm_color_lut_extract(color->blue, 10);
938 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
940 return drm_color_lut_extract(color->red, 10);
943 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
944 const struct drm_property_blob *blob)
946 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
947 const struct drm_color_lut *lut = blob->data;
948 int i, lut_size = drm_color_lut_size(blob);
949 enum pipe pipe = crtc->pipe;
951 for (i = 0; i < lut_size; i++) {
952 I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0),
953 chv_cgm_gamma_ldw(&lut[i]));
954 I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1),
955 chv_cgm_gamma_udw(&lut[i]));
959 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
961 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
962 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
963 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
965 cherryview_load_csc_matrix(crtc_state);
967 if (crtc_state_is_legacy_gamma(crtc_state)) {
968 i9xx_load_luts(crtc_state);
973 chv_load_cgm_degamma(crtc, degamma_lut);
976 chv_load_cgm_gamma(crtc, gamma_lut);
979 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
981 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
983 dev_priv->display.load_luts(crtc_state);
986 void intel_color_commit(const struct intel_crtc_state *crtc_state)
988 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
990 dev_priv->display.color_commit(crtc_state);
993 int intel_color_check(struct intel_crtc_state *crtc_state)
995 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
997 return dev_priv->display.color_check(crtc_state);
1000 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1002 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1004 if (dev_priv->display.read_luts)
1005 dev_priv->display.read_luts(crtc_state);
1008 static bool need_plane_update(struct intel_plane *plane,
1009 const struct intel_crtc_state *crtc_state)
1011 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1014 * On pre-SKL the pipe gamma enable and pipe csc enable for
1015 * the pipe bottom color are configured via the primary plane.
1016 * We have to reconfigure that even if the plane is inactive.
1018 return crtc_state->active_planes & BIT(plane->id) ||
1019 (INTEL_GEN(dev_priv) < 9 &&
1020 plane->id == PLANE_PRIMARY);
1024 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1026 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1027 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1028 struct intel_atomic_state *state =
1029 to_intel_atomic_state(new_crtc_state->base.state);
1030 const struct intel_crtc_state *old_crtc_state =
1031 intel_atomic_get_old_crtc_state(state, crtc);
1032 struct intel_plane *plane;
1034 if (!new_crtc_state->base.active ||
1035 drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
1038 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1039 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1042 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
1043 struct intel_plane_state *plane_state;
1045 if (!need_plane_update(plane, new_crtc_state))
1048 plane_state = intel_atomic_get_plane_state(state, plane);
1049 if (IS_ERR(plane_state))
1050 return PTR_ERR(plane_state);
1052 new_crtc_state->update_planes |= BIT(plane->id);
1058 static int check_lut_size(const struct drm_property_blob *lut, int expected)
1065 len = drm_color_lut_size(lut);
1066 if (len != expected) {
1067 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1075 static int check_luts(const struct intel_crtc_state *crtc_state)
1077 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1078 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
1079 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
1080 int gamma_length, degamma_length;
1081 u32 gamma_tests, degamma_tests;
1083 /* Always allow legacy gamma LUT with no further checking. */
1084 if (crtc_state_is_legacy_gamma(crtc_state))
1087 /* C8 relies on its palette being stored in the legacy LUT */
1088 if (crtc_state->c8_planes) {
1089 DRM_DEBUG_KMS("C8 pixelformat requires the legacy LUT\n");
1093 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
1094 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1095 degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
1096 gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
1098 if (check_lut_size(degamma_lut, degamma_length) ||
1099 check_lut_size(gamma_lut, gamma_length))
1102 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
1103 drm_color_lut_check(gamma_lut, gamma_tests))
1109 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
1111 if (!crtc_state->gamma_enable ||
1112 crtc_state_is_legacy_gamma(crtc_state))
1113 return GAMMA_MODE_MODE_8BIT;
1115 return GAMMA_MODE_MODE_10BIT; /* i965+ only */
1118 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1122 ret = check_luts(crtc_state);
1126 crtc_state->gamma_enable =
1127 crtc_state->base.gamma_lut &&
1128 !crtc_state->c8_planes;
1130 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1132 ret = intel_color_add_affected_planes(crtc_state);
1139 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1143 if (crtc_state_is_legacy_gamma(crtc_state))
1146 if (crtc_state->base.degamma_lut)
1147 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1148 if (crtc_state->base.ctm)
1149 cgm_mode |= CGM_PIPE_MODE_CSC;
1150 if (crtc_state->base.gamma_lut)
1151 cgm_mode |= CGM_PIPE_MODE_GAMMA;
1157 * CHV color pipeline:
1158 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
1159 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
1161 * We always bypass the WGC csc and use the CGM csc
1162 * instead since it has degamma and better precision.
1164 static int chv_color_check(struct intel_crtc_state *crtc_state)
1168 ret = check_luts(crtc_state);
1173 * Pipe gamma will be used only for the legacy LUT.
1174 * Otherwise we bypass it and use the CGM gamma instead.
1176 crtc_state->gamma_enable =
1177 crtc_state_is_legacy_gamma(crtc_state) &&
1178 !crtc_state->c8_planes;
1180 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1182 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1184 ret = intel_color_add_affected_planes(crtc_state);
1191 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1193 if (!crtc_state->gamma_enable ||
1194 crtc_state_is_legacy_gamma(crtc_state))
1195 return GAMMA_MODE_MODE_8BIT;
1197 return GAMMA_MODE_MODE_10BIT;
1200 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1204 ret = check_luts(crtc_state);
1208 crtc_state->gamma_enable =
1209 crtc_state->base.gamma_lut &&
1210 !crtc_state->c8_planes;
1213 * We don't expose the ctm on ilk/snb currently,
1214 * nor do we enable YCbCr output. Also RGB limited
1215 * range output is handled by the hw automagically.
1217 crtc_state->csc_enable = false;
1219 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1221 crtc_state->csc_mode = 0;
1223 ret = intel_color_add_affected_planes(crtc_state);
1230 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1232 if (!crtc_state->gamma_enable ||
1233 crtc_state_is_legacy_gamma(crtc_state))
1234 return GAMMA_MODE_MODE_8BIT;
1235 else if (crtc_state->base.gamma_lut &&
1236 crtc_state->base.degamma_lut)
1237 return GAMMA_MODE_MODE_SPLIT;
1239 return GAMMA_MODE_MODE_10BIT;
1242 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1244 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1247 * CSC comes after the LUT in degamma, RGB->YCbCr,
1248 * and RGB full->limited range mode.
1250 if (crtc_state->base.degamma_lut ||
1251 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1252 limited_color_range)
1255 return CSC_POSITION_BEFORE_GAMMA;
1258 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1260 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1263 ret = check_luts(crtc_state);
1267 crtc_state->gamma_enable =
1268 (crtc_state->base.gamma_lut ||
1269 crtc_state->base.degamma_lut) &&
1270 !crtc_state->c8_planes;
1272 crtc_state->csc_enable =
1273 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1274 crtc_state->base.ctm || limited_color_range;
1276 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1278 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1280 ret = intel_color_add_affected_planes(crtc_state);
1287 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1289 if (!crtc_state->gamma_enable ||
1290 crtc_state_is_legacy_gamma(crtc_state))
1291 return GAMMA_MODE_MODE_8BIT;
1293 return GAMMA_MODE_MODE_10BIT;
1296 static int glk_color_check(struct intel_crtc_state *crtc_state)
1300 ret = check_luts(crtc_state);
1304 crtc_state->gamma_enable =
1305 crtc_state->base.gamma_lut &&
1306 !crtc_state->c8_planes;
1308 /* On GLK+ degamma LUT is controlled by csc_enable */
1309 crtc_state->csc_enable =
1310 crtc_state->base.degamma_lut ||
1311 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1312 crtc_state->base.ctm || crtc_state->limited_color_range;
1314 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1316 crtc_state->csc_mode = 0;
1318 ret = intel_color_add_affected_planes(crtc_state);
1325 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1329 if (crtc_state->base.degamma_lut)
1330 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1332 if (crtc_state->base.gamma_lut &&
1333 !crtc_state->c8_planes)
1334 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1336 if (!crtc_state->base.gamma_lut ||
1337 crtc_state_is_legacy_gamma(crtc_state))
1338 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1340 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
1345 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1349 if (crtc_state->base.ctm)
1350 csc_mode |= ICL_CSC_ENABLE;
1352 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1353 crtc_state->limited_color_range)
1354 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1359 static int icl_color_check(struct intel_crtc_state *crtc_state)
1363 ret = check_luts(crtc_state);
1367 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1369 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1374 void intel_color_init(struct intel_crtc *crtc)
1376 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1377 bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0;
1379 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
1381 if (HAS_GMCH(dev_priv)) {
1382 if (IS_CHERRYVIEW(dev_priv)) {
1383 dev_priv->display.color_check = chv_color_check;
1384 dev_priv->display.color_commit = i9xx_color_commit;
1385 dev_priv->display.load_luts = chv_load_luts;
1386 } else if (INTEL_GEN(dev_priv) >= 4) {
1387 dev_priv->display.color_check = i9xx_color_check;
1388 dev_priv->display.color_commit = i9xx_color_commit;
1389 dev_priv->display.load_luts = i965_load_luts;
1391 dev_priv->display.color_check = i9xx_color_check;
1392 dev_priv->display.color_commit = i9xx_color_commit;
1393 dev_priv->display.load_luts = i9xx_load_luts;
1396 if (INTEL_GEN(dev_priv) >= 11)
1397 dev_priv->display.color_check = icl_color_check;
1398 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1399 dev_priv->display.color_check = glk_color_check;
1400 else if (INTEL_GEN(dev_priv) >= 7)
1401 dev_priv->display.color_check = ivb_color_check;
1403 dev_priv->display.color_check = ilk_color_check;
1405 if (INTEL_GEN(dev_priv) >= 9)
1406 dev_priv->display.color_commit = skl_color_commit;
1407 else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
1408 dev_priv->display.color_commit = hsw_color_commit;
1410 dev_priv->display.color_commit = ilk_color_commit;
1412 if (INTEL_GEN(dev_priv) >= 11)
1413 dev_priv->display.load_luts = icl_load_luts;
1414 else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
1415 dev_priv->display.load_luts = glk_load_luts;
1416 else if (INTEL_GEN(dev_priv) >= 8)
1417 dev_priv->display.load_luts = bdw_load_luts;
1418 else if (INTEL_GEN(dev_priv) >= 7)
1419 dev_priv->display.load_luts = ivb_load_luts;
1421 dev_priv->display.load_luts = ilk_load_luts;
1424 drm_crtc_enable_color_mgmt(&crtc->base,
1425 INTEL_INFO(dev_priv)->color.degamma_lut_size,
1427 INTEL_INFO(dev_priv)->color.gamma_lut_size);