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