This source file includes following definitions.
- lut_is_legacy
- crtc_state_is_legacy_gamma
- ctm_mult_by_limited
- ilk_update_pipe_csc
- icl_update_output_csc
- ilk_csc_limited_range
- ilk_csc_convert_ctm
- ilk_load_csc_matrix
- icl_load_csc_matrix
- cherryview_load_csc_matrix
- i965_lut_10p6_ldw
- i965_lut_10p6_udw
- ilk_lut_10
- i9xx_load_luts_internal
- i9xx_load_luts
- i9xx_color_commit
- ilk_color_commit
- hsw_color_commit
- skl_color_commit
- i965_load_lut_10p6
- i965_load_luts
- ilk_load_lut_10
- ilk_load_luts
- ivb_lut_10_size
- ivb_load_lut_10
- bdw_load_lut_10
- ivb_load_lut_ext_max
- ivb_load_luts
- bdw_load_luts
- glk_load_degamma_lut
- glk_load_degamma_lut_linear
- glk_load_luts
- ilk_lut_12p4_udw
- ilk_lut_12p4_ldw
- icl_load_gcmax
- icl_program_gamma_superfine_segment
- icl_program_gamma_multi_segment
- icl_load_luts
- chv_cgm_degamma_ldw
- chv_cgm_degamma_udw
- chv_load_cgm_degamma
- chv_cgm_gamma_ldw
- chv_cgm_gamma_udw
- chv_load_cgm_gamma
- chv_load_luts
- intel_color_load_luts
- intel_color_commit
- intel_can_preload_luts
- chv_can_preload_luts
- glk_can_preload_luts
- intel_color_check
- intel_color_get_config
- need_plane_update
- intel_color_add_affected_planes
- check_lut_size
- check_luts
- i9xx_gamma_mode
- i9xx_color_check
- chv_cgm_mode
- chv_color_check
- ilk_gamma_mode
- ilk_color_check
- ivb_gamma_mode
- ivb_csc_mode
- ivb_color_check
- glk_gamma_mode
- glk_color_check
- icl_gamma_mode
- icl_csc_mode
- icl_color_check
- intel_color_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "intel_color.h"
26 #include "intel_display_types.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
46
47
48
49
50
51
52
53
54 #define ILK_CSC_COEFF_FP(coeff, fbits) \
55 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
56
57 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
58 #define ILK_CSC_COEFF_1_0 0x7800
59
60 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
61
62 static const u16 ilk_csc_off_zero[3] = {};
63
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,
68 };
69
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,
74 };
75
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,
80 };
81
82
83
84
85
86 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
87 0x1e08, 0x9cc0, 0xb528,
88 0x2ba8, 0x09d8, 0x37e8,
89 0xbce8, 0x9ad8, 0x1e08,
90 };
91
92
93 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
94 0x0800, 0x0100, 0x0800,
95 };
96
97 static bool lut_is_legacy(const struct drm_property_blob *lut)
98 {
99 return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
100 }
101
102 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
103 {
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);
108 }
109
110
111
112
113
114 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
115 {
116 int i;
117
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;
123
124
125
126
127
128
129 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
130 result[i] |= user_coeff & CTM_COEFF_SIGN;
131 }
132
133 return result;
134 }
135
136 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
137 const u16 preoff[3],
138 const u16 coeff[9],
139 const u16 postoff[3])
140 {
141 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
142 enum pipe pipe = crtc->pipe;
143
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]);
147
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);
150
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);
153
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);
156
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]);
161 }
162 }
163
164 static void icl_update_output_csc(struct intel_crtc *crtc,
165 const u16 preoff[3],
166 const u16 coeff[9],
167 const u16 postoff[3])
168 {
169 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
170 enum pipe pipe = crtc->pipe;
171
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]);
175
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);
178
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);
181
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);
184
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]);
188 }
189
190 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
191 {
192 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
193
194
195
196
197
198 return crtc_state->limited_color_range &&
199 (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
200 IS_GEN_RANGE(dev_priv, 9, 10));
201 }
202
203 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
204 u16 coeffs[9])
205 {
206 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
207 const u64 *input;
208 u64 temp[9];
209 int i;
210
211 if (ilk_csc_limited_range(crtc_state))
212 input = ctm_mult_by_limited(temp, ctm->matrix);
213 else
214 input = ctm->matrix;
215
216
217
218
219
220 for (i = 0; i < 9; i++) {
221 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
222
223
224
225
226
227 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
228
229 coeffs[i] = 0;
230
231
232 if (CTM_COEFF_NEGATIVE(input[i]))
233 coeffs[i] |= 1 << 15;
234
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);
249 else
250 coeffs[i] |= (6 << 12) |
251 ILK_CSC_COEFF_FP(abs_coeff, 7);
252 }
253 }
254
255 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
256 {
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);
260
261 if (crtc_state->base.ctm) {
262 u16 coeff[9];
263
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 :
268 ilk_csc_off_zero);
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) {
278
279
280
281
282
283
284 WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
285
286 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
287 ilk_csc_coeff_identity,
288 ilk_csc_off_zero);
289 }
290
291 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
292 }
293
294 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
295 {
296 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
297 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
298
299 if (crtc_state->base.ctm) {
300 u16 coeff[9];
301
302 ilk_csc_convert_ctm(crtc_state, coeff);
303 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
304 coeff, ilk_csc_off_zero);
305 }
306
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);
315 }
316
317 I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
318 }
319
320
321
322
323 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
324 {
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;
328
329 if (crtc_state->base.ctm) {
330 const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
331 u16 coeffs[9] = {};
332 int i;
333
334 for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
335 u64 abs_coeff =
336 ((1ULL << 63) - 1) & ctm->matrix[i];
337
338
339 abs_coeff += 1 << (32 - 13);
340
341 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
342
343
344 if (ctm->matrix[i] & (1ULL << 63))
345 coeffs[i] = 1 << 15;
346 coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
347 coeffs[i] |= (abs_coeff >> 20) & 0xfff;
348 }
349
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]);
359 }
360
361 I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
362 }
363
364
365 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
366 {
367 return (color->red & 0xff) << 16 |
368 (color->green & 0xff) << 8 |
369 (color->blue & 0xff);
370 }
371
372
373 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
374 {
375 return (color->red >> 8) << 16 |
376 (color->green >> 8) << 8 |
377 (color->blue >> 8);
378 }
379
380 static u32 ilk_lut_10(const struct drm_color_lut *color)
381 {
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);
385 }
386
387
388 static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
389 const struct drm_property_blob *blob)
390 {
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;
394 int i;
395
396 if (HAS_GMCH(dev_priv)) {
397 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
398 assert_dsi_pll_enabled(dev_priv);
399 else
400 assert_pll_enabled(dev_priv, pipe);
401 }
402
403 if (blob) {
404 const struct drm_color_lut *lut = blob->data;
405
406 for (i = 0; i < 256; i++) {
407 u32 word =
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);
411
412 if (HAS_GMCH(dev_priv))
413 I915_WRITE(PALETTE(pipe, i), word);
414 else
415 I915_WRITE(LGC_PALETTE(pipe, i), word);
416 }
417 }
418 }
419
420 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
421 {
422 i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
423 }
424
425 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
426 {
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;
430 u32 val;
431
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);
436 }
437
438 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
439 {
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;
443 u32 val;
444
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);
449
450 ilk_load_csc_matrix(crtc_state);
451 }
452
453 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
454 {
455 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
456 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
457
458 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
459
460 ilk_load_csc_matrix(crtc_state);
461 }
462
463 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
464 {
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;
468 u32 val = 0;
469
470
471
472
473
474
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);
480
481 I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
482
483 if (INTEL_GEN(dev_priv) >= 11)
484 icl_load_csc_matrix(crtc_state);
485 else
486 ilk_load_csc_matrix(crtc_state);
487 }
488
489 static void i965_load_lut_10p6(struct intel_crtc *crtc,
490 const struct drm_property_blob *blob)
491 {
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;
496
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]));
502 }
503
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);
507 }
508
509 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
510 {
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;
513
514 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
515 i9xx_load_luts(crtc_state);
516 else
517 i965_load_lut_10p6(crtc, gamma_lut);
518 }
519
520 static void ilk_load_lut_10(struct intel_crtc *crtc,
521 const struct drm_property_blob *blob)
522 {
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;
527
528 for (i = 0; i < lut_size; i++)
529 I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
530 }
531
532 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
533 {
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;
536
537 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
538 i9xx_load_luts(crtc_state);
539 else
540 ilk_load_lut_10(crtc, gamma_lut);
541 }
542
543 static int ivb_lut_10_size(u32 prec_index)
544 {
545 if (prec_index & PAL_PREC_SPLIT_MODE)
546 return 512;
547 else
548 return 1024;
549 }
550
551
552
553
554
555
556 static void ivb_load_lut_10(struct intel_crtc *crtc,
557 const struct drm_property_blob *blob,
558 u32 prec_index)
559 {
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;
565
566 for (i = 0; i < hw_lut_size; i++) {
567
568 const struct drm_color_lut *entry =
569 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
570
571 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
572 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
573 }
574
575
576
577
578
579 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
580 }
581
582
583 static void bdw_load_lut_10(struct intel_crtc *crtc,
584 const struct drm_property_blob *blob,
585 u32 prec_index)
586 {
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;
592
593 I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
594 PAL_PREC_AUTO_INCREMENT);
595
596 for (i = 0; i < hw_lut_size; i++) {
597
598 const struct drm_color_lut *entry =
599 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
600
601 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
602 }
603
604
605
606
607
608 I915_WRITE(PREC_PAL_INDEX(pipe), 0);
609 }
610
611 static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
612 {
613 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
614 enum pipe pipe = crtc->pipe;
615
616
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);
620
621
622
623
624
625
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);
630 }
631 }
632
633 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
634 {
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;
638
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));
647 } else {
648 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
649
650 ivb_load_lut_10(crtc, blob,
651 PAL_PREC_INDEX_VALUE(0));
652 ivb_load_lut_ext_max(crtc);
653 }
654 }
655
656 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
657 {
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;
661
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));
670 } else {
671 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
672
673 bdw_load_lut_10(crtc, blob,
674 PAL_PREC_INDEX_VALUE(0));
675 ivb_load_lut_ext_max(crtc);
676 }
677 }
678
679 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
680 {
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;
686 u32 i;
687
688
689
690
691
692
693 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
694 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
695
696 for (i = 0; i < lut_size; i++) {
697
698
699
700
701
702
703
704
705
706
707
708
709
710 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
711 }
712
713
714 while (i++ < 35)
715 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
716 }
717
718 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
719 {
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;
724 u32 i;
725
726
727
728
729
730
731 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
732 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
733
734 for (i = 0; i < lut_size; i++) {
735 u32 v = (i << 16) / (lut_size - 1);
736
737 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
738 }
739
740
741 while (i++ < 35)
742 I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
743 }
744
745 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
746 {
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);
749
750
751
752
753
754
755
756
757
758 if (crtc_state->base.degamma_lut)
759 glk_load_degamma_lut(crtc_state);
760 else
761 glk_load_degamma_lut_linear(crtc_state);
762
763 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
764 i9xx_load_luts(crtc_state);
765 } else {
766 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
767 ivb_load_lut_ext_max(crtc);
768 }
769 }
770
771
772 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
773 {
774 return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
775 (color->blue >> 6);
776 }
777
778
779 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
780 {
781 return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
782 (color->blue & 0x3f) << 4;
783 }
784
785 static void
786 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
787 const struct drm_color_lut *color)
788 {
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;
792
793
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);
797 }
798
799 static void
800 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
801 {
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;
807 u32 i;
808
809
810
811
812
813
814
815
816 I915_WRITE(PREC_PAL_MULTI_SEG_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
817
818 for (i = 0; i < 9; i++) {
819 const struct drm_color_lut *entry = &lut[i];
820
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));
825 }
826 }
827
828 static void
829 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
830 {
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;
837 u32 i;
838
839
840
841
842
843
844
845
846
847
848
849
850 I915_WRITE(PREC_PAL_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
851 for (i = 1; i < 257; i++) {
852 entry = &lut[i * 8];
853 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_ldw(entry));
854 I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_udw(entry));
855 }
856
857
858
859
860
861
862
863
864
865
866
867
868
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));
873 }
874
875
876 entry = &lut[256 * 8 * 128];
877 icl_load_gcmax(crtc_state, entry);
878 ivb_load_lut_ext_max(crtc);
879 }
880
881 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
882 {
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);
885
886 if (crtc_state->base.degamma_lut)
887 glk_load_degamma_lut(crtc_state);
888
889 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
890 case GAMMA_MODE_MODE_8BIT:
891 i9xx_load_luts(crtc_state);
892 break;
893
894 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
895 icl_program_gamma_superfine_segment(crtc_state);
896 icl_program_gamma_multi_segment(crtc_state);
897 break;
898
899 default:
900 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
901 ivb_load_lut_ext_max(crtc);
902 }
903 }
904
905 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
906 {
907 return drm_color_lut_extract(color->green, 14) << 16 |
908 drm_color_lut_extract(color->blue, 14);
909 }
910
911 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
912 {
913 return drm_color_lut_extract(color->red, 14);
914 }
915
916 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
917 const struct drm_property_blob *blob)
918 {
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;
923
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]));
929 }
930 }
931
932 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
933 {
934 return drm_color_lut_extract(color->green, 10) << 16 |
935 drm_color_lut_extract(color->blue, 10);
936 }
937
938 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
939 {
940 return drm_color_lut_extract(color->red, 10);
941 }
942
943 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
944 const struct drm_property_blob *blob)
945 {
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;
950
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]));
956 }
957 }
958
959 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
960 {
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;
964
965 cherryview_load_csc_matrix(crtc_state);
966
967 if (crtc_state_is_legacy_gamma(crtc_state)) {
968 i9xx_load_luts(crtc_state);
969 return;
970 }
971
972 if (degamma_lut)
973 chv_load_cgm_degamma(crtc, degamma_lut);
974
975 if (gamma_lut)
976 chv_load_cgm_gamma(crtc, gamma_lut);
977 }
978
979 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
980 {
981 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
982
983 dev_priv->display.load_luts(crtc_state);
984 }
985
986 void intel_color_commit(const struct intel_crtc_state *crtc_state)
987 {
988 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
989
990 dev_priv->display.color_commit(crtc_state);
991 }
992
993 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
994 {
995 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
996 struct intel_atomic_state *state =
997 to_intel_atomic_state(new_crtc_state->base.state);
998 const struct intel_crtc_state *old_crtc_state =
999 intel_atomic_get_old_crtc_state(state, crtc);
1000
1001 return !old_crtc_state->base.gamma_lut &&
1002 !old_crtc_state->base.degamma_lut;
1003 }
1004
1005 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1006 {
1007 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1008 struct intel_atomic_state *state =
1009 to_intel_atomic_state(new_crtc_state->base.state);
1010 const struct intel_crtc_state *old_crtc_state =
1011 intel_atomic_get_old_crtc_state(state, crtc);
1012
1013
1014
1015
1016
1017
1018 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1019 return false;
1020
1021 return !old_crtc_state->base.gamma_lut;
1022 }
1023
1024 static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1025 {
1026 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1027 struct intel_atomic_state *state =
1028 to_intel_atomic_state(new_crtc_state->base.state);
1029 const struct intel_crtc_state *old_crtc_state =
1030 intel_atomic_get_old_crtc_state(state, crtc);
1031
1032
1033
1034
1035
1036
1037
1038 return !old_crtc_state->csc_enable &&
1039 !old_crtc_state->base.gamma_lut;
1040 }
1041
1042 int intel_color_check(struct intel_crtc_state *crtc_state)
1043 {
1044 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1045
1046 return dev_priv->display.color_check(crtc_state);
1047 }
1048
1049 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1050 {
1051 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1052
1053 if (dev_priv->display.read_luts)
1054 dev_priv->display.read_luts(crtc_state);
1055 }
1056
1057 static bool need_plane_update(struct intel_plane *plane,
1058 const struct intel_crtc_state *crtc_state)
1059 {
1060 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1061
1062
1063
1064
1065
1066
1067 return crtc_state->active_planes & BIT(plane->id) ||
1068 (INTEL_GEN(dev_priv) < 9 &&
1069 plane->id == PLANE_PRIMARY);
1070 }
1071
1072 static int
1073 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1074 {
1075 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1076 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1077 struct intel_atomic_state *state =
1078 to_intel_atomic_state(new_crtc_state->base.state);
1079 const struct intel_crtc_state *old_crtc_state =
1080 intel_atomic_get_old_crtc_state(state, crtc);
1081 struct intel_plane *plane;
1082
1083 if (!new_crtc_state->base.active ||
1084 drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
1085 return 0;
1086
1087 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1088 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1089 return 0;
1090
1091 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
1092 struct intel_plane_state *plane_state;
1093
1094 if (!need_plane_update(plane, new_crtc_state))
1095 continue;
1096
1097 plane_state = intel_atomic_get_plane_state(state, plane);
1098 if (IS_ERR(plane_state))
1099 return PTR_ERR(plane_state);
1100
1101 new_crtc_state->update_planes |= BIT(plane->id);
1102 }
1103
1104 return 0;
1105 }
1106
1107 static int check_lut_size(const struct drm_property_blob *lut, int expected)
1108 {
1109 int len;
1110
1111 if (!lut)
1112 return 0;
1113
1114 len = drm_color_lut_size(lut);
1115 if (len != expected) {
1116 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1117 len, expected);
1118 return -EINVAL;
1119 }
1120
1121 return 0;
1122 }
1123
1124 static int check_luts(const struct intel_crtc_state *crtc_state)
1125 {
1126 struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1127 const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
1128 const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
1129 int gamma_length, degamma_length;
1130 u32 gamma_tests, degamma_tests;
1131
1132
1133 if (crtc_state_is_legacy_gamma(crtc_state))
1134 return 0;
1135
1136
1137 if (crtc_state->c8_planes) {
1138 DRM_DEBUG_KMS("C8 pixelformat requires the legacy LUT\n");
1139 return -EINVAL;
1140 }
1141
1142 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
1143 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1144 degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
1145 gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
1146
1147 if (check_lut_size(degamma_lut, degamma_length) ||
1148 check_lut_size(gamma_lut, gamma_length))
1149 return -EINVAL;
1150
1151 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
1152 drm_color_lut_check(gamma_lut, gamma_tests))
1153 return -EINVAL;
1154
1155 return 0;
1156 }
1157
1158 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
1159 {
1160 if (!crtc_state->gamma_enable ||
1161 crtc_state_is_legacy_gamma(crtc_state))
1162 return GAMMA_MODE_MODE_8BIT;
1163 else
1164 return GAMMA_MODE_MODE_10BIT;
1165 }
1166
1167 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1168 {
1169 int ret;
1170
1171 ret = check_luts(crtc_state);
1172 if (ret)
1173 return ret;
1174
1175 crtc_state->gamma_enable =
1176 crtc_state->base.gamma_lut &&
1177 !crtc_state->c8_planes;
1178
1179 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1180
1181 ret = intel_color_add_affected_planes(crtc_state);
1182 if (ret)
1183 return ret;
1184
1185 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1186
1187 return 0;
1188 }
1189
1190 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1191 {
1192 u32 cgm_mode = 0;
1193
1194 if (crtc_state_is_legacy_gamma(crtc_state))
1195 return 0;
1196
1197 if (crtc_state->base.degamma_lut)
1198 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1199 if (crtc_state->base.ctm)
1200 cgm_mode |= CGM_PIPE_MODE_CSC;
1201 if (crtc_state->base.gamma_lut)
1202 cgm_mode |= CGM_PIPE_MODE_GAMMA;
1203
1204 return cgm_mode;
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215 static int chv_color_check(struct intel_crtc_state *crtc_state)
1216 {
1217 int ret;
1218
1219 ret = check_luts(crtc_state);
1220 if (ret)
1221 return ret;
1222
1223
1224
1225
1226
1227 crtc_state->gamma_enable =
1228 crtc_state_is_legacy_gamma(crtc_state) &&
1229 !crtc_state->c8_planes;
1230
1231 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1232
1233 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1234
1235 ret = intel_color_add_affected_planes(crtc_state);
1236 if (ret)
1237 return ret;
1238
1239 crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
1240
1241 return 0;
1242 }
1243
1244 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1245 {
1246 if (!crtc_state->gamma_enable ||
1247 crtc_state_is_legacy_gamma(crtc_state))
1248 return GAMMA_MODE_MODE_8BIT;
1249 else
1250 return GAMMA_MODE_MODE_10BIT;
1251 }
1252
1253 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1254 {
1255 int ret;
1256
1257 ret = check_luts(crtc_state);
1258 if (ret)
1259 return ret;
1260
1261 crtc_state->gamma_enable =
1262 crtc_state->base.gamma_lut &&
1263 !crtc_state->c8_planes;
1264
1265
1266
1267
1268
1269
1270 crtc_state->csc_enable = false;
1271
1272 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1273
1274 crtc_state->csc_mode = 0;
1275
1276 ret = intel_color_add_affected_planes(crtc_state);
1277 if (ret)
1278 return ret;
1279
1280 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1281
1282 return 0;
1283 }
1284
1285 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1286 {
1287 if (!crtc_state->gamma_enable ||
1288 crtc_state_is_legacy_gamma(crtc_state))
1289 return GAMMA_MODE_MODE_8BIT;
1290 else if (crtc_state->base.gamma_lut &&
1291 crtc_state->base.degamma_lut)
1292 return GAMMA_MODE_MODE_SPLIT;
1293 else
1294 return GAMMA_MODE_MODE_10BIT;
1295 }
1296
1297 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1298 {
1299 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1300
1301
1302
1303
1304
1305 if (crtc_state->base.degamma_lut ||
1306 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1307 limited_color_range)
1308 return 0;
1309
1310 return CSC_POSITION_BEFORE_GAMMA;
1311 }
1312
1313 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1314 {
1315 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1316 int ret;
1317
1318 ret = check_luts(crtc_state);
1319 if (ret)
1320 return ret;
1321
1322 crtc_state->gamma_enable =
1323 (crtc_state->base.gamma_lut ||
1324 crtc_state->base.degamma_lut) &&
1325 !crtc_state->c8_planes;
1326
1327 crtc_state->csc_enable =
1328 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1329 crtc_state->base.ctm || limited_color_range;
1330
1331 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1332
1333 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1334
1335 ret = intel_color_add_affected_planes(crtc_state);
1336 if (ret)
1337 return ret;
1338
1339 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1340
1341 return 0;
1342 }
1343
1344 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1345 {
1346 if (!crtc_state->gamma_enable ||
1347 crtc_state_is_legacy_gamma(crtc_state))
1348 return GAMMA_MODE_MODE_8BIT;
1349 else
1350 return GAMMA_MODE_MODE_10BIT;
1351 }
1352
1353 static int glk_color_check(struct intel_crtc_state *crtc_state)
1354 {
1355 int ret;
1356
1357 ret = check_luts(crtc_state);
1358 if (ret)
1359 return ret;
1360
1361 crtc_state->gamma_enable =
1362 crtc_state->base.gamma_lut &&
1363 !crtc_state->c8_planes;
1364
1365
1366 crtc_state->csc_enable =
1367 crtc_state->base.degamma_lut ||
1368 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1369 crtc_state->base.ctm || crtc_state->limited_color_range;
1370
1371 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1372
1373 crtc_state->csc_mode = 0;
1374
1375 ret = intel_color_add_affected_planes(crtc_state);
1376 if (ret)
1377 return ret;
1378
1379 crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
1380
1381 return 0;
1382 }
1383
1384 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1385 {
1386 u32 gamma_mode = 0;
1387
1388 if (crtc_state->base.degamma_lut)
1389 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1390
1391 if (crtc_state->base.gamma_lut &&
1392 !crtc_state->c8_planes)
1393 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1394
1395 if (!crtc_state->base.gamma_lut ||
1396 crtc_state_is_legacy_gamma(crtc_state))
1397 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1398 else
1399 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
1400
1401 return gamma_mode;
1402 }
1403
1404 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1405 {
1406 u32 csc_mode = 0;
1407
1408 if (crtc_state->base.ctm)
1409 csc_mode |= ICL_CSC_ENABLE;
1410
1411 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1412 crtc_state->limited_color_range)
1413 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1414
1415 return csc_mode;
1416 }
1417
1418 static int icl_color_check(struct intel_crtc_state *crtc_state)
1419 {
1420 int ret;
1421
1422 ret = check_luts(crtc_state);
1423 if (ret)
1424 return ret;
1425
1426 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1427
1428 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1429
1430 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1431
1432 return 0;
1433 }
1434
1435 void intel_color_init(struct intel_crtc *crtc)
1436 {
1437 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1438 bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0;
1439
1440 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
1441
1442 if (HAS_GMCH(dev_priv)) {
1443 if (IS_CHERRYVIEW(dev_priv)) {
1444 dev_priv->display.color_check = chv_color_check;
1445 dev_priv->display.color_commit = i9xx_color_commit;
1446 dev_priv->display.load_luts = chv_load_luts;
1447 } else if (INTEL_GEN(dev_priv) >= 4) {
1448 dev_priv->display.color_check = i9xx_color_check;
1449 dev_priv->display.color_commit = i9xx_color_commit;
1450 dev_priv->display.load_luts = i965_load_luts;
1451 } else {
1452 dev_priv->display.color_check = i9xx_color_check;
1453 dev_priv->display.color_commit = i9xx_color_commit;
1454 dev_priv->display.load_luts = i9xx_load_luts;
1455 }
1456 } else {
1457 if (INTEL_GEN(dev_priv) >= 11)
1458 dev_priv->display.color_check = icl_color_check;
1459 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1460 dev_priv->display.color_check = glk_color_check;
1461 else if (INTEL_GEN(dev_priv) >= 7)
1462 dev_priv->display.color_check = ivb_color_check;
1463 else
1464 dev_priv->display.color_check = ilk_color_check;
1465
1466 if (INTEL_GEN(dev_priv) >= 9)
1467 dev_priv->display.color_commit = skl_color_commit;
1468 else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
1469 dev_priv->display.color_commit = hsw_color_commit;
1470 else
1471 dev_priv->display.color_commit = ilk_color_commit;
1472
1473 if (INTEL_GEN(dev_priv) >= 11)
1474 dev_priv->display.load_luts = icl_load_luts;
1475 else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
1476 dev_priv->display.load_luts = glk_load_luts;
1477 else if (INTEL_GEN(dev_priv) >= 8)
1478 dev_priv->display.load_luts = bdw_load_luts;
1479 else if (INTEL_GEN(dev_priv) >= 7)
1480 dev_priv->display.load_luts = ivb_load_luts;
1481 else
1482 dev_priv->display.load_luts = ilk_load_luts;
1483 }
1484
1485 drm_crtc_enable_color_mgmt(&crtc->base,
1486 INTEL_INFO(dev_priv)->color.degamma_lut_size,
1487 has_ctm,
1488 INTEL_INFO(dev_priv)->color.gamma_lut_size);
1489 }