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 "intel_color.h"
26 #include "intel_de.h"
27 #include "intel_display_types.h"
28 #include "intel_dpll.h"
29 #include "intel_dsb.h"
30 #include "vlv_dsi_pll.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 * Load LUTs (and other single buffered color management
52 * registers). Will (hopefully) be called during the vblank
53 * following the latching of any double buffered registers
54 * involved with the same commit.
55 */
56 void (*load_luts)(const struct intel_crtc_state *crtc_state);
57 void (*read_luts)(struct intel_crtc_state *crtc_state);
58 };
59
60 #define CTM_COEFF_SIGN (1ULL << 63)
61
62 #define CTM_COEFF_1_0 (1ULL << 32)
63 #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1)
64 #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1)
65 #define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1)
66 #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1)
67 #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1)
68 #define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1)
69
70 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
71
72 #define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
73 #define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
74
75 #define LEGACY_LUT_LENGTH 256
76
77 /*
78 * ILK+ csc matrix:
79 *
80 * |R/Cr| | c0 c1 c2 | ( |R/Cr| |preoff0| ) |postoff0|
81 * |G/Y | = | c3 c4 c5 | x ( |G/Y | + |preoff1| ) + |postoff1|
82 * |B/Cb| | c6 c7 c8 | ( |B/Cb| |preoff2| ) |postoff2|
83 *
84 * ILK/SNB don't have explicit post offsets, and instead
85 * CSC_MODE_YUV_TO_RGB and CSC_BLACK_SCREEN_OFFSET are used:
86 * CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=0 -> 1/2, 0, 1/2
87 * CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/2, 1/16, 1/2
88 * CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=0 -> 0, 0, 0
89 * CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/16, 1/16, 1/16
90 */
91
92 /*
93 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
94 * format). This macro takes the coefficient we want transformed and the
95 * number of fractional bits.
96 *
97 * We only have a 9 bits precision window which slides depending on the value
98 * of the CTM coefficient and we write the value from bit 3. We also round the
99 * value.
100 */
101 #define ILK_CSC_COEFF_FP(coeff, fbits) \
102 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
103
104 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
105 #define ILK_CSC_COEFF_1_0 0x7800
106
107 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
108
109 /* Nop pre/post offsets */
110 static const u16 ilk_csc_off_zero[3] = {};
111
112 /* Identity matrix */
113 static const u16 ilk_csc_coeff_identity[9] = {
114 ILK_CSC_COEFF_1_0, 0, 0,
115 0, ILK_CSC_COEFF_1_0, 0,
116 0, 0, ILK_CSC_COEFF_1_0,
117 };
118
119 /* Limited range RGB post offsets */
120 static const u16 ilk_csc_postoff_limited_range[3] = {
121 ILK_CSC_POSTOFF_LIMITED_RANGE,
122 ILK_CSC_POSTOFF_LIMITED_RANGE,
123 ILK_CSC_POSTOFF_LIMITED_RANGE,
124 };
125
126 /* Full range RGB -> limited range RGB matrix */
127 static const u16 ilk_csc_coeff_limited_range[9] = {
128 ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
129 0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
130 0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
131 };
132
133 /* BT.709 full range RGB -> limited range YCbCr matrix */
134 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
135 0x1e08, 0x9cc0, 0xb528,
136 0x2ba8, 0x09d8, 0x37e8,
137 0xbce8, 0x9ad8, 0x1e08,
138 };
139
140 /* Limited range YCbCr post offsets */
141 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
142 0x0800, 0x0100, 0x0800,
143 };
144
lut_is_legacy(const struct drm_property_blob * lut)145 static bool lut_is_legacy(const struct drm_property_blob *lut)
146 {
147 return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
148 }
149
crtc_state_is_legacy_gamma(const struct intel_crtc_state * crtc_state)150 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
151 {
152 return !crtc_state->hw.degamma_lut &&
153 !crtc_state->hw.ctm &&
154 crtc_state->hw.gamma_lut &&
155 lut_is_legacy(crtc_state->hw.gamma_lut);
156 }
157
158 /*
159 * When using limited range, multiply the matrix given by userspace by
160 * the matrix that we would use for the limited range.
161 */
ctm_mult_by_limited(u64 * result,const u64 * input)162 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
163 {
164 int i;
165
166 for (i = 0; i < 9; i++) {
167 u64 user_coeff = input[i];
168 u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
169 u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
170 CTM_COEFF_4_0 - 1) >> 2;
171
172 /*
173 * By scaling every co-efficient with limited range (16-235)
174 * vs full range (0-255) the final o/p will be scaled down to
175 * fit in the limited range supported by the panel.
176 */
177 result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
178 result[i] |= user_coeff & CTM_COEFF_SIGN;
179 }
180
181 return result;
182 }
183
ilk_update_pipe_csc(struct intel_crtc * crtc,const u16 preoff[3],const u16 coeff[9],const u16 postoff[3])184 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
185 const u16 preoff[3],
186 const u16 coeff[9],
187 const u16 postoff[3])
188 {
189 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
190 enum pipe pipe = crtc->pipe;
191
192 intel_de_write_fw(dev_priv, PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
193 intel_de_write_fw(dev_priv, PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
194 intel_de_write_fw(dev_priv, PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
195
196 intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_RY_GY(pipe),
197 coeff[0] << 16 | coeff[1]);
198 intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
199
200 intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_RU_GU(pipe),
201 coeff[3] << 16 | coeff[4]);
202 intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
203
204 intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_RV_GV(pipe),
205 coeff[6] << 16 | coeff[7]);
206 intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
207
208 if (DISPLAY_VER(dev_priv) >= 7) {
209 intel_de_write_fw(dev_priv, PIPE_CSC_POSTOFF_HI(pipe),
210 postoff[0]);
211 intel_de_write_fw(dev_priv, PIPE_CSC_POSTOFF_ME(pipe),
212 postoff[1]);
213 intel_de_write_fw(dev_priv, PIPE_CSC_POSTOFF_LO(pipe),
214 postoff[2]);
215 }
216 }
217
icl_update_output_csc(struct intel_crtc * crtc,const u16 preoff[3],const u16 coeff[9],const u16 postoff[3])218 static void icl_update_output_csc(struct intel_crtc *crtc,
219 const u16 preoff[3],
220 const u16 coeff[9],
221 const u16 postoff[3])
222 {
223 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
224 enum pipe pipe = crtc->pipe;
225
226 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
227 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
228 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
229
230 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
231 coeff[0] << 16 | coeff[1]);
232 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
233 coeff[2] << 16);
234
235 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
236 coeff[3] << 16 | coeff[4]);
237 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
238 coeff[5] << 16);
239
240 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
241 coeff[6] << 16 | coeff[7]);
242 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
243 coeff[8] << 16);
244
245 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
246 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
247 intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
248 }
249
ilk_csc_limited_range(const struct intel_crtc_state * crtc_state)250 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
251 {
252 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
253
254 /*
255 * FIXME if there's a gamma LUT after the CSC, we should
256 * do the range compression using the gamma LUT instead.
257 */
258 return crtc_state->limited_color_range &&
259 (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
260 IS_DISPLAY_VER(dev_priv, 9, 10));
261 }
262
ilk_csc_convert_ctm(const struct intel_crtc_state * crtc_state,u16 coeffs[9])263 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
264 u16 coeffs[9])
265 {
266 const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
267 const u64 *input;
268 u64 temp[9];
269 int i;
270
271 if (ilk_csc_limited_range(crtc_state))
272 input = ctm_mult_by_limited(temp, ctm->matrix);
273 else
274 input = ctm->matrix;
275
276 /*
277 * Convert fixed point S31.32 input to format supported by the
278 * hardware.
279 */
280 for (i = 0; i < 9; i++) {
281 u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
282
283 /*
284 * Clamp input value to min/max supported by
285 * hardware.
286 */
287 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
288
289 coeffs[i] = 0;
290
291 /* sign bit */
292 if (CTM_COEFF_NEGATIVE(input[i]))
293 coeffs[i] |= 1 << 15;
294
295 if (abs_coeff < CTM_COEFF_0_125)
296 coeffs[i] |= (3 << 12) |
297 ILK_CSC_COEFF_FP(abs_coeff, 12);
298 else if (abs_coeff < CTM_COEFF_0_25)
299 coeffs[i] |= (2 << 12) |
300 ILK_CSC_COEFF_FP(abs_coeff, 11);
301 else if (abs_coeff < CTM_COEFF_0_5)
302 coeffs[i] |= (1 << 12) |
303 ILK_CSC_COEFF_FP(abs_coeff, 10);
304 else if (abs_coeff < CTM_COEFF_1_0)
305 coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
306 else if (abs_coeff < CTM_COEFF_2_0)
307 coeffs[i] |= (7 << 12) |
308 ILK_CSC_COEFF_FP(abs_coeff, 8);
309 else
310 coeffs[i] |= (6 << 12) |
311 ILK_CSC_COEFF_FP(abs_coeff, 7);
312 }
313 }
314
ilk_load_csc_matrix(const struct intel_crtc_state * crtc_state)315 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
316 {
317 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
318 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
319 bool limited_color_range = ilk_csc_limited_range(crtc_state);
320
321 if (crtc_state->hw.ctm) {
322 u16 coeff[9];
323
324 ilk_csc_convert_ctm(crtc_state, coeff);
325 ilk_update_pipe_csc(crtc, ilk_csc_off_zero, coeff,
326 limited_color_range ?
327 ilk_csc_postoff_limited_range :
328 ilk_csc_off_zero);
329 } else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
330 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
331 ilk_csc_coeff_rgb_to_ycbcr,
332 ilk_csc_postoff_rgb_to_ycbcr);
333 } else if (limited_color_range) {
334 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
335 ilk_csc_coeff_limited_range,
336 ilk_csc_postoff_limited_range);
337 } else if (crtc_state->csc_enable) {
338 /*
339 * On GLK both pipe CSC and degamma LUT are controlled
340 * by csc_enable. Hence for the cases where the degama
341 * LUT is needed but CSC is not we need to load an
342 * identity matrix.
343 */
344 drm_WARN_ON(&dev_priv->drm, !IS_GEMINILAKE(dev_priv));
345
346 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
347 ilk_csc_coeff_identity,
348 ilk_csc_off_zero);
349 }
350 }
351
icl_load_csc_matrix(const struct intel_crtc_state * crtc_state)352 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
353 {
354 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
355
356 if (crtc_state->hw.ctm) {
357 u16 coeff[9];
358
359 ilk_csc_convert_ctm(crtc_state, coeff);
360 ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
361 coeff, ilk_csc_off_zero);
362 }
363
364 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
365 icl_update_output_csc(crtc, ilk_csc_off_zero,
366 ilk_csc_coeff_rgb_to_ycbcr,
367 ilk_csc_postoff_rgb_to_ycbcr);
368 } else if (crtc_state->limited_color_range) {
369 icl_update_output_csc(crtc, ilk_csc_off_zero,
370 ilk_csc_coeff_limited_range,
371 ilk_csc_postoff_limited_range);
372 }
373 }
374
chv_load_cgm_csc(struct intel_crtc * crtc,const struct drm_property_blob * blob)375 static void chv_load_cgm_csc(struct intel_crtc *crtc,
376 const struct drm_property_blob *blob)
377 {
378 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
379 const struct drm_color_ctm *ctm = blob->data;
380 enum pipe pipe = crtc->pipe;
381 u16 coeffs[9];
382 int i;
383
384 for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
385 u64 abs_coeff = ((1ULL << 63) - 1) & ctm->matrix[i];
386
387 /* Round coefficient. */
388 abs_coeff += 1 << (32 - 13);
389 /* Clamp to hardware limits. */
390 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
391
392 coeffs[i] = 0;
393
394 /* Write coefficients in S3.12 format. */
395 if (ctm->matrix[i] & (1ULL << 63))
396 coeffs[i] |= 1 << 15;
397
398 coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
399 coeffs[i] |= (abs_coeff >> 20) & 0xfff;
400 }
401
402 intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF01(pipe),
403 coeffs[1] << 16 | coeffs[0]);
404 intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF23(pipe),
405 coeffs[3] << 16 | coeffs[2]);
406 intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF45(pipe),
407 coeffs[5] << 16 | coeffs[4]);
408 intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF67(pipe),
409 coeffs[7] << 16 | coeffs[6]);
410 intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF8(pipe),
411 coeffs[8]);
412 }
413
414 /* convert hw value with given bit_precision to lut property val */
intel_color_lut_pack(u32 val,int bit_precision)415 static u32 intel_color_lut_pack(u32 val, int bit_precision)
416 {
417 u32 max = 0xffff >> (16 - bit_precision);
418
419 val = clamp_val(val, 0, max);
420
421 if (bit_precision < 16)
422 val <<= 16 - bit_precision;
423
424 return val;
425 }
426
i9xx_lut_8(const struct drm_color_lut * color)427 static u32 i9xx_lut_8(const struct drm_color_lut *color)
428 {
429 return drm_color_lut_extract(color->red, 8) << 16 |
430 drm_color_lut_extract(color->green, 8) << 8 |
431 drm_color_lut_extract(color->blue, 8);
432 }
433
i9xx_lut_8_pack(struct drm_color_lut * entry,u32 val)434 static void i9xx_lut_8_pack(struct drm_color_lut *entry, u32 val)
435 {
436 entry->red = intel_color_lut_pack(REG_FIELD_GET(LGC_PALETTE_RED_MASK, val), 8);
437 entry->green = intel_color_lut_pack(REG_FIELD_GET(LGC_PALETTE_GREEN_MASK, val), 8);
438 entry->blue = intel_color_lut_pack(REG_FIELD_GET(LGC_PALETTE_BLUE_MASK, val), 8);
439 }
440
441 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
i965_lut_10p6_ldw(const struct drm_color_lut * color)442 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
443 {
444 return (color->red & 0xff) << 16 |
445 (color->green & 0xff) << 8 |
446 (color->blue & 0xff);
447 }
448
449 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
i965_lut_10p6_udw(const struct drm_color_lut * color)450 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
451 {
452 return (color->red >> 8) << 16 |
453 (color->green >> 8) << 8 |
454 (color->blue >> 8);
455 }
456
i965_lut_10p6_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)457 static void i965_lut_10p6_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
458 {
459 entry->red = REG_FIELD_GET(PALETTE_RED_MASK, udw) << 8 |
460 REG_FIELD_GET(PALETTE_RED_MASK, ldw);
461 entry->green = REG_FIELD_GET(PALETTE_GREEN_MASK, udw) << 8 |
462 REG_FIELD_GET(PALETTE_GREEN_MASK, ldw);
463 entry->blue = REG_FIELD_GET(PALETTE_BLUE_MASK, udw) << 8 |
464 REG_FIELD_GET(PALETTE_BLUE_MASK, ldw);
465 }
466
i965_lut_11p6_max_pack(u32 val)467 static u16 i965_lut_11p6_max_pack(u32 val)
468 {
469 /* PIPEGCMAX is 11.6, clamp to 10.6 */
470 return clamp_val(val, 0, 0xffff);
471 }
472
ilk_lut_10(const struct drm_color_lut * color)473 static u32 ilk_lut_10(const struct drm_color_lut *color)
474 {
475 return drm_color_lut_extract(color->red, 10) << 20 |
476 drm_color_lut_extract(color->green, 10) << 10 |
477 drm_color_lut_extract(color->blue, 10);
478 }
479
ilk_lut_10_pack(struct drm_color_lut * entry,u32 val)480 static void ilk_lut_10_pack(struct drm_color_lut *entry, u32 val)
481 {
482 entry->red = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_RED_MASK, val), 10);
483 entry->green = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_GREEN_MASK, val), 10);
484 entry->blue = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_BLUE_MASK, val), 10);
485 }
486
icl_lut_multi_seg_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)487 static void icl_lut_multi_seg_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
488 {
489 entry->red = REG_FIELD_GET(PAL_PREC_MULTI_SEG_RED_UDW_MASK, udw) << 6 |
490 REG_FIELD_GET(PAL_PREC_MULTI_SEG_RED_LDW_MASK, ldw);
491 entry->green = REG_FIELD_GET(PAL_PREC_MULTI_SEG_GREEN_UDW_MASK, udw) << 6 |
492 REG_FIELD_GET(PAL_PREC_MULTI_SEG_GREEN_LDW_MASK, ldw);
493 entry->blue = REG_FIELD_GET(PAL_PREC_MULTI_SEG_BLUE_UDW_MASK, udw) << 6 |
494 REG_FIELD_GET(PAL_PREC_MULTI_SEG_BLUE_LDW_MASK, ldw);
495 }
496
icl_color_commit_noarm(const struct intel_crtc_state * crtc_state)497 static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
498 {
499 icl_load_csc_matrix(crtc_state);
500 }
501
skl_color_commit_noarm(const struct intel_crtc_state * crtc_state)502 static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
503 {
504 /*
505 * Possibly related to display WA #1184, SKL CSC loses the latched
506 * CSC coeff/offset register values if the CSC registers are disarmed
507 * between DC5 exit and PSR exit. This will cause the plane(s) to
508 * output all black (until CSC_MODE is rearmed and properly latched).
509 * Once PSR exit (and proper register latching) has occurred the
510 * danger is over. Thus when PSR is enabled the CSC coeff/offset
511 * register programming will be peformed from skl_color_commit_arm()
512 * which is called after PSR exit.
513 */
514 if (!crtc_state->has_psr)
515 ilk_load_csc_matrix(crtc_state);
516 }
517
ilk_color_commit_noarm(const struct intel_crtc_state * crtc_state)518 static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
519 {
520 ilk_load_csc_matrix(crtc_state);
521 }
522
i9xx_color_commit_arm(const struct intel_crtc_state * crtc_state)523 static void i9xx_color_commit_arm(const struct intel_crtc_state *crtc_state)
524 {
525 /* update PIPECONF GAMMA_MODE */
526 i9xx_set_pipeconf(crtc_state);
527 }
528
ilk_color_commit_arm(const struct intel_crtc_state * crtc_state)529 static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state)
530 {
531 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
532 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
533
534 /* update PIPECONF GAMMA_MODE */
535 ilk_set_pipeconf(crtc_state);
536
537 intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
538 crtc_state->csc_mode);
539 }
540
hsw_color_commit_arm(const struct intel_crtc_state * crtc_state)541 static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state)
542 {
543 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
544 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
545
546 intel_de_write(dev_priv, GAMMA_MODE(crtc->pipe),
547 crtc_state->gamma_mode);
548
549 intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
550 crtc_state->csc_mode);
551 }
552
skl_color_commit_arm(const struct intel_crtc_state * crtc_state)553 static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
554 {
555 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
556 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
557 enum pipe pipe = crtc->pipe;
558 u32 val = 0;
559
560 if (crtc_state->has_psr)
561 ilk_load_csc_matrix(crtc_state);
562
563 /*
564 * We don't (yet) allow userspace to control the pipe background color,
565 * so force it to black, but apply pipe gamma and CSC appropriately
566 * so that its handling will match how we program our planes.
567 */
568 if (crtc_state->gamma_enable)
569 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
570 if (crtc_state->csc_enable)
571 val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
572 intel_de_write(dev_priv, SKL_BOTTOM_COLOR(pipe), val);
573
574 intel_de_write(dev_priv, GAMMA_MODE(crtc->pipe),
575 crtc_state->gamma_mode);
576
577 intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
578 crtc_state->csc_mode);
579 }
580
i9xx_load_lut_8(struct intel_crtc * crtc,const struct drm_property_blob * blob)581 static void i9xx_load_lut_8(struct intel_crtc *crtc,
582 const struct drm_property_blob *blob)
583 {
584 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
585 const struct drm_color_lut *lut;
586 enum pipe pipe = crtc->pipe;
587 int i;
588
589 if (!blob)
590 return;
591
592 lut = blob->data;
593
594 for (i = 0; i < 256; i++)
595 intel_de_write_fw(dev_priv, PALETTE(pipe, i),
596 i9xx_lut_8(&lut[i]));
597 }
598
i9xx_load_luts(const struct intel_crtc_state * crtc_state)599 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
600 {
601 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
602 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
603 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
604
605 assert_pll_enabled(dev_priv, crtc->pipe);
606
607 i9xx_load_lut_8(crtc, gamma_lut);
608 }
609
i965_load_lut_10p6(struct intel_crtc * crtc,const struct drm_property_blob * blob)610 static void i965_load_lut_10p6(struct intel_crtc *crtc,
611 const struct drm_property_blob *blob)
612 {
613 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
614 const struct drm_color_lut *lut = blob->data;
615 int i, lut_size = drm_color_lut_size(blob);
616 enum pipe pipe = crtc->pipe;
617
618 for (i = 0; i < lut_size - 1; i++) {
619 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 0),
620 i965_lut_10p6_ldw(&lut[i]));
621 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 1),
622 i965_lut_10p6_udw(&lut[i]));
623 }
624
625 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 0), lut[i].red);
626 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 1), lut[i].green);
627 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 2), lut[i].blue);
628 }
629
i965_load_luts(const struct intel_crtc_state * crtc_state)630 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
631 {
632 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
633 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
634 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
635
636 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
637 assert_dsi_pll_enabled(dev_priv);
638 else
639 assert_pll_enabled(dev_priv, crtc->pipe);
640
641 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
642 i9xx_load_lut_8(crtc, gamma_lut);
643 else
644 i965_load_lut_10p6(crtc, gamma_lut);
645 }
646
ilk_load_lut_8(struct intel_crtc * crtc,const struct drm_property_blob * blob)647 static void ilk_load_lut_8(struct intel_crtc *crtc,
648 const struct drm_property_blob *blob)
649 {
650 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
651 const struct drm_color_lut *lut;
652 enum pipe pipe = crtc->pipe;
653 int i;
654
655 if (!blob)
656 return;
657
658 lut = blob->data;
659
660 for (i = 0; i < 256; i++)
661 intel_de_write_fw(dev_priv, LGC_PALETTE(pipe, i),
662 i9xx_lut_8(&lut[i]));
663 }
664
ilk_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob)665 static void ilk_load_lut_10(struct intel_crtc *crtc,
666 const struct drm_property_blob *blob)
667 {
668 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
669 const struct drm_color_lut *lut = blob->data;
670 int i, lut_size = drm_color_lut_size(blob);
671 enum pipe pipe = crtc->pipe;
672
673 for (i = 0; i < lut_size; i++)
674 intel_de_write_fw(dev_priv, PREC_PALETTE(pipe, i),
675 ilk_lut_10(&lut[i]));
676 }
677
ilk_load_luts(const struct intel_crtc_state * crtc_state)678 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
679 {
680 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
681 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
682
683 switch (crtc_state->gamma_mode) {
684 case GAMMA_MODE_MODE_8BIT:
685 ilk_load_lut_8(crtc, gamma_lut);
686 break;
687 case GAMMA_MODE_MODE_10BIT:
688 ilk_load_lut_10(crtc, gamma_lut);
689 break;
690 default:
691 MISSING_CASE(crtc_state->gamma_mode);
692 break;
693 }
694 }
695
ivb_lut_10_size(u32 prec_index)696 static int ivb_lut_10_size(u32 prec_index)
697 {
698 if (prec_index & PAL_PREC_SPLIT_MODE)
699 return 512;
700 else
701 return 1024;
702 }
703
704 /*
705 * IVB/HSW Bspec / PAL_PREC_INDEX:
706 * "Restriction : Index auto increment mode is not
707 * supported and must not be enabled."
708 */
ivb_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob,u32 prec_index)709 static void ivb_load_lut_10(struct intel_crtc *crtc,
710 const struct drm_property_blob *blob,
711 u32 prec_index)
712 {
713 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
714 int hw_lut_size = ivb_lut_10_size(prec_index);
715 const struct drm_color_lut *lut = blob->data;
716 int i, lut_size = drm_color_lut_size(blob);
717 enum pipe pipe = crtc->pipe;
718
719 for (i = 0; i < hw_lut_size; i++) {
720 /* We discard half the user entries in split gamma mode */
721 const struct drm_color_lut *entry =
722 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
723
724 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), prec_index++);
725 intel_de_write_fw(dev_priv, PREC_PAL_DATA(pipe),
726 ilk_lut_10(entry));
727 }
728
729 /*
730 * Reset the index, otherwise it prevents the legacy palette to be
731 * written properly.
732 */
733 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), 0);
734 }
735
736 /* On BDW+ the index auto increment mode actually works */
bdw_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob,u32 prec_index)737 static void bdw_load_lut_10(struct intel_crtc *crtc,
738 const struct drm_property_blob *blob,
739 u32 prec_index)
740 {
741 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
742 int hw_lut_size = ivb_lut_10_size(prec_index);
743 const struct drm_color_lut *lut = blob->data;
744 int i, lut_size = drm_color_lut_size(blob);
745 enum pipe pipe = crtc->pipe;
746
747 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
748 prec_index | PAL_PREC_AUTO_INCREMENT);
749
750 for (i = 0; i < hw_lut_size; i++) {
751 /* We discard half the user entries in split gamma mode */
752 const struct drm_color_lut *entry =
753 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
754
755 intel_de_write_fw(dev_priv, PREC_PAL_DATA(pipe),
756 ilk_lut_10(entry));
757 }
758
759 /*
760 * Reset the index, otherwise it prevents the legacy palette to be
761 * written properly.
762 */
763 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), 0);
764 }
765
ivb_load_lut_ext_max(const struct intel_crtc_state * crtc_state)766 static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
767 {
768 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
769 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
770 enum pipe pipe = crtc->pipe;
771
772 /* Program the max register to clamp values > 1.0. */
773 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
774 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
775 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
776
777 /*
778 * Program the gc max 2 register to clamp values > 1.0.
779 * ToDo: Extend the ABI to be able to program values
780 * from 3.0 to 7.0
781 */
782 if (DISPLAY_VER(dev_priv) >= 10) {
783 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 0),
784 1 << 16);
785 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 1),
786 1 << 16);
787 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 2),
788 1 << 16);
789 }
790 }
791
ivb_load_luts(const struct intel_crtc_state * crtc_state)792 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
793 {
794 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
795 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
796 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
797 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
798
799 switch (crtc_state->gamma_mode) {
800 case GAMMA_MODE_MODE_8BIT:
801 ilk_load_lut_8(crtc, blob);
802 break;
803 case GAMMA_MODE_MODE_SPLIT:
804 ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
805 PAL_PREC_INDEX_VALUE(0));
806 ivb_load_lut_ext_max(crtc_state);
807 ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
808 PAL_PREC_INDEX_VALUE(512));
809 break;
810 case GAMMA_MODE_MODE_10BIT:
811 ivb_load_lut_10(crtc, blob,
812 PAL_PREC_INDEX_VALUE(0));
813 ivb_load_lut_ext_max(crtc_state);
814 break;
815 default:
816 MISSING_CASE(crtc_state->gamma_mode);
817 break;
818 }
819 }
820
bdw_load_luts(const struct intel_crtc_state * crtc_state)821 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
822 {
823 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
824 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
825 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
826 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
827
828 switch (crtc_state->gamma_mode) {
829 case GAMMA_MODE_MODE_8BIT:
830 ilk_load_lut_8(crtc, blob);
831 break;
832 case GAMMA_MODE_MODE_SPLIT:
833 bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
834 PAL_PREC_INDEX_VALUE(0));
835 ivb_load_lut_ext_max(crtc_state);
836 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
837 PAL_PREC_INDEX_VALUE(512));
838 break;
839 case GAMMA_MODE_MODE_10BIT:
840
841 bdw_load_lut_10(crtc, blob,
842 PAL_PREC_INDEX_VALUE(0));
843 ivb_load_lut_ext_max(crtc_state);
844 break;
845 default:
846 MISSING_CASE(crtc_state->gamma_mode);
847 break;
848 }
849 }
850
glk_degamma_lut_size(struct drm_i915_private * i915)851 static int glk_degamma_lut_size(struct drm_i915_private *i915)
852 {
853 if (DISPLAY_VER(i915) >= 13)
854 return 131;
855 else
856 return 35;
857 }
858
glk_load_degamma_lut(const struct intel_crtc_state * crtc_state)859 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
860 {
861 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
862 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
863 enum pipe pipe = crtc->pipe;
864 int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
865 const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
866
867 /*
868 * When setting the auto-increment bit, the hardware seems to
869 * ignore the index bits, so we need to reset it to index 0
870 * separately.
871 */
872 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
873 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
874 PRE_CSC_GAMC_AUTO_INCREMENT);
875
876 for (i = 0; i < lut_size; i++) {
877 /*
878 * First lut_size entries represent range from 0 to 1.0
879 * 3 additional lut entries will represent extended range
880 * inputs 3.0 and 7.0 respectively, currently clamped
881 * at 1.0. Since the precision is 16bit, the user
882 * value can be directly filled to register.
883 * The pipe degamma table in GLK+ onwards doesn't
884 * support different values per channel, so this just
885 * programs green value which will be equal to Red and
886 * Blue into the lut registers.
887 * ToDo: Extend to max 7.0. Enable 32 bit input value
888 * as compared to just 16 to achieve this.
889 */
890 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe),
891 lut[i].green);
892 }
893
894 /* Clamp values > 1.0. */
895 while (i++ < glk_degamma_lut_size(dev_priv))
896 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
897
898 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
899 }
900
glk_load_degamma_lut_linear(const struct intel_crtc_state * crtc_state)901 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
902 {
903 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
904 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
905 enum pipe pipe = crtc->pipe;
906 int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
907
908 /*
909 * When setting the auto-increment bit, the hardware seems to
910 * ignore the index bits, so we need to reset it to index 0
911 * separately.
912 */
913 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
914 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
915 PRE_CSC_GAMC_AUTO_INCREMENT);
916
917 for (i = 0; i < lut_size; i++) {
918 u32 v = (i << 16) / (lut_size - 1);
919
920 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), v);
921 }
922
923 /* Clamp values > 1.0. */
924 while (i++ < 35)
925 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
926
927 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
928 }
929
glk_load_luts(const struct intel_crtc_state * crtc_state)930 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
931 {
932 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
933 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
934
935 /*
936 * On GLK+ both pipe CSC and degamma LUT are controlled
937 * by csc_enable. Hence for the cases where the CSC is
938 * needed but degamma LUT is not we need to load a
939 * linear degamma LUT. In fact we'll just always load
940 * the degama LUT so that we don't have to reload
941 * it every time the pipe CSC is being enabled.
942 */
943 if (crtc_state->hw.degamma_lut)
944 glk_load_degamma_lut(crtc_state);
945 else
946 glk_load_degamma_lut_linear(crtc_state);
947
948 switch (crtc_state->gamma_mode) {
949 case GAMMA_MODE_MODE_8BIT:
950 ilk_load_lut_8(crtc, gamma_lut);
951 break;
952 case GAMMA_MODE_MODE_10BIT:
953 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
954 ivb_load_lut_ext_max(crtc_state);
955 break;
956 default:
957 MISSING_CASE(crtc_state->gamma_mode);
958 break;
959 }
960 }
961
962 /* ilk+ "12.4" interpolated format (high 10 bits) */
ilk_lut_12p4_udw(const struct drm_color_lut * color)963 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
964 {
965 return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
966 (color->blue >> 6);
967 }
968
969 /* ilk+ "12.4" interpolated format (low 6 bits) */
ilk_lut_12p4_ldw(const struct drm_color_lut * color)970 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
971 {
972 return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
973 (color->blue & 0x3f) << 4;
974 }
975
976 static void
icl_load_gcmax(const struct intel_crtc_state * crtc_state,const struct drm_color_lut * color)977 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
978 const struct drm_color_lut *color)
979 {
980 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
981 enum pipe pipe = crtc->pipe;
982
983 /* FIXME LUT entries are 16 bit only, so we can prog 0xFFFF max */
984 intel_dsb_reg_write(crtc_state, PREC_PAL_GC_MAX(pipe, 0), color->red);
985 intel_dsb_reg_write(crtc_state, PREC_PAL_GC_MAX(pipe, 1), color->green);
986 intel_dsb_reg_write(crtc_state, PREC_PAL_GC_MAX(pipe, 2), color->blue);
987 }
988
989 static void
icl_program_gamma_superfine_segment(const struct intel_crtc_state * crtc_state)990 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
991 {
992 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
993 const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
994 const struct drm_color_lut *lut = blob->data;
995 enum pipe pipe = crtc->pipe;
996 int i;
997
998 /*
999 * Program Super Fine segment (let's call it seg1)...
1000 *
1001 * Super Fine segment's step is 1/(8 * 128 * 256) and it has
1002 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256),
1003 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256).
1004 */
1005 intel_dsb_reg_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1006 PAL_PREC_AUTO_INCREMENT);
1007
1008 for (i = 0; i < 9; i++) {
1009 const struct drm_color_lut *entry = &lut[i];
1010
1011 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
1012 ilk_lut_12p4_ldw(entry));
1013 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
1014 ilk_lut_12p4_udw(entry));
1015 }
1016 }
1017
1018 static void
icl_program_gamma_multi_segment(const struct intel_crtc_state * crtc_state)1019 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
1020 {
1021 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1022 const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
1023 const struct drm_color_lut *lut = blob->data;
1024 const struct drm_color_lut *entry;
1025 enum pipe pipe = crtc->pipe;
1026 int i;
1027
1028 /*
1029 * Program Fine segment (let's call it seg2)...
1030 *
1031 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256)
1032 * ... 256/(128 * 256). So in order to program fine segment of LUT we
1033 * need to pick every 8th entry in the LUT, and program 256 indexes.
1034 *
1035 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
1036 * seg2[0] being unused by the hardware.
1037 */
1038 intel_dsb_reg_write(crtc_state, PREC_PAL_INDEX(pipe),
1039 PAL_PREC_AUTO_INCREMENT);
1040 for (i = 1; i < 257; i++) {
1041 entry = &lut[i * 8];
1042 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1043 ilk_lut_12p4_ldw(entry));
1044 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1045 ilk_lut_12p4_udw(entry));
1046 }
1047
1048 /*
1049 * Program Coarse segment (let's call it seg3)...
1050 *
1051 * Coarse segment starts from index 0 and it's step is 1/256 ie 0,
1052 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT
1053 * above, we need to pick every (8 * 128)th entry in LUT, and
1054 * program 256 of those.
1055 *
1056 * Spec is not very clear about if entries seg3[0] and seg3[1] are
1057 * being used or not, but we still need to program these to advance
1058 * the index.
1059 */
1060 for (i = 0; i < 256; i++) {
1061 entry = &lut[i * 8 * 128];
1062 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1063 ilk_lut_12p4_ldw(entry));
1064 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1065 ilk_lut_12p4_udw(entry));
1066 }
1067
1068 /* The last entry in the LUT is to be programmed in GCMAX */
1069 entry = &lut[256 * 8 * 128];
1070 icl_load_gcmax(crtc_state, entry);
1071 ivb_load_lut_ext_max(crtc_state);
1072 }
1073
icl_load_luts(const struct intel_crtc_state * crtc_state)1074 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
1075 {
1076 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1077 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1078
1079 if (crtc_state->hw.degamma_lut)
1080 glk_load_degamma_lut(crtc_state);
1081
1082 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
1083 case GAMMA_MODE_MODE_8BIT:
1084 ilk_load_lut_8(crtc, gamma_lut);
1085 break;
1086 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
1087 icl_program_gamma_superfine_segment(crtc_state);
1088 icl_program_gamma_multi_segment(crtc_state);
1089 break;
1090 case GAMMA_MODE_MODE_10BIT:
1091 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
1092 ivb_load_lut_ext_max(crtc_state);
1093 break;
1094 default:
1095 MISSING_CASE(crtc_state->gamma_mode);
1096 break;
1097 }
1098
1099 intel_dsb_commit(crtc_state);
1100 }
1101
chv_cgm_degamma_ldw(const struct drm_color_lut * color)1102 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
1103 {
1104 return drm_color_lut_extract(color->green, 14) << 16 |
1105 drm_color_lut_extract(color->blue, 14);
1106 }
1107
chv_cgm_degamma_udw(const struct drm_color_lut * color)1108 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
1109 {
1110 return drm_color_lut_extract(color->red, 14);
1111 }
1112
chv_load_cgm_degamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)1113 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
1114 const struct drm_property_blob *blob)
1115 {
1116 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1117 const struct drm_color_lut *lut = blob->data;
1118 int i, lut_size = drm_color_lut_size(blob);
1119 enum pipe pipe = crtc->pipe;
1120
1121 for (i = 0; i < lut_size; i++) {
1122 intel_de_write_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 0),
1123 chv_cgm_degamma_ldw(&lut[i]));
1124 intel_de_write_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 1),
1125 chv_cgm_degamma_udw(&lut[i]));
1126 }
1127 }
1128
chv_cgm_gamma_ldw(const struct drm_color_lut * color)1129 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
1130 {
1131 return drm_color_lut_extract(color->green, 10) << 16 |
1132 drm_color_lut_extract(color->blue, 10);
1133 }
1134
chv_cgm_gamma_udw(const struct drm_color_lut * color)1135 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
1136 {
1137 return drm_color_lut_extract(color->red, 10);
1138 }
1139
chv_cgm_gamma_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)1140 static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
1141 {
1142 entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_MASK, ldw), 10);
1143 entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_MASK, ldw), 10);
1144 entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_MASK, udw), 10);
1145 }
1146
chv_load_cgm_gamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)1147 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
1148 const struct drm_property_blob *blob)
1149 {
1150 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1151 const struct drm_color_lut *lut = blob->data;
1152 int i, lut_size = drm_color_lut_size(blob);
1153 enum pipe pipe = crtc->pipe;
1154
1155 for (i = 0; i < lut_size; i++) {
1156 intel_de_write_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 0),
1157 chv_cgm_gamma_ldw(&lut[i]));
1158 intel_de_write_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 1),
1159 chv_cgm_gamma_udw(&lut[i]));
1160 }
1161 }
1162
chv_load_luts(const struct intel_crtc_state * crtc_state)1163 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
1164 {
1165 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1166 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1167 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
1168 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1169 const struct drm_property_blob *ctm = crtc_state->hw.ctm;
1170
1171 if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
1172 chv_load_cgm_csc(crtc, ctm);
1173
1174 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
1175 chv_load_cgm_degamma(crtc, degamma_lut);
1176
1177 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1178 chv_load_cgm_gamma(crtc, gamma_lut);
1179 else
1180 i965_load_luts(crtc_state);
1181
1182 intel_de_write_fw(dev_priv, CGM_PIPE_MODE(crtc->pipe),
1183 crtc_state->cgm_mode);
1184 }
1185
intel_color_load_luts(const struct intel_crtc_state * crtc_state)1186 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
1187 {
1188 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1189
1190 dev_priv->display.funcs.color->load_luts(crtc_state);
1191 }
1192
intel_color_commit_noarm(const struct intel_crtc_state * crtc_state)1193 void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state)
1194 {
1195 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1196
1197 if (dev_priv->display.funcs.color->color_commit_noarm)
1198 dev_priv->display.funcs.color->color_commit_noarm(crtc_state);
1199 }
1200
intel_color_commit_arm(const struct intel_crtc_state * crtc_state)1201 void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
1202 {
1203 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1204
1205 dev_priv->display.funcs.color->color_commit_arm(crtc_state);
1206 }
1207
intel_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1208 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1209 {
1210 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1211 struct intel_atomic_state *state =
1212 to_intel_atomic_state(new_crtc_state->uapi.state);
1213 const struct intel_crtc_state *old_crtc_state =
1214 intel_atomic_get_old_crtc_state(state, crtc);
1215
1216 return !old_crtc_state->hw.gamma_lut &&
1217 !old_crtc_state->hw.degamma_lut;
1218 }
1219
chv_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1220 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1221 {
1222 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1223 struct intel_atomic_state *state =
1224 to_intel_atomic_state(new_crtc_state->uapi.state);
1225 const struct intel_crtc_state *old_crtc_state =
1226 intel_atomic_get_old_crtc_state(state, crtc);
1227
1228 /*
1229 * CGM_PIPE_MODE is itself single buffered. We'd have to
1230 * somehow split it out from chv_load_luts() if we wanted
1231 * the ability to preload the CGM LUTs/CSC without tearing.
1232 */
1233 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1234 return false;
1235
1236 return !old_crtc_state->hw.gamma_lut;
1237 }
1238
glk_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1239 static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1240 {
1241 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1242 struct intel_atomic_state *state =
1243 to_intel_atomic_state(new_crtc_state->uapi.state);
1244 const struct intel_crtc_state *old_crtc_state =
1245 intel_atomic_get_old_crtc_state(state, crtc);
1246
1247 /*
1248 * The hardware degamma is active whenever the pipe
1249 * CSC is active. Thus even if the old state has no
1250 * software degamma we need to avoid clobbering the
1251 * linear hardware degamma mid scanout.
1252 */
1253 return !old_crtc_state->csc_enable &&
1254 !old_crtc_state->hw.gamma_lut;
1255 }
1256
intel_color_check(struct intel_crtc_state * crtc_state)1257 int intel_color_check(struct intel_crtc_state *crtc_state)
1258 {
1259 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1260
1261 return dev_priv->display.funcs.color->color_check(crtc_state);
1262 }
1263
intel_color_get_config(struct intel_crtc_state * crtc_state)1264 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1265 {
1266 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1267
1268 if (dev_priv->display.funcs.color->read_luts)
1269 dev_priv->display.funcs.color->read_luts(crtc_state);
1270 }
1271
need_plane_update(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)1272 static bool need_plane_update(struct intel_plane *plane,
1273 const struct intel_crtc_state *crtc_state)
1274 {
1275 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1276
1277 /*
1278 * On pre-SKL the pipe gamma enable and pipe csc enable for
1279 * the pipe bottom color are configured via the primary plane.
1280 * We have to reconfigure that even if the plane is inactive.
1281 */
1282 return crtc_state->active_planes & BIT(plane->id) ||
1283 (DISPLAY_VER(dev_priv) < 9 &&
1284 plane->id == PLANE_PRIMARY);
1285 }
1286
1287 static int
intel_color_add_affected_planes(struct intel_crtc_state * new_crtc_state)1288 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1289 {
1290 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1291 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1292 struct intel_atomic_state *state =
1293 to_intel_atomic_state(new_crtc_state->uapi.state);
1294 const struct intel_crtc_state *old_crtc_state =
1295 intel_atomic_get_old_crtc_state(state, crtc);
1296 struct intel_plane *plane;
1297
1298 if (!new_crtc_state->hw.active ||
1299 drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
1300 return 0;
1301
1302 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1303 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1304 return 0;
1305
1306 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
1307 struct intel_plane_state *plane_state;
1308
1309 if (!need_plane_update(plane, new_crtc_state))
1310 continue;
1311
1312 plane_state = intel_atomic_get_plane_state(state, plane);
1313 if (IS_ERR(plane_state))
1314 return PTR_ERR(plane_state);
1315
1316 new_crtc_state->update_planes |= BIT(plane->id);
1317 }
1318
1319 return 0;
1320 }
1321
check_lut_size(const struct drm_property_blob * lut,int expected)1322 static int check_lut_size(const struct drm_property_blob *lut, int expected)
1323 {
1324 int len;
1325
1326 if (!lut)
1327 return 0;
1328
1329 len = drm_color_lut_size(lut);
1330 if (len != expected) {
1331 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1332 len, expected);
1333 return -EINVAL;
1334 }
1335
1336 return 0;
1337 }
1338
check_luts(const struct intel_crtc_state * crtc_state)1339 static int check_luts(const struct intel_crtc_state *crtc_state)
1340 {
1341 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1342 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1343 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
1344 int gamma_length, degamma_length;
1345 u32 gamma_tests, degamma_tests;
1346
1347 /* Always allow legacy gamma LUT with no further checking. */
1348 if (crtc_state_is_legacy_gamma(crtc_state))
1349 return 0;
1350
1351 /* C8 relies on its palette being stored in the legacy LUT */
1352 if (crtc_state->c8_planes) {
1353 drm_dbg_kms(&dev_priv->drm,
1354 "C8 pixelformat requires the legacy LUT\n");
1355 return -EINVAL;
1356 }
1357
1358 degamma_length = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
1359 gamma_length = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1360 degamma_tests = INTEL_INFO(dev_priv)->display.color.degamma_lut_tests;
1361 gamma_tests = INTEL_INFO(dev_priv)->display.color.gamma_lut_tests;
1362
1363 if (check_lut_size(degamma_lut, degamma_length) ||
1364 check_lut_size(gamma_lut, gamma_length))
1365 return -EINVAL;
1366
1367 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
1368 drm_color_lut_check(gamma_lut, gamma_tests))
1369 return -EINVAL;
1370
1371 return 0;
1372 }
1373
i9xx_gamma_mode(struct intel_crtc_state * crtc_state)1374 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
1375 {
1376 if (!crtc_state->gamma_enable ||
1377 crtc_state_is_legacy_gamma(crtc_state))
1378 return GAMMA_MODE_MODE_8BIT;
1379 else
1380 return GAMMA_MODE_MODE_10BIT; /* i965+ only */
1381 }
1382
i9xx_color_check(struct intel_crtc_state * crtc_state)1383 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1384 {
1385 int ret;
1386
1387 ret = check_luts(crtc_state);
1388 if (ret)
1389 return ret;
1390
1391 crtc_state->gamma_enable =
1392 crtc_state->hw.gamma_lut &&
1393 !crtc_state->c8_planes;
1394
1395 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1396
1397 ret = intel_color_add_affected_planes(crtc_state);
1398 if (ret)
1399 return ret;
1400
1401 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1402
1403 return 0;
1404 }
1405
chv_cgm_mode(const struct intel_crtc_state * crtc_state)1406 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1407 {
1408 u32 cgm_mode = 0;
1409
1410 if (crtc_state_is_legacy_gamma(crtc_state))
1411 return 0;
1412
1413 if (crtc_state->hw.degamma_lut)
1414 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1415 if (crtc_state->hw.ctm)
1416 cgm_mode |= CGM_PIPE_MODE_CSC;
1417 if (crtc_state->hw.gamma_lut)
1418 cgm_mode |= CGM_PIPE_MODE_GAMMA;
1419
1420 return cgm_mode;
1421 }
1422
1423 /*
1424 * CHV color pipeline:
1425 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
1426 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
1427 *
1428 * We always bypass the WGC csc and use the CGM csc
1429 * instead since it has degamma and better precision.
1430 */
chv_color_check(struct intel_crtc_state * crtc_state)1431 static int chv_color_check(struct intel_crtc_state *crtc_state)
1432 {
1433 int ret;
1434
1435 ret = check_luts(crtc_state);
1436 if (ret)
1437 return ret;
1438
1439 /*
1440 * Pipe gamma will be used only for the legacy LUT.
1441 * Otherwise we bypass it and use the CGM gamma instead.
1442 */
1443 crtc_state->gamma_enable =
1444 crtc_state_is_legacy_gamma(crtc_state) &&
1445 !crtc_state->c8_planes;
1446
1447 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1448
1449 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1450
1451 ret = intel_color_add_affected_planes(crtc_state);
1452 if (ret)
1453 return ret;
1454
1455 crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
1456
1457 return 0;
1458 }
1459
ilk_gamma_mode(const struct intel_crtc_state * crtc_state)1460 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1461 {
1462 if (!crtc_state->gamma_enable ||
1463 crtc_state_is_legacy_gamma(crtc_state))
1464 return GAMMA_MODE_MODE_8BIT;
1465 else
1466 return GAMMA_MODE_MODE_10BIT;
1467 }
1468
ilk_csc_mode(const struct intel_crtc_state * crtc_state)1469 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
1470 {
1471 /*
1472 * CSC comes after the LUT in RGB->YCbCr mode.
1473 * RGB->YCbCr needs the limited range offsets added to
1474 * the output. RGB limited range output is handled by
1475 * the hw automagically elsewhere.
1476 */
1477 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
1478 return CSC_BLACK_SCREEN_OFFSET;
1479
1480 return CSC_MODE_YUV_TO_RGB |
1481 CSC_POSITION_BEFORE_GAMMA;
1482 }
1483
ilk_color_check(struct intel_crtc_state * crtc_state)1484 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1485 {
1486 int ret;
1487
1488 ret = check_luts(crtc_state);
1489 if (ret)
1490 return ret;
1491
1492 crtc_state->gamma_enable =
1493 crtc_state->hw.gamma_lut &&
1494 !crtc_state->c8_planes;
1495
1496 /*
1497 * We don't expose the ctm on ilk/snb currently, also RGB
1498 * limited range output is handled by the hw automagically.
1499 */
1500 crtc_state->csc_enable =
1501 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
1502
1503 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1504
1505 crtc_state->csc_mode = ilk_csc_mode(crtc_state);
1506
1507 ret = intel_color_add_affected_planes(crtc_state);
1508 if (ret)
1509 return ret;
1510
1511 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1512
1513 return 0;
1514 }
1515
ivb_gamma_mode(const struct intel_crtc_state * crtc_state)1516 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1517 {
1518 if (!crtc_state->gamma_enable ||
1519 crtc_state_is_legacy_gamma(crtc_state))
1520 return GAMMA_MODE_MODE_8BIT;
1521 else if (crtc_state->hw.gamma_lut &&
1522 crtc_state->hw.degamma_lut)
1523 return GAMMA_MODE_MODE_SPLIT;
1524 else
1525 return GAMMA_MODE_MODE_10BIT;
1526 }
1527
ivb_csc_mode(const struct intel_crtc_state * crtc_state)1528 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1529 {
1530 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1531
1532 /*
1533 * CSC comes after the LUT in degamma, RGB->YCbCr,
1534 * and RGB full->limited range mode.
1535 */
1536 if (crtc_state->hw.degamma_lut ||
1537 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1538 limited_color_range)
1539 return 0;
1540
1541 return CSC_POSITION_BEFORE_GAMMA;
1542 }
1543
ivb_color_check(struct intel_crtc_state * crtc_state)1544 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1545 {
1546 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1547 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1548 int ret;
1549
1550 ret = check_luts(crtc_state);
1551 if (ret)
1552 return ret;
1553
1554 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
1555 crtc_state->hw.ctm) {
1556 drm_dbg_kms(&dev_priv->drm,
1557 "YCBCR and CTM together are not possible\n");
1558 return -EINVAL;
1559 }
1560
1561 crtc_state->gamma_enable =
1562 (crtc_state->hw.gamma_lut ||
1563 crtc_state->hw.degamma_lut) &&
1564 !crtc_state->c8_planes;
1565
1566 crtc_state->csc_enable =
1567 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1568 crtc_state->hw.ctm || limited_color_range;
1569
1570 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1571
1572 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1573
1574 ret = intel_color_add_affected_planes(crtc_state);
1575 if (ret)
1576 return ret;
1577
1578 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1579
1580 return 0;
1581 }
1582
glk_gamma_mode(const struct intel_crtc_state * crtc_state)1583 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1584 {
1585 if (!crtc_state->gamma_enable ||
1586 crtc_state_is_legacy_gamma(crtc_state))
1587 return GAMMA_MODE_MODE_8BIT;
1588 else
1589 return GAMMA_MODE_MODE_10BIT;
1590 }
1591
glk_color_check(struct intel_crtc_state * crtc_state)1592 static int glk_color_check(struct intel_crtc_state *crtc_state)
1593 {
1594 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1595 int ret;
1596
1597 ret = check_luts(crtc_state);
1598 if (ret)
1599 return ret;
1600
1601 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
1602 crtc_state->hw.ctm) {
1603 drm_dbg_kms(&dev_priv->drm,
1604 "YCBCR and CTM together are not possible\n");
1605 return -EINVAL;
1606 }
1607
1608 crtc_state->gamma_enable =
1609 crtc_state->hw.gamma_lut &&
1610 !crtc_state->c8_planes;
1611
1612 /* On GLK+ degamma LUT is controlled by csc_enable */
1613 crtc_state->csc_enable =
1614 crtc_state->hw.degamma_lut ||
1615 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1616 crtc_state->hw.ctm || crtc_state->limited_color_range;
1617
1618 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1619
1620 crtc_state->csc_mode = 0;
1621
1622 ret = intel_color_add_affected_planes(crtc_state);
1623 if (ret)
1624 return ret;
1625
1626 crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
1627
1628 return 0;
1629 }
1630
icl_gamma_mode(const struct intel_crtc_state * crtc_state)1631 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1632 {
1633 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1634 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1635 u32 gamma_mode = 0;
1636
1637 if (crtc_state->hw.degamma_lut)
1638 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1639
1640 if (crtc_state->hw.gamma_lut &&
1641 !crtc_state->c8_planes)
1642 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1643
1644 if (!crtc_state->hw.gamma_lut ||
1645 crtc_state_is_legacy_gamma(crtc_state))
1646 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1647 /*
1648 * Enable 10bit gamma for D13
1649 * ToDo: Extend to Logarithmic Gamma once the new UAPI
1650 * is accepted and implemented by a userspace consumer
1651 */
1652 else if (DISPLAY_VER(i915) >= 13)
1653 gamma_mode |= GAMMA_MODE_MODE_10BIT;
1654 else
1655 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
1656
1657 return gamma_mode;
1658 }
1659
icl_csc_mode(const struct intel_crtc_state * crtc_state)1660 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1661 {
1662 u32 csc_mode = 0;
1663
1664 if (crtc_state->hw.ctm)
1665 csc_mode |= ICL_CSC_ENABLE;
1666
1667 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1668 crtc_state->limited_color_range)
1669 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1670
1671 return csc_mode;
1672 }
1673
icl_color_check(struct intel_crtc_state * crtc_state)1674 static int icl_color_check(struct intel_crtc_state *crtc_state)
1675 {
1676 int ret;
1677
1678 ret = check_luts(crtc_state);
1679 if (ret)
1680 return ret;
1681
1682 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1683
1684 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1685
1686 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1687
1688 return 0;
1689 }
1690
i9xx_gamma_precision(const struct intel_crtc_state * crtc_state)1691 static int i9xx_gamma_precision(const struct intel_crtc_state *crtc_state)
1692 {
1693 if (!crtc_state->gamma_enable)
1694 return 0;
1695
1696 switch (crtc_state->gamma_mode) {
1697 case GAMMA_MODE_MODE_8BIT:
1698 return 8;
1699 case GAMMA_MODE_MODE_10BIT:
1700 return 16;
1701 default:
1702 MISSING_CASE(crtc_state->gamma_mode);
1703 return 0;
1704 }
1705 }
1706
ilk_gamma_precision(const struct intel_crtc_state * crtc_state)1707 static int ilk_gamma_precision(const struct intel_crtc_state *crtc_state)
1708 {
1709 if (!crtc_state->gamma_enable)
1710 return 0;
1711
1712 if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
1713 return 0;
1714
1715 switch (crtc_state->gamma_mode) {
1716 case GAMMA_MODE_MODE_8BIT:
1717 return 8;
1718 case GAMMA_MODE_MODE_10BIT:
1719 return 10;
1720 default:
1721 MISSING_CASE(crtc_state->gamma_mode);
1722 return 0;
1723 }
1724 }
1725
chv_gamma_precision(const struct intel_crtc_state * crtc_state)1726 static int chv_gamma_precision(const struct intel_crtc_state *crtc_state)
1727 {
1728 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1729 return 10;
1730 else
1731 return i9xx_gamma_precision(crtc_state);
1732 }
1733
glk_gamma_precision(const struct intel_crtc_state * crtc_state)1734 static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
1735 {
1736 if (!crtc_state->gamma_enable)
1737 return 0;
1738
1739 switch (crtc_state->gamma_mode) {
1740 case GAMMA_MODE_MODE_8BIT:
1741 return 8;
1742 case GAMMA_MODE_MODE_10BIT:
1743 return 10;
1744 default:
1745 MISSING_CASE(crtc_state->gamma_mode);
1746 return 0;
1747 }
1748 }
1749
icl_gamma_precision(const struct intel_crtc_state * crtc_state)1750 static int icl_gamma_precision(const struct intel_crtc_state *crtc_state)
1751 {
1752 if ((crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE) == 0)
1753 return 0;
1754
1755 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
1756 case GAMMA_MODE_MODE_8BIT:
1757 return 8;
1758 case GAMMA_MODE_MODE_10BIT:
1759 return 10;
1760 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
1761 return 16;
1762 default:
1763 MISSING_CASE(crtc_state->gamma_mode);
1764 return 0;
1765 }
1766 }
1767
intel_color_get_gamma_bit_precision(const struct intel_crtc_state * crtc_state)1768 int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
1769 {
1770 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1771 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1772
1773 if (HAS_GMCH(dev_priv)) {
1774 if (IS_CHERRYVIEW(dev_priv))
1775 return chv_gamma_precision(crtc_state);
1776 else
1777 return i9xx_gamma_precision(crtc_state);
1778 } else {
1779 if (DISPLAY_VER(dev_priv) >= 11)
1780 return icl_gamma_precision(crtc_state);
1781 else if (DISPLAY_VER(dev_priv) == 10)
1782 return glk_gamma_precision(crtc_state);
1783 else if (IS_IRONLAKE(dev_priv))
1784 return ilk_gamma_precision(crtc_state);
1785 }
1786
1787 return 0;
1788 }
1789
err_check(struct drm_color_lut * lut1,struct drm_color_lut * lut2,u32 err)1790 static bool err_check(struct drm_color_lut *lut1,
1791 struct drm_color_lut *lut2, u32 err)
1792 {
1793 return ((abs((long)lut2->red - lut1->red)) <= err) &&
1794 ((abs((long)lut2->blue - lut1->blue)) <= err) &&
1795 ((abs((long)lut2->green - lut1->green)) <= err);
1796 }
1797
intel_color_lut_entries_equal(struct drm_color_lut * lut1,struct drm_color_lut * lut2,int lut_size,u32 err)1798 static bool intel_color_lut_entries_equal(struct drm_color_lut *lut1,
1799 struct drm_color_lut *lut2,
1800 int lut_size, u32 err)
1801 {
1802 int i;
1803
1804 for (i = 0; i < lut_size; i++) {
1805 if (!err_check(&lut1[i], &lut2[i], err))
1806 return false;
1807 }
1808
1809 return true;
1810 }
1811
intel_color_lut_equal(struct drm_property_blob * blob1,struct drm_property_blob * blob2,u32 gamma_mode,u32 bit_precision)1812 bool intel_color_lut_equal(struct drm_property_blob *blob1,
1813 struct drm_property_blob *blob2,
1814 u32 gamma_mode, u32 bit_precision)
1815 {
1816 struct drm_color_lut *lut1, *lut2;
1817 int lut_size1, lut_size2;
1818 u32 err;
1819
1820 if (!blob1 != !blob2)
1821 return false;
1822
1823 if (!blob1)
1824 return true;
1825
1826 lut_size1 = drm_color_lut_size(blob1);
1827 lut_size2 = drm_color_lut_size(blob2);
1828
1829 /* check sw and hw lut size */
1830 if (lut_size1 != lut_size2)
1831 return false;
1832
1833 lut1 = blob1->data;
1834 lut2 = blob2->data;
1835
1836 err = 0xffff >> bit_precision;
1837
1838 /* check sw and hw lut entry to be equal */
1839 switch (gamma_mode & GAMMA_MODE_MODE_MASK) {
1840 case GAMMA_MODE_MODE_8BIT:
1841 case GAMMA_MODE_MODE_10BIT:
1842 if (!intel_color_lut_entries_equal(lut1, lut2,
1843 lut_size2, err))
1844 return false;
1845 break;
1846 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
1847 if (!intel_color_lut_entries_equal(lut1, lut2,
1848 9, err))
1849 return false;
1850 break;
1851 default:
1852 MISSING_CASE(gamma_mode);
1853 return false;
1854 }
1855
1856 return true;
1857 }
1858
i9xx_read_lut_8(struct intel_crtc * crtc)1859 static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)
1860 {
1861 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1862 enum pipe pipe = crtc->pipe;
1863 struct drm_property_blob *blob;
1864 struct drm_color_lut *lut;
1865 int i;
1866
1867 blob = drm_property_create_blob(&dev_priv->drm,
1868 sizeof(struct drm_color_lut) * LEGACY_LUT_LENGTH,
1869 NULL);
1870 if (IS_ERR(blob))
1871 return NULL;
1872
1873 lut = blob->data;
1874
1875 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
1876 u32 val = intel_de_read_fw(dev_priv, PALETTE(pipe, i));
1877
1878 i9xx_lut_8_pack(&lut[i], val);
1879 }
1880
1881 return blob;
1882 }
1883
i9xx_read_luts(struct intel_crtc_state * crtc_state)1884 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
1885 {
1886 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1887
1888 if (!crtc_state->gamma_enable)
1889 return;
1890
1891 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
1892 }
1893
i965_read_lut_10p6(struct intel_crtc * crtc)1894 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
1895 {
1896 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1897 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1898 enum pipe pipe = crtc->pipe;
1899 struct drm_property_blob *blob;
1900 struct drm_color_lut *lut;
1901
1902 blob = drm_property_create_blob(&dev_priv->drm,
1903 sizeof(struct drm_color_lut) * lut_size,
1904 NULL);
1905 if (IS_ERR(blob))
1906 return NULL;
1907
1908 lut = blob->data;
1909
1910 for (i = 0; i < lut_size - 1; i++) {
1911 u32 ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
1912 u32 udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
1913
1914 i965_lut_10p6_pack(&lut[i], ldw, udw);
1915 }
1916
1917 lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
1918 lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
1919 lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
1920
1921 return blob;
1922 }
1923
i965_read_luts(struct intel_crtc_state * crtc_state)1924 static void i965_read_luts(struct intel_crtc_state *crtc_state)
1925 {
1926 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1927
1928 if (!crtc_state->gamma_enable)
1929 return;
1930
1931 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
1932 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
1933 else
1934 crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc);
1935 }
1936
chv_read_cgm_gamma(struct intel_crtc * crtc)1937 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
1938 {
1939 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1940 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1941 enum pipe pipe = crtc->pipe;
1942 struct drm_property_blob *blob;
1943 struct drm_color_lut *lut;
1944
1945 blob = drm_property_create_blob(&dev_priv->drm,
1946 sizeof(struct drm_color_lut) * lut_size,
1947 NULL);
1948 if (IS_ERR(blob))
1949 return NULL;
1950
1951 lut = blob->data;
1952
1953 for (i = 0; i < lut_size; i++) {
1954 u32 ldw = intel_de_read_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 0));
1955 u32 udw = intel_de_read_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 1));
1956
1957 chv_cgm_gamma_pack(&lut[i], ldw, udw);
1958 }
1959
1960 return blob;
1961 }
1962
chv_read_luts(struct intel_crtc_state * crtc_state)1963 static void chv_read_luts(struct intel_crtc_state *crtc_state)
1964 {
1965 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1966
1967 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1968 crtc_state->hw.gamma_lut = chv_read_cgm_gamma(crtc);
1969 else
1970 i965_read_luts(crtc_state);
1971 }
1972
ilk_read_lut_8(struct intel_crtc * crtc)1973 static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc)
1974 {
1975 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1976 enum pipe pipe = crtc->pipe;
1977 struct drm_property_blob *blob;
1978 struct drm_color_lut *lut;
1979 int i;
1980
1981 blob = drm_property_create_blob(&dev_priv->drm,
1982 sizeof(struct drm_color_lut) * LEGACY_LUT_LENGTH,
1983 NULL);
1984 if (IS_ERR(blob))
1985 return NULL;
1986
1987 lut = blob->data;
1988
1989 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
1990 u32 val = intel_de_read_fw(dev_priv, LGC_PALETTE(pipe, i));
1991
1992 i9xx_lut_8_pack(&lut[i], val);
1993 }
1994
1995 return blob;
1996 }
1997
ilk_read_lut_10(struct intel_crtc * crtc)1998 static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc)
1999 {
2000 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2001 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
2002 enum pipe pipe = crtc->pipe;
2003 struct drm_property_blob *blob;
2004 struct drm_color_lut *lut;
2005
2006 blob = drm_property_create_blob(&dev_priv->drm,
2007 sizeof(struct drm_color_lut) * lut_size,
2008 NULL);
2009 if (IS_ERR(blob))
2010 return NULL;
2011
2012 lut = blob->data;
2013
2014 for (i = 0; i < lut_size; i++) {
2015 u32 val = intel_de_read_fw(dev_priv, PREC_PALETTE(pipe, i));
2016
2017 ilk_lut_10_pack(&lut[i], val);
2018 }
2019
2020 return blob;
2021 }
2022
ilk_read_luts(struct intel_crtc_state * crtc_state)2023 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
2024 {
2025 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2026
2027 if (!crtc_state->gamma_enable)
2028 return;
2029
2030 if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
2031 return;
2032
2033 switch (crtc_state->gamma_mode) {
2034 case GAMMA_MODE_MODE_8BIT:
2035 crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
2036 break;
2037 case GAMMA_MODE_MODE_10BIT:
2038 crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc);
2039 break;
2040 default:
2041 MISSING_CASE(crtc_state->gamma_mode);
2042 break;
2043 }
2044 }
2045
2046 /* On BDW+ the index auto increment mode actually works */
bdw_read_lut_10(struct intel_crtc * crtc,u32 prec_index)2047 static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
2048 u32 prec_index)
2049 {
2050 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2051 int i, hw_lut_size = ivb_lut_10_size(prec_index);
2052 int lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
2053 enum pipe pipe = crtc->pipe;
2054 struct drm_property_blob *blob;
2055 struct drm_color_lut *lut;
2056
2057 drm_WARN_ON(&dev_priv->drm, lut_size != hw_lut_size);
2058
2059 blob = drm_property_create_blob(&dev_priv->drm,
2060 sizeof(struct drm_color_lut) * lut_size,
2061 NULL);
2062 if (IS_ERR(blob))
2063 return NULL;
2064
2065 lut = blob->data;
2066
2067 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
2068 prec_index | PAL_PREC_AUTO_INCREMENT);
2069
2070 for (i = 0; i < lut_size; i++) {
2071 u32 val = intel_de_read_fw(dev_priv, PREC_PAL_DATA(pipe));
2072
2073 ilk_lut_10_pack(&lut[i], val);
2074 }
2075
2076 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), 0);
2077
2078 return blob;
2079 }
2080
glk_read_luts(struct intel_crtc_state * crtc_state)2081 static void glk_read_luts(struct intel_crtc_state *crtc_state)
2082 {
2083 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2084
2085 if (!crtc_state->gamma_enable)
2086 return;
2087
2088 switch (crtc_state->gamma_mode) {
2089 case GAMMA_MODE_MODE_8BIT:
2090 crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
2091 break;
2092 case GAMMA_MODE_MODE_10BIT:
2093 crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
2094 break;
2095 default:
2096 MISSING_CASE(crtc_state->gamma_mode);
2097 break;
2098 }
2099 }
2100
icl_color_commit_arm(const struct intel_crtc_state * crtc_state)2101 static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state)
2102 {
2103 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2104 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2105 enum pipe pipe = crtc->pipe;
2106
2107 /*
2108 * We don't (yet) allow userspace to control the pipe background color,
2109 * so force it to black.
2110 */
2111 intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0);
2112
2113 intel_de_write(i915, GAMMA_MODE(crtc->pipe),
2114 crtc_state->gamma_mode);
2115
2116 intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
2117 crtc_state->csc_mode);
2118 }
2119
2120 static struct drm_property_blob *
icl_read_lut_multi_segment(struct intel_crtc * crtc)2121 icl_read_lut_multi_segment(struct intel_crtc *crtc)
2122 {
2123 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2124 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
2125 enum pipe pipe = crtc->pipe;
2126 struct drm_property_blob *blob;
2127 struct drm_color_lut *lut;
2128
2129 blob = drm_property_create_blob(&dev_priv->drm,
2130 sizeof(struct drm_color_lut) * lut_size,
2131 NULL);
2132 if (IS_ERR(blob))
2133 return NULL;
2134
2135 lut = blob->data;
2136
2137 intel_de_write_fw(dev_priv, PREC_PAL_MULTI_SEG_INDEX(pipe),
2138 PAL_PREC_AUTO_INCREMENT);
2139
2140 for (i = 0; i < 9; i++) {
2141 u32 ldw = intel_de_read_fw(dev_priv, PREC_PAL_MULTI_SEG_DATA(pipe));
2142 u32 udw = intel_de_read_fw(dev_priv, PREC_PAL_MULTI_SEG_DATA(pipe));
2143
2144 icl_lut_multi_seg_pack(&lut[i], ldw, udw);
2145 }
2146
2147 intel_de_write_fw(dev_priv, PREC_PAL_MULTI_SEG_INDEX(pipe), 0);
2148
2149 /*
2150 * FIXME readouts from PAL_PREC_DATA register aren't giving
2151 * correct values in the case of fine and coarse segments.
2152 * Restricting readouts only for super fine segment as of now.
2153 */
2154
2155 return blob;
2156 }
2157
icl_read_luts(struct intel_crtc_state * crtc_state)2158 static void icl_read_luts(struct intel_crtc_state *crtc_state)
2159 {
2160 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2161
2162 if ((crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE) == 0)
2163 return;
2164
2165 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
2166 case GAMMA_MODE_MODE_8BIT:
2167 crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
2168 break;
2169 case GAMMA_MODE_MODE_10BIT:
2170 crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
2171 break;
2172 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
2173 crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
2174 break;
2175 default:
2176 MISSING_CASE(crtc_state->gamma_mode);
2177 break;
2178 }
2179 }
2180
2181 static const struct intel_color_funcs chv_color_funcs = {
2182 .color_check = chv_color_check,
2183 .color_commit_arm = i9xx_color_commit_arm,
2184 .load_luts = chv_load_luts,
2185 .read_luts = chv_read_luts,
2186 };
2187
2188 static const struct intel_color_funcs i965_color_funcs = {
2189 .color_check = i9xx_color_check,
2190 .color_commit_arm = i9xx_color_commit_arm,
2191 .load_luts = i965_load_luts,
2192 .read_luts = i965_read_luts,
2193 };
2194
2195 static const struct intel_color_funcs i9xx_color_funcs = {
2196 .color_check = i9xx_color_check,
2197 .color_commit_arm = i9xx_color_commit_arm,
2198 .load_luts = i9xx_load_luts,
2199 .read_luts = i9xx_read_luts,
2200 };
2201
2202 static const struct intel_color_funcs icl_color_funcs = {
2203 .color_check = icl_color_check,
2204 .color_commit_noarm = icl_color_commit_noarm,
2205 .color_commit_arm = icl_color_commit_arm,
2206 .load_luts = icl_load_luts,
2207 .read_luts = icl_read_luts,
2208 };
2209
2210 static const struct intel_color_funcs glk_color_funcs = {
2211 .color_check = glk_color_check,
2212 .color_commit_noarm = skl_color_commit_noarm,
2213 .color_commit_arm = skl_color_commit_arm,
2214 .load_luts = glk_load_luts,
2215 .read_luts = glk_read_luts,
2216 };
2217
2218 static const struct intel_color_funcs skl_color_funcs = {
2219 .color_check = ivb_color_check,
2220 .color_commit_noarm = skl_color_commit_noarm,
2221 .color_commit_arm = skl_color_commit_arm,
2222 .load_luts = bdw_load_luts,
2223 .read_luts = NULL,
2224 };
2225
2226 static const struct intel_color_funcs bdw_color_funcs = {
2227 .color_check = ivb_color_check,
2228 .color_commit_noarm = ilk_color_commit_noarm,
2229 .color_commit_arm = hsw_color_commit_arm,
2230 .load_luts = bdw_load_luts,
2231 .read_luts = NULL,
2232 };
2233
2234 static const struct intel_color_funcs hsw_color_funcs = {
2235 .color_check = ivb_color_check,
2236 .color_commit_noarm = ilk_color_commit_noarm,
2237 .color_commit_arm = hsw_color_commit_arm,
2238 .load_luts = ivb_load_luts,
2239 .read_luts = NULL,
2240 };
2241
2242 static const struct intel_color_funcs ivb_color_funcs = {
2243 .color_check = ivb_color_check,
2244 .color_commit_noarm = ilk_color_commit_noarm,
2245 .color_commit_arm = ilk_color_commit_arm,
2246 .load_luts = ivb_load_luts,
2247 .read_luts = NULL,
2248 };
2249
2250 static const struct intel_color_funcs ilk_color_funcs = {
2251 .color_check = ilk_color_check,
2252 .color_commit_noarm = ilk_color_commit_noarm,
2253 .color_commit_arm = ilk_color_commit_arm,
2254 .load_luts = ilk_load_luts,
2255 .read_luts = ilk_read_luts,
2256 };
2257
intel_color_init(struct intel_crtc * crtc)2258 void intel_color_init(struct intel_crtc *crtc)
2259 {
2260 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2261 bool has_ctm = INTEL_INFO(dev_priv)->display.color.degamma_lut_size != 0;
2262
2263 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
2264
2265 if (HAS_GMCH(dev_priv)) {
2266 if (IS_CHERRYVIEW(dev_priv)) {
2267 dev_priv->display.funcs.color = &chv_color_funcs;
2268 } else if (DISPLAY_VER(dev_priv) >= 4) {
2269 dev_priv->display.funcs.color = &i965_color_funcs;
2270 } else {
2271 dev_priv->display.funcs.color = &i9xx_color_funcs;
2272 }
2273 } else {
2274 if (DISPLAY_VER(dev_priv) >= 11)
2275 dev_priv->display.funcs.color = &icl_color_funcs;
2276 else if (DISPLAY_VER(dev_priv) == 10)
2277 dev_priv->display.funcs.color = &glk_color_funcs;
2278 else if (DISPLAY_VER(dev_priv) == 9)
2279 dev_priv->display.funcs.color = &skl_color_funcs;
2280 else if (DISPLAY_VER(dev_priv) == 8)
2281 dev_priv->display.funcs.color = &bdw_color_funcs;
2282 else if (DISPLAY_VER(dev_priv) == 7) {
2283 if (IS_HASWELL(dev_priv))
2284 dev_priv->display.funcs.color = &hsw_color_funcs;
2285 else
2286 dev_priv->display.funcs.color = &ivb_color_funcs;
2287 } else
2288 dev_priv->display.funcs.color = &ilk_color_funcs;
2289 }
2290
2291 drm_crtc_enable_color_mgmt(&crtc->base,
2292 INTEL_INFO(dev_priv)->display.color.degamma_lut_size,
2293 has_ctm,
2294 INTEL_INFO(dev_priv)->display.color.gamma_lut_size);
2295 }
2296