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
45 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
46 * format). This macro takes the coefficient we want transformed and the
47 * number of fractional bits.
49 * We only have a 9 bits precision window which slides depending on the value
50 * of the CTM coefficient and we write the value from bit 3. We also round the
53 #define ILK_CSC_COEFF_FP(coeff, fbits) \
54 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
56 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
57 #define ILK_CSC_COEFF_1_0 0x7800
59 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
61 static const u16 ilk_csc_off_zero[3] = {};
63 static const u16 ilk_csc_coeff_identity[9] = {
64 ILK_CSC_COEFF_1_0, 0, 0,
65 0, ILK_CSC_COEFF_1_0, 0,
66 0, 0, ILK_CSC_COEFF_1_0,
69 static const u16 ilk_csc_postoff_limited_range[3] = {
70 ILK_CSC_POSTOFF_LIMITED_RANGE,
71 ILK_CSC_POSTOFF_LIMITED_RANGE,
72 ILK_CSC_POSTOFF_LIMITED_RANGE,
75 static const u16 ilk_csc_coeff_limited_range[9] = {
76 ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
77 0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
78 0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
82 * These values are direct register values specified in the Bspec,
83 * for RGB->YUV conversion matrix (colorspace BT709)
85 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
86 0x1e08, 0x9cc0, 0xb528,
87 0x2ba8, 0x09d8, 0x37e8,
88 0xbce8, 0x9ad8, 0x1e08,
91 /* Post offset values for RGB->YCBCR conversion */
92 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
93 0x0800, 0x0100, 0x0800,
96 static bool lut_is_legacy(const struct drm_property_blob *lut)
98 return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
101 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
103 return !crtc_state->base.degamma_lut &&
104 !crtc_state->base.ctm &&
105 crtc_state->base.gamma_lut &&
106 lut_is_legacy(crtc_state->base.gamma_lut);
110 * When using limited range, multiply the matrix given by userspace by
111 * the matrix that we would use for the limited range.
113 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
117 for (i = 0; i < 9; i++) {
118 u64 user_coeff = input[i];
119 u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
120 u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
121 CTM_COEFF_4_0 - 1) >> 2;
124 * By scaling every co-efficient with limited range (16-235)
125 * vs full range (0-255) the final o/p will be scaled down to
126 * fit in the limited range supported by the panel.
128 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
129 result[i] |= user_coeff & CTM_COEFF_SIGN;
135 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
138 const u16 postoff[3])
140 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
141 enum pipe pipe = crtc->pipe;
143 I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
144 I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
145 I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
147 I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
148 I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
150 I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
151 I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
153 I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
154 I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
156 if (INTEL_GEN(dev_priv) >= 7) {
157 I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff[0]);
158 I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff[1]);
159 I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff[2]);
163 static void icl_update_output_csc(struct intel_crtc *crtc,
166 const u16 postoff[3])
168 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
169 enum pipe pipe = crtc->pipe;
171 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
172 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
173 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
175 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
176 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2] << 16);
178 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
179 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5] << 16);
181 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
182 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8] << 16);
184 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
185 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
186 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
189 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
191 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
194 * FIXME if there's a gamma LUT after the CSC, we should
195 * do the range compression using the gamma LUT instead.
197 return crtc_state->limited_color_range &&
198 (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
199 IS_GEN_RANGE(dev_priv, 9, 10));
202 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
205 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
210 if (ilk_csc_limited_range(crtc_state))
211 input = ctm_mult_by_limited(temp, ctm->matrix);
216 * Convert fixed point S31.32 input to format supported by the
219 for (i = 0; i < 9; i++) {
220 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
223 * Clamp input value to min/max supported by
226 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
231 if (CTM_COEFF_NEGATIVE(input[i]))
232 coeffs[i] |= 1 << 15;
234 if (abs_coeff < CTM_COEFF_0_125)
235 coeffs[i] |= (3 << 12) |
236 ILK_CSC_COEFF_FP(abs_coeff, 12);
237 else if (abs_coeff < CTM_COEFF_0_25)
238 coeffs[i] |= (2 << 12) |
239 ILK_CSC_COEFF_FP(abs_coeff, 11);
240 else if (abs_coeff < CTM_COEFF_0_5)
241 coeffs[i] |= (1 << 12) |
242 ILK_CSC_COEFF_FP(abs_coeff, 10);
243 else if (abs_coeff < CTM_COEFF_1_0)
244 coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
245 else if (abs_coeff < CTM_COEFF_2_0)
246 coeffs[i] |= (7 << 12) |
247 ILK_CSC_COEFF_FP(abs_coeff, 8);
249 coeffs[i] |= (6 << 12) |
250 ILK_CSC_COEFF_FP(abs_coeff, 7);
254 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
256 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
257 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
258 bool limited_color_range = ilk_csc_limited_range(crtc_state);
260 if (crtc_state->base.ctm) {
263 ilk_csc_convert_ctm(crtc_state, coeff);
264 ilk_update_pipe_csc(crtc, ilk_csc_off_zero, coeff,
265 limited_color_range ?
266 ilk_csc_postoff_limited_range :
268 } else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
269 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
270 ilk_csc_coeff_rgb_to_ycbcr,
271 ilk_csc_postoff_rgb_to_ycbcr);
272 } else if (limited_color_range) {
273 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
274 ilk_csc_coeff_limited_range,
275 ilk_csc_postoff_limited_range);
276 } else if (crtc_state->csc_enable) {
278 * On GLK+ both pipe CSC and degamma LUT are controlled
279 * by csc_enable. Hence for the cases where the degama
280 * LUT is needed but CSC is not we need to load an
283 WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
285 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
286 ilk_csc_coeff_identity,
290 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
293 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
295 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
296 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
298 if (crtc_state->base.ctm) {
301 ilk_csc_convert_ctm(crtc_state, coeff);
302 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
303 coeff, ilk_csc_off_zero);
306 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
307 icl_update_output_csc(crtc, ilk_csc_off_zero,
308 ilk_csc_coeff_rgb_to_ycbcr,
309 ilk_csc_postoff_rgb_to_ycbcr);
310 } else if (crtc_state->limited_color_range) {
311 icl_update_output_csc(crtc, ilk_csc_off_zero,
312 ilk_csc_coeff_limited_range,
313 ilk_csc_postoff_limited_range);
316 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
320 * Set up the pipe CSC unit on CherryView.
322 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
324 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
325 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
326 enum pipe pipe = crtc->pipe;
328 if (crtc_state->base.ctm) {
329 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
333 for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
335 ((1ULL << 63) - 1) & ctm->matrix[i];
337 /* Round coefficient. */
338 abs_coeff += 1 << (32 - 13);
339 /* Clamp to hardware limits. */
340 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
342 /* Write coefficients in S3.12 format. */
343 if (ctm->matrix[i] & (1ULL << 63))
345 coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
346 coeffs[i] |= (abs_coeff >> 20) & 0xfff;
349 I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe),
350 coeffs[1] << 16 | coeffs[0]);
351 I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe),
352 coeffs[3] << 16 | coeffs[2]);
353 I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe),
354 coeffs[5] << 16 | coeffs[4]);
355 I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe),
356 coeffs[7] << 16 | coeffs[6]);
357 I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]);
360 I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
363 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
364 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
366 return (color->red & 0xff) << 16 |
367 (color->green & 0xff) << 8 |
368 (color->blue & 0xff);
371 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
372 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
374 return (color->red >> 8) << 16 |
375 (color->green >> 8) << 8 |
379 static u32 ilk_lut_10(const struct drm_color_lut *color)
381 return drm_color_lut_extract(color->red, 10) << 20 |
382 drm_color_lut_extract(color->green, 10) << 10 |
383 drm_color_lut_extract(color->blue, 10);
386 /* Loads the legacy palette/gamma unit for the CRTC. */
387 static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
388 const struct drm_property_blob *blob)
390 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
391 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
392 enum pipe pipe = crtc->pipe;
395 if (HAS_GMCH(dev_priv)) {
396 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
397 assert_dsi_pll_enabled(dev_priv);
399 assert_pll_enabled(dev_priv, pipe);
403 const struct drm_color_lut *lut = blob->data;
405 for (i = 0; i < 256; i++) {
407 (drm_color_lut_extract(lut[i].red, 8) << 16) |
408 (drm_color_lut_extract(lut[i].green, 8) << 8) |
409 drm_color_lut_extract(lut[i].blue, 8);
411 if (HAS_GMCH(dev_priv))
412 I915_WRITE(PALETTE(pipe, i), word);
414 I915_WRITE(LGC_PALETTE(pipe, i), word);
419 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
421 i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
424 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
426 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
427 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
428 enum pipe pipe = crtc->pipe;
431 val = I915_READ(PIPECONF(pipe));
432 val &= ~PIPECONF_GAMMA_MODE_MASK_I9XX;
433 val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
434 I915_WRITE(PIPECONF(pipe), val);
437 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
439 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
440 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
441 enum pipe pipe = crtc->pipe;
444 val = I915_READ(PIPECONF(pipe));
445 val &= ~PIPECONF_GAMMA_MODE_MASK_ILK;
446 val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
447 I915_WRITE(PIPECONF(pipe), val);
449 ilk_load_csc_matrix(crtc_state);
452 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
454 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
455 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
457 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
459 ilk_load_csc_matrix(crtc_state);
462 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
464 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
465 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
466 enum pipe pipe = crtc->pipe;
470 * We don't (yet) allow userspace to control the pipe background color,
471 * so force it to black, but apply pipe gamma and CSC appropriately
472 * so that its handling will match how we program our planes.
474 if (crtc_state->gamma_enable)
475 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
476 if (crtc_state->csc_enable)
477 val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
478 I915_WRITE(SKL_BOTTOM_COLOR(pipe), val);
480 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
482 if (INTEL_GEN(dev_priv) >= 11)
483 icl_load_csc_matrix(crtc_state);
485 ilk_load_csc_matrix(crtc_state);
488 static void i965_load_lut_10p6(struct intel_crtc *crtc,
489 const struct drm_property_blob *blob)
491 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
492 const struct drm_color_lut *lut = blob->data;
493 int i, lut_size = drm_color_lut_size(blob);
494 enum pipe pipe = crtc->pipe;
496 for (i = 0; i < lut_size - 1; i++) {
497 I915_WRITE(PALETTE(pipe, 2 * i + 0),
498 i965_lut_10p6_ldw(&lut[i]));
499 I915_WRITE(PALETTE(pipe, 2 * i + 1),
500 i965_lut_10p6_udw(&lut[i]));
503 I915_WRITE(PIPEGCMAX(pipe, 0), lut[i].red);
504 I915_WRITE(PIPEGCMAX(pipe, 1), lut[i].green);
505 I915_WRITE(PIPEGCMAX(pipe, 2), lut[i].blue);
508 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
510 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
511 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
513 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
514 i9xx_load_luts(crtc_state);
516 i965_load_lut_10p6(crtc, gamma_lut);
519 static void ilk_load_lut_10(struct intel_crtc *crtc,
520 const struct drm_property_blob *blob)
522 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
523 const struct drm_color_lut *lut = blob->data;
524 int i, lut_size = drm_color_lut_size(blob);
525 enum pipe pipe = crtc->pipe;
527 for (i = 0; i < lut_size; i++)
528 I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
531 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
533 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
534 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
536 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
537 i9xx_load_luts(crtc_state);
539 ilk_load_lut_10(crtc, gamma_lut);
542 static int ivb_lut_10_size(u32 prec_index)
544 if (prec_index & PAL_PREC_SPLIT_MODE)
551 * IVB/HSW Bspec / PAL_PREC_INDEX:
552 * "Restriction : Index auto increment mode is not
553 * supported and must not be enabled."
555 static void ivb_load_lut_10(struct intel_crtc *crtc,
556 const struct drm_property_blob *blob,
559 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
560 int hw_lut_size = ivb_lut_10_size(prec_index);
561 const struct drm_color_lut *lut = blob->data;
562 int i, lut_size = drm_color_lut_size(blob);
563 enum pipe pipe = crtc->pipe;
565 for (i = 0; i < hw_lut_size; i++) {
566 /* We discard half the user entries in split gamma mode */
567 const struct drm_color_lut *entry =
568 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
570 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
571 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
575 * Reset the index, otherwise it prevents the legacy palette to be
578 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
581 /* On BDW+ the index auto increment mode actually works */
582 static void bdw_load_lut_10(struct intel_crtc *crtc,
583 const struct drm_property_blob *blob,
586 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
587 int hw_lut_size = ivb_lut_10_size(prec_index);
588 const struct drm_color_lut *lut = blob->data;
589 int i, lut_size = drm_color_lut_size(blob);
590 enum pipe pipe = crtc->pipe;
592 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
593 PAL_PREC_AUTO_INCREMENT);
595 for (i = 0; i < hw_lut_size; i++) {
596 /* We discard half the user entries in split gamma mode */
597 const struct drm_color_lut *entry =
598 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
600 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
604 * Reset the index, otherwise it prevents the legacy palette to be
607 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
610 static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
612 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
613 enum pipe pipe = crtc->pipe;
615 /* Program the max register to clamp values > 1.0. */
616 I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
617 I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
618 I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
621 * Program the gc max 2 register to clamp values > 1.0.
622 * ToDo: Extend the ABI to be able to program values
625 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
626 I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16);
627 I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16);
628 I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16);
632 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
634 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
635 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
636 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
638 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
639 i9xx_load_luts(crtc_state);
640 } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
641 ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
642 PAL_PREC_INDEX_VALUE(0));
643 ivb_load_lut_ext_max(crtc);
644 ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
645 PAL_PREC_INDEX_VALUE(512));
647 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
649 ivb_load_lut_10(crtc, blob,
650 PAL_PREC_INDEX_VALUE(0));
651 ivb_load_lut_ext_max(crtc);
655 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
657 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
658 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
659 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
661 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
662 i9xx_load_luts(crtc_state);
663 } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
664 bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
665 PAL_PREC_INDEX_VALUE(0));
666 ivb_load_lut_ext_max(crtc);
667 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
668 PAL_PREC_INDEX_VALUE(512));
670 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
672 bdw_load_lut_10(crtc, blob,
673 PAL_PREC_INDEX_VALUE(0));
674 ivb_load_lut_ext_max(crtc);
678 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
680 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
681 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
682 enum pipe pipe = crtc->pipe;
683 const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
684 const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data;
688 * When setting the auto-increment bit, the hardware seems to
689 * ignore the index bits, so we need to reset it to index 0
692 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
693 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
695 for (i = 0; i < lut_size; i++) {
697 * First 33 entries represent range from 0 to 1.0
698 * 34th and 35th entry will represent extended range
699 * inputs 3.0 and 7.0 respectively, currently clamped
700 * at 1.0. Since the precision is 16bit, the user
701 * value can be directly filled to register.
702 * The pipe degamma table in GLK+ onwards doesn't
703 * support different values per channel, so this just
704 * programs green value which will be equal to Red and
705 * Blue into the lut registers.
706 * ToDo: Extend to max 7.0. Enable 32 bit input value
707 * as compared to just 16 to achieve this.
709 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
712 /* Clamp values > 1.0. */
714 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
717 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
719 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
720 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
721 enum pipe pipe = crtc->pipe;
722 const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
726 * When setting the auto-increment bit, the hardware seems to
727 * ignore the index bits, so we need to reset it to index 0
730 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
731 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
733 for (i = 0; i < lut_size; i++) {
734 u32 v = (i << 16) / (lut_size - 1);
736 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
739 /* Clamp values > 1.0. */
741 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
744 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
746 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
747 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
750 * On GLK+ both pipe CSC and degamma LUT are controlled
751 * by csc_enable. Hence for the cases where the CSC is
752 * needed but degamma LUT is not we need to load a
753 * linear degamma LUT. In fact we'll just always load
754 * the degama LUT so that we don't have to reload
755 * it every time the pipe CSC is being enabled.
757 if (crtc_state->base.degamma_lut)
758 glk_load_degamma_lut(crtc_state);
760 glk_load_degamma_lut_linear(crtc_state);
762 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
763 i9xx_load_luts(crtc_state);
765 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
766 ivb_load_lut_ext_max(crtc);
770 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
772 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
773 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
775 if (crtc_state->base.degamma_lut)
776 glk_load_degamma_lut(crtc_state);
778 if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) ==
779 GAMMA_MODE_MODE_8BIT) {
780 i9xx_load_luts(crtc_state);
782 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
783 ivb_load_lut_ext_max(crtc);
787 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
789 return drm_color_lut_extract(color->green, 14) << 16 |
790 drm_color_lut_extract(color->blue, 14);
793 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
795 return drm_color_lut_extract(color->red, 14);
798 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
799 const struct drm_property_blob *blob)
801 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
802 const struct drm_color_lut *lut = blob->data;
803 int i, lut_size = drm_color_lut_size(blob);
804 enum pipe pipe = crtc->pipe;
806 for (i = 0; i < lut_size; i++) {
807 I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0),
808 chv_cgm_degamma_ldw(&lut[i]));
809 I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1),
810 chv_cgm_degamma_udw(&lut[i]));
814 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
816 return drm_color_lut_extract(color->green, 10) << 16 |
817 drm_color_lut_extract(color->blue, 10);
820 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
822 return drm_color_lut_extract(color->red, 10);
825 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
826 const struct drm_property_blob *blob)
828 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
829 const struct drm_color_lut *lut = blob->data;
830 int i, lut_size = drm_color_lut_size(blob);
831 enum pipe pipe = crtc->pipe;
833 for (i = 0; i < lut_size; i++) {
834 I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0),
835 chv_cgm_gamma_ldw(&lut[i]));
836 I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1),
837 chv_cgm_gamma_udw(&lut[i]));
841 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
843 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
844 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
845 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
847 cherryview_load_csc_matrix(crtc_state);
849 if (crtc_state_is_legacy_gamma(crtc_state)) {
850 i9xx_load_luts(crtc_state);
855 chv_load_cgm_degamma(crtc, degamma_lut);
858 chv_load_cgm_gamma(crtc, gamma_lut);
861 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
863 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
865 dev_priv->display.load_luts(crtc_state);
868 void intel_color_commit(const struct intel_crtc_state *crtc_state)
870 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
872 dev_priv->display.color_commit(crtc_state);
875 int intel_color_check(struct intel_crtc_state *crtc_state)
877 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
879 return dev_priv->display.color_check(crtc_state);
882 void intel_color_get_config(struct intel_crtc_state *crtc_state)
884 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
886 if (dev_priv->display.read_luts)
887 dev_priv->display.read_luts(crtc_state);
890 static bool need_plane_update(struct intel_plane *plane,
891 const struct intel_crtc_state *crtc_state)
893 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
896 * On pre-SKL the pipe gamma enable and pipe csc enable for
897 * the pipe bottom color are configured via the primary plane.
898 * We have to reconfigure that even if the plane is inactive.
900 return crtc_state->active_planes & BIT(plane->id) ||
901 (INTEL_GEN(dev_priv) < 9 &&
902 plane->id == PLANE_PRIMARY);
906 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
908 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
909 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
910 struct intel_atomic_state *state =
911 to_intel_atomic_state(new_crtc_state->base.state);
912 const struct intel_crtc_state *old_crtc_state =
913 intel_atomic_get_old_crtc_state(state, crtc);
914 struct intel_plane *plane;
916 if (!new_crtc_state->base.active ||
917 drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
920 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
921 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
924 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
925 struct intel_plane_state *plane_state;
927 if (!need_plane_update(plane, new_crtc_state))
930 plane_state = intel_atomic_get_plane_state(state, plane);
931 if (IS_ERR(plane_state))
932 return PTR_ERR(plane_state);
934 new_crtc_state->update_planes |= BIT(plane->id);
940 static int check_lut_size(const struct drm_property_blob *lut, int expected)
947 len = drm_color_lut_size(lut);
948 if (len != expected) {
949 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
957 static int check_luts(const struct intel_crtc_state *crtc_state)
959 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
960 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
961 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
962 int gamma_length, degamma_length;
963 u32 gamma_tests, degamma_tests;
965 /* Always allow legacy gamma LUT with no further checking. */
966 if (crtc_state_is_legacy_gamma(crtc_state))
969 /* C8 relies on its palette being stored in the legacy LUT */
970 if (crtc_state->c8_planes) {
971 DRM_DEBUG_KMS("C8 pixelformat requires the legacy LUT\n");
975 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
976 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
977 degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
978 gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
980 if (check_lut_size(degamma_lut, degamma_length) ||
981 check_lut_size(gamma_lut, gamma_length))
984 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
985 drm_color_lut_check(gamma_lut, gamma_tests))
991 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
993 if (!crtc_state->gamma_enable ||
994 crtc_state_is_legacy_gamma(crtc_state))
995 return GAMMA_MODE_MODE_8BIT;
997 return GAMMA_MODE_MODE_10BIT; /* i965+ only */
1000 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1004 ret = check_luts(crtc_state);
1008 crtc_state->gamma_enable =
1009 crtc_state->base.gamma_lut &&
1010 !crtc_state->c8_planes;
1012 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1014 ret = intel_color_add_affected_planes(crtc_state);
1021 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1025 if (crtc_state_is_legacy_gamma(crtc_state))
1028 if (crtc_state->base.degamma_lut)
1029 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1030 if (crtc_state->base.ctm)
1031 cgm_mode |= CGM_PIPE_MODE_CSC;
1032 if (crtc_state->base.gamma_lut)
1033 cgm_mode |= CGM_PIPE_MODE_GAMMA;
1039 * CHV color pipeline:
1040 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
1041 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
1043 * We always bypass the WGC csc and use the CGM csc
1044 * instead since it has degamma and better precision.
1046 static int chv_color_check(struct intel_crtc_state *crtc_state)
1050 ret = check_luts(crtc_state);
1055 * Pipe gamma will be used only for the legacy LUT.
1056 * Otherwise we bypass it and use the CGM gamma instead.
1058 crtc_state->gamma_enable =
1059 crtc_state_is_legacy_gamma(crtc_state) &&
1060 !crtc_state->c8_planes;
1062 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1064 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1066 ret = intel_color_add_affected_planes(crtc_state);
1073 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1075 if (!crtc_state->gamma_enable ||
1076 crtc_state_is_legacy_gamma(crtc_state))
1077 return GAMMA_MODE_MODE_8BIT;
1079 return GAMMA_MODE_MODE_10BIT;
1082 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1086 ret = check_luts(crtc_state);
1090 crtc_state->gamma_enable =
1091 crtc_state->base.gamma_lut &&
1092 !crtc_state->c8_planes;
1095 * We don't expose the ctm on ilk/snb currently,
1096 * nor do we enable YCbCr output. Also RGB limited
1097 * range output is handled by the hw automagically.
1099 crtc_state->csc_enable = false;
1101 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1103 crtc_state->csc_mode = 0;
1105 ret = intel_color_add_affected_planes(crtc_state);
1112 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1114 if (!crtc_state->gamma_enable ||
1115 crtc_state_is_legacy_gamma(crtc_state))
1116 return GAMMA_MODE_MODE_8BIT;
1117 else if (crtc_state->base.gamma_lut &&
1118 crtc_state->base.degamma_lut)
1119 return GAMMA_MODE_MODE_SPLIT;
1121 return GAMMA_MODE_MODE_10BIT;
1124 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1126 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1129 * CSC comes after the LUT in degamma, RGB->YCbCr,
1130 * and RGB full->limited range mode.
1132 if (crtc_state->base.degamma_lut ||
1133 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1134 limited_color_range)
1137 return CSC_POSITION_BEFORE_GAMMA;
1140 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1142 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1145 ret = check_luts(crtc_state);
1149 crtc_state->gamma_enable =
1150 (crtc_state->base.gamma_lut ||
1151 crtc_state->base.degamma_lut) &&
1152 !crtc_state->c8_planes;
1154 crtc_state->csc_enable =
1155 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1156 crtc_state->base.ctm || limited_color_range;
1158 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1160 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1162 ret = intel_color_add_affected_planes(crtc_state);
1169 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1171 if (!crtc_state->gamma_enable ||
1172 crtc_state_is_legacy_gamma(crtc_state))
1173 return GAMMA_MODE_MODE_8BIT;
1175 return GAMMA_MODE_MODE_10BIT;
1178 static int glk_color_check(struct intel_crtc_state *crtc_state)
1182 ret = check_luts(crtc_state);
1186 crtc_state->gamma_enable =
1187 crtc_state->base.gamma_lut &&
1188 !crtc_state->c8_planes;
1190 /* On GLK+ degamma LUT is controlled by csc_enable */
1191 crtc_state->csc_enable =
1192 crtc_state->base.degamma_lut ||
1193 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1194 crtc_state->base.ctm || crtc_state->limited_color_range;
1196 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1198 crtc_state->csc_mode = 0;
1200 ret = intel_color_add_affected_planes(crtc_state);
1207 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1211 if (crtc_state->base.degamma_lut)
1212 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1214 if (crtc_state->base.gamma_lut &&
1215 !crtc_state->c8_planes)
1216 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1218 if (!crtc_state->base.gamma_lut ||
1219 crtc_state_is_legacy_gamma(crtc_state))
1220 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1222 gamma_mode |= GAMMA_MODE_MODE_10BIT;
1227 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1231 if (crtc_state->base.ctm)
1232 csc_mode |= ICL_CSC_ENABLE;
1234 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1235 crtc_state->limited_color_range)
1236 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1241 static int icl_color_check(struct intel_crtc_state *crtc_state)
1245 ret = check_luts(crtc_state);
1249 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1251 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1256 void intel_color_init(struct intel_crtc *crtc)
1258 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1259 bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0;
1261 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
1263 if (HAS_GMCH(dev_priv)) {
1264 if (IS_CHERRYVIEW(dev_priv)) {
1265 dev_priv->display.color_check = chv_color_check;
1266 dev_priv->display.color_commit = i9xx_color_commit;
1267 dev_priv->display.load_luts = chv_load_luts;
1268 } else if (INTEL_GEN(dev_priv) >= 4) {
1269 dev_priv->display.color_check = i9xx_color_check;
1270 dev_priv->display.color_commit = i9xx_color_commit;
1271 dev_priv->display.load_luts = i965_load_luts;
1273 dev_priv->display.color_check = i9xx_color_check;
1274 dev_priv->display.color_commit = i9xx_color_commit;
1275 dev_priv->display.load_luts = i9xx_load_luts;
1278 if (INTEL_GEN(dev_priv) >= 11)
1279 dev_priv->display.color_check = icl_color_check;
1280 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1281 dev_priv->display.color_check = glk_color_check;
1282 else if (INTEL_GEN(dev_priv) >= 7)
1283 dev_priv->display.color_check = ivb_color_check;
1285 dev_priv->display.color_check = ilk_color_check;
1287 if (INTEL_GEN(dev_priv) >= 9)
1288 dev_priv->display.color_commit = skl_color_commit;
1289 else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
1290 dev_priv->display.color_commit = hsw_color_commit;
1292 dev_priv->display.color_commit = ilk_color_commit;
1294 if (INTEL_GEN(dev_priv) >= 11)
1295 dev_priv->display.load_luts = icl_load_luts;
1296 else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
1297 dev_priv->display.load_luts = glk_load_luts;
1298 else if (INTEL_GEN(dev_priv) >= 8)
1299 dev_priv->display.load_luts = bdw_load_luts;
1300 else if (INTEL_GEN(dev_priv) >= 7)
1301 dev_priv->display.load_luts = ivb_load_luts;
1303 dev_priv->display.load_luts = ilk_load_luts;
1306 drm_crtc_enable_color_mgmt(&crtc->base,
1307 INTEL_INFO(dev_priv)->color.degamma_lut_size,
1309 INTEL_INFO(dev_priv)->color.gamma_lut_size);