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 "i915_reg.h"
26 #include "intel_color.h"
27 #include "intel_de.h"
28 #include "intel_display_types.h"
29 #include "intel_dsb.h"
30
31 struct intel_color_funcs {
32 int (*color_check)(struct intel_crtc_state *crtc_state);
33 /*
34 * Program non-arming double buffered color management registers
35 * before vblank evasion. The registers should then latch after
36 * the arming register is written (by color_commit_arm()) during
37 * the next vblank start, alongside any other double buffered
38 * registers involved with the same commit. This hook is optional.
39 */
40 void (*color_commit_noarm)(const struct intel_crtc_state *crtc_state);
41 /*
42 * Program arming double buffered color management registers
43 * during vblank evasion. The registers (and whatever other registers
44 * they arm that were written by color_commit_noarm) should then latch
45 * during the next vblank start, alongside any other double buffered
46 * registers involved with the same commit.
47 */
48 void (*color_commit_arm)(const struct intel_crtc_state *crtc_state);
49 /*
50 * Perform any extra tasks needed after all the
51 * double buffered registers have been latched.
52 */
53 void (*color_post_update)(const struct intel_crtc_state *crtc_state);
54 /*
55 * Load LUTs (and other single buffered color management
56 * registers). Will (hopefully) be called during the vblank
57 * following the latching of any double buffered registers
58 * involved with the same commit.
59 */
60 void (*load_luts)(const struct intel_crtc_state *crtc_state);
61 /*
62 * Read out the LUTs from the hardware into the software state.
63 * Used by eg. the hardware state checker.
64 */
65 void (*read_luts)(struct intel_crtc_state *crtc_state);
66 /*
67 * Compare the LUTs
68 */
69 bool (*lut_equal)(const struct intel_crtc_state *crtc_state,
70 const struct drm_property_blob *blob1,
71 const struct drm_property_blob *blob2,
72 bool is_pre_csc_lut);
73 /*
74 * Read out the CSCs (if any) from the hardware into the
75 * software state. Used by eg. the hardware state checker.
76 */
77 void (*read_csc)(struct intel_crtc_state *crtc_state);
78 };
79
80 #define CTM_COEFF_SIGN (1ULL << 63)
81
82 #define CTM_COEFF_1_0 (1ULL << 32)
83 #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1)
84 #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1)
85 #define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1)
86 #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1)
87 #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1)
88 #define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1)
89
90 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
91
92 #define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
93 #define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
94
95 #define LEGACY_LUT_LENGTH 256
96
97 /*
98 * ILK+ csc matrix:
99 *
100 * |R/Cr| | c0 c1 c2 | ( |R/Cr| |preoff0| ) |postoff0|
101 * |G/Y | = | c3 c4 c5 | x ( |G/Y | + |preoff1| ) + |postoff1|
102 * |B/Cb| | c6 c7 c8 | ( |B/Cb| |preoff2| ) |postoff2|
103 *
104 * ILK/SNB don't have explicit post offsets, and instead
105 * CSC_MODE_YUV_TO_RGB and CSC_BLACK_SCREEN_OFFSET are used:
106 * CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=0 -> 1/2, 0, 1/2
107 * CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/2, 1/16, 1/2
108 * CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=0 -> 0, 0, 0
109 * CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/16, 1/16, 1/16
110 */
111
112 /*
113 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
114 * format). This macro takes the coefficient we want transformed and the
115 * number of fractional bits.
116 *
117 * We only have a 9 bits precision window which slides depending on the value
118 * of the CTM coefficient and we write the value from bit 3. We also round the
119 * value.
120 */
121 #define ILK_CSC_COEFF_FP(coeff, fbits) \
122 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
123
124 #define ILK_CSC_COEFF_1_0 0x7800
125 #define ILK_CSC_COEFF_LIMITED_RANGE ((235 - 16) << (12 - 8)) /* exponent 0 */
126 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 << (12 - 8))
127
128 static const struct intel_csc_matrix ilk_csc_matrix_identity = {
129 .preoff = {},
130 .coeff = {
131 ILK_CSC_COEFF_1_0, 0, 0,
132 0, ILK_CSC_COEFF_1_0, 0,
133 0, 0, ILK_CSC_COEFF_1_0,
134 },
135 .postoff = {},
136 };
137
138 /* Full range RGB -> limited range RGB matrix */
139 static const struct intel_csc_matrix ilk_csc_matrix_limited_range = {
140 .preoff = {},
141 .coeff = {
142 ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
143 0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
144 0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
145 },
146 .postoff = {
147 ILK_CSC_POSTOFF_LIMITED_RANGE,
148 ILK_CSC_POSTOFF_LIMITED_RANGE,
149 ILK_CSC_POSTOFF_LIMITED_RANGE,
150 },
151 };
152
153 /* BT.709 full range RGB -> limited range YCbCr matrix */
154 static const struct intel_csc_matrix ilk_csc_matrix_rgb_to_ycbcr = {
155 .preoff = {},
156 .coeff = {
157 0x1e08, 0x9cc0, 0xb528,
158 0x2ba8, 0x09d8, 0x37e8,
159 0xbce8, 0x9ad8, 0x1e08,
160 },
161 .postoff = {
162 0x0800, 0x0100, 0x0800,
163 },
164 };
165
intel_csc_clear(struct intel_csc_matrix * csc)166 static void intel_csc_clear(struct intel_csc_matrix *csc)
167 {
168 memset(csc, 0, sizeof(*csc));
169 }
170
lut_is_legacy(const struct drm_property_blob * lut)171 static bool lut_is_legacy(const struct drm_property_blob *lut)
172 {
173 return lut && drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
174 }
175
176 /*
177 * When using limited range, multiply the matrix given by userspace by
178 * the matrix that we would use for the limited range.
179 */
ctm_mult_by_limited(u64 * result,const u64 * input)180 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
181 {
182 int i;
183
184 for (i = 0; i < 9; i++) {
185 u64 user_coeff = input[i];
186 u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
187 u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
188 CTM_COEFF_4_0 - 1) >> 2;
189
190 /*
191 * By scaling every co-efficient with limited range (16-235)
192 * vs full range (0-255) the final o/p will be scaled down to
193 * fit in the limited range supported by the panel.
194 */
195 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
196 result[i] |= user_coeff & CTM_COEFF_SIGN;
197 }
198
199 return result;
200 }
201
ilk_update_pipe_csc(struct intel_crtc * crtc,const struct intel_csc_matrix * csc)202 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
203 const struct intel_csc_matrix *csc)
204 {
205 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
206 enum pipe pipe = crtc->pipe;
207
208 intel_de_write_fw(i915, PIPE_CSC_PREOFF_HI(pipe), csc->preoff[0]);
209 intel_de_write_fw(i915, PIPE_CSC_PREOFF_ME(pipe), csc->preoff[1]);
210 intel_de_write_fw(i915, PIPE_CSC_PREOFF_LO(pipe), csc->preoff[2]);
211
212 intel_de_write_fw(i915, PIPE_CSC_COEFF_RY_GY(pipe),
213 csc->coeff[0] << 16 | csc->coeff[1]);
214 intel_de_write_fw(i915, PIPE_CSC_COEFF_BY(pipe),
215 csc->coeff[2] << 16);
216
217 intel_de_write_fw(i915, PIPE_CSC_COEFF_RU_GU(pipe),
218 csc->coeff[3] << 16 | csc->coeff[4]);
219 intel_de_write_fw(i915, PIPE_CSC_COEFF_BU(pipe),
220 csc->coeff[5] << 16);
221
222 intel_de_write_fw(i915, PIPE_CSC_COEFF_RV_GV(pipe),
223 csc->coeff[6] << 16 | csc->coeff[7]);
224 intel_de_write_fw(i915, PIPE_CSC_COEFF_BV(pipe),
225 csc->coeff[8] << 16);
226
227 if (DISPLAY_VER(i915) < 7)
228 return;
229
230 intel_de_write_fw(i915, PIPE_CSC_POSTOFF_HI(pipe), csc->postoff[0]);
231 intel_de_write_fw(i915, PIPE_CSC_POSTOFF_ME(pipe), csc->postoff[1]);
232 intel_de_write_fw(i915, PIPE_CSC_POSTOFF_LO(pipe), csc->postoff[2]);
233 }
234
ilk_read_pipe_csc(struct intel_crtc * crtc,struct intel_csc_matrix * csc)235 static void ilk_read_pipe_csc(struct intel_crtc *crtc,
236 struct intel_csc_matrix *csc)
237 {
238 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
239 enum pipe pipe = crtc->pipe;
240 u32 tmp;
241
242 csc->preoff[0] = intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(pipe));
243 csc->preoff[1] = intel_de_read_fw(i915, PIPE_CSC_PREOFF_ME(pipe));
244 csc->preoff[2] = intel_de_read_fw(i915, PIPE_CSC_PREOFF_LO(pipe));
245
246 tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_RY_GY(pipe));
247 csc->coeff[0] = tmp >> 16;
248 csc->coeff[1] = tmp & 0xffff;
249 tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_BY(pipe));
250 csc->coeff[2] = tmp >> 16;
251
252 tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_RU_GU(pipe));
253 csc->coeff[3] = tmp >> 16;
254 csc->coeff[4] = tmp & 0xffff;
255 tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_BU(pipe));
256 csc->coeff[5] = tmp >> 16;
257
258 tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_RV_GV(pipe));
259 csc->coeff[6] = tmp >> 16;
260 csc->coeff[7] = tmp & 0xffff;
261 tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_BV(pipe));
262 csc->coeff[8] = tmp >> 16;
263
264 if (DISPLAY_VER(i915) < 7)
265 return;
266
267 csc->postoff[0] = intel_de_read_fw(i915, PIPE_CSC_POSTOFF_HI(pipe));
268 csc->postoff[1] = intel_de_read_fw(i915, PIPE_CSC_POSTOFF_ME(pipe));
269 csc->postoff[2] = intel_de_read_fw(i915, PIPE_CSC_POSTOFF_LO(pipe));
270 }
271
ilk_read_csc(struct intel_crtc_state * crtc_state)272 static void ilk_read_csc(struct intel_crtc_state *crtc_state)
273 {
274 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
275
276 if (crtc_state->csc_enable)
277 ilk_read_pipe_csc(crtc, &crtc_state->csc);
278 }
279
skl_read_csc(struct intel_crtc_state * crtc_state)280 static void skl_read_csc(struct intel_crtc_state *crtc_state)
281 {
282 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
283
284 /*
285 * Display WA #1184: skl,glk
286 * Wa_1406463849: icl
287 *
288 * Danger! On SKL-ICL *reads* from the CSC coeff/offset registers
289 * will disarm an already armed CSC double buffer update.
290 * So this must not be called while armed. Fortunately the state checker
291 * readout happens only after the update has been already been latched.
292 *
293 * On earlier and later platforms only writes to said registers will
294 * disarm the update. This is considered normal behavior and also
295 * happens with various other hardware units.
296 */
297 if (crtc_state->csc_enable)
298 ilk_read_pipe_csc(crtc, &crtc_state->csc);
299 }
300
icl_update_output_csc(struct intel_crtc * crtc,const struct intel_csc_matrix * csc)301 static void icl_update_output_csc(struct intel_crtc *crtc,
302 const struct intel_csc_matrix *csc)
303 {
304 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
305 enum pipe pipe = crtc->pipe;
306
307 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), csc->preoff[0]);
308 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), csc->preoff[1]);
309 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), csc->preoff[2]);
310
311 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
312 csc->coeff[0] << 16 | csc->coeff[1]);
313 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
314 csc->coeff[2] << 16);
315
316 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
317 csc->coeff[3] << 16 | csc->coeff[4]);
318 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
319 csc->coeff[5] << 16);
320
321 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
322 csc->coeff[6] << 16 | csc->coeff[7]);
323 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
324 csc->coeff[8] << 16);
325
326 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), csc->postoff[0]);
327 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), csc->postoff[1]);
328 intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), csc->postoff[2]);
329 }
330
icl_read_output_csc(struct intel_crtc * crtc,struct intel_csc_matrix * csc)331 static void icl_read_output_csc(struct intel_crtc *crtc,
332 struct intel_csc_matrix *csc)
333 {
334 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
335 enum pipe pipe = crtc->pipe;
336 u32 tmp;
337
338 csc->preoff[0] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_PREOFF_HI(pipe));
339 csc->preoff[1] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_PREOFF_ME(pipe));
340 csc->preoff[2] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_PREOFF_LO(pipe));
341
342 tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe));
343 csc->coeff[0] = tmp >> 16;
344 csc->coeff[1] = tmp & 0xffff;
345 tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_BY(pipe));
346 csc->coeff[2] = tmp >> 16;
347
348 tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe));
349 csc->coeff[3] = tmp >> 16;
350 csc->coeff[4] = tmp & 0xffff;
351 tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_BU(pipe));
352 csc->coeff[5] = tmp >> 16;
353
354 tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe));
355 csc->coeff[6] = tmp >> 16;
356 csc->coeff[7] = tmp & 0xffff;
357 tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_BV(pipe));
358 csc->coeff[8] = tmp >> 16;
359
360 csc->postoff[0] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe));
361 csc->postoff[1] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe));
362 csc->postoff[2] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe));
363 }
364
icl_read_csc(struct intel_crtc_state * crtc_state)365 static void icl_read_csc(struct intel_crtc_state *crtc_state)
366 {
367 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
368
369 /*
370 * Wa_1406463849: icl
371 *
372 * See skl_read_csc()
373 */
374 if (crtc_state->csc_mode & ICL_CSC_ENABLE)
375 ilk_read_pipe_csc(crtc, &crtc_state->csc);
376
377 if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE)
378 icl_read_output_csc(crtc, &crtc_state->output_csc);
379 }
380
ilk_limited_range(const struct intel_crtc_state * crtc_state)381 static bool ilk_limited_range(const struct intel_crtc_state *crtc_state)
382 {
383 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
384
385 /* icl+ have dedicated output CSC */
386 if (DISPLAY_VER(i915) >= 11)
387 return false;
388
389 /* pre-hsw have TRANSCONF_COLOR_RANGE_SELECT */
390 if (DISPLAY_VER(i915) < 7 || IS_IVYBRIDGE(i915))
391 return false;
392
393 return crtc_state->limited_color_range;
394 }
395
ilk_lut_limited_range(const struct intel_crtc_state * crtc_state)396 static bool ilk_lut_limited_range(const struct intel_crtc_state *crtc_state)
397 {
398 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
399
400 if (!ilk_limited_range(crtc_state))
401 return false;
402
403 if (crtc_state->c8_planes)
404 return false;
405
406 if (DISPLAY_VER(i915) == 10)
407 return crtc_state->hw.gamma_lut;
408 else
409 return crtc_state->hw.gamma_lut &&
410 (crtc_state->hw.degamma_lut || crtc_state->hw.ctm);
411 }
412
ilk_csc_limited_range(const struct intel_crtc_state * crtc_state)413 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
414 {
415 if (!ilk_limited_range(crtc_state))
416 return false;
417
418 return !ilk_lut_limited_range(crtc_state);
419 }
420
ilk_csc_copy(struct drm_i915_private * i915,struct intel_csc_matrix * dst,const struct intel_csc_matrix * src)421 static void ilk_csc_copy(struct drm_i915_private *i915,
422 struct intel_csc_matrix *dst,
423 const struct intel_csc_matrix *src)
424 {
425 *dst = *src;
426
427 if (DISPLAY_VER(i915) < 7)
428 memset(dst->postoff, 0, sizeof(dst->postoff));
429 }
430
ilk_csc_convert_ctm(const struct intel_crtc_state * crtc_state,struct intel_csc_matrix * csc,bool limited_color_range)431 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
432 struct intel_csc_matrix *csc,
433 bool limited_color_range)
434 {
435 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
436 const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
437 const u64 *input;
438 u64 temp[9];
439 int i;
440
441 /* for preoff/postoff */
442 if (limited_color_range)
443 ilk_csc_copy(i915, csc, &ilk_csc_matrix_limited_range);
444 else
445 ilk_csc_copy(i915, csc, &ilk_csc_matrix_identity);
446
447 if (limited_color_range)
448 input = ctm_mult_by_limited(temp, ctm->matrix);
449 else
450 input = ctm->matrix;
451
452 /*
453 * Convert fixed point S31.32 input to format supported by the
454 * hardware.
455 */
456 for (i = 0; i < 9; i++) {
457 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
458
459 /*
460 * Clamp input value to min/max supported by
461 * hardware.
462 */
463 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
464
465 csc->coeff[i] = 0;
466
467 /* sign bit */
468 if (CTM_COEFF_NEGATIVE(input[i]))
469 csc->coeff[i] |= 1 << 15;
470
471 if (abs_coeff < CTM_COEFF_0_125)
472 csc->coeff[i] |= (3 << 12) |
473 ILK_CSC_COEFF_FP(abs_coeff, 12);
474 else if (abs_coeff < CTM_COEFF_0_25)
475 csc->coeff[i] |= (2 << 12) |
476 ILK_CSC_COEFF_FP(abs_coeff, 11);
477 else if (abs_coeff < CTM_COEFF_0_5)
478 csc->coeff[i] |= (1 << 12) |
479 ILK_CSC_COEFF_FP(abs_coeff, 10);
480 else if (abs_coeff < CTM_COEFF_1_0)
481 csc->coeff[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
482 else if (abs_coeff < CTM_COEFF_2_0)
483 csc->coeff[i] |= (7 << 12) |
484 ILK_CSC_COEFF_FP(abs_coeff, 8);
485 else
486 csc->coeff[i] |= (6 << 12) |
487 ILK_CSC_COEFF_FP(abs_coeff, 7);
488 }
489 }
490
ilk_assign_csc(struct intel_crtc_state * crtc_state)491 static void ilk_assign_csc(struct intel_crtc_state *crtc_state)
492 {
493 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
494 bool limited_color_range = ilk_csc_limited_range(crtc_state);
495
496 if (crtc_state->hw.ctm) {
497 drm_WARN_ON(&i915->drm, !crtc_state->csc_enable);
498
499 ilk_csc_convert_ctm(crtc_state, &crtc_state->csc, limited_color_range);
500 } else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
501 drm_WARN_ON(&i915->drm, !crtc_state->csc_enable);
502
503 ilk_csc_copy(i915, &crtc_state->csc, &ilk_csc_matrix_rgb_to_ycbcr);
504 } else if (limited_color_range) {
505 drm_WARN_ON(&i915->drm, !crtc_state->csc_enable);
506
507 ilk_csc_copy(i915, &crtc_state->csc, &ilk_csc_matrix_limited_range);
508 } else if (crtc_state->csc_enable) {
509 /*
510 * On GLK both pipe CSC and degamma LUT are controlled
511 * by csc_enable. Hence for the cases where the degama
512 * LUT is needed but CSC is not we need to load an
513 * identity matrix.
514 */
515 drm_WARN_ON(&i915->drm, !IS_GEMINILAKE(i915));
516
517 ilk_csc_copy(i915, &crtc_state->csc, &ilk_csc_matrix_identity);
518 } else {
519 intel_csc_clear(&crtc_state->csc);
520 }
521 }
522
ilk_load_csc_matrix(const struct intel_crtc_state * crtc_state)523 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
524 {
525 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
526
527 if (crtc_state->csc_enable)
528 ilk_update_pipe_csc(crtc, &crtc_state->csc);
529 }
530
icl_assign_csc(struct intel_crtc_state * crtc_state)531 static void icl_assign_csc(struct intel_crtc_state *crtc_state)
532 {
533 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
534
535 if (crtc_state->hw.ctm) {
536 drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_CSC_ENABLE) == 0);
537
538 ilk_csc_convert_ctm(crtc_state, &crtc_state->csc, false);
539 } else {
540 drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_CSC_ENABLE) != 0);
541
542 intel_csc_clear(&crtc_state->csc);
543 }
544
545 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
546 drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) == 0);
547
548 ilk_csc_copy(i915, &crtc_state->output_csc, &ilk_csc_matrix_rgb_to_ycbcr);
549 } else if (crtc_state->limited_color_range) {
550 drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) == 0);
551
552 ilk_csc_copy(i915, &crtc_state->output_csc, &ilk_csc_matrix_limited_range);
553 } else {
554 drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) != 0);
555
556 intel_csc_clear(&crtc_state->output_csc);
557 }
558 }
559
icl_load_csc_matrix(const struct intel_crtc_state * crtc_state)560 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
561 {
562 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
563
564 if (crtc_state->csc_mode & ICL_CSC_ENABLE)
565 ilk_update_pipe_csc(crtc, &crtc_state->csc);
566
567 if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE)
568 icl_update_output_csc(crtc, &crtc_state->output_csc);
569 }
570
ctm_to_twos_complement(u64 coeff,int int_bits,int frac_bits)571 static u16 ctm_to_twos_complement(u64 coeff, int int_bits, int frac_bits)
572 {
573 s64 c = CTM_COEFF_ABS(coeff);
574
575 /* leave an extra bit for rounding */
576 c >>= 32 - frac_bits - 1;
577
578 /* round and drop the extra bit */
579 c = (c + 1) >> 1;
580
581 if (CTM_COEFF_NEGATIVE(coeff))
582 c = -c;
583
584 c = clamp(c, -(s64)BIT(int_bits + frac_bits - 1),
585 (s64)(BIT(int_bits + frac_bits - 1) - 1));
586
587 return c & (BIT(int_bits + frac_bits) - 1);
588 }
589
590 /*
591 * VLV/CHV Wide Gamut Color Correction (WGC) CSC
592 * |r| | c0 c1 c2 | |r|
593 * |g| = | c3 c4 c5 | x |g|
594 * |b| | c6 c7 c8 | |b|
595 *
596 * Coefficients are two's complement s2.10.
597 */
vlv_wgc_csc_convert_ctm(const struct intel_crtc_state * crtc_state,struct intel_csc_matrix * csc)598 static void vlv_wgc_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
599 struct intel_csc_matrix *csc)
600 {
601 const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
602 int i;
603
604 for (i = 0; i < 9; i++)
605 csc->coeff[i] = ctm_to_twos_complement(ctm->matrix[i], 2, 10);
606 }
607
vlv_load_wgc_csc(struct intel_crtc * crtc,const struct intel_csc_matrix * csc)608 static void vlv_load_wgc_csc(struct intel_crtc *crtc,
609 const struct intel_csc_matrix *csc)
610 {
611 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
612 enum pipe pipe = crtc->pipe;
613
614 intel_de_write_fw(dev_priv, PIPE_WGC_C01_C00(pipe),
615 csc->coeff[1] << 16 | csc->coeff[0]);
616 intel_de_write_fw(dev_priv, PIPE_WGC_C02(pipe),
617 csc->coeff[2]);
618
619 intel_de_write_fw(dev_priv, PIPE_WGC_C11_C10(pipe),
620 csc->coeff[4] << 16 | csc->coeff[3]);
621 intel_de_write_fw(dev_priv, PIPE_WGC_C12(pipe),
622 csc->coeff[5]);
623
624 intel_de_write_fw(dev_priv, PIPE_WGC_C21_C20(pipe),
625 csc->coeff[7] << 16 | csc->coeff[6]);
626 intel_de_write_fw(dev_priv, PIPE_WGC_C22(pipe),
627 csc->coeff[8]);
628 }
629
vlv_read_wgc_csc(struct intel_crtc * crtc,struct intel_csc_matrix * csc)630 static void vlv_read_wgc_csc(struct intel_crtc *crtc,
631 struct intel_csc_matrix *csc)
632 {
633 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
634 enum pipe pipe = crtc->pipe;
635 u32 tmp;
636
637 tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C01_C00(pipe));
638 csc->coeff[0] = tmp & 0xffff;
639 csc->coeff[1] = tmp >> 16;
640
641 tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C02(pipe));
642 csc->coeff[2] = tmp & 0xffff;
643
644 tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C11_C10(pipe));
645 csc->coeff[3] = tmp & 0xffff;
646 csc->coeff[4] = tmp >> 16;
647
648 tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C12(pipe));
649 csc->coeff[5] = tmp & 0xffff;
650
651 tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C21_C20(pipe));
652 csc->coeff[6] = tmp & 0xffff;
653 csc->coeff[7] = tmp >> 16;
654
655 tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C22(pipe));
656 csc->coeff[8] = tmp & 0xffff;
657 }
658
vlv_read_csc(struct intel_crtc_state * crtc_state)659 static void vlv_read_csc(struct intel_crtc_state *crtc_state)
660 {
661 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
662
663 if (crtc_state->wgc_enable)
664 vlv_read_wgc_csc(crtc, &crtc_state->csc);
665 }
666
vlv_assign_csc(struct intel_crtc_state * crtc_state)667 static void vlv_assign_csc(struct intel_crtc_state *crtc_state)
668 {
669 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
670
671 if (crtc_state->hw.ctm) {
672 drm_WARN_ON(&i915->drm, !crtc_state->wgc_enable);
673
674 vlv_wgc_csc_convert_ctm(crtc_state, &crtc_state->csc);
675 } else {
676 drm_WARN_ON(&i915->drm, crtc_state->wgc_enable);
677
678 intel_csc_clear(&crtc_state->csc);
679 }
680 }
681
682 /*
683 * CHV Color Gamut Mapping (CGM) CSC
684 * |r| | c0 c1 c2 | |r|
685 * |g| = | c3 c4 c5 | x |g|
686 * |b| | c6 c7 c8 | |b|
687 *
688 * Coefficients are two's complement s4.12.
689 */
chv_cgm_csc_convert_ctm(const struct intel_crtc_state * crtc_state,struct intel_csc_matrix * csc)690 static void chv_cgm_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
691 struct intel_csc_matrix *csc)
692 {
693 const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
694 int i;
695
696 for (i = 0; i < 9; i++)
697 csc->coeff[i] = ctm_to_twos_complement(ctm->matrix[i], 4, 12);
698 }
699
700 #define CHV_CGM_CSC_COEFF_1_0 (1 << 12)
701
702 static const struct intel_csc_matrix chv_cgm_csc_matrix_identity = {
703 .coeff = {
704 CHV_CGM_CSC_COEFF_1_0, 0, 0,
705 0, CHV_CGM_CSC_COEFF_1_0, 0,
706 0, 0, CHV_CGM_CSC_COEFF_1_0,
707 },
708 };
709
chv_load_cgm_csc(struct intel_crtc * crtc,const struct intel_csc_matrix * csc)710 static void chv_load_cgm_csc(struct intel_crtc *crtc,
711 const struct intel_csc_matrix *csc)
712 {
713 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
714 enum pipe pipe = crtc->pipe;
715
716 intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF01(pipe),
717 csc->coeff[1] << 16 | csc->coeff[0]);
718 intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF23(pipe),
719 csc->coeff[3] << 16 | csc->coeff[2]);
720 intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF45(pipe),
721 csc->coeff[5] << 16 | csc->coeff[4]);
722 intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF67(pipe),
723 csc->coeff[7] << 16 | csc->coeff[6]);
724 intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF8(pipe),
725 csc->coeff[8]);
726 }
727
chv_read_cgm_csc(struct intel_crtc * crtc,struct intel_csc_matrix * csc)728 static void chv_read_cgm_csc(struct intel_crtc *crtc,
729 struct intel_csc_matrix *csc)
730 {
731 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
732 enum pipe pipe = crtc->pipe;
733 u32 tmp;
734
735 tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF01(pipe));
736 csc->coeff[0] = tmp & 0xffff;
737 csc->coeff[1] = tmp >> 16;
738
739 tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF23(pipe));
740 csc->coeff[2] = tmp & 0xffff;
741 csc->coeff[3] = tmp >> 16;
742
743 tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF45(pipe));
744 csc->coeff[4] = tmp & 0xffff;
745 csc->coeff[5] = tmp >> 16;
746
747 tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF67(pipe));
748 csc->coeff[6] = tmp & 0xffff;
749 csc->coeff[7] = tmp >> 16;
750
751 tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF8(pipe));
752 csc->coeff[8] = tmp & 0xffff;
753 }
754
chv_read_csc(struct intel_crtc_state * crtc_state)755 static void chv_read_csc(struct intel_crtc_state *crtc_state)
756 {
757 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
758
759 if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
760 chv_read_cgm_csc(crtc, &crtc_state->csc);
761 }
762
chv_assign_csc(struct intel_crtc_state * crtc_state)763 static void chv_assign_csc(struct intel_crtc_state *crtc_state)
764 {
765 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
766
767 drm_WARN_ON(&i915->drm, crtc_state->wgc_enable);
768
769 if (crtc_state->hw.ctm) {
770 drm_WARN_ON(&i915->drm, (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC) == 0);
771
772 chv_cgm_csc_convert_ctm(crtc_state, &crtc_state->csc);
773 } else {
774 drm_WARN_ON(&i915->drm, (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC) == 0);
775
776 crtc_state->csc = chv_cgm_csc_matrix_identity;
777 }
778 }
779
780 /* convert hw value with given bit_precision to lut property val */
intel_color_lut_pack(u32 val,int bit_precision)781 static u32 intel_color_lut_pack(u32 val, int bit_precision)
782 {
783 u32 max = 0xffff >> (16 - bit_precision);
784
785 val = clamp_val(val, 0, max);
786
787 if (bit_precision < 16)
788 val <<= 16 - bit_precision;
789
790 return val;
791 }
792
i9xx_lut_8(const struct drm_color_lut * color)793 static u32 i9xx_lut_8(const struct drm_color_lut *color)
794 {
795 return REG_FIELD_PREP(PALETTE_RED_MASK, drm_color_lut_extract(color->red, 8)) |
796 REG_FIELD_PREP(PALETTE_GREEN_MASK, drm_color_lut_extract(color->green, 8)) |
797 REG_FIELD_PREP(PALETTE_BLUE_MASK, drm_color_lut_extract(color->blue, 8));
798 }
799
i9xx_lut_8_pack(struct drm_color_lut * entry,u32 val)800 static void i9xx_lut_8_pack(struct drm_color_lut *entry, u32 val)
801 {
802 entry->red = intel_color_lut_pack(REG_FIELD_GET(PALETTE_RED_MASK, val), 8);
803 entry->green = intel_color_lut_pack(REG_FIELD_GET(PALETTE_GREEN_MASK, val), 8);
804 entry->blue = intel_color_lut_pack(REG_FIELD_GET(PALETTE_BLUE_MASK, val), 8);
805 }
806
807 /* i8xx/i9xx+ 10bit slope format "even DW" (low 8 bits) */
_i9xx_lut_10_ldw(u16 a)808 static u32 _i9xx_lut_10_ldw(u16 a)
809 {
810 return drm_color_lut_extract(a, 10) & 0xff;
811 }
812
i9xx_lut_10_ldw(const struct drm_color_lut * color)813 static u32 i9xx_lut_10_ldw(const struct drm_color_lut *color)
814 {
815 return REG_FIELD_PREP(PALETTE_RED_MASK, _i9xx_lut_10_ldw(color[0].red)) |
816 REG_FIELD_PREP(PALETTE_GREEN_MASK, _i9xx_lut_10_ldw(color[0].green)) |
817 REG_FIELD_PREP(PALETTE_BLUE_MASK, _i9xx_lut_10_ldw(color[0].blue));
818 }
819
820 /* i8xx/i9xx+ 10bit slope format "odd DW" (high 2 bits + slope) */
_i9xx_lut_10_udw(u16 a,u16 b)821 static u32 _i9xx_lut_10_udw(u16 a, u16 b)
822 {
823 unsigned int mantissa, exponent;
824
825 a = drm_color_lut_extract(a, 10);
826 b = drm_color_lut_extract(b, 10);
827
828 /* b = a + 8 * m * 2 ^ -e */
829 mantissa = clamp(b - a, 0, 0x7f);
830 exponent = 3;
831 while (mantissa > 0xf) {
832 mantissa >>= 1;
833 exponent--;
834 }
835
836 return (exponent << 6) |
837 (mantissa << 2) |
838 (a >> 8);
839 }
840
i9xx_lut_10_udw(const struct drm_color_lut * color)841 static u32 i9xx_lut_10_udw(const struct drm_color_lut *color)
842 {
843 return REG_FIELD_PREP(PALETTE_RED_MASK, _i9xx_lut_10_udw(color[0].red, color[1].red)) |
844 REG_FIELD_PREP(PALETTE_GREEN_MASK, _i9xx_lut_10_udw(color[0].green, color[1].green)) |
845 REG_FIELD_PREP(PALETTE_BLUE_MASK, _i9xx_lut_10_udw(color[0].blue, color[1].blue));
846 }
847
i9xx_lut_10_pack(struct drm_color_lut * color,u32 ldw,u32 udw)848 static void i9xx_lut_10_pack(struct drm_color_lut *color,
849 u32 ldw, u32 udw)
850 {
851 u16 red = REG_FIELD_GET(PALETTE_10BIT_RED_LDW_MASK, ldw) |
852 REG_FIELD_GET(PALETTE_10BIT_RED_UDW_MASK, udw) << 8;
853 u16 green = REG_FIELD_GET(PALETTE_10BIT_GREEN_LDW_MASK, ldw) |
854 REG_FIELD_GET(PALETTE_10BIT_GREEN_UDW_MASK, udw) << 8;
855 u16 blue = REG_FIELD_GET(PALETTE_10BIT_BLUE_LDW_MASK, ldw) |
856 REG_FIELD_GET(PALETTE_10BIT_BLUE_UDW_MASK, udw) << 8;
857
858 color->red = intel_color_lut_pack(red, 10);
859 color->green = intel_color_lut_pack(green, 10);
860 color->blue = intel_color_lut_pack(blue, 10);
861 }
862
i9xx_lut_10_pack_slope(struct drm_color_lut * color,u32 ldw,u32 udw)863 static void i9xx_lut_10_pack_slope(struct drm_color_lut *color,
864 u32 ldw, u32 udw)
865 {
866 int r_exp = REG_FIELD_GET(PALETTE_10BIT_RED_EXP_MASK, udw);
867 int r_mant = REG_FIELD_GET(PALETTE_10BIT_RED_MANT_MASK, udw);
868 int g_exp = REG_FIELD_GET(PALETTE_10BIT_GREEN_EXP_MASK, udw);
869 int g_mant = REG_FIELD_GET(PALETTE_10BIT_GREEN_MANT_MASK, udw);
870 int b_exp = REG_FIELD_GET(PALETTE_10BIT_BLUE_EXP_MASK, udw);
871 int b_mant = REG_FIELD_GET(PALETTE_10BIT_BLUE_MANT_MASK, udw);
872
873 i9xx_lut_10_pack(color, ldw, udw);
874
875 color->red += r_mant << (3 - r_exp);
876 color->green += g_mant << (3 - g_exp);
877 color->blue += b_mant << (3 - b_exp);
878 }
879
880 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
i965_lut_10p6_ldw(const struct drm_color_lut * color)881 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
882 {
883 return REG_FIELD_PREP(PALETTE_RED_MASK, color->red & 0xff) |
884 REG_FIELD_PREP(PALETTE_GREEN_MASK, color->green & 0xff) |
885 REG_FIELD_PREP(PALETTE_BLUE_MASK, color->blue & 0xff);
886 }
887
888 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
i965_lut_10p6_udw(const struct drm_color_lut * color)889 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
890 {
891 return REG_FIELD_PREP(PALETTE_RED_MASK, color->red >> 8) |
892 REG_FIELD_PREP(PALETTE_GREEN_MASK, color->green >> 8) |
893 REG_FIELD_PREP(PALETTE_BLUE_MASK, color->blue >> 8);
894 }
895
i965_lut_10p6_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)896 static void i965_lut_10p6_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
897 {
898 entry->red = REG_FIELD_GET(PALETTE_RED_MASK, udw) << 8 |
899 REG_FIELD_GET(PALETTE_RED_MASK, ldw);
900 entry->green = REG_FIELD_GET(PALETTE_GREEN_MASK, udw) << 8 |
901 REG_FIELD_GET(PALETTE_GREEN_MASK, ldw);
902 entry->blue = REG_FIELD_GET(PALETTE_BLUE_MASK, udw) << 8 |
903 REG_FIELD_GET(PALETTE_BLUE_MASK, ldw);
904 }
905
i965_lut_11p6_max_pack(u32 val)906 static u16 i965_lut_11p6_max_pack(u32 val)
907 {
908 /* PIPEGCMAX is 11.6, clamp to 10.6 */
909 return clamp_val(val, 0, 0xffff);
910 }
911
ilk_lut_10(const struct drm_color_lut * color)912 static u32 ilk_lut_10(const struct drm_color_lut *color)
913 {
914 return REG_FIELD_PREP(PREC_PALETTE_10_RED_MASK, drm_color_lut_extract(color->red, 10)) |
915 REG_FIELD_PREP(PREC_PALETTE_10_GREEN_MASK, drm_color_lut_extract(color->green, 10)) |
916 REG_FIELD_PREP(PREC_PALETTE_10_BLUE_MASK, drm_color_lut_extract(color->blue, 10));
917 }
918
ilk_lut_10_pack(struct drm_color_lut * entry,u32 val)919 static void ilk_lut_10_pack(struct drm_color_lut *entry, u32 val)
920 {
921 entry->red = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_10_RED_MASK, val), 10);
922 entry->green = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_10_GREEN_MASK, val), 10);
923 entry->blue = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_10_BLUE_MASK, val), 10);
924 }
925
926 /* ilk+ "12.4" interpolated format (low 6 bits) */
ilk_lut_12p4_ldw(const struct drm_color_lut * color)927 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
928 {
929 return REG_FIELD_PREP(PREC_PALETTE_12P4_RED_LDW_MASK, color->red & 0x3f) |
930 REG_FIELD_PREP(PREC_PALETTE_12P4_GREEN_LDW_MASK, color->green & 0x3f) |
931 REG_FIELD_PREP(PREC_PALETTE_12P4_BLUE_LDW_MASK, color->blue & 0x3f);
932 }
933
934 /* ilk+ "12.4" interpolated format (high 10 bits) */
ilk_lut_12p4_udw(const struct drm_color_lut * color)935 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
936 {
937 return REG_FIELD_PREP(PREC_PALETTE_12P4_RED_UDW_MASK, color->red >> 6) |
938 REG_FIELD_PREP(PREC_PALETTE_12P4_GREEN_UDW_MASK, color->green >> 6) |
939 REG_FIELD_PREP(PREC_PALETTE_12P4_BLUE_UDW_MASK, color->blue >> 6);
940 }
941
ilk_lut_12p4_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)942 static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
943 {
944 entry->red = REG_FIELD_GET(PREC_PALETTE_12P4_RED_UDW_MASK, udw) << 6 |
945 REG_FIELD_GET(PREC_PALETTE_12P4_RED_LDW_MASK, ldw);
946 entry->green = REG_FIELD_GET(PREC_PALETTE_12P4_GREEN_UDW_MASK, udw) << 6 |
947 REG_FIELD_GET(PREC_PALETTE_12P4_GREEN_LDW_MASK, ldw);
948 entry->blue = REG_FIELD_GET(PREC_PALETTE_12P4_BLUE_UDW_MASK, udw) << 6 |
949 REG_FIELD_GET(PREC_PALETTE_12P4_BLUE_LDW_MASK, ldw);
950 }
951
icl_color_commit_noarm(const struct intel_crtc_state * crtc_state)952 static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
953 {
954 /*
955 * Despite Wa_1406463849, ICL no longer suffers from the SKL
956 * DC5/PSR CSC black screen issue (see skl_color_commit_noarm()).
957 * Possibly due to the extra sticky CSC arming
958 * (see icl_color_post_update()).
959 *
960 * On TGL+ all CSC arming issues have been properly fixed.
961 */
962 icl_load_csc_matrix(crtc_state);
963 }
964
skl_color_commit_noarm(const struct intel_crtc_state * crtc_state)965 static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
966 {
967 /*
968 * Possibly related to display WA #1184, SKL CSC loses the latched
969 * CSC coeff/offset register values if the CSC registers are disarmed
970 * between DC5 exit and PSR exit. This will cause the plane(s) to
971 * output all black (until CSC_MODE is rearmed and properly latched).
972 * Once PSR exit (and proper register latching) has occurred the
973 * danger is over. Thus when PSR is enabled the CSC coeff/offset
974 * register programming will be peformed from skl_color_commit_arm()
975 * which is called after PSR exit.
976 */
977 if (!crtc_state->has_psr)
978 ilk_load_csc_matrix(crtc_state);
979 }
980
ilk_color_commit_noarm(const struct intel_crtc_state * crtc_state)981 static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
982 {
983 ilk_load_csc_matrix(crtc_state);
984 }
985
i9xx_color_commit_arm(const struct intel_crtc_state * crtc_state)986 static void i9xx_color_commit_arm(const struct intel_crtc_state *crtc_state)
987 {
988 /* update TRANSCONF GAMMA_MODE */
989 i9xx_set_pipeconf(crtc_state);
990 }
991
ilk_color_commit_arm(const struct intel_crtc_state * crtc_state)992 static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state)
993 {
994 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
995 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
996
997 /* update TRANSCONF GAMMA_MODE */
998 ilk_set_pipeconf(crtc_state);
999
1000 intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1001 crtc_state->csc_mode);
1002 }
1003
hsw_color_commit_arm(const struct intel_crtc_state * crtc_state)1004 static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state)
1005 {
1006 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1007 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1008
1009 intel_de_write(i915, GAMMA_MODE(crtc->pipe),
1010 crtc_state->gamma_mode);
1011
1012 intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1013 crtc_state->csc_mode);
1014 }
1015
skl_color_commit_arm(const struct intel_crtc_state * crtc_state)1016 static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
1017 {
1018 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1019 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1020 enum pipe pipe = crtc->pipe;
1021 u32 val = 0;
1022
1023 if (crtc_state->has_psr)
1024 ilk_load_csc_matrix(crtc_state);
1025
1026 /*
1027 * We don't (yet) allow userspace to control the pipe background color,
1028 * so force it to black, but apply pipe gamma and CSC appropriately
1029 * so that its handling will match how we program our planes.
1030 */
1031 if (crtc_state->gamma_enable)
1032 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
1033 if (crtc_state->csc_enable)
1034 val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
1035 intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), val);
1036
1037 intel_de_write(i915, GAMMA_MODE(crtc->pipe),
1038 crtc_state->gamma_mode);
1039
1040 intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1041 crtc_state->csc_mode);
1042 }
1043
icl_color_commit_arm(const struct intel_crtc_state * crtc_state)1044 static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state)
1045 {
1046 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1047 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1048 enum pipe pipe = crtc->pipe;
1049
1050 /*
1051 * We don't (yet) allow userspace to control the pipe background color,
1052 * so force it to black.
1053 */
1054 intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0);
1055
1056 intel_de_write(i915, GAMMA_MODE(crtc->pipe),
1057 crtc_state->gamma_mode);
1058
1059 intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1060 crtc_state->csc_mode);
1061 }
1062
icl_color_post_update(const struct intel_crtc_state * crtc_state)1063 static void icl_color_post_update(const struct intel_crtc_state *crtc_state)
1064 {
1065 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1066 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1067
1068 /*
1069 * Despite Wa_1406463849, ICL CSC is no longer disarmed by
1070 * coeff/offset register *writes*. Instead, once CSC_MODE
1071 * is armed it stays armed, even after it has been latched.
1072 * Afterwards the coeff/offset registers become effectively
1073 * self-arming. That self-arming must be disabled before the
1074 * next icl_color_commit_noarm() tries to write the next set
1075 * of coeff/offset registers. Fortunately register *reads*
1076 * do still disarm the CSC. Naturally this must not be done
1077 * until the previously written CSC registers have actually
1078 * been latched.
1079 *
1080 * TGL+ no longer need this workaround.
1081 */
1082 intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(crtc->pipe));
1083 }
1084
1085 static struct drm_property_blob *
create_linear_lut(struct drm_i915_private * i915,int lut_size)1086 create_linear_lut(struct drm_i915_private *i915, int lut_size)
1087 {
1088 struct drm_property_blob *blob;
1089 struct drm_color_lut *lut;
1090 int i;
1091
1092 blob = drm_property_create_blob(&i915->drm,
1093 sizeof(lut[0]) * lut_size,
1094 NULL);
1095 if (IS_ERR(blob))
1096 return blob;
1097
1098 lut = blob->data;
1099
1100 for (i = 0; i < lut_size; i++) {
1101 u16 val = 0xffff * i / (lut_size - 1);
1102
1103 lut[i].red = val;
1104 lut[i].green = val;
1105 lut[i].blue = val;
1106 }
1107
1108 return blob;
1109 }
1110
lut_limited_range(unsigned int value)1111 static u16 lut_limited_range(unsigned int value)
1112 {
1113 unsigned int min = 16 << 8;
1114 unsigned int max = 235 << 8;
1115
1116 return value * (max - min) / 0xffff + min;
1117 }
1118
1119 static struct drm_property_blob *
create_resized_lut(struct drm_i915_private * i915,const struct drm_property_blob * blob_in,int lut_out_size,bool limited_color_range)1120 create_resized_lut(struct drm_i915_private *i915,
1121 const struct drm_property_blob *blob_in, int lut_out_size,
1122 bool limited_color_range)
1123 {
1124 int i, lut_in_size = drm_color_lut_size(blob_in);
1125 struct drm_property_blob *blob_out;
1126 const struct drm_color_lut *lut_in;
1127 struct drm_color_lut *lut_out;
1128
1129 blob_out = drm_property_create_blob(&i915->drm,
1130 sizeof(lut_out[0]) * lut_out_size,
1131 NULL);
1132 if (IS_ERR(blob_out))
1133 return blob_out;
1134
1135 lut_in = blob_in->data;
1136 lut_out = blob_out->data;
1137
1138 for (i = 0; i < lut_out_size; i++) {
1139 const struct drm_color_lut *entry =
1140 &lut_in[i * (lut_in_size - 1) / (lut_out_size - 1)];
1141
1142 if (limited_color_range) {
1143 lut_out[i].red = lut_limited_range(entry->red);
1144 lut_out[i].green = lut_limited_range(entry->green);
1145 lut_out[i].blue = lut_limited_range(entry->blue);
1146 } else {
1147 lut_out[i] = *entry;
1148 }
1149 }
1150
1151 return blob_out;
1152 }
1153
i9xx_load_lut_8(struct intel_crtc * crtc,const struct drm_property_blob * blob)1154 static void i9xx_load_lut_8(struct intel_crtc *crtc,
1155 const struct drm_property_blob *blob)
1156 {
1157 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1158 const struct drm_color_lut *lut;
1159 enum pipe pipe = crtc->pipe;
1160 int i;
1161
1162 if (!blob)
1163 return;
1164
1165 lut = blob->data;
1166
1167 for (i = 0; i < 256; i++)
1168 intel_de_write_fw(dev_priv, PALETTE(pipe, i),
1169 i9xx_lut_8(&lut[i]));
1170 }
1171
i9xx_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob)1172 static void i9xx_load_lut_10(struct intel_crtc *crtc,
1173 const struct drm_property_blob *blob)
1174 {
1175 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1176 const struct drm_color_lut *lut = blob->data;
1177 int i, lut_size = drm_color_lut_size(blob);
1178 enum pipe pipe = crtc->pipe;
1179
1180 for (i = 0; i < lut_size - 1; i++) {
1181 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 0),
1182 i9xx_lut_10_ldw(&lut[i]));
1183 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 1),
1184 i9xx_lut_10_udw(&lut[i]));
1185 }
1186 }
1187
i9xx_load_luts(const struct intel_crtc_state * crtc_state)1188 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
1189 {
1190 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1191 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1192
1193 switch (crtc_state->gamma_mode) {
1194 case GAMMA_MODE_MODE_8BIT:
1195 i9xx_load_lut_8(crtc, post_csc_lut);
1196 break;
1197 case GAMMA_MODE_MODE_10BIT:
1198 i9xx_load_lut_10(crtc, post_csc_lut);
1199 break;
1200 default:
1201 MISSING_CASE(crtc_state->gamma_mode);
1202 break;
1203 }
1204 }
1205
i965_load_lut_10p6(struct intel_crtc * crtc,const struct drm_property_blob * blob)1206 static void i965_load_lut_10p6(struct intel_crtc *crtc,
1207 const struct drm_property_blob *blob)
1208 {
1209 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1210 const struct drm_color_lut *lut = blob->data;
1211 int i, lut_size = drm_color_lut_size(blob);
1212 enum pipe pipe = crtc->pipe;
1213
1214 for (i = 0; i < lut_size - 1; i++) {
1215 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 0),
1216 i965_lut_10p6_ldw(&lut[i]));
1217 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 1),
1218 i965_lut_10p6_udw(&lut[i]));
1219 }
1220
1221 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 0), lut[i].red);
1222 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 1), lut[i].green);
1223 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 2), lut[i].blue);
1224 }
1225
i965_load_luts(const struct intel_crtc_state * crtc_state)1226 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
1227 {
1228 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1229 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1230
1231 switch (crtc_state->gamma_mode) {
1232 case GAMMA_MODE_MODE_8BIT:
1233 i9xx_load_lut_8(crtc, post_csc_lut);
1234 break;
1235 case GAMMA_MODE_MODE_10BIT:
1236 i965_load_lut_10p6(crtc, post_csc_lut);
1237 break;
1238 default:
1239 MISSING_CASE(crtc_state->gamma_mode);
1240 break;
1241 }
1242 }
1243
ilk_lut_write(const struct intel_crtc_state * crtc_state,i915_reg_t reg,u32 val)1244 static void ilk_lut_write(const struct intel_crtc_state *crtc_state,
1245 i915_reg_t reg, u32 val)
1246 {
1247 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1248
1249 if (crtc_state->dsb)
1250 intel_dsb_reg_write(crtc_state->dsb, reg, val);
1251 else
1252 intel_de_write_fw(i915, reg, val);
1253 }
1254
ilk_load_lut_8(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob)1255 static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
1256 const struct drm_property_blob *blob)
1257 {
1258 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1259 const struct drm_color_lut *lut;
1260 enum pipe pipe = crtc->pipe;
1261 int i;
1262
1263 if (!blob)
1264 return;
1265
1266 lut = blob->data;
1267
1268 for (i = 0; i < 256; i++)
1269 ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
1270 i9xx_lut_8(&lut[i]));
1271 }
1272
ilk_load_lut_10(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob)1273 static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,
1274 const struct drm_property_blob *blob)
1275 {
1276 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1277 const struct drm_color_lut *lut = blob->data;
1278 int i, lut_size = drm_color_lut_size(blob);
1279 enum pipe pipe = crtc->pipe;
1280
1281 for (i = 0; i < lut_size; i++)
1282 ilk_lut_write(crtc_state, PREC_PALETTE(pipe, i),
1283 ilk_lut_10(&lut[i]));
1284 }
1285
ilk_load_luts(const struct intel_crtc_state * crtc_state)1286 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
1287 {
1288 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1289 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1290 const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
1291
1292 switch (crtc_state->gamma_mode) {
1293 case GAMMA_MODE_MODE_8BIT:
1294 ilk_load_lut_8(crtc_state, blob);
1295 break;
1296 case GAMMA_MODE_MODE_10BIT:
1297 ilk_load_lut_10(crtc_state, blob);
1298 break;
1299 default:
1300 MISSING_CASE(crtc_state->gamma_mode);
1301 break;
1302 }
1303 }
1304
ivb_lut_10_size(u32 prec_index)1305 static int ivb_lut_10_size(u32 prec_index)
1306 {
1307 if (prec_index & PAL_PREC_SPLIT_MODE)
1308 return 512;
1309 else
1310 return 1024;
1311 }
1312
1313 /*
1314 * IVB/HSW Bspec / PAL_PREC_INDEX:
1315 * "Restriction : Index auto increment mode is not
1316 * supported and must not be enabled."
1317 */
ivb_load_lut_10(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob,u32 prec_index)1318 static void ivb_load_lut_10(const struct intel_crtc_state *crtc_state,
1319 const struct drm_property_blob *blob,
1320 u32 prec_index)
1321 {
1322 const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1323 const struct drm_color_lut *lut = blob->data;
1324 int i, lut_size = drm_color_lut_size(blob);
1325 enum pipe pipe = crtc->pipe;
1326
1327 for (i = 0; i < lut_size; i++) {
1328 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1329 prec_index + i);
1330 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1331 ilk_lut_10(&lut[i]));
1332 }
1333
1334 /*
1335 * Reset the index, otherwise it prevents the legacy palette to be
1336 * written properly.
1337 */
1338 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1339 PAL_PREC_INDEX_VALUE(0));
1340 }
1341
1342 /* On BDW+ the index auto increment mode actually works */
bdw_load_lut_10(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob,u32 prec_index)1343 static void bdw_load_lut_10(const struct intel_crtc_state *crtc_state,
1344 const struct drm_property_blob *blob,
1345 u32 prec_index)
1346 {
1347 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1348 const struct drm_color_lut *lut = blob->data;
1349 int i, lut_size = drm_color_lut_size(blob);
1350 enum pipe pipe = crtc->pipe;
1351
1352 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1353 prec_index);
1354 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1355 PAL_PREC_AUTO_INCREMENT |
1356 prec_index);
1357
1358 for (i = 0; i < lut_size; i++)
1359 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1360 ilk_lut_10(&lut[i]));
1361
1362 /*
1363 * Reset the index, otherwise it prevents the legacy palette to be
1364 * written properly.
1365 */
1366 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1367 PAL_PREC_INDEX_VALUE(0));
1368 }
1369
ivb_load_lut_ext_max(const struct intel_crtc_state * crtc_state)1370 static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
1371 {
1372 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1373 enum pipe pipe = crtc->pipe;
1374
1375 /* Program the max register to clamp values > 1.0. */
1376 ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
1377 ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
1378 ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
1379 }
1380
glk_load_lut_ext2_max(const struct intel_crtc_state * crtc_state)1381 static void glk_load_lut_ext2_max(const struct intel_crtc_state *crtc_state)
1382 {
1383 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1384 enum pipe pipe = crtc->pipe;
1385
1386 /* Program the max register to clamp values > 1.0. */
1387 ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16);
1388 ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16);
1389 ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16);
1390 }
1391
ivb_load_luts(const struct intel_crtc_state * crtc_state)1392 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
1393 {
1394 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1395 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1396 const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
1397
1398 switch (crtc_state->gamma_mode) {
1399 case GAMMA_MODE_MODE_8BIT:
1400 ilk_load_lut_8(crtc_state, blob);
1401 break;
1402 case GAMMA_MODE_MODE_SPLIT:
1403 ivb_load_lut_10(crtc_state, pre_csc_lut, PAL_PREC_SPLIT_MODE |
1404 PAL_PREC_INDEX_VALUE(0));
1405 ivb_load_lut_ext_max(crtc_state);
1406 ivb_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_SPLIT_MODE |
1407 PAL_PREC_INDEX_VALUE(512));
1408 break;
1409 case GAMMA_MODE_MODE_10BIT:
1410 ivb_load_lut_10(crtc_state, blob,
1411 PAL_PREC_INDEX_VALUE(0));
1412 ivb_load_lut_ext_max(crtc_state);
1413 break;
1414 default:
1415 MISSING_CASE(crtc_state->gamma_mode);
1416 break;
1417 }
1418 }
1419
bdw_load_luts(const struct intel_crtc_state * crtc_state)1420 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
1421 {
1422 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1423 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1424 const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
1425
1426 switch (crtc_state->gamma_mode) {
1427 case GAMMA_MODE_MODE_8BIT:
1428 ilk_load_lut_8(crtc_state, blob);
1429 break;
1430 case GAMMA_MODE_MODE_SPLIT:
1431 bdw_load_lut_10(crtc_state, pre_csc_lut, PAL_PREC_SPLIT_MODE |
1432 PAL_PREC_INDEX_VALUE(0));
1433 ivb_load_lut_ext_max(crtc_state);
1434 bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_SPLIT_MODE |
1435 PAL_PREC_INDEX_VALUE(512));
1436 break;
1437 case GAMMA_MODE_MODE_10BIT:
1438 bdw_load_lut_10(crtc_state, blob,
1439 PAL_PREC_INDEX_VALUE(0));
1440 ivb_load_lut_ext_max(crtc_state);
1441 break;
1442 default:
1443 MISSING_CASE(crtc_state->gamma_mode);
1444 break;
1445 }
1446 }
1447
glk_degamma_lut_size(struct drm_i915_private * i915)1448 static int glk_degamma_lut_size(struct drm_i915_private *i915)
1449 {
1450 if (DISPLAY_VER(i915) >= 13)
1451 return 131;
1452 else
1453 return 35;
1454 }
1455
1456 /*
1457 * change_lut_val_precision: helper function to upscale or downscale lut values.
1458 * Parameters 'to' and 'from' needs to be less than 32. This should be sufficient
1459 * as currently there are no lut values exceeding 32 bit.
1460 */
change_lut_val_precision(u32 lut_val,int to,int from)1461 static u32 change_lut_val_precision(u32 lut_val, int to, int from)
1462 {
1463 return mul_u32_u32(lut_val, (1 << to)) / (1 << from);
1464 }
1465
glk_load_degamma_lut(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob)1466 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
1467 const struct drm_property_blob *blob)
1468 {
1469 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1470 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1471 const struct drm_color_lut *lut = blob->data;
1472 int i, lut_size = drm_color_lut_size(blob);
1473 enum pipe pipe = crtc->pipe;
1474
1475 /*
1476 * When setting the auto-increment bit, the hardware seems to
1477 * ignore the index bits, so we need to reset it to index 0
1478 * separately.
1479 */
1480 ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe),
1481 PRE_CSC_GAMC_INDEX_VALUE(0));
1482 ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe),
1483 PRE_CSC_GAMC_AUTO_INCREMENT |
1484 PRE_CSC_GAMC_INDEX_VALUE(0));
1485
1486 for (i = 0; i < lut_size; i++) {
1487 /*
1488 * First lut_size entries represent range from 0 to 1.0
1489 * 3 additional lut entries will represent extended range
1490 * inputs 3.0 and 7.0 respectively, currently clamped
1491 * at 1.0. Since the precision is 16bit, the user
1492 * value can be directly filled to register.
1493 * The pipe degamma table in GLK+ onwards doesn't
1494 * support different values per channel, so this just
1495 * programs green value which will be equal to Red and
1496 * Blue into the lut registers.
1497 * ToDo: Extend to max 7.0. Enable 32 bit input value
1498 * as compared to just 16 to achieve this.
1499 */
1500 u32 lut_val;
1501
1502 if (DISPLAY_VER(i915) >= 14)
1503 lut_val = change_lut_val_precision(lut[i].green, 24, 16);
1504 else
1505 lut_val = lut[i].green;
1506
1507 ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
1508 lut_val);
1509 }
1510
1511 /* Clamp values > 1.0. */
1512 while (i++ < glk_degamma_lut_size(i915))
1513 ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
1514
1515 ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 0);
1516 }
1517
glk_load_luts(const struct intel_crtc_state * crtc_state)1518 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
1519 {
1520 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1521 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1522
1523 if (pre_csc_lut)
1524 glk_load_degamma_lut(crtc_state, pre_csc_lut);
1525
1526 switch (crtc_state->gamma_mode) {
1527 case GAMMA_MODE_MODE_8BIT:
1528 ilk_load_lut_8(crtc_state, post_csc_lut);
1529 break;
1530 case GAMMA_MODE_MODE_10BIT:
1531 bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
1532 ivb_load_lut_ext_max(crtc_state);
1533 glk_load_lut_ext2_max(crtc_state);
1534 break;
1535 default:
1536 MISSING_CASE(crtc_state->gamma_mode);
1537 break;
1538 }
1539 }
1540
1541 static void
ivb_load_lut_max(const struct intel_crtc_state * crtc_state,const struct drm_color_lut * color)1542 ivb_load_lut_max(const struct intel_crtc_state *crtc_state,
1543 const struct drm_color_lut *color)
1544 {
1545 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1546 enum pipe pipe = crtc->pipe;
1547
1548 /* FIXME LUT entries are 16 bit only, so we can prog 0xFFFF max */
1549 ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 0), color->red);
1550 ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 1), color->green);
1551 ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 2), color->blue);
1552 }
1553
1554 static void
icl_program_gamma_superfine_segment(const struct intel_crtc_state * crtc_state)1555 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
1556 {
1557 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1558 const struct drm_property_blob *blob = crtc_state->post_csc_lut;
1559 const struct drm_color_lut *lut = blob->data;
1560 enum pipe pipe = crtc->pipe;
1561 int i;
1562
1563 /*
1564 * Program Super Fine segment (let's call it seg1)...
1565 *
1566 * Super Fine segment's step is 1/(8 * 128 * 256) and it has
1567 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256),
1568 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256).
1569 */
1570 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1571 PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
1572 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1573 PAL_PREC_AUTO_INCREMENT |
1574 PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
1575
1576 for (i = 0; i < 9; i++) {
1577 const struct drm_color_lut *entry = &lut[i];
1578
1579 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
1580 ilk_lut_12p4_ldw(entry));
1581 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
1582 ilk_lut_12p4_udw(entry));
1583 }
1584
1585 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1586 PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
1587 }
1588
1589 static void
icl_program_gamma_multi_segment(const struct intel_crtc_state * crtc_state)1590 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
1591 {
1592 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1593 const struct drm_property_blob *blob = crtc_state->post_csc_lut;
1594 const struct drm_color_lut *lut = blob->data;
1595 const struct drm_color_lut *entry;
1596 enum pipe pipe = crtc->pipe;
1597 int i;
1598
1599 /*
1600 * Program Fine segment (let's call it seg2)...
1601 *
1602 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256)
1603 * ... 256/(128 * 256). So in order to program fine segment of LUT we
1604 * need to pick every 8th entry in the LUT, and program 256 indexes.
1605 *
1606 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
1607 * seg2[0] being unused by the hardware.
1608 */
1609 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1610 PAL_PREC_INDEX_VALUE(0));
1611 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1612 PAL_PREC_AUTO_INCREMENT |
1613 PAL_PREC_INDEX_VALUE(0));
1614
1615 for (i = 1; i < 257; i++) {
1616 entry = &lut[i * 8];
1617
1618 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1619 ilk_lut_12p4_ldw(entry));
1620 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1621 ilk_lut_12p4_udw(entry));
1622 }
1623
1624 /*
1625 * Program Coarse segment (let's call it seg3)...
1626 *
1627 * Coarse segment starts from index 0 and it's step is 1/256 ie 0,
1628 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT
1629 * above, we need to pick every (8 * 128)th entry in LUT, and
1630 * program 256 of those.
1631 *
1632 * Spec is not very clear about if entries seg3[0] and seg3[1] are
1633 * being used or not, but we still need to program these to advance
1634 * the index.
1635 */
1636 for (i = 0; i < 256; i++) {
1637 entry = &lut[i * 8 * 128];
1638
1639 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1640 ilk_lut_12p4_ldw(entry));
1641 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1642 ilk_lut_12p4_udw(entry));
1643 }
1644
1645 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1646 PAL_PREC_INDEX_VALUE(0));
1647
1648 /* The last entry in the LUT is to be programmed in GCMAX */
1649 entry = &lut[256 * 8 * 128];
1650 ivb_load_lut_max(crtc_state, entry);
1651 }
1652
icl_load_luts(const struct intel_crtc_state * crtc_state)1653 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
1654 {
1655 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1656 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1657
1658 if (pre_csc_lut)
1659 glk_load_degamma_lut(crtc_state, pre_csc_lut);
1660
1661 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
1662 case GAMMA_MODE_MODE_8BIT:
1663 ilk_load_lut_8(crtc_state, post_csc_lut);
1664 break;
1665 case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
1666 icl_program_gamma_superfine_segment(crtc_state);
1667 icl_program_gamma_multi_segment(crtc_state);
1668 ivb_load_lut_ext_max(crtc_state);
1669 glk_load_lut_ext2_max(crtc_state);
1670 break;
1671 case GAMMA_MODE_MODE_10BIT:
1672 bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
1673 ivb_load_lut_ext_max(crtc_state);
1674 glk_load_lut_ext2_max(crtc_state);
1675 break;
1676 default:
1677 MISSING_CASE(crtc_state->gamma_mode);
1678 break;
1679 }
1680
1681 if (crtc_state->dsb) {
1682 intel_dsb_finish(crtc_state->dsb);
1683 intel_dsb_commit(crtc_state->dsb, false);
1684 intel_dsb_wait(crtc_state->dsb);
1685 }
1686 }
1687
vlv_load_luts(const struct intel_crtc_state * crtc_state)1688 static void vlv_load_luts(const struct intel_crtc_state *crtc_state)
1689 {
1690 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1691
1692 if (crtc_state->wgc_enable)
1693 vlv_load_wgc_csc(crtc, &crtc_state->csc);
1694
1695 i965_load_luts(crtc_state);
1696 }
1697
chv_cgm_degamma_ldw(const struct drm_color_lut * color)1698 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
1699 {
1700 return REG_FIELD_PREP(CGM_PIPE_DEGAMMA_GREEN_LDW_MASK, drm_color_lut_extract(color->green, 14)) |
1701 REG_FIELD_PREP(CGM_PIPE_DEGAMMA_BLUE_LDW_MASK, drm_color_lut_extract(color->blue, 14));
1702 }
1703
chv_cgm_degamma_udw(const struct drm_color_lut * color)1704 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
1705 {
1706 return REG_FIELD_PREP(CGM_PIPE_DEGAMMA_RED_UDW_MASK, drm_color_lut_extract(color->red, 14));
1707 }
1708
chv_cgm_degamma_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)1709 static void chv_cgm_degamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
1710 {
1711 entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_GREEN_LDW_MASK, ldw), 14);
1712 entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_BLUE_LDW_MASK, ldw), 14);
1713 entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_RED_UDW_MASK, udw), 14);
1714 }
1715
chv_load_cgm_degamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)1716 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
1717 const struct drm_property_blob *blob)
1718 {
1719 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1720 const struct drm_color_lut *lut = blob->data;
1721 int i, lut_size = drm_color_lut_size(blob);
1722 enum pipe pipe = crtc->pipe;
1723
1724 for (i = 0; i < lut_size; i++) {
1725 intel_de_write_fw(i915, CGM_PIPE_DEGAMMA(pipe, i, 0),
1726 chv_cgm_degamma_ldw(&lut[i]));
1727 intel_de_write_fw(i915, CGM_PIPE_DEGAMMA(pipe, i, 1),
1728 chv_cgm_degamma_udw(&lut[i]));
1729 }
1730 }
1731
chv_cgm_gamma_ldw(const struct drm_color_lut * color)1732 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
1733 {
1734 return REG_FIELD_PREP(CGM_PIPE_GAMMA_GREEN_LDW_MASK, drm_color_lut_extract(color->green, 10)) |
1735 REG_FIELD_PREP(CGM_PIPE_GAMMA_BLUE_LDW_MASK, drm_color_lut_extract(color->blue, 10));
1736 }
1737
chv_cgm_gamma_udw(const struct drm_color_lut * color)1738 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
1739 {
1740 return REG_FIELD_PREP(CGM_PIPE_GAMMA_RED_UDW_MASK, drm_color_lut_extract(color->red, 10));
1741 }
1742
chv_cgm_gamma_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)1743 static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
1744 {
1745 entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_LDW_MASK, ldw), 10);
1746 entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_LDW_MASK, ldw), 10);
1747 entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_UDW_MASK, udw), 10);
1748 }
1749
chv_load_cgm_gamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)1750 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
1751 const struct drm_property_blob *blob)
1752 {
1753 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1754 const struct drm_color_lut *lut = blob->data;
1755 int i, lut_size = drm_color_lut_size(blob);
1756 enum pipe pipe = crtc->pipe;
1757
1758 for (i = 0; i < lut_size; i++) {
1759 intel_de_write_fw(i915, CGM_PIPE_GAMMA(pipe, i, 0),
1760 chv_cgm_gamma_ldw(&lut[i]));
1761 intel_de_write_fw(i915, CGM_PIPE_GAMMA(pipe, i, 1),
1762 chv_cgm_gamma_udw(&lut[i]));
1763 }
1764 }
1765
chv_load_luts(const struct intel_crtc_state * crtc_state)1766 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
1767 {
1768 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1769 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1770 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1771 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1772
1773 if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
1774 chv_load_cgm_csc(crtc, &crtc_state->csc);
1775
1776 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
1777 chv_load_cgm_degamma(crtc, pre_csc_lut);
1778
1779 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1780 chv_load_cgm_gamma(crtc, post_csc_lut);
1781 else
1782 i965_load_luts(crtc_state);
1783
1784 intel_de_write_fw(i915, CGM_PIPE_MODE(crtc->pipe),
1785 crtc_state->cgm_mode);
1786 }
1787
intel_color_load_luts(const struct intel_crtc_state * crtc_state)1788 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
1789 {
1790 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1791
1792 i915->display.funcs.color->load_luts(crtc_state);
1793 }
1794
intel_color_commit_noarm(const struct intel_crtc_state * crtc_state)1795 void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state)
1796 {
1797 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1798
1799 if (i915->display.funcs.color->color_commit_noarm)
1800 i915->display.funcs.color->color_commit_noarm(crtc_state);
1801 }
1802
intel_color_commit_arm(const struct intel_crtc_state * crtc_state)1803 void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
1804 {
1805 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1806
1807 i915->display.funcs.color->color_commit_arm(crtc_state);
1808 }
1809
intel_color_post_update(const struct intel_crtc_state * crtc_state)1810 void intel_color_post_update(const struct intel_crtc_state *crtc_state)
1811 {
1812 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1813
1814 if (i915->display.funcs.color->color_post_update)
1815 i915->display.funcs.color->color_post_update(crtc_state);
1816 }
1817
intel_color_prepare_commit(struct intel_crtc_state * crtc_state)1818 void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
1819 {
1820 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1821
1822 /* FIXME DSB has issues loading LUTs, disable it for now */
1823 return;
1824
1825 if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
1826 return;
1827
1828 crtc_state->dsb = intel_dsb_prepare(crtc, 1024);
1829 }
1830
intel_color_cleanup_commit(struct intel_crtc_state * crtc_state)1831 void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
1832 {
1833 if (!crtc_state->dsb)
1834 return;
1835
1836 intel_dsb_cleanup(crtc_state->dsb);
1837 crtc_state->dsb = NULL;
1838 }
1839
intel_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1840 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1841 {
1842 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1843 struct intel_atomic_state *state =
1844 to_intel_atomic_state(new_crtc_state->uapi.state);
1845 const struct intel_crtc_state *old_crtc_state =
1846 intel_atomic_get_old_crtc_state(state, crtc);
1847
1848 return !old_crtc_state->post_csc_lut &&
1849 !old_crtc_state->pre_csc_lut;
1850 }
1851
vlv_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1852 static bool vlv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1853 {
1854 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1855 struct intel_atomic_state *state =
1856 to_intel_atomic_state(new_crtc_state->uapi.state);
1857 const struct intel_crtc_state *old_crtc_state =
1858 intel_atomic_get_old_crtc_state(state, crtc);
1859
1860 return !old_crtc_state->wgc_enable &&
1861 !old_crtc_state->post_csc_lut;
1862 }
1863
chv_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1864 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1865 {
1866 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1867 struct intel_atomic_state *state =
1868 to_intel_atomic_state(new_crtc_state->uapi.state);
1869 const struct intel_crtc_state *old_crtc_state =
1870 intel_atomic_get_old_crtc_state(state, crtc);
1871
1872 /*
1873 * CGM_PIPE_MODE is itself single buffered. We'd have to
1874 * somehow split it out from chv_load_luts() if we wanted
1875 * the ability to preload the CGM LUTs/CSC without tearing.
1876 */
1877 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1878 return false;
1879
1880 return vlv_can_preload_luts(new_crtc_state);
1881 }
1882
intel_color_check(struct intel_crtc_state * crtc_state)1883 int intel_color_check(struct intel_crtc_state *crtc_state)
1884 {
1885 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1886
1887 return i915->display.funcs.color->color_check(crtc_state);
1888 }
1889
intel_color_get_config(struct intel_crtc_state * crtc_state)1890 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1891 {
1892 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1893
1894 i915->display.funcs.color->read_luts(crtc_state);
1895
1896 if (i915->display.funcs.color->read_csc)
1897 i915->display.funcs.color->read_csc(crtc_state);
1898 }
1899
intel_color_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)1900 bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state,
1901 const struct drm_property_blob *blob1,
1902 const struct drm_property_blob *blob2,
1903 bool is_pre_csc_lut)
1904 {
1905 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1906
1907 /*
1908 * FIXME c8_planes readout missing thus
1909 * .read_luts() doesn't read out post_csc_lut.
1910 */
1911 if (!is_pre_csc_lut && crtc_state->c8_planes)
1912 return true;
1913
1914 return i915->display.funcs.color->lut_equal(crtc_state, blob1, blob2,
1915 is_pre_csc_lut);
1916 }
1917
need_plane_update(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)1918 static bool need_plane_update(struct intel_plane *plane,
1919 const struct intel_crtc_state *crtc_state)
1920 {
1921 struct drm_i915_private *i915 = to_i915(plane->base.dev);
1922
1923 /*
1924 * On pre-SKL the pipe gamma enable and pipe csc enable for
1925 * the pipe bottom color are configured via the primary plane.
1926 * We have to reconfigure that even if the plane is inactive.
1927 */
1928 return crtc_state->active_planes & BIT(plane->id) ||
1929 (DISPLAY_VER(i915) < 9 &&
1930 plane->id == PLANE_PRIMARY);
1931 }
1932
1933 static int
intel_color_add_affected_planes(struct intel_crtc_state * new_crtc_state)1934 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1935 {
1936 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1937 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1938 struct intel_atomic_state *state =
1939 to_intel_atomic_state(new_crtc_state->uapi.state);
1940 const struct intel_crtc_state *old_crtc_state =
1941 intel_atomic_get_old_crtc_state(state, crtc);
1942 struct intel_plane *plane;
1943
1944 if (!new_crtc_state->hw.active ||
1945 intel_crtc_needs_modeset(new_crtc_state))
1946 return 0;
1947
1948 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1949 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1950 return 0;
1951
1952 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
1953 struct intel_plane_state *plane_state;
1954
1955 if (!need_plane_update(plane, new_crtc_state))
1956 continue;
1957
1958 plane_state = intel_atomic_get_plane_state(state, plane);
1959 if (IS_ERR(plane_state))
1960 return PTR_ERR(plane_state);
1961
1962 new_crtc_state->update_planes |= BIT(plane->id);
1963 new_crtc_state->async_flip_planes = 0;
1964 new_crtc_state->do_async_flip = false;
1965
1966 /* plane control register changes blocked by CxSR */
1967 if (HAS_GMCH(i915))
1968 new_crtc_state->disable_cxsr = true;
1969 }
1970
1971 return 0;
1972 }
1973
intel_gamma_lut_tests(const struct intel_crtc_state * crtc_state)1974 static u32 intel_gamma_lut_tests(const struct intel_crtc_state *crtc_state)
1975 {
1976 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1977 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1978
1979 if (lut_is_legacy(gamma_lut))
1980 return 0;
1981
1982 return DISPLAY_INFO(i915)->color.gamma_lut_tests;
1983 }
1984
intel_degamma_lut_tests(const struct intel_crtc_state * crtc_state)1985 static u32 intel_degamma_lut_tests(const struct intel_crtc_state *crtc_state)
1986 {
1987 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1988
1989 return DISPLAY_INFO(i915)->color.degamma_lut_tests;
1990 }
1991
intel_gamma_lut_size(const struct intel_crtc_state * crtc_state)1992 static int intel_gamma_lut_size(const struct intel_crtc_state *crtc_state)
1993 {
1994 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1995 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1996
1997 if (lut_is_legacy(gamma_lut))
1998 return LEGACY_LUT_LENGTH;
1999
2000 return DISPLAY_INFO(i915)->color.gamma_lut_size;
2001 }
2002
intel_degamma_lut_size(const struct intel_crtc_state * crtc_state)2003 static u32 intel_degamma_lut_size(const struct intel_crtc_state *crtc_state)
2004 {
2005 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2006
2007 return DISPLAY_INFO(i915)->color.degamma_lut_size;
2008 }
2009
check_lut_size(const struct drm_property_blob * lut,int expected)2010 static int check_lut_size(const struct drm_property_blob *lut, int expected)
2011 {
2012 int len;
2013
2014 if (!lut)
2015 return 0;
2016
2017 len = drm_color_lut_size(lut);
2018 if (len != expected) {
2019 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
2020 len, expected);
2021 return -EINVAL;
2022 }
2023
2024 return 0;
2025 }
2026
_check_luts(const struct intel_crtc_state * crtc_state,u32 degamma_tests,u32 gamma_tests)2027 static int _check_luts(const struct intel_crtc_state *crtc_state,
2028 u32 degamma_tests, u32 gamma_tests)
2029 {
2030 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2031 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
2032 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
2033 int gamma_length, degamma_length;
2034
2035 /* C8 relies on its palette being stored in the legacy LUT */
2036 if (crtc_state->c8_planes && !lut_is_legacy(crtc_state->hw.gamma_lut)) {
2037 drm_dbg_kms(&i915->drm,
2038 "C8 pixelformat requires the legacy LUT\n");
2039 return -EINVAL;
2040 }
2041
2042 degamma_length = intel_degamma_lut_size(crtc_state);
2043 gamma_length = intel_gamma_lut_size(crtc_state);
2044
2045 if (check_lut_size(degamma_lut, degamma_length) ||
2046 check_lut_size(gamma_lut, gamma_length))
2047 return -EINVAL;
2048
2049 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
2050 drm_color_lut_check(gamma_lut, gamma_tests))
2051 return -EINVAL;
2052
2053 return 0;
2054 }
2055
check_luts(const struct intel_crtc_state * crtc_state)2056 static int check_luts(const struct intel_crtc_state *crtc_state)
2057 {
2058 return _check_luts(crtc_state,
2059 intel_degamma_lut_tests(crtc_state),
2060 intel_gamma_lut_tests(crtc_state));
2061 }
2062
i9xx_gamma_mode(struct intel_crtc_state * crtc_state)2063 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
2064 {
2065 if (!crtc_state->gamma_enable ||
2066 lut_is_legacy(crtc_state->hw.gamma_lut))
2067 return GAMMA_MODE_MODE_8BIT;
2068 else
2069 return GAMMA_MODE_MODE_10BIT;
2070 }
2071
i9xx_lut_10_diff(u16 a,u16 b)2072 static int i9xx_lut_10_diff(u16 a, u16 b)
2073 {
2074 return drm_color_lut_extract(a, 10) -
2075 drm_color_lut_extract(b, 10);
2076 }
2077
i9xx_check_lut_10(struct drm_i915_private * dev_priv,const struct drm_property_blob * blob)2078 static int i9xx_check_lut_10(struct drm_i915_private *dev_priv,
2079 const struct drm_property_blob *blob)
2080 {
2081 const struct drm_color_lut *lut = blob->data;
2082 int lut_size = drm_color_lut_size(blob);
2083 const struct drm_color_lut *a = &lut[lut_size - 2];
2084 const struct drm_color_lut *b = &lut[lut_size - 1];
2085
2086 if (i9xx_lut_10_diff(b->red, a->red) > 0x7f ||
2087 i9xx_lut_10_diff(b->green, a->green) > 0x7f ||
2088 i9xx_lut_10_diff(b->blue, a->blue) > 0x7f) {
2089 drm_dbg_kms(&dev_priv->drm, "Last gamma LUT entry exceeds max slope\n");
2090 return -EINVAL;
2091 }
2092
2093 return 0;
2094 }
2095
intel_color_assert_luts(const struct intel_crtc_state * crtc_state)2096 void intel_color_assert_luts(const struct intel_crtc_state *crtc_state)
2097 {
2098 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2099
2100 /* make sure {pre,post}_csc_lut were correctly assigned */
2101 if (DISPLAY_VER(i915) >= 11 || HAS_GMCH(i915)) {
2102 drm_WARN_ON(&i915->drm,
2103 crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut);
2104 drm_WARN_ON(&i915->drm,
2105 crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2106 } else if (DISPLAY_VER(i915) == 10) {
2107 drm_WARN_ON(&i915->drm,
2108 crtc_state->post_csc_lut == crtc_state->hw.gamma_lut &&
2109 crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2110 crtc_state->pre_csc_lut != i915->display.color.glk_linear_degamma_lut);
2111 drm_WARN_ON(&i915->drm,
2112 !ilk_lut_limited_range(crtc_state) &&
2113 crtc_state->post_csc_lut != NULL &&
2114 crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2115 } else if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT) {
2116 drm_WARN_ON(&i915->drm,
2117 crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2118 crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut);
2119 drm_WARN_ON(&i915->drm,
2120 !ilk_lut_limited_range(crtc_state) &&
2121 crtc_state->post_csc_lut != crtc_state->hw.degamma_lut &&
2122 crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2123 }
2124 }
2125
intel_assign_luts(struct intel_crtc_state * crtc_state)2126 static void intel_assign_luts(struct intel_crtc_state *crtc_state)
2127 {
2128 drm_property_replace_blob(&crtc_state->pre_csc_lut,
2129 crtc_state->hw.degamma_lut);
2130 drm_property_replace_blob(&crtc_state->post_csc_lut,
2131 crtc_state->hw.gamma_lut);
2132 }
2133
i9xx_color_check(struct intel_crtc_state * crtc_state)2134 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
2135 {
2136 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2137 int ret;
2138
2139 ret = check_luts(crtc_state);
2140 if (ret)
2141 return ret;
2142
2143 crtc_state->gamma_enable =
2144 crtc_state->hw.gamma_lut &&
2145 !crtc_state->c8_planes;
2146
2147 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2148
2149 if (DISPLAY_VER(i915) < 4 &&
2150 crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT) {
2151 ret = i9xx_check_lut_10(i915, crtc_state->hw.gamma_lut);
2152 if (ret)
2153 return ret;
2154 }
2155
2156 ret = intel_color_add_affected_planes(crtc_state);
2157 if (ret)
2158 return ret;
2159
2160 intel_assign_luts(crtc_state);
2161
2162 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2163
2164 return 0;
2165 }
2166
2167 /*
2168 * VLV color pipeline:
2169 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2170 */
vlv_color_check(struct intel_crtc_state * crtc_state)2171 static int vlv_color_check(struct intel_crtc_state *crtc_state)
2172 {
2173 int ret;
2174
2175 ret = check_luts(crtc_state);
2176 if (ret)
2177 return ret;
2178
2179 crtc_state->gamma_enable =
2180 crtc_state->hw.gamma_lut &&
2181 !crtc_state->c8_planes;
2182
2183 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2184
2185 crtc_state->wgc_enable = crtc_state->hw.ctm;
2186
2187 ret = intel_color_add_affected_planes(crtc_state);
2188 if (ret)
2189 return ret;
2190
2191 intel_assign_luts(crtc_state);
2192
2193 vlv_assign_csc(crtc_state);
2194
2195 crtc_state->preload_luts = vlv_can_preload_luts(crtc_state);
2196
2197 return 0;
2198 }
2199
chv_cgm_mode(const struct intel_crtc_state * crtc_state)2200 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
2201 {
2202 u32 cgm_mode = 0;
2203
2204 if (crtc_state->hw.degamma_lut)
2205 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
2206 if (crtc_state->hw.ctm)
2207 cgm_mode |= CGM_PIPE_MODE_CSC;
2208 if (crtc_state->hw.gamma_lut &&
2209 !lut_is_legacy(crtc_state->hw.gamma_lut))
2210 cgm_mode |= CGM_PIPE_MODE_GAMMA;
2211
2212 /*
2213 * Toggling the CGM CSC on/off outside of the tiny window
2214 * between start of vblank and frame start causes underruns.
2215 * Always enable the CGM CSC as a workaround.
2216 */
2217 cgm_mode |= CGM_PIPE_MODE_CSC;
2218
2219 return cgm_mode;
2220 }
2221
2222 /*
2223 * CHV color pipeline:
2224 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
2225 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2226 *
2227 * We always bypass the WGC csc and use the CGM csc
2228 * instead since it has degamma and better precision.
2229 */
chv_color_check(struct intel_crtc_state * crtc_state)2230 static int chv_color_check(struct intel_crtc_state *crtc_state)
2231 {
2232 int ret;
2233
2234 ret = check_luts(crtc_state);
2235 if (ret)
2236 return ret;
2237
2238 /*
2239 * Pipe gamma will be used only for the legacy LUT.
2240 * Otherwise we bypass it and use the CGM gamma instead.
2241 */
2242 crtc_state->gamma_enable =
2243 lut_is_legacy(crtc_state->hw.gamma_lut) &&
2244 !crtc_state->c8_planes;
2245
2246 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
2247
2248 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
2249
2250 /*
2251 * We always bypass the WGC CSC and use the CGM CSC
2252 * instead since it has degamma and better precision.
2253 */
2254 crtc_state->wgc_enable = false;
2255
2256 ret = intel_color_add_affected_planes(crtc_state);
2257 if (ret)
2258 return ret;
2259
2260 intel_assign_luts(crtc_state);
2261
2262 chv_assign_csc(crtc_state);
2263
2264 crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
2265
2266 return 0;
2267 }
2268
ilk_gamma_enable(const struct intel_crtc_state * crtc_state)2269 static bool ilk_gamma_enable(const struct intel_crtc_state *crtc_state)
2270 {
2271 return (crtc_state->hw.gamma_lut ||
2272 crtc_state->hw.degamma_lut) &&
2273 !crtc_state->c8_planes;
2274 }
2275
ilk_csc_enable(const struct intel_crtc_state * crtc_state)2276 static bool ilk_csc_enable(const struct intel_crtc_state *crtc_state)
2277 {
2278 return crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2279 ilk_csc_limited_range(crtc_state) ||
2280 crtc_state->hw.ctm;
2281 }
2282
ilk_gamma_mode(const struct intel_crtc_state * crtc_state)2283 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
2284 {
2285 if (!crtc_state->gamma_enable ||
2286 lut_is_legacy(crtc_state->hw.gamma_lut))
2287 return GAMMA_MODE_MODE_8BIT;
2288 else
2289 return GAMMA_MODE_MODE_10BIT;
2290 }
2291
ilk_csc_mode(const struct intel_crtc_state * crtc_state)2292 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
2293 {
2294 /*
2295 * CSC comes after the LUT in RGB->YCbCr mode.
2296 * RGB->YCbCr needs the limited range offsets added to
2297 * the output. RGB limited range output is handled by
2298 * the hw automagically elsewhere.
2299 */
2300 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
2301 return CSC_BLACK_SCREEN_OFFSET;
2302
2303 if (crtc_state->hw.degamma_lut)
2304 return CSC_MODE_YUV_TO_RGB;
2305
2306 return CSC_MODE_YUV_TO_RGB |
2307 CSC_POSITION_BEFORE_GAMMA;
2308 }
2309
ilk_assign_luts(struct intel_crtc_state * crtc_state)2310 static int ilk_assign_luts(struct intel_crtc_state *crtc_state)
2311 {
2312 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2313
2314 if (ilk_lut_limited_range(crtc_state)) {
2315 struct drm_property_blob *gamma_lut;
2316
2317 gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2318 drm_color_lut_size(crtc_state->hw.gamma_lut),
2319 true);
2320 if (IS_ERR(gamma_lut))
2321 return PTR_ERR(gamma_lut);
2322
2323 drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2324
2325 drm_property_blob_put(gamma_lut);
2326
2327 drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2328
2329 return 0;
2330 }
2331
2332 if (crtc_state->hw.degamma_lut ||
2333 crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
2334 drm_property_replace_blob(&crtc_state->pre_csc_lut,
2335 crtc_state->hw.degamma_lut);
2336 drm_property_replace_blob(&crtc_state->post_csc_lut,
2337 crtc_state->hw.gamma_lut);
2338 } else {
2339 drm_property_replace_blob(&crtc_state->pre_csc_lut,
2340 crtc_state->hw.gamma_lut);
2341 drm_property_replace_blob(&crtc_state->post_csc_lut,
2342 NULL);
2343 }
2344
2345 return 0;
2346 }
2347
ilk_color_check(struct intel_crtc_state * crtc_state)2348 static int ilk_color_check(struct intel_crtc_state *crtc_state)
2349 {
2350 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2351 int ret;
2352
2353 ret = check_luts(crtc_state);
2354 if (ret)
2355 return ret;
2356
2357 if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2358 drm_dbg_kms(&i915->drm,
2359 "Degamma and gamma together are not possible\n");
2360 return -EINVAL;
2361 }
2362
2363 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2364 crtc_state->hw.ctm) {
2365 drm_dbg_kms(&i915->drm,
2366 "YCbCr and CTM together are not possible\n");
2367 return -EINVAL;
2368 }
2369
2370 crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2371
2372 crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2373
2374 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
2375
2376 crtc_state->csc_mode = ilk_csc_mode(crtc_state);
2377
2378 ret = intel_color_add_affected_planes(crtc_state);
2379 if (ret)
2380 return ret;
2381
2382 ret = ilk_assign_luts(crtc_state);
2383 if (ret)
2384 return ret;
2385
2386 ilk_assign_csc(crtc_state);
2387
2388 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2389
2390 return 0;
2391 }
2392
ivb_gamma_mode(const struct intel_crtc_state * crtc_state)2393 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
2394 {
2395 if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut)
2396 return GAMMA_MODE_MODE_SPLIT;
2397
2398 return ilk_gamma_mode(crtc_state);
2399 }
2400
ivb_csc_mode(const struct intel_crtc_state * crtc_state)2401 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
2402 {
2403 bool limited_color_range = ilk_csc_limited_range(crtc_state);
2404
2405 /*
2406 * CSC comes after the LUT in degamma, RGB->YCbCr,
2407 * and RGB full->limited range mode.
2408 */
2409 if (crtc_state->hw.degamma_lut ||
2410 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2411 limited_color_range)
2412 return 0;
2413
2414 return CSC_POSITION_BEFORE_GAMMA;
2415 }
2416
ivb_assign_luts(struct intel_crtc_state * crtc_state)2417 static int ivb_assign_luts(struct intel_crtc_state *crtc_state)
2418 {
2419 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2420 struct drm_property_blob *degamma_lut, *gamma_lut;
2421
2422 if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT)
2423 return ilk_assign_luts(crtc_state);
2424
2425 drm_WARN_ON(&i915->drm, drm_color_lut_size(crtc_state->hw.degamma_lut) != 1024);
2426 drm_WARN_ON(&i915->drm, drm_color_lut_size(crtc_state->hw.gamma_lut) != 1024);
2427
2428 degamma_lut = create_resized_lut(i915, crtc_state->hw.degamma_lut, 512,
2429 false);
2430 if (IS_ERR(degamma_lut))
2431 return PTR_ERR(degamma_lut);
2432
2433 gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut, 512,
2434 ilk_lut_limited_range(crtc_state));
2435 if (IS_ERR(gamma_lut)) {
2436 drm_property_blob_put(degamma_lut);
2437 return PTR_ERR(gamma_lut);
2438 }
2439
2440 drm_property_replace_blob(&crtc_state->pre_csc_lut, degamma_lut);
2441 drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2442
2443 drm_property_blob_put(degamma_lut);
2444 drm_property_blob_put(gamma_lut);
2445
2446 return 0;
2447 }
2448
ivb_color_check(struct intel_crtc_state * crtc_state)2449 static int ivb_color_check(struct intel_crtc_state *crtc_state)
2450 {
2451 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2452 int ret;
2453
2454 ret = check_luts(crtc_state);
2455 if (ret)
2456 return ret;
2457
2458 if (crtc_state->c8_planes && crtc_state->hw.degamma_lut) {
2459 drm_dbg_kms(&i915->drm,
2460 "C8 pixelformat and degamma together are not possible\n");
2461 return -EINVAL;
2462 }
2463
2464 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2465 crtc_state->hw.ctm) {
2466 drm_dbg_kms(&i915->drm,
2467 "YCbCr and CTM together are not possible\n");
2468 return -EINVAL;
2469 }
2470
2471 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2472 crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2473 drm_dbg_kms(&i915->drm,
2474 "YCbCr and degamma+gamma together are not possible\n");
2475 return -EINVAL;
2476 }
2477
2478 crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2479
2480 crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2481
2482 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
2483
2484 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
2485
2486 ret = intel_color_add_affected_planes(crtc_state);
2487 if (ret)
2488 return ret;
2489
2490 ret = ivb_assign_luts(crtc_state);
2491 if (ret)
2492 return ret;
2493
2494 ilk_assign_csc(crtc_state);
2495
2496 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2497
2498 return 0;
2499 }
2500
glk_gamma_mode(const struct intel_crtc_state * crtc_state)2501 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
2502 {
2503 if (!crtc_state->gamma_enable ||
2504 lut_is_legacy(crtc_state->hw.gamma_lut))
2505 return GAMMA_MODE_MODE_8BIT;
2506 else
2507 return GAMMA_MODE_MODE_10BIT;
2508 }
2509
glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state * crtc_state)2510 static bool glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state *crtc_state)
2511 {
2512 return crtc_state->hw.gamma_lut &&
2513 !crtc_state->c8_planes &&
2514 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
2515 }
2516
glk_assign_luts(struct intel_crtc_state * crtc_state)2517 static int glk_assign_luts(struct intel_crtc_state *crtc_state)
2518 {
2519 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2520
2521 if (glk_use_pre_csc_lut_for_gamma(crtc_state)) {
2522 struct drm_property_blob *gamma_lut;
2523
2524 gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2525 DISPLAY_INFO(i915)->color.degamma_lut_size,
2526 false);
2527 if (IS_ERR(gamma_lut))
2528 return PTR_ERR(gamma_lut);
2529
2530 drm_property_replace_blob(&crtc_state->pre_csc_lut, gamma_lut);
2531 drm_property_replace_blob(&crtc_state->post_csc_lut, NULL);
2532
2533 drm_property_blob_put(gamma_lut);
2534
2535 return 0;
2536 }
2537
2538 if (ilk_lut_limited_range(crtc_state)) {
2539 struct drm_property_blob *gamma_lut;
2540
2541 gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2542 drm_color_lut_size(crtc_state->hw.gamma_lut),
2543 true);
2544 if (IS_ERR(gamma_lut))
2545 return PTR_ERR(gamma_lut);
2546
2547 drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2548
2549 drm_property_blob_put(gamma_lut);
2550 } else {
2551 drm_property_replace_blob(&crtc_state->post_csc_lut, crtc_state->hw.gamma_lut);
2552 }
2553
2554 drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2555
2556 /*
2557 * On GLK+ both pipe CSC and degamma LUT are controlled
2558 * by csc_enable. Hence for the cases where the CSC is
2559 * needed but degamma LUT is not we need to load a
2560 * linear degamma LUT.
2561 */
2562 if (crtc_state->csc_enable && !crtc_state->pre_csc_lut)
2563 drm_property_replace_blob(&crtc_state->pre_csc_lut,
2564 i915->display.color.glk_linear_degamma_lut);
2565
2566 return 0;
2567 }
2568
glk_check_luts(const struct intel_crtc_state * crtc_state)2569 static int glk_check_luts(const struct intel_crtc_state *crtc_state)
2570 {
2571 u32 degamma_tests = intel_degamma_lut_tests(crtc_state);
2572 u32 gamma_tests = intel_gamma_lut_tests(crtc_state);
2573
2574 if (glk_use_pre_csc_lut_for_gamma(crtc_state))
2575 gamma_tests |= degamma_tests;
2576
2577 return _check_luts(crtc_state, degamma_tests, gamma_tests);
2578 }
2579
glk_color_check(struct intel_crtc_state * crtc_state)2580 static int glk_color_check(struct intel_crtc_state *crtc_state)
2581 {
2582 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2583 int ret;
2584
2585 ret = glk_check_luts(crtc_state);
2586 if (ret)
2587 return ret;
2588
2589 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2590 crtc_state->hw.ctm) {
2591 drm_dbg_kms(&i915->drm,
2592 "YCbCr and CTM together are not possible\n");
2593 return -EINVAL;
2594 }
2595
2596 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2597 crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2598 drm_dbg_kms(&i915->drm,
2599 "YCbCr and degamma+gamma together are not possible\n");
2600 return -EINVAL;
2601 }
2602
2603 crtc_state->gamma_enable =
2604 !glk_use_pre_csc_lut_for_gamma(crtc_state) &&
2605 crtc_state->hw.gamma_lut &&
2606 !crtc_state->c8_planes;
2607
2608 /* On GLK+ degamma LUT is controlled by csc_enable */
2609 crtc_state->csc_enable =
2610 glk_use_pre_csc_lut_for_gamma(crtc_state) ||
2611 crtc_state->hw.degamma_lut ||
2612 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2613 crtc_state->hw.ctm || ilk_csc_limited_range(crtc_state);
2614
2615 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
2616
2617 crtc_state->csc_mode = 0;
2618
2619 ret = intel_color_add_affected_planes(crtc_state);
2620 if (ret)
2621 return ret;
2622
2623 ret = glk_assign_luts(crtc_state);
2624 if (ret)
2625 return ret;
2626
2627 ilk_assign_csc(crtc_state);
2628
2629 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2630
2631 return 0;
2632 }
2633
icl_gamma_mode(const struct intel_crtc_state * crtc_state)2634 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
2635 {
2636 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2637 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2638 u32 gamma_mode = 0;
2639
2640 if (crtc_state->hw.degamma_lut)
2641 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
2642
2643 if (crtc_state->hw.gamma_lut &&
2644 !crtc_state->c8_planes)
2645 gamma_mode |= POST_CSC_GAMMA_ENABLE;
2646
2647 if (!crtc_state->hw.gamma_lut ||
2648 lut_is_legacy(crtc_state->hw.gamma_lut))
2649 gamma_mode |= GAMMA_MODE_MODE_8BIT;
2650 /*
2651 * Enable 10bit gamma for D13
2652 * ToDo: Extend to Logarithmic Gamma once the new UAPI
2653 * is accepted and implemented by a userspace consumer
2654 */
2655 else if (DISPLAY_VER(i915) >= 13)
2656 gamma_mode |= GAMMA_MODE_MODE_10BIT;
2657 else
2658 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEG;
2659
2660 return gamma_mode;
2661 }
2662
icl_csc_mode(const struct intel_crtc_state * crtc_state)2663 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
2664 {
2665 u32 csc_mode = 0;
2666
2667 if (crtc_state->hw.ctm)
2668 csc_mode |= ICL_CSC_ENABLE;
2669
2670 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2671 crtc_state->limited_color_range)
2672 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
2673
2674 return csc_mode;
2675 }
2676
icl_color_check(struct intel_crtc_state * crtc_state)2677 static int icl_color_check(struct intel_crtc_state *crtc_state)
2678 {
2679 int ret;
2680
2681 ret = check_luts(crtc_state);
2682 if (ret)
2683 return ret;
2684
2685 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
2686
2687 crtc_state->csc_mode = icl_csc_mode(crtc_state);
2688
2689 intel_assign_luts(crtc_state);
2690
2691 icl_assign_csc(crtc_state);
2692
2693 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2694
2695 return 0;
2696 }
2697
i9xx_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2698 static int i9xx_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2699 {
2700 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2701 return 0;
2702
2703 switch (crtc_state->gamma_mode) {
2704 case GAMMA_MODE_MODE_8BIT:
2705 return 8;
2706 case GAMMA_MODE_MODE_10BIT:
2707 return 10;
2708 default:
2709 MISSING_CASE(crtc_state->gamma_mode);
2710 return 0;
2711 }
2712 }
2713
i9xx_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2714 static int i9xx_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2715 {
2716 return 0;
2717 }
2718
i965_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2719 static int i965_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2720 {
2721 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2722 return 0;
2723
2724 switch (crtc_state->gamma_mode) {
2725 case GAMMA_MODE_MODE_8BIT:
2726 return 8;
2727 case GAMMA_MODE_MODE_10BIT:
2728 return 16;
2729 default:
2730 MISSING_CASE(crtc_state->gamma_mode);
2731 return 0;
2732 }
2733 }
2734
ilk_gamma_mode_precision(u32 gamma_mode)2735 static int ilk_gamma_mode_precision(u32 gamma_mode)
2736 {
2737 switch (gamma_mode) {
2738 case GAMMA_MODE_MODE_8BIT:
2739 return 8;
2740 case GAMMA_MODE_MODE_10BIT:
2741 return 10;
2742 default:
2743 MISSING_CASE(gamma_mode);
2744 return 0;
2745 }
2746 }
2747
ilk_has_post_csc_lut(const struct intel_crtc_state * crtc_state)2748 static bool ilk_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2749 {
2750 if (crtc_state->c8_planes)
2751 return true;
2752
2753 return crtc_state->gamma_enable &&
2754 (crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) != 0;
2755 }
2756
ilk_has_pre_csc_lut(const struct intel_crtc_state * crtc_state)2757 static bool ilk_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2758 {
2759 return crtc_state->gamma_enable &&
2760 (crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0;
2761 }
2762
ilk_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2763 static int ilk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2764 {
2765 if (!ilk_has_post_csc_lut(crtc_state))
2766 return 0;
2767
2768 return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2769 }
2770
ilk_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2771 static int ilk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2772 {
2773 if (!ilk_has_pre_csc_lut(crtc_state))
2774 return 0;
2775
2776 return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2777 }
2778
ivb_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2779 static int ivb_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2780 {
2781 if (crtc_state->gamma_enable &&
2782 crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
2783 return 10;
2784
2785 return ilk_post_csc_lut_precision(crtc_state);
2786 }
2787
ivb_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2788 static int ivb_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2789 {
2790 if (crtc_state->gamma_enable &&
2791 crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
2792 return 10;
2793
2794 return ilk_pre_csc_lut_precision(crtc_state);
2795 }
2796
chv_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2797 static int chv_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2798 {
2799 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
2800 return 10;
2801
2802 return i965_post_csc_lut_precision(crtc_state);
2803 }
2804
chv_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2805 static int chv_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2806 {
2807 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
2808 return 14;
2809
2810 return 0;
2811 }
2812
glk_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2813 static int glk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2814 {
2815 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2816 return 0;
2817
2818 return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2819 }
2820
glk_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2821 static int glk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2822 {
2823 if (!crtc_state->csc_enable)
2824 return 0;
2825
2826 return 16;
2827 }
2828
icl_has_post_csc_lut(const struct intel_crtc_state * crtc_state)2829 static bool icl_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2830 {
2831 if (crtc_state->c8_planes)
2832 return true;
2833
2834 return crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE;
2835 }
2836
icl_has_pre_csc_lut(const struct intel_crtc_state * crtc_state)2837 static bool icl_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2838 {
2839 return crtc_state->gamma_mode & PRE_CSC_GAMMA_ENABLE;
2840 }
2841
icl_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2842 static int icl_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2843 {
2844 if (!icl_has_post_csc_lut(crtc_state))
2845 return 0;
2846
2847 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
2848 case GAMMA_MODE_MODE_8BIT:
2849 return 8;
2850 case GAMMA_MODE_MODE_10BIT:
2851 return 10;
2852 case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
2853 return 16;
2854 default:
2855 MISSING_CASE(crtc_state->gamma_mode);
2856 return 0;
2857 }
2858 }
2859
icl_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2860 static int icl_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2861 {
2862 if (!icl_has_pre_csc_lut(crtc_state))
2863 return 0;
2864
2865 return 16;
2866 }
2867
err_check(struct drm_color_lut * lut1,struct drm_color_lut * lut2,u32 err)2868 static bool err_check(struct drm_color_lut *lut1,
2869 struct drm_color_lut *lut2, u32 err)
2870 {
2871 return ((abs((long)lut2->red - lut1->red)) <= err) &&
2872 ((abs((long)lut2->blue - lut1->blue)) <= err) &&
2873 ((abs((long)lut2->green - lut1->green)) <= err);
2874 }
2875
intel_lut_entries_equal(struct drm_color_lut * lut1,struct drm_color_lut * lut2,int lut_size,u32 err)2876 static bool intel_lut_entries_equal(struct drm_color_lut *lut1,
2877 struct drm_color_lut *lut2,
2878 int lut_size, u32 err)
2879 {
2880 int i;
2881
2882 for (i = 0; i < lut_size; i++) {
2883 if (!err_check(&lut1[i], &lut2[i], err))
2884 return false;
2885 }
2886
2887 return true;
2888 }
2889
intel_lut_equal(const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,int check_size,int precision)2890 static bool intel_lut_equal(const struct drm_property_blob *blob1,
2891 const struct drm_property_blob *blob2,
2892 int check_size, int precision)
2893 {
2894 struct drm_color_lut *lut1, *lut2;
2895 int lut_size1, lut_size2;
2896 u32 err;
2897
2898 if (!blob1 != !blob2)
2899 return false;
2900
2901 if (!blob1 != !precision)
2902 return false;
2903
2904 if (!blob1)
2905 return true;
2906
2907 lut_size1 = drm_color_lut_size(blob1);
2908 lut_size2 = drm_color_lut_size(blob2);
2909
2910 if (lut_size1 != lut_size2)
2911 return false;
2912
2913 if (check_size > lut_size1)
2914 return false;
2915
2916 lut1 = blob1->data;
2917 lut2 = blob2->data;
2918
2919 err = 0xffff >> precision;
2920
2921 if (!check_size)
2922 check_size = lut_size1;
2923
2924 return intel_lut_entries_equal(lut1, lut2, check_size, err);
2925 }
2926
i9xx_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)2927 static bool i9xx_lut_equal(const struct intel_crtc_state *crtc_state,
2928 const struct drm_property_blob *blob1,
2929 const struct drm_property_blob *blob2,
2930 bool is_pre_csc_lut)
2931 {
2932 int check_size = 0;
2933
2934 if (is_pre_csc_lut)
2935 return intel_lut_equal(blob1, blob2, 0,
2936 i9xx_pre_csc_lut_precision(crtc_state));
2937
2938 /* 10bit mode last entry is implicit, just skip it */
2939 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT)
2940 check_size = 128;
2941
2942 return intel_lut_equal(blob1, blob2, check_size,
2943 i9xx_post_csc_lut_precision(crtc_state));
2944 }
2945
i965_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)2946 static bool i965_lut_equal(const struct intel_crtc_state *crtc_state,
2947 const struct drm_property_blob *blob1,
2948 const struct drm_property_blob *blob2,
2949 bool is_pre_csc_lut)
2950 {
2951 if (is_pre_csc_lut)
2952 return intel_lut_equal(blob1, blob2, 0,
2953 i9xx_pre_csc_lut_precision(crtc_state));
2954 else
2955 return intel_lut_equal(blob1, blob2, 0,
2956 i965_post_csc_lut_precision(crtc_state));
2957 }
2958
chv_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)2959 static bool chv_lut_equal(const struct intel_crtc_state *crtc_state,
2960 const struct drm_property_blob *blob1,
2961 const struct drm_property_blob *blob2,
2962 bool is_pre_csc_lut)
2963 {
2964 if (is_pre_csc_lut)
2965 return intel_lut_equal(blob1, blob2, 0,
2966 chv_pre_csc_lut_precision(crtc_state));
2967 else
2968 return intel_lut_equal(blob1, blob2, 0,
2969 chv_post_csc_lut_precision(crtc_state));
2970 }
2971
ilk_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)2972 static bool ilk_lut_equal(const struct intel_crtc_state *crtc_state,
2973 const struct drm_property_blob *blob1,
2974 const struct drm_property_blob *blob2,
2975 bool is_pre_csc_lut)
2976 {
2977 if (is_pre_csc_lut)
2978 return intel_lut_equal(blob1, blob2, 0,
2979 ilk_pre_csc_lut_precision(crtc_state));
2980 else
2981 return intel_lut_equal(blob1, blob2, 0,
2982 ilk_post_csc_lut_precision(crtc_state));
2983 }
2984
ivb_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)2985 static bool ivb_lut_equal(const struct intel_crtc_state *crtc_state,
2986 const struct drm_property_blob *blob1,
2987 const struct drm_property_blob *blob2,
2988 bool is_pre_csc_lut)
2989 {
2990 if (is_pre_csc_lut)
2991 return intel_lut_equal(blob1, blob2, 0,
2992 ivb_pre_csc_lut_precision(crtc_state));
2993 else
2994 return intel_lut_equal(blob1, blob2, 0,
2995 ivb_post_csc_lut_precision(crtc_state));
2996 }
2997
glk_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)2998 static bool glk_lut_equal(const struct intel_crtc_state *crtc_state,
2999 const struct drm_property_blob *blob1,
3000 const struct drm_property_blob *blob2,
3001 bool is_pre_csc_lut)
3002 {
3003 if (is_pre_csc_lut)
3004 return intel_lut_equal(blob1, blob2, 0,
3005 glk_pre_csc_lut_precision(crtc_state));
3006 else
3007 return intel_lut_equal(blob1, blob2, 0,
3008 glk_post_csc_lut_precision(crtc_state));
3009 }
3010
icl_lut_equal(const struct intel_crtc_state * crtc_state,const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,bool is_pre_csc_lut)3011 static bool icl_lut_equal(const struct intel_crtc_state *crtc_state,
3012 const struct drm_property_blob *blob1,
3013 const struct drm_property_blob *blob2,
3014 bool is_pre_csc_lut)
3015 {
3016 int check_size = 0;
3017
3018 if (is_pre_csc_lut)
3019 return intel_lut_equal(blob1, blob2, 0,
3020 icl_pre_csc_lut_precision(crtc_state));
3021
3022 /* hw readout broken except for the super fine segment :( */
3023 if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) ==
3024 GAMMA_MODE_MODE_12BIT_MULTI_SEG)
3025 check_size = 9;
3026
3027 return intel_lut_equal(blob1, blob2, check_size,
3028 icl_post_csc_lut_precision(crtc_state));
3029 }
3030
i9xx_read_lut_8(struct intel_crtc * crtc)3031 static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)
3032 {
3033 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3034 enum pipe pipe = crtc->pipe;
3035 struct drm_property_blob *blob;
3036 struct drm_color_lut *lut;
3037 int i;
3038
3039 blob = drm_property_create_blob(&dev_priv->drm,
3040 sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3041 NULL);
3042 if (IS_ERR(blob))
3043 return NULL;
3044
3045 lut = blob->data;
3046
3047 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3048 u32 val = intel_de_read_fw(dev_priv, PALETTE(pipe, i));
3049
3050 i9xx_lut_8_pack(&lut[i], val);
3051 }
3052
3053 return blob;
3054 }
3055
i9xx_read_lut_10(struct intel_crtc * crtc)3056 static struct drm_property_blob *i9xx_read_lut_10(struct intel_crtc *crtc)
3057 {
3058 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3059 u32 lut_size = DISPLAY_INFO(dev_priv)->color.gamma_lut_size;
3060 enum pipe pipe = crtc->pipe;
3061 struct drm_property_blob *blob;
3062 struct drm_color_lut *lut;
3063 u32 ldw, udw;
3064 int i;
3065
3066 blob = drm_property_create_blob(&dev_priv->drm,
3067 lut_size * sizeof(lut[0]), NULL);
3068 if (IS_ERR(blob))
3069 return NULL;
3070
3071 lut = blob->data;
3072
3073 for (i = 0; i < lut_size - 1; i++) {
3074 ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
3075 udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
3076
3077 i9xx_lut_10_pack(&lut[i], ldw, udw);
3078 }
3079
3080 i9xx_lut_10_pack_slope(&lut[i], ldw, udw);
3081
3082 return blob;
3083 }
3084
i9xx_read_luts(struct intel_crtc_state * crtc_state)3085 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
3086 {
3087 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3088
3089 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3090 return;
3091
3092 switch (crtc_state->gamma_mode) {
3093 case GAMMA_MODE_MODE_8BIT:
3094 crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3095 break;
3096 case GAMMA_MODE_MODE_10BIT:
3097 crtc_state->post_csc_lut = i9xx_read_lut_10(crtc);
3098 break;
3099 default:
3100 MISSING_CASE(crtc_state->gamma_mode);
3101 break;
3102 }
3103 }
3104
i965_read_lut_10p6(struct intel_crtc * crtc)3105 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
3106 {
3107 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3108 int i, lut_size = DISPLAY_INFO(dev_priv)->color.gamma_lut_size;
3109 enum pipe pipe = crtc->pipe;
3110 struct drm_property_blob *blob;
3111 struct drm_color_lut *lut;
3112
3113 blob = drm_property_create_blob(&dev_priv->drm,
3114 sizeof(lut[0]) * lut_size,
3115 NULL);
3116 if (IS_ERR(blob))
3117 return NULL;
3118
3119 lut = blob->data;
3120
3121 for (i = 0; i < lut_size - 1; i++) {
3122 u32 ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
3123 u32 udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
3124
3125 i965_lut_10p6_pack(&lut[i], ldw, udw);
3126 }
3127
3128 lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
3129 lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
3130 lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
3131
3132 return blob;
3133 }
3134
i965_read_luts(struct intel_crtc_state * crtc_state)3135 static void i965_read_luts(struct intel_crtc_state *crtc_state)
3136 {
3137 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3138
3139 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3140 return;
3141
3142 switch (crtc_state->gamma_mode) {
3143 case GAMMA_MODE_MODE_8BIT:
3144 crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3145 break;
3146 case GAMMA_MODE_MODE_10BIT:
3147 crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
3148 break;
3149 default:
3150 MISSING_CASE(crtc_state->gamma_mode);
3151 break;
3152 }
3153 }
3154
chv_read_cgm_degamma(struct intel_crtc * crtc)3155 static struct drm_property_blob *chv_read_cgm_degamma(struct intel_crtc *crtc)
3156 {
3157 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3158 int i, lut_size = DISPLAY_INFO(dev_priv)->color.degamma_lut_size;
3159 enum pipe pipe = crtc->pipe;
3160 struct drm_property_blob *blob;
3161 struct drm_color_lut *lut;
3162
3163 blob = drm_property_create_blob(&dev_priv->drm,
3164 sizeof(lut[0]) * lut_size,
3165 NULL);
3166 if (IS_ERR(blob))
3167 return NULL;
3168
3169 lut = blob->data;
3170
3171 for (i = 0; i < lut_size; i++) {
3172 u32 ldw = intel_de_read_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 0));
3173 u32 udw = intel_de_read_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 1));
3174
3175 chv_cgm_degamma_pack(&lut[i], ldw, udw);
3176 }
3177
3178 return blob;
3179 }
3180
chv_read_cgm_gamma(struct intel_crtc * crtc)3181 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
3182 {
3183 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3184 int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3185 enum pipe pipe = crtc->pipe;
3186 struct drm_property_blob *blob;
3187 struct drm_color_lut *lut;
3188
3189 blob = drm_property_create_blob(&i915->drm,
3190 sizeof(lut[0]) * lut_size,
3191 NULL);
3192 if (IS_ERR(blob))
3193 return NULL;
3194
3195 lut = blob->data;
3196
3197 for (i = 0; i < lut_size; i++) {
3198 u32 ldw = intel_de_read_fw(i915, CGM_PIPE_GAMMA(pipe, i, 0));
3199 u32 udw = intel_de_read_fw(i915, CGM_PIPE_GAMMA(pipe, i, 1));
3200
3201 chv_cgm_gamma_pack(&lut[i], ldw, udw);
3202 }
3203
3204 return blob;
3205 }
3206
chv_read_luts(struct intel_crtc_state * crtc_state)3207 static void chv_read_luts(struct intel_crtc_state *crtc_state)
3208 {
3209 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3210
3211 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
3212 crtc_state->pre_csc_lut = chv_read_cgm_degamma(crtc);
3213
3214 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
3215 crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
3216 else
3217 i965_read_luts(crtc_state);
3218 }
3219
ilk_read_lut_8(struct intel_crtc * crtc)3220 static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc)
3221 {
3222 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3223 enum pipe pipe = crtc->pipe;
3224 struct drm_property_blob *blob;
3225 struct drm_color_lut *lut;
3226 int i;
3227
3228 blob = drm_property_create_blob(&i915->drm,
3229 sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3230 NULL);
3231 if (IS_ERR(blob))
3232 return NULL;
3233
3234 lut = blob->data;
3235
3236 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3237 u32 val = intel_de_read_fw(i915, LGC_PALETTE(pipe, i));
3238
3239 i9xx_lut_8_pack(&lut[i], val);
3240 }
3241
3242 return blob;
3243 }
3244
ilk_read_lut_10(struct intel_crtc * crtc)3245 static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc)
3246 {
3247 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3248 int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3249 enum pipe pipe = crtc->pipe;
3250 struct drm_property_blob *blob;
3251 struct drm_color_lut *lut;
3252
3253 blob = drm_property_create_blob(&i915->drm,
3254 sizeof(lut[0]) * lut_size,
3255 NULL);
3256 if (IS_ERR(blob))
3257 return NULL;
3258
3259 lut = blob->data;
3260
3261 for (i = 0; i < lut_size; i++) {
3262 u32 val = intel_de_read_fw(i915, PREC_PALETTE(pipe, i));
3263
3264 ilk_lut_10_pack(&lut[i], val);
3265 }
3266
3267 return blob;
3268 }
3269
ilk_read_luts(struct intel_crtc_state * crtc_state)3270 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
3271 {
3272 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3273 struct drm_property_blob **blob =
3274 ilk_has_post_csc_lut(crtc_state) ?
3275 &crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3276
3277 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3278 return;
3279
3280 switch (crtc_state->gamma_mode) {
3281 case GAMMA_MODE_MODE_8BIT:
3282 *blob = ilk_read_lut_8(crtc);
3283 break;
3284 case GAMMA_MODE_MODE_10BIT:
3285 *blob = ilk_read_lut_10(crtc);
3286 break;
3287 default:
3288 MISSING_CASE(crtc_state->gamma_mode);
3289 break;
3290 }
3291 }
3292
3293 /*
3294 * IVB/HSW Bspec / PAL_PREC_INDEX:
3295 * "Restriction : Index auto increment mode is not
3296 * supported and must not be enabled."
3297 */
ivb_read_lut_10(struct intel_crtc * crtc,u32 prec_index)3298 static struct drm_property_blob *ivb_read_lut_10(struct intel_crtc *crtc,
3299 u32 prec_index)
3300 {
3301 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3302 int i, lut_size = ivb_lut_10_size(prec_index);
3303 enum pipe pipe = crtc->pipe;
3304 struct drm_property_blob *blob;
3305 struct drm_color_lut *lut;
3306
3307 blob = drm_property_create_blob(&dev_priv->drm,
3308 sizeof(lut[0]) * lut_size,
3309 NULL);
3310 if (IS_ERR(blob))
3311 return NULL;
3312
3313 lut = blob->data;
3314
3315 for (i = 0; i < lut_size; i++) {
3316 u32 val;
3317
3318 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
3319 prec_index + i);
3320 val = intel_de_read_fw(dev_priv, PREC_PAL_DATA(pipe));
3321
3322 ilk_lut_10_pack(&lut[i], val);
3323 }
3324
3325 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
3326 PAL_PREC_INDEX_VALUE(0));
3327
3328 return blob;
3329 }
3330
ivb_read_luts(struct intel_crtc_state * crtc_state)3331 static void ivb_read_luts(struct intel_crtc_state *crtc_state)
3332 {
3333 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3334 struct drm_property_blob **blob =
3335 ilk_has_post_csc_lut(crtc_state) ?
3336 &crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3337
3338 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3339 return;
3340
3341 switch (crtc_state->gamma_mode) {
3342 case GAMMA_MODE_MODE_8BIT:
3343 *blob = ilk_read_lut_8(crtc);
3344 break;
3345 case GAMMA_MODE_MODE_SPLIT:
3346 crtc_state->pre_csc_lut =
3347 ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3348 PAL_PREC_INDEX_VALUE(0));
3349 crtc_state->post_csc_lut =
3350 ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3351 PAL_PREC_INDEX_VALUE(512));
3352 break;
3353 case GAMMA_MODE_MODE_10BIT:
3354 *blob = ivb_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3355 break;
3356 default:
3357 MISSING_CASE(crtc_state->gamma_mode);
3358 break;
3359 }
3360 }
3361
3362 /* On BDW+ the index auto increment mode actually works */
bdw_read_lut_10(struct intel_crtc * crtc,u32 prec_index)3363 static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
3364 u32 prec_index)
3365 {
3366 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3367 int i, lut_size = ivb_lut_10_size(prec_index);
3368 enum pipe pipe = crtc->pipe;
3369 struct drm_property_blob *blob;
3370 struct drm_color_lut *lut;
3371
3372 blob = drm_property_create_blob(&i915->drm,
3373 sizeof(lut[0]) * lut_size,
3374 NULL);
3375 if (IS_ERR(blob))
3376 return NULL;
3377
3378 lut = blob->data;
3379
3380 intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3381 prec_index);
3382 intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3383 PAL_PREC_AUTO_INCREMENT |
3384 prec_index);
3385
3386 for (i = 0; i < lut_size; i++) {
3387 u32 val = intel_de_read_fw(i915, PREC_PAL_DATA(pipe));
3388
3389 ilk_lut_10_pack(&lut[i], val);
3390 }
3391
3392 intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3393 PAL_PREC_INDEX_VALUE(0));
3394
3395 return blob;
3396 }
3397
bdw_read_luts(struct intel_crtc_state * crtc_state)3398 static void bdw_read_luts(struct intel_crtc_state *crtc_state)
3399 {
3400 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3401 struct drm_property_blob **blob =
3402 ilk_has_post_csc_lut(crtc_state) ?
3403 &crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3404
3405 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3406 return;
3407
3408 switch (crtc_state->gamma_mode) {
3409 case GAMMA_MODE_MODE_8BIT:
3410 *blob = ilk_read_lut_8(crtc);
3411 break;
3412 case GAMMA_MODE_MODE_SPLIT:
3413 crtc_state->pre_csc_lut =
3414 bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3415 PAL_PREC_INDEX_VALUE(0));
3416 crtc_state->post_csc_lut =
3417 bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3418 PAL_PREC_INDEX_VALUE(512));
3419 break;
3420 case GAMMA_MODE_MODE_10BIT:
3421 *blob = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3422 break;
3423 default:
3424 MISSING_CASE(crtc_state->gamma_mode);
3425 break;
3426 }
3427 }
3428
glk_read_degamma_lut(struct intel_crtc * crtc)3429 static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc)
3430 {
3431 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3432 int i, lut_size = DISPLAY_INFO(dev_priv)->color.degamma_lut_size;
3433 enum pipe pipe = crtc->pipe;
3434 struct drm_property_blob *blob;
3435 struct drm_color_lut *lut;
3436
3437 blob = drm_property_create_blob(&dev_priv->drm,
3438 sizeof(lut[0]) * lut_size,
3439 NULL);
3440 if (IS_ERR(blob))
3441 return NULL;
3442
3443 lut = blob->data;
3444
3445 /*
3446 * When setting the auto-increment bit, the hardware seems to
3447 * ignore the index bits, so we need to reset it to index 0
3448 * separately.
3449 */
3450 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3451 PRE_CSC_GAMC_INDEX_VALUE(0));
3452 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3453 PRE_CSC_GAMC_AUTO_INCREMENT |
3454 PRE_CSC_GAMC_INDEX_VALUE(0));
3455
3456 for (i = 0; i < lut_size; i++) {
3457 u32 val = intel_de_read_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe));
3458
3459 /*
3460 * For MTL and beyond, convert back the 24 bit lut values
3461 * read from HW to 16 bit values to maintain parity with
3462 * userspace values
3463 */
3464 if (DISPLAY_VER(dev_priv) >= 14)
3465 val = change_lut_val_precision(val, 16, 24);
3466
3467 lut[i].red = val;
3468 lut[i].green = val;
3469 lut[i].blue = val;
3470 }
3471
3472 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3473 PRE_CSC_GAMC_INDEX_VALUE(0));
3474
3475 return blob;
3476 }
3477
glk_read_luts(struct intel_crtc_state * crtc_state)3478 static void glk_read_luts(struct intel_crtc_state *crtc_state)
3479 {
3480 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3481
3482 if (crtc_state->csc_enable)
3483 crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3484
3485 if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3486 return;
3487
3488 switch (crtc_state->gamma_mode) {
3489 case GAMMA_MODE_MODE_8BIT:
3490 crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3491 break;
3492 case GAMMA_MODE_MODE_10BIT:
3493 crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3494 break;
3495 default:
3496 MISSING_CASE(crtc_state->gamma_mode);
3497 break;
3498 }
3499 }
3500
3501 static struct drm_property_blob *
icl_read_lut_multi_segment(struct intel_crtc * crtc)3502 icl_read_lut_multi_segment(struct intel_crtc *crtc)
3503 {
3504 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3505 int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3506 enum pipe pipe = crtc->pipe;
3507 struct drm_property_blob *blob;
3508 struct drm_color_lut *lut;
3509
3510 blob = drm_property_create_blob(&i915->drm,
3511 sizeof(lut[0]) * lut_size,
3512 NULL);
3513 if (IS_ERR(blob))
3514 return NULL;
3515
3516 lut = blob->data;
3517
3518 intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3519 PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3520 intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3521 PAL_PREC_MULTI_SEG_AUTO_INCREMENT |
3522 PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3523
3524 for (i = 0; i < 9; i++) {
3525 u32 ldw = intel_de_read_fw(i915, PREC_PAL_MULTI_SEG_DATA(pipe));
3526 u32 udw = intel_de_read_fw(i915, PREC_PAL_MULTI_SEG_DATA(pipe));
3527
3528 ilk_lut_12p4_pack(&lut[i], ldw, udw);
3529 }
3530
3531 intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3532 PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3533
3534 /*
3535 * FIXME readouts from PAL_PREC_DATA register aren't giving
3536 * correct values in the case of fine and coarse segments.
3537 * Restricting readouts only for super fine segment as of now.
3538 */
3539
3540 return blob;
3541 }
3542
icl_read_luts(struct intel_crtc_state * crtc_state)3543 static void icl_read_luts(struct intel_crtc_state *crtc_state)
3544 {
3545 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3546
3547 if (icl_has_pre_csc_lut(crtc_state))
3548 crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3549
3550 if (!icl_has_post_csc_lut(crtc_state))
3551 return;
3552
3553 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
3554 case GAMMA_MODE_MODE_8BIT:
3555 crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3556 break;
3557 case GAMMA_MODE_MODE_10BIT:
3558 crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3559 break;
3560 case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
3561 crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
3562 break;
3563 default:
3564 MISSING_CASE(crtc_state->gamma_mode);
3565 break;
3566 }
3567 }
3568
3569 static const struct intel_color_funcs chv_color_funcs = {
3570 .color_check = chv_color_check,
3571 .color_commit_arm = i9xx_color_commit_arm,
3572 .load_luts = chv_load_luts,
3573 .read_luts = chv_read_luts,
3574 .lut_equal = chv_lut_equal,
3575 .read_csc = chv_read_csc,
3576 };
3577
3578 static const struct intel_color_funcs vlv_color_funcs = {
3579 .color_check = vlv_color_check,
3580 .color_commit_arm = i9xx_color_commit_arm,
3581 .load_luts = vlv_load_luts,
3582 .read_luts = i965_read_luts,
3583 .lut_equal = i965_lut_equal,
3584 .read_csc = vlv_read_csc,
3585 };
3586
3587 static const struct intel_color_funcs i965_color_funcs = {
3588 .color_check = i9xx_color_check,
3589 .color_commit_arm = i9xx_color_commit_arm,
3590 .load_luts = i965_load_luts,
3591 .read_luts = i965_read_luts,
3592 .lut_equal = i965_lut_equal,
3593 };
3594
3595 static const struct intel_color_funcs i9xx_color_funcs = {
3596 .color_check = i9xx_color_check,
3597 .color_commit_arm = i9xx_color_commit_arm,
3598 .load_luts = i9xx_load_luts,
3599 .read_luts = i9xx_read_luts,
3600 .lut_equal = i9xx_lut_equal,
3601 };
3602
3603 static const struct intel_color_funcs tgl_color_funcs = {
3604 .color_check = icl_color_check,
3605 .color_commit_noarm = icl_color_commit_noarm,
3606 .color_commit_arm = icl_color_commit_arm,
3607 .load_luts = icl_load_luts,
3608 .read_luts = icl_read_luts,
3609 .lut_equal = icl_lut_equal,
3610 .read_csc = icl_read_csc,
3611 };
3612
3613 static const struct intel_color_funcs icl_color_funcs = {
3614 .color_check = icl_color_check,
3615 .color_commit_noarm = icl_color_commit_noarm,
3616 .color_commit_arm = icl_color_commit_arm,
3617 .color_post_update = icl_color_post_update,
3618 .load_luts = icl_load_luts,
3619 .read_luts = icl_read_luts,
3620 .lut_equal = icl_lut_equal,
3621 .read_csc = icl_read_csc,
3622 };
3623
3624 static const struct intel_color_funcs glk_color_funcs = {
3625 .color_check = glk_color_check,
3626 .color_commit_noarm = skl_color_commit_noarm,
3627 .color_commit_arm = skl_color_commit_arm,
3628 .load_luts = glk_load_luts,
3629 .read_luts = glk_read_luts,
3630 .lut_equal = glk_lut_equal,
3631 .read_csc = skl_read_csc,
3632 };
3633
3634 static const struct intel_color_funcs skl_color_funcs = {
3635 .color_check = ivb_color_check,
3636 .color_commit_noarm = skl_color_commit_noarm,
3637 .color_commit_arm = skl_color_commit_arm,
3638 .load_luts = bdw_load_luts,
3639 .read_luts = bdw_read_luts,
3640 .lut_equal = ivb_lut_equal,
3641 .read_csc = skl_read_csc,
3642 };
3643
3644 static const struct intel_color_funcs bdw_color_funcs = {
3645 .color_check = ivb_color_check,
3646 .color_commit_noarm = ilk_color_commit_noarm,
3647 .color_commit_arm = hsw_color_commit_arm,
3648 .load_luts = bdw_load_luts,
3649 .read_luts = bdw_read_luts,
3650 .lut_equal = ivb_lut_equal,
3651 .read_csc = ilk_read_csc,
3652 };
3653
3654 static const struct intel_color_funcs hsw_color_funcs = {
3655 .color_check = ivb_color_check,
3656 .color_commit_noarm = ilk_color_commit_noarm,
3657 .color_commit_arm = hsw_color_commit_arm,
3658 .load_luts = ivb_load_luts,
3659 .read_luts = ivb_read_luts,
3660 .lut_equal = ivb_lut_equal,
3661 .read_csc = ilk_read_csc,
3662 };
3663
3664 static const struct intel_color_funcs ivb_color_funcs = {
3665 .color_check = ivb_color_check,
3666 .color_commit_noarm = ilk_color_commit_noarm,
3667 .color_commit_arm = ilk_color_commit_arm,
3668 .load_luts = ivb_load_luts,
3669 .read_luts = ivb_read_luts,
3670 .lut_equal = ivb_lut_equal,
3671 .read_csc = ilk_read_csc,
3672 };
3673
3674 static const struct intel_color_funcs ilk_color_funcs = {
3675 .color_check = ilk_color_check,
3676 .color_commit_noarm = ilk_color_commit_noarm,
3677 .color_commit_arm = ilk_color_commit_arm,
3678 .load_luts = ilk_load_luts,
3679 .read_luts = ilk_read_luts,
3680 .lut_equal = ilk_lut_equal,
3681 .read_csc = ilk_read_csc,
3682 };
3683
intel_color_crtc_init(struct intel_crtc * crtc)3684 void intel_color_crtc_init(struct intel_crtc *crtc)
3685 {
3686 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3687 int degamma_lut_size, gamma_lut_size;
3688 bool has_ctm;
3689
3690 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
3691
3692 gamma_lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3693 degamma_lut_size = DISPLAY_INFO(i915)->color.degamma_lut_size;
3694 has_ctm = DISPLAY_VER(i915) >= 5;
3695
3696 /*
3697 * "DPALETTE_A: NOTE: The 8-bit (non-10-bit) mode is the
3698 * only mode supported by Alviso and Grantsdale."
3699 *
3700 * Actually looks like this affects all of gen3.
3701 * Confirmed on alv,cst,pnv. Mobile gen2 parts (alm,mgm)
3702 * are confirmed not to suffer from this restriction.
3703 */
3704 if (DISPLAY_VER(i915) == 3 && crtc->pipe == PIPE_A)
3705 gamma_lut_size = 256;
3706
3707 drm_crtc_enable_color_mgmt(&crtc->base, degamma_lut_size,
3708 has_ctm, gamma_lut_size);
3709 }
3710
intel_color_init(struct drm_i915_private * i915)3711 int intel_color_init(struct drm_i915_private *i915)
3712 {
3713 struct drm_property_blob *blob;
3714
3715 if (DISPLAY_VER(i915) != 10)
3716 return 0;
3717
3718 blob = create_linear_lut(i915,
3719 DISPLAY_INFO(i915)->color.degamma_lut_size);
3720 if (IS_ERR(blob))
3721 return PTR_ERR(blob);
3722
3723 i915->display.color.glk_linear_degamma_lut = blob;
3724
3725 return 0;
3726 }
3727
intel_color_init_hooks(struct drm_i915_private * i915)3728 void intel_color_init_hooks(struct drm_i915_private *i915)
3729 {
3730 if (HAS_GMCH(i915)) {
3731 if (IS_CHERRYVIEW(i915))
3732 i915->display.funcs.color = &chv_color_funcs;
3733 else if (IS_VALLEYVIEW(i915))
3734 i915->display.funcs.color = &vlv_color_funcs;
3735 else if (DISPLAY_VER(i915) >= 4)
3736 i915->display.funcs.color = &i965_color_funcs;
3737 else
3738 i915->display.funcs.color = &i9xx_color_funcs;
3739 } else {
3740 if (DISPLAY_VER(i915) >= 12)
3741 i915->display.funcs.color = &tgl_color_funcs;
3742 else if (DISPLAY_VER(i915) == 11)
3743 i915->display.funcs.color = &icl_color_funcs;
3744 else if (DISPLAY_VER(i915) == 10)
3745 i915->display.funcs.color = &glk_color_funcs;
3746 else if (DISPLAY_VER(i915) == 9)
3747 i915->display.funcs.color = &skl_color_funcs;
3748 else if (DISPLAY_VER(i915) == 8)
3749 i915->display.funcs.color = &bdw_color_funcs;
3750 else if (IS_HASWELL(i915))
3751 i915->display.funcs.color = &hsw_color_funcs;
3752 else if (DISPLAY_VER(i915) == 7)
3753 i915->display.funcs.color = &ivb_color_funcs;
3754 else
3755 i915->display.funcs.color = &ilk_color_funcs;
3756 }
3757 }
3758