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