]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/i915/intel_color.c
46443ae06bf58a1cf752d8b2b00ba95271a233ea
[linux.git] / drivers / gpu / drm / i915 / intel_color.c
1 /*
2  * Copyright © 2016 Intel Corporation
3  *
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:
10  *
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
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE 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.
22  *
23  */
24
25 #include "intel_color.h"
26 #include "intel_drv.h"
27
28 #define CTM_COEFF_SIGN  (1ULL << 63)
29
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)
37
38 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
39
40 #define CTM_COEFF_NEGATIVE(coeff)       (((coeff) & CTM_COEFF_SIGN) != 0)
41 #define CTM_COEFF_ABS(coeff)            ((coeff) & (CTM_COEFF_SIGN - 1))
42
43 #define LEGACY_LUT_LENGTH               256
44 /*
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.
48  *
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
51  * value.
52  */
53 #define ILK_CSC_COEFF_FP(coeff, fbits)  \
54         (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
55
56 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
57 #define ILK_CSC_COEFF_1_0 0x7800
58
59 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
60
61 static const u16 ilk_csc_off_zero[3] = {};
62
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,
67 };
68
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,
73 };
74
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,
79 };
80
81 /*
82  * These values are direct register values specified in the Bspec,
83  * for RGB->YUV conversion matrix (colorspace BT709)
84  */
85 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
86         0x1e08, 0x9cc0, 0xb528,
87         0x2ba8, 0x09d8, 0x37e8,
88         0xbce8, 0x9ad8, 0x1e08,
89 };
90
91 /* Post offset values for RGB->YCBCR conversion */
92 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
93         0x0800, 0x0100, 0x0800,
94 };
95
96 static bool lut_is_legacy(const struct drm_property_blob *lut)
97 {
98         return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
99 }
100
101 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
102 {
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);
107 }
108
109 /*
110  * When using limited range, multiply the matrix given by userspace by
111  * the matrix that we would use for the limited range.
112  */
113 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
114 {
115         int i;
116
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;
122
123                 /*
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.
127                  */
128                 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
129                 result[i] |= user_coeff & CTM_COEFF_SIGN;
130         }
131
132         return result;
133 }
134
135 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
136                                 const u16 preoff[3],
137                                 const u16 coeff[9],
138                                 const u16 postoff[3])
139 {
140         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
141         enum pipe pipe = crtc->pipe;
142
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]);
146
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);
149
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);
152
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);
155
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]);
160         }
161 }
162
163 static void icl_update_output_csc(struct intel_crtc *crtc,
164                                   const u16 preoff[3],
165                                   const u16 coeff[9],
166                                   const u16 postoff[3])
167 {
168         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
169         enum pipe pipe = crtc->pipe;
170
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]);
174
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);
177
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);
180
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);
183
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]);
187 }
188
189 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
190 {
191         struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
192
193         /*
194          * FIXME if there's a gamma LUT after the CSC, we should
195          * do the range compression using the gamma LUT instead.
196          */
197         return crtc_state->limited_color_range &&
198                 (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
199                  IS_GEN_RANGE(dev_priv, 9, 10));
200 }
201
202 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
203                                 u16 coeffs[9])
204 {
205         const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
206         const u64 *input;
207         u64 temp[9];
208         int i;
209
210         if (ilk_csc_limited_range(crtc_state))
211                 input = ctm_mult_by_limited(temp, ctm->matrix);
212         else
213                 input = ctm->matrix;
214
215         /*
216          * Convert fixed point S31.32 input to format supported by the
217          * hardware.
218          */
219         for (i = 0; i < 9; i++) {
220                 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
221
222                 /*
223                  * Clamp input value to min/max supported by
224                  * hardware.
225                  */
226                 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
227
228                 coeffs[i] = 0;
229
230                 /* sign bit */
231                 if (CTM_COEFF_NEGATIVE(input[i]))
232                         coeffs[i] |= 1 << 15;
233
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);
248                 else
249                         coeffs[i] |= (6 << 12) |
250                                 ILK_CSC_COEFF_FP(abs_coeff, 7);
251         }
252 }
253
254 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
255 {
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);
259
260         if (crtc_state->base.ctm) {
261                 u16 coeff[9];
262
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 :
267                                     ilk_csc_off_zero);
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) {
277                 /*
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
281                  * identity matrix.
282                  */
283                 WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
284
285                 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
286                                     ilk_csc_coeff_identity,
287                                     ilk_csc_off_zero);
288         }
289
290         I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
291 }
292
293 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
294 {
295         struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
296         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
297
298         if (crtc_state->base.ctm) {
299                 u16 coeff[9];
300
301                 ilk_csc_convert_ctm(crtc_state, coeff);
302                 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
303                                     coeff, ilk_csc_off_zero);
304         }
305
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);
314         }
315
316         I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
317 }
318
319 /*
320  * Set up the pipe CSC unit on CherryView.
321  */
322 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
323 {
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;
327
328         if (crtc_state->base.ctm) {
329                 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
330                 u16 coeffs[9] = {};
331                 int i;
332
333                 for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
334                         u64 abs_coeff =
335                                 ((1ULL << 63) - 1) & ctm->matrix[i];
336
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);
341
342                         /* Write coefficients in S3.12 format. */
343                         if (ctm->matrix[i] & (1ULL << 63))
344                                 coeffs[i] = 1 << 15;
345                         coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
346                         coeffs[i] |= (abs_coeff >> 20) & 0xfff;
347                 }
348
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]);
358         }
359
360         I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
361 }
362
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)
365 {
366         return (color->red & 0xff) << 16 |
367                 (color->green & 0xff) << 8 |
368                 (color->blue & 0xff);
369 }
370
371 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
372 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
373 {
374         return (color->red >> 8) << 16 |
375                 (color->green >> 8) << 8 |
376                 (color->blue >> 8);
377 }
378
379 static u32 ilk_lut_10(const struct drm_color_lut *color)
380 {
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);
384 }
385
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)
389 {
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;
393         int i;
394
395         if (HAS_GMCH(dev_priv)) {
396                 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
397                         assert_dsi_pll_enabled(dev_priv);
398                 else
399                         assert_pll_enabled(dev_priv, pipe);
400         }
401
402         if (blob) {
403                 const struct drm_color_lut *lut = blob->data;
404
405                 for (i = 0; i < 256; i++) {
406                         u32 word =
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);
410
411                         if (HAS_GMCH(dev_priv))
412                                 I915_WRITE(PALETTE(pipe, i), word);
413                         else
414                                 I915_WRITE(LGC_PALETTE(pipe, i), word);
415                 }
416         }
417 }
418
419 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
420 {
421         i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
422 }
423
424 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
425 {
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;
429         u32 val;
430
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);
435 }
436
437 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
438 {
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;
442         u32 val;
443
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);
448
449         ilk_load_csc_matrix(crtc_state);
450 }
451
452 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
453 {
454         struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
455         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
456
457         I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
458
459         ilk_load_csc_matrix(crtc_state);
460 }
461
462 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
463 {
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;
467         u32 val = 0;
468
469         /*
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.
473          */
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);
479
480         I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
481
482         if (INTEL_GEN(dev_priv) >= 11)
483                 icl_load_csc_matrix(crtc_state);
484         else
485                 ilk_load_csc_matrix(crtc_state);
486 }
487
488 static void i965_load_lut_10p6(struct intel_crtc *crtc,
489                                const struct drm_property_blob *blob)
490 {
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;
495
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]));
501         }
502
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);
506 }
507
508 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
509 {
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;
512
513         if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
514                 i9xx_load_luts(crtc_state);
515         else
516                 i965_load_lut_10p6(crtc, gamma_lut);
517 }
518
519 static void ilk_load_lut_10(struct intel_crtc *crtc,
520                             const struct drm_property_blob *blob)
521 {
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;
526
527         for (i = 0; i < lut_size; i++)
528                 I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
529 }
530
531 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
532 {
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;
535
536         if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
537                 i9xx_load_luts(crtc_state);
538         else
539                 ilk_load_lut_10(crtc, gamma_lut);
540 }
541
542 static int ivb_lut_10_size(u32 prec_index)
543 {
544         if (prec_index & PAL_PREC_SPLIT_MODE)
545                 return 512;
546         else
547                 return 1024;
548 }
549
550 /*
551  * IVB/HSW Bspec / PAL_PREC_INDEX:
552  * "Restriction : Index auto increment mode is not
553  *  supported and must not be enabled."
554  */
555 static void ivb_load_lut_10(struct intel_crtc *crtc,
556                             const struct drm_property_blob *blob,
557                             u32 prec_index)
558 {
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;
564
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)];
569
570                 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
571                 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
572         }
573
574         /*
575          * Reset the index, otherwise it prevents the legacy palette to be
576          * written properly.
577          */
578         I915_WRITE(PREC_PAL_INDEX(pipe), 0);
579 }
580
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,
584                             u32 prec_index)
585 {
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;
591
592         I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
593                    PAL_PREC_AUTO_INCREMENT);
594
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)];
599
600                 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
601         }
602
603         /*
604          * Reset the index, otherwise it prevents the legacy palette to be
605          * written properly.
606          */
607         I915_WRITE(PREC_PAL_INDEX(pipe), 0);
608 }
609
610 static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
611 {
612         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
613         enum pipe pipe = crtc->pipe;
614
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);
619
620         /*
621          * Program the gc max 2 register to clamp values > 1.0.
622          * ToDo: Extend the ABI to be able to program values
623          * from 3.0 to 7.0
624          */
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);
629         }
630 }
631
632 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
633 {
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;
637
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));
646         } else {
647                 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
648
649                 ivb_load_lut_10(crtc, blob,
650                                 PAL_PREC_INDEX_VALUE(0));
651                 ivb_load_lut_ext_max(crtc);
652         }
653 }
654
655 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
656 {
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;
660
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));
669         } else {
670                 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
671
672                 bdw_load_lut_10(crtc, blob,
673                                 PAL_PREC_INDEX_VALUE(0));
674                 ivb_load_lut_ext_max(crtc);
675         }
676 }
677
678 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
679 {
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;
685         u32 i;
686
687         /*
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
690          * separately.
691          */
692         I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
693         I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
694
695         for (i = 0; i < lut_size; i++) {
696                 /*
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.
708                  */
709                 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
710         }
711
712         /* Clamp values > 1.0. */
713         while (i++ < 35)
714                 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
715 }
716
717 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
718 {
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;
723         u32 i;
724
725         /*
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
728          * separately.
729          */
730         I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
731         I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
732
733         for (i = 0; i < lut_size; i++) {
734                 u32 v = (i << 16) / (lut_size - 1);
735
736                 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
737         }
738
739         /* Clamp values > 1.0. */
740         while (i++ < 35)
741                 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
742 }
743
744 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
745 {
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);
748
749         /*
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.
756          */
757         if (crtc_state->base.degamma_lut)
758                 glk_load_degamma_lut(crtc_state);
759         else
760                 glk_load_degamma_lut_linear(crtc_state);
761
762         if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
763                 i9xx_load_luts(crtc_state);
764         } else {
765                 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
766                 ivb_load_lut_ext_max(crtc);
767         }
768 }
769
770 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
771 {
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);
774
775         if (crtc_state->base.degamma_lut)
776                 glk_load_degamma_lut(crtc_state);
777
778         if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) ==
779             GAMMA_MODE_MODE_8BIT) {
780                 i9xx_load_luts(crtc_state);
781         } else {
782                 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
783                 ivb_load_lut_ext_max(crtc);
784         }
785 }
786
787 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
788 {
789         return drm_color_lut_extract(color->green, 14) << 16 |
790                 drm_color_lut_extract(color->blue, 14);
791 }
792
793 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
794 {
795         return drm_color_lut_extract(color->red, 14);
796 }
797
798 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
799                                  const struct drm_property_blob *blob)
800 {
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;
805
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]));
811         }
812 }
813
814 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
815 {
816         return drm_color_lut_extract(color->green, 10) << 16 |
817                 drm_color_lut_extract(color->blue, 10);
818 }
819
820 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
821 {
822         return drm_color_lut_extract(color->red, 10);
823 }
824
825 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
826                                const struct drm_property_blob *blob)
827 {
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;
832
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]));
838         }
839 }
840
841 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
842 {
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;
846
847         cherryview_load_csc_matrix(crtc_state);
848
849         if (crtc_state_is_legacy_gamma(crtc_state)) {
850                 i9xx_load_luts(crtc_state);
851                 return;
852         }
853
854         if (degamma_lut)
855                 chv_load_cgm_degamma(crtc, degamma_lut);
856
857         if (gamma_lut)
858                 chv_load_cgm_gamma(crtc, gamma_lut);
859 }
860
861 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
862 {
863         struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
864
865         dev_priv->display.load_luts(crtc_state);
866 }
867
868 void intel_color_commit(const struct intel_crtc_state *crtc_state)
869 {
870         struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
871
872         dev_priv->display.color_commit(crtc_state);
873 }
874
875 int intel_color_check(struct intel_crtc_state *crtc_state)
876 {
877         struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
878
879         return dev_priv->display.color_check(crtc_state);
880 }
881
882 void intel_color_get_config(struct intel_crtc_state *crtc_state)
883 {
884         struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
885
886         if (dev_priv->display.read_luts)
887                 dev_priv->display.read_luts(crtc_state);
888 }
889
890 static bool need_plane_update(struct intel_plane *plane,
891                               const struct intel_crtc_state *crtc_state)
892 {
893         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
894
895         /*
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.
899          */
900         return crtc_state->active_planes & BIT(plane->id) ||
901                 (INTEL_GEN(dev_priv) < 9 &&
902                  plane->id == PLANE_PRIMARY);
903 }
904
905 static int
906 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
907 {
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;
915
916         if (!new_crtc_state->base.active ||
917             drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
918                 return 0;
919
920         if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
921             new_crtc_state->csc_enable == old_crtc_state->csc_enable)
922                 return 0;
923
924         for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
925                 struct intel_plane_state *plane_state;
926
927                 if (!need_plane_update(plane, new_crtc_state))
928                         continue;
929
930                 plane_state = intel_atomic_get_plane_state(state, plane);
931                 if (IS_ERR(plane_state))
932                         return PTR_ERR(plane_state);
933
934                 new_crtc_state->update_planes |= BIT(plane->id);
935         }
936
937         return 0;
938 }
939
940 static int check_lut_size(const struct drm_property_blob *lut, int expected)
941 {
942         int len;
943
944         if (!lut)
945                 return 0;
946
947         len = drm_color_lut_size(lut);
948         if (len != expected) {
949                 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
950                               len, expected);
951                 return -EINVAL;
952         }
953
954         return 0;
955 }
956
957 static int check_luts(const struct intel_crtc_state *crtc_state)
958 {
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;
964
965         /* Always allow legacy gamma LUT with no further checking. */
966         if (crtc_state_is_legacy_gamma(crtc_state))
967                 return 0;
968
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");
972                 return -EINVAL;
973         }
974
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;
979
980         if (check_lut_size(degamma_lut, degamma_length) ||
981             check_lut_size(gamma_lut, gamma_length))
982                 return -EINVAL;
983
984         if (drm_color_lut_check(degamma_lut, degamma_tests) ||
985             drm_color_lut_check(gamma_lut, gamma_tests))
986                 return -EINVAL;
987
988         return 0;
989 }
990
991 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
992 {
993         if (!crtc_state->gamma_enable ||
994             crtc_state_is_legacy_gamma(crtc_state))
995                 return GAMMA_MODE_MODE_8BIT;
996         else
997                 return GAMMA_MODE_MODE_10BIT; /* i965+ only */
998 }
999
1000 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1001 {
1002         int ret;
1003
1004         ret = check_luts(crtc_state);
1005         if (ret)
1006                 return ret;
1007
1008         crtc_state->gamma_enable =
1009                 crtc_state->base.gamma_lut &&
1010                 !crtc_state->c8_planes;
1011
1012         crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1013
1014         ret = intel_color_add_affected_planes(crtc_state);
1015         if (ret)
1016                 return ret;
1017
1018         return 0;
1019 }
1020
1021 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1022 {
1023         u32 cgm_mode = 0;
1024
1025         if (crtc_state_is_legacy_gamma(crtc_state))
1026                 return 0;
1027
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;
1034
1035         return cgm_mode;
1036 }
1037
1038 /*
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
1042  *
1043  * We always bypass the WGC csc and use the CGM csc
1044  * instead since it has degamma and better precision.
1045  */
1046 static int chv_color_check(struct intel_crtc_state *crtc_state)
1047 {
1048         int ret;
1049
1050         ret = check_luts(crtc_state);
1051         if (ret)
1052                 return ret;
1053
1054         /*
1055          * Pipe gamma will be used only for the legacy LUT.
1056          * Otherwise we bypass it and use the CGM gamma instead.
1057          */
1058         crtc_state->gamma_enable =
1059                 crtc_state_is_legacy_gamma(crtc_state) &&
1060                 !crtc_state->c8_planes;
1061
1062         crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1063
1064         crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1065
1066         ret = intel_color_add_affected_planes(crtc_state);
1067         if (ret)
1068                 return ret;
1069
1070         return 0;
1071 }
1072
1073 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1074 {
1075         if (!crtc_state->gamma_enable ||
1076             crtc_state_is_legacy_gamma(crtc_state))
1077                 return GAMMA_MODE_MODE_8BIT;
1078         else
1079                 return GAMMA_MODE_MODE_10BIT;
1080 }
1081
1082 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1083 {
1084         int ret;
1085
1086         ret = check_luts(crtc_state);
1087         if (ret)
1088                 return ret;
1089
1090         crtc_state->gamma_enable =
1091                 crtc_state->base.gamma_lut &&
1092                 !crtc_state->c8_planes;
1093
1094         /*
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.
1098          */
1099         crtc_state->csc_enable = false;
1100
1101         crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1102
1103         crtc_state->csc_mode = 0;
1104
1105         ret = intel_color_add_affected_planes(crtc_state);
1106         if (ret)
1107                 return ret;
1108
1109         return 0;
1110 }
1111
1112 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1113 {
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;
1120         else
1121                 return GAMMA_MODE_MODE_10BIT;
1122 }
1123
1124 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1125 {
1126         bool limited_color_range = ilk_csc_limited_range(crtc_state);
1127
1128         /*
1129          * CSC comes after the LUT in degamma, RGB->YCbCr,
1130          * and RGB full->limited range mode.
1131          */
1132         if (crtc_state->base.degamma_lut ||
1133             crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1134             limited_color_range)
1135                 return 0;
1136
1137         return CSC_POSITION_BEFORE_GAMMA;
1138 }
1139
1140 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1141 {
1142         bool limited_color_range = ilk_csc_limited_range(crtc_state);
1143         int ret;
1144
1145         ret = check_luts(crtc_state);
1146         if (ret)
1147                 return ret;
1148
1149         crtc_state->gamma_enable =
1150                 (crtc_state->base.gamma_lut ||
1151                  crtc_state->base.degamma_lut) &&
1152                 !crtc_state->c8_planes;
1153
1154         crtc_state->csc_enable =
1155                 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1156                 crtc_state->base.ctm || limited_color_range;
1157
1158         crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1159
1160         crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1161
1162         ret = intel_color_add_affected_planes(crtc_state);
1163         if (ret)
1164                 return ret;
1165
1166         return 0;
1167 }
1168
1169 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1170 {
1171         if (!crtc_state->gamma_enable ||
1172             crtc_state_is_legacy_gamma(crtc_state))
1173                 return GAMMA_MODE_MODE_8BIT;
1174         else
1175                 return GAMMA_MODE_MODE_10BIT;
1176 }
1177
1178 static int glk_color_check(struct intel_crtc_state *crtc_state)
1179 {
1180         int ret;
1181
1182         ret = check_luts(crtc_state);
1183         if (ret)
1184                 return ret;
1185
1186         crtc_state->gamma_enable =
1187                 crtc_state->base.gamma_lut &&
1188                 !crtc_state->c8_planes;
1189
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;
1195
1196         crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1197
1198         crtc_state->csc_mode = 0;
1199
1200         ret = intel_color_add_affected_planes(crtc_state);
1201         if (ret)
1202                 return ret;
1203
1204         return 0;
1205 }
1206
1207 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1208 {
1209         u32 gamma_mode = 0;
1210
1211         if (crtc_state->base.degamma_lut)
1212                 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1213
1214         if (crtc_state->base.gamma_lut &&
1215             !crtc_state->c8_planes)
1216                 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1217
1218         if (!crtc_state->base.gamma_lut ||
1219             crtc_state_is_legacy_gamma(crtc_state))
1220                 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1221         else
1222                 gamma_mode |= GAMMA_MODE_MODE_10BIT;
1223
1224         return gamma_mode;
1225 }
1226
1227 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1228 {
1229         u32 csc_mode = 0;
1230
1231         if (crtc_state->base.ctm)
1232                 csc_mode |= ICL_CSC_ENABLE;
1233
1234         if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1235             crtc_state->limited_color_range)
1236                 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1237
1238         return csc_mode;
1239 }
1240
1241 static int icl_color_check(struct intel_crtc_state *crtc_state)
1242 {
1243         int ret;
1244
1245         ret = check_luts(crtc_state);
1246         if (ret)
1247                 return ret;
1248
1249         crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1250
1251         crtc_state->csc_mode = icl_csc_mode(crtc_state);
1252
1253         return 0;
1254 }
1255
1256 void intel_color_init(struct intel_crtc *crtc)
1257 {
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;
1260
1261         drm_mode_crtc_set_gamma_size(&crtc->base, 256);
1262
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;
1272                 } else {
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;
1276                 }
1277         } else {
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;
1284                 else
1285                         dev_priv->display.color_check = ilk_color_check;
1286
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;
1291                 else
1292                         dev_priv->display.color_commit = ilk_color_commit;
1293
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;
1302                 else
1303                         dev_priv->display.load_luts = ilk_load_luts;
1304         }
1305
1306         drm_crtc_enable_color_mgmt(&crtc->base,
1307                                    INTEL_INFO(dev_priv)->color.degamma_lut_size,
1308                                    has_ctm,
1309                                    INTEL_INFO(dev_priv)->color.gamma_lut_size);
1310 }