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