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
ilk_color_commit_noarm(const struct intel_crtc_state * crtc_state)502 static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
503 {
504 ilk_load_csc_matrix(crtc_state);
505 }
506
i9xx_color_commit_arm(const struct intel_crtc_state * crtc_state)507 static void i9xx_color_commit_arm(const struct intel_crtc_state *crtc_state)
508 {
509 /* update PIPECONF GAMMA_MODE */
510 i9xx_set_pipeconf(crtc_state);
511 }
512
ilk_color_commit_arm(const struct intel_crtc_state * crtc_state)513 static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state)
514 {
515 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
516 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
517
518 /* update PIPECONF GAMMA_MODE */
519 ilk_set_pipeconf(crtc_state);
520
521 intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
522 crtc_state->csc_mode);
523 }
524
hsw_color_commit_arm(const struct intel_crtc_state * crtc_state)525 static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state)
526 {
527 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
528 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
529
530 intel_de_write(dev_priv, GAMMA_MODE(crtc->pipe),
531 crtc_state->gamma_mode);
532
533 intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
534 crtc_state->csc_mode);
535 }
536
skl_color_commit_arm(const struct intel_crtc_state * crtc_state)537 static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
538 {
539 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
540 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
541 enum pipe pipe = crtc->pipe;
542 u32 val = 0;
543
544 /*
545 * We don't (yet) allow userspace to control the pipe background color,
546 * so force it to black, but apply pipe gamma and CSC appropriately
547 * so that its handling will match how we program our planes.
548 */
549 if (crtc_state->gamma_enable)
550 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
551 if (crtc_state->csc_enable)
552 val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
553 intel_de_write(dev_priv, SKL_BOTTOM_COLOR(pipe), val);
554
555 intel_de_write(dev_priv, GAMMA_MODE(crtc->pipe),
556 crtc_state->gamma_mode);
557
558 intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
559 crtc_state->csc_mode);
560 }
561
i9xx_load_lut_8(struct intel_crtc * crtc,const struct drm_property_blob * blob)562 static void i9xx_load_lut_8(struct intel_crtc *crtc,
563 const struct drm_property_blob *blob)
564 {
565 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
566 const struct drm_color_lut *lut;
567 enum pipe pipe = crtc->pipe;
568 int i;
569
570 if (!blob)
571 return;
572
573 lut = blob->data;
574
575 for (i = 0; i < 256; i++)
576 intel_de_write_fw(dev_priv, PALETTE(pipe, i),
577 i9xx_lut_8(&lut[i]));
578 }
579
i9xx_load_luts(const struct intel_crtc_state * crtc_state)580 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
581 {
582 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
583 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
584 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
585
586 assert_pll_enabled(dev_priv, crtc->pipe);
587
588 i9xx_load_lut_8(crtc, gamma_lut);
589 }
590
i965_load_lut_10p6(struct intel_crtc * crtc,const struct drm_property_blob * blob)591 static void i965_load_lut_10p6(struct intel_crtc *crtc,
592 const struct drm_property_blob *blob)
593 {
594 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
595 const struct drm_color_lut *lut = blob->data;
596 int i, lut_size = drm_color_lut_size(blob);
597 enum pipe pipe = crtc->pipe;
598
599 for (i = 0; i < lut_size - 1; i++) {
600 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 0),
601 i965_lut_10p6_ldw(&lut[i]));
602 intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 1),
603 i965_lut_10p6_udw(&lut[i]));
604 }
605
606 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 0), lut[i].red);
607 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 1), lut[i].green);
608 intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 2), lut[i].blue);
609 }
610
i965_load_luts(const struct intel_crtc_state * crtc_state)611 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
612 {
613 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
614 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
615 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
616
617 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
618 assert_dsi_pll_enabled(dev_priv);
619 else
620 assert_pll_enabled(dev_priv, crtc->pipe);
621
622 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
623 i9xx_load_lut_8(crtc, gamma_lut);
624 else
625 i965_load_lut_10p6(crtc, gamma_lut);
626 }
627
ilk_load_lut_8(struct intel_crtc * crtc,const struct drm_property_blob * blob)628 static void ilk_load_lut_8(struct intel_crtc *crtc,
629 const struct drm_property_blob *blob)
630 {
631 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
632 const struct drm_color_lut *lut;
633 enum pipe pipe = crtc->pipe;
634 int i;
635
636 if (!blob)
637 return;
638
639 lut = blob->data;
640
641 for (i = 0; i < 256; i++)
642 intel_de_write_fw(dev_priv, LGC_PALETTE(pipe, i),
643 i9xx_lut_8(&lut[i]));
644 }
645
ilk_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob)646 static void ilk_load_lut_10(struct intel_crtc *crtc,
647 const struct drm_property_blob *blob)
648 {
649 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
650 const struct drm_color_lut *lut = blob->data;
651 int i, lut_size = drm_color_lut_size(blob);
652 enum pipe pipe = crtc->pipe;
653
654 for (i = 0; i < lut_size; i++)
655 intel_de_write_fw(dev_priv, PREC_PALETTE(pipe, i),
656 ilk_lut_10(&lut[i]));
657 }
658
ilk_load_luts(const struct intel_crtc_state * crtc_state)659 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
660 {
661 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
662 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
663
664 switch (crtc_state->gamma_mode) {
665 case GAMMA_MODE_MODE_8BIT:
666 ilk_load_lut_8(crtc, gamma_lut);
667 break;
668 case GAMMA_MODE_MODE_10BIT:
669 ilk_load_lut_10(crtc, gamma_lut);
670 break;
671 default:
672 MISSING_CASE(crtc_state->gamma_mode);
673 break;
674 }
675 }
676
ivb_lut_10_size(u32 prec_index)677 static int ivb_lut_10_size(u32 prec_index)
678 {
679 if (prec_index & PAL_PREC_SPLIT_MODE)
680 return 512;
681 else
682 return 1024;
683 }
684
685 /*
686 * IVB/HSW Bspec / PAL_PREC_INDEX:
687 * "Restriction : Index auto increment mode is not
688 * supported and must not be enabled."
689 */
ivb_load_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob,u32 prec_index)690 static void ivb_load_lut_10(struct intel_crtc *crtc,
691 const struct drm_property_blob *blob,
692 u32 prec_index)
693 {
694 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
695 int hw_lut_size = ivb_lut_10_size(prec_index);
696 const struct drm_color_lut *lut = blob->data;
697 int i, lut_size = drm_color_lut_size(blob);
698 enum pipe pipe = crtc->pipe;
699
700 for (i = 0; i < hw_lut_size; i++) {
701 /* We discard half the user entries in split gamma mode */
702 const struct drm_color_lut *entry =
703 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
704
705 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), prec_index++);
706 intel_de_write_fw(dev_priv, PREC_PAL_DATA(pipe),
707 ilk_lut_10(entry));
708 }
709
710 /*
711 * Reset the index, otherwise it prevents the legacy palette to be
712 * written properly.
713 */
714 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), 0);
715 }
716
717 /* 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)718 static void bdw_load_lut_10(struct intel_crtc *crtc,
719 const struct drm_property_blob *blob,
720 u32 prec_index)
721 {
722 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
723 int hw_lut_size = ivb_lut_10_size(prec_index);
724 const struct drm_color_lut *lut = blob->data;
725 int i, lut_size = drm_color_lut_size(blob);
726 enum pipe pipe = crtc->pipe;
727
728 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
729 prec_index | PAL_PREC_AUTO_INCREMENT);
730
731 for (i = 0; i < hw_lut_size; i++) {
732 /* We discard half the user entries in split gamma mode */
733 const struct drm_color_lut *entry =
734 &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
735
736 intel_de_write_fw(dev_priv, PREC_PAL_DATA(pipe),
737 ilk_lut_10(entry));
738 }
739
740 /*
741 * Reset the index, otherwise it prevents the legacy palette to be
742 * written properly.
743 */
744 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), 0);
745 }
746
ivb_load_lut_ext_max(const struct intel_crtc_state * crtc_state)747 static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
748 {
749 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
750 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
751 enum pipe pipe = crtc->pipe;
752
753 /* Program the max register to clamp values > 1.0. */
754 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
755 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
756 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
757
758 /*
759 * Program the gc max 2 register to clamp values > 1.0.
760 * ToDo: Extend the ABI to be able to program values
761 * from 3.0 to 7.0
762 */
763 if (DISPLAY_VER(dev_priv) >= 10) {
764 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 0),
765 1 << 16);
766 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 1),
767 1 << 16);
768 intel_dsb_reg_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 2),
769 1 << 16);
770 }
771 }
772
ivb_load_luts(const struct intel_crtc_state * crtc_state)773 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
774 {
775 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
776 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
777 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
778 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
779
780 switch (crtc_state->gamma_mode) {
781 case GAMMA_MODE_MODE_8BIT:
782 ilk_load_lut_8(crtc, blob);
783 break;
784 case GAMMA_MODE_MODE_SPLIT:
785 ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
786 PAL_PREC_INDEX_VALUE(0));
787 ivb_load_lut_ext_max(crtc_state);
788 ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
789 PAL_PREC_INDEX_VALUE(512));
790 break;
791 case GAMMA_MODE_MODE_10BIT:
792 ivb_load_lut_10(crtc, blob,
793 PAL_PREC_INDEX_VALUE(0));
794 ivb_load_lut_ext_max(crtc_state);
795 break;
796 default:
797 MISSING_CASE(crtc_state->gamma_mode);
798 break;
799 }
800 }
801
bdw_load_luts(const struct intel_crtc_state * crtc_state)802 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
803 {
804 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
805 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
806 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
807 const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
808
809 switch (crtc_state->gamma_mode) {
810 case GAMMA_MODE_MODE_8BIT:
811 ilk_load_lut_8(crtc, blob);
812 break;
813 case GAMMA_MODE_MODE_SPLIT:
814 bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
815 PAL_PREC_INDEX_VALUE(0));
816 ivb_load_lut_ext_max(crtc_state);
817 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
818 PAL_PREC_INDEX_VALUE(512));
819 break;
820 case GAMMA_MODE_MODE_10BIT:
821
822 bdw_load_lut_10(crtc, blob,
823 PAL_PREC_INDEX_VALUE(0));
824 ivb_load_lut_ext_max(crtc_state);
825 break;
826 default:
827 MISSING_CASE(crtc_state->gamma_mode);
828 break;
829 }
830 }
831
glk_degamma_lut_size(struct drm_i915_private * i915)832 static int glk_degamma_lut_size(struct drm_i915_private *i915)
833 {
834 if (DISPLAY_VER(i915) >= 13)
835 return 131;
836 else
837 return 35;
838 }
839
glk_load_degamma_lut(const struct intel_crtc_state * crtc_state)840 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
841 {
842 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
843 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
844 enum pipe pipe = crtc->pipe;
845 int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
846 const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
847
848 /*
849 * When setting the auto-increment bit, the hardware seems to
850 * ignore the index bits, so we need to reset it to index 0
851 * separately.
852 */
853 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
854 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
855 PRE_CSC_GAMC_AUTO_INCREMENT);
856
857 for (i = 0; i < lut_size; i++) {
858 /*
859 * First lut_size entries represent range from 0 to 1.0
860 * 3 additional lut entries will represent extended range
861 * inputs 3.0 and 7.0 respectively, currently clamped
862 * at 1.0. Since the precision is 16bit, the user
863 * value can be directly filled to register.
864 * The pipe degamma table in GLK+ onwards doesn't
865 * support different values per channel, so this just
866 * programs green value which will be equal to Red and
867 * Blue into the lut registers.
868 * ToDo: Extend to max 7.0. Enable 32 bit input value
869 * as compared to just 16 to achieve this.
870 */
871 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe),
872 lut[i].green);
873 }
874
875 /* Clamp values > 1.0. */
876 while (i++ < glk_degamma_lut_size(dev_priv))
877 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
878
879 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
880 }
881
glk_load_degamma_lut_linear(const struct intel_crtc_state * crtc_state)882 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
883 {
884 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
885 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
886 enum pipe pipe = crtc->pipe;
887 int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
888
889 /*
890 * When setting the auto-increment bit, the hardware seems to
891 * ignore the index bits, so we need to reset it to index 0
892 * separately.
893 */
894 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
895 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
896 PRE_CSC_GAMC_AUTO_INCREMENT);
897
898 for (i = 0; i < lut_size; i++) {
899 u32 v = (i << 16) / (lut_size - 1);
900
901 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), v);
902 }
903
904 /* Clamp values > 1.0. */
905 while (i++ < 35)
906 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
907
908 intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
909 }
910
glk_load_luts(const struct intel_crtc_state * crtc_state)911 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
912 {
913 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
914 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
915
916 /*
917 * On GLK+ both pipe CSC and degamma LUT are controlled
918 * by csc_enable. Hence for the cases where the CSC is
919 * needed but degamma LUT is not we need to load a
920 * linear degamma LUT. In fact we'll just always load
921 * the degama LUT so that we don't have to reload
922 * it every time the pipe CSC is being enabled.
923 */
924 if (crtc_state->hw.degamma_lut)
925 glk_load_degamma_lut(crtc_state);
926 else
927 glk_load_degamma_lut_linear(crtc_state);
928
929 switch (crtc_state->gamma_mode) {
930 case GAMMA_MODE_MODE_8BIT:
931 ilk_load_lut_8(crtc, gamma_lut);
932 break;
933 case GAMMA_MODE_MODE_10BIT:
934 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
935 ivb_load_lut_ext_max(crtc_state);
936 break;
937 default:
938 MISSING_CASE(crtc_state->gamma_mode);
939 break;
940 }
941 }
942
943 /* ilk+ "12.4" interpolated format (high 10 bits) */
ilk_lut_12p4_udw(const struct drm_color_lut * color)944 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
945 {
946 return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
947 (color->blue >> 6);
948 }
949
950 /* ilk+ "12.4" interpolated format (low 6 bits) */
ilk_lut_12p4_ldw(const struct drm_color_lut * color)951 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
952 {
953 return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
954 (color->blue & 0x3f) << 4;
955 }
956
957 static void
icl_load_gcmax(const struct intel_crtc_state * crtc_state,const struct drm_color_lut * color)958 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
959 const struct drm_color_lut *color)
960 {
961 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
962 enum pipe pipe = crtc->pipe;
963
964 /* FIXME LUT entries are 16 bit only, so we can prog 0xFFFF max */
965 intel_dsb_reg_write(crtc_state, PREC_PAL_GC_MAX(pipe, 0), color->red);
966 intel_dsb_reg_write(crtc_state, PREC_PAL_GC_MAX(pipe, 1), color->green);
967 intel_dsb_reg_write(crtc_state, PREC_PAL_GC_MAX(pipe, 2), color->blue);
968 }
969
970 static void
icl_program_gamma_superfine_segment(const struct intel_crtc_state * crtc_state)971 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
972 {
973 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
974 const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
975 const struct drm_color_lut *lut = blob->data;
976 enum pipe pipe = crtc->pipe;
977 int i;
978
979 /*
980 * Program Super Fine segment (let's call it seg1)...
981 *
982 * Super Fine segment's step is 1/(8 * 128 * 256) and it has
983 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256),
984 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256).
985 */
986 intel_dsb_reg_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
987 PAL_PREC_AUTO_INCREMENT);
988
989 for (i = 0; i < 9; i++) {
990 const struct drm_color_lut *entry = &lut[i];
991
992 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
993 ilk_lut_12p4_ldw(entry));
994 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
995 ilk_lut_12p4_udw(entry));
996 }
997 }
998
999 static void
icl_program_gamma_multi_segment(const struct intel_crtc_state * crtc_state)1000 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
1001 {
1002 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1003 const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
1004 const struct drm_color_lut *lut = blob->data;
1005 const struct drm_color_lut *entry;
1006 enum pipe pipe = crtc->pipe;
1007 int i;
1008
1009 /*
1010 * Program Fine segment (let's call it seg2)...
1011 *
1012 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256)
1013 * ... 256/(128 * 256). So in order to program fine segment of LUT we
1014 * need to pick every 8th entry in the LUT, and program 256 indexes.
1015 *
1016 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
1017 * seg2[0] being unused by the hardware.
1018 */
1019 intel_dsb_reg_write(crtc_state, PREC_PAL_INDEX(pipe),
1020 PAL_PREC_AUTO_INCREMENT);
1021 for (i = 1; i < 257; i++) {
1022 entry = &lut[i * 8];
1023 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1024 ilk_lut_12p4_ldw(entry));
1025 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1026 ilk_lut_12p4_udw(entry));
1027 }
1028
1029 /*
1030 * Program Coarse segment (let's call it seg3)...
1031 *
1032 * Coarse segment starts from index 0 and it's step is 1/256 ie 0,
1033 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT
1034 * above, we need to pick every (8 * 128)th entry in LUT, and
1035 * program 256 of those.
1036 *
1037 * Spec is not very clear about if entries seg3[0] and seg3[1] are
1038 * being used or not, but we still need to program these to advance
1039 * the index.
1040 */
1041 for (i = 0; i < 256; i++) {
1042 entry = &lut[i * 8 * 128];
1043 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1044 ilk_lut_12p4_ldw(entry));
1045 intel_dsb_indexed_reg_write(crtc_state, PREC_PAL_DATA(pipe),
1046 ilk_lut_12p4_udw(entry));
1047 }
1048
1049 /* The last entry in the LUT is to be programmed in GCMAX */
1050 entry = &lut[256 * 8 * 128];
1051 icl_load_gcmax(crtc_state, entry);
1052 ivb_load_lut_ext_max(crtc_state);
1053 }
1054
icl_load_luts(const struct intel_crtc_state * crtc_state)1055 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
1056 {
1057 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1058 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1059
1060 if (crtc_state->hw.degamma_lut)
1061 glk_load_degamma_lut(crtc_state);
1062
1063 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
1064 case GAMMA_MODE_MODE_8BIT:
1065 ilk_load_lut_8(crtc, gamma_lut);
1066 break;
1067 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
1068 icl_program_gamma_superfine_segment(crtc_state);
1069 icl_program_gamma_multi_segment(crtc_state);
1070 break;
1071 case GAMMA_MODE_MODE_10BIT:
1072 bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
1073 ivb_load_lut_ext_max(crtc_state);
1074 break;
1075 default:
1076 MISSING_CASE(crtc_state->gamma_mode);
1077 break;
1078 }
1079
1080 intel_dsb_commit(crtc_state);
1081 }
1082
chv_cgm_degamma_ldw(const struct drm_color_lut * color)1083 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
1084 {
1085 return drm_color_lut_extract(color->green, 14) << 16 |
1086 drm_color_lut_extract(color->blue, 14);
1087 }
1088
chv_cgm_degamma_udw(const struct drm_color_lut * color)1089 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
1090 {
1091 return drm_color_lut_extract(color->red, 14);
1092 }
1093
chv_load_cgm_degamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)1094 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
1095 const struct drm_property_blob *blob)
1096 {
1097 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1098 const struct drm_color_lut *lut = blob->data;
1099 int i, lut_size = drm_color_lut_size(blob);
1100 enum pipe pipe = crtc->pipe;
1101
1102 for (i = 0; i < lut_size; i++) {
1103 intel_de_write_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 0),
1104 chv_cgm_degamma_ldw(&lut[i]));
1105 intel_de_write_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 1),
1106 chv_cgm_degamma_udw(&lut[i]));
1107 }
1108 }
1109
chv_cgm_gamma_ldw(const struct drm_color_lut * color)1110 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
1111 {
1112 return drm_color_lut_extract(color->green, 10) << 16 |
1113 drm_color_lut_extract(color->blue, 10);
1114 }
1115
chv_cgm_gamma_udw(const struct drm_color_lut * color)1116 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
1117 {
1118 return drm_color_lut_extract(color->red, 10);
1119 }
1120
chv_cgm_gamma_pack(struct drm_color_lut * entry,u32 ldw,u32 udw)1121 static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
1122 {
1123 entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_MASK, ldw), 10);
1124 entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_MASK, ldw), 10);
1125 entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_MASK, udw), 10);
1126 }
1127
chv_load_cgm_gamma(struct intel_crtc * crtc,const struct drm_property_blob * blob)1128 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
1129 const struct drm_property_blob *blob)
1130 {
1131 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1132 const struct drm_color_lut *lut = blob->data;
1133 int i, lut_size = drm_color_lut_size(blob);
1134 enum pipe pipe = crtc->pipe;
1135
1136 for (i = 0; i < lut_size; i++) {
1137 intel_de_write_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 0),
1138 chv_cgm_gamma_ldw(&lut[i]));
1139 intel_de_write_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 1),
1140 chv_cgm_gamma_udw(&lut[i]));
1141 }
1142 }
1143
chv_load_luts(const struct intel_crtc_state * crtc_state)1144 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
1145 {
1146 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1147 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1148 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
1149 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1150 const struct drm_property_blob *ctm = crtc_state->hw.ctm;
1151
1152 if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
1153 chv_load_cgm_csc(crtc, ctm);
1154
1155 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
1156 chv_load_cgm_degamma(crtc, degamma_lut);
1157
1158 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1159 chv_load_cgm_gamma(crtc, gamma_lut);
1160 else
1161 i965_load_luts(crtc_state);
1162
1163 intel_de_write_fw(dev_priv, CGM_PIPE_MODE(crtc->pipe),
1164 crtc_state->cgm_mode);
1165 }
1166
intel_color_load_luts(const struct intel_crtc_state * crtc_state)1167 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
1168 {
1169 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1170
1171 dev_priv->display.funcs.color->load_luts(crtc_state);
1172 }
1173
intel_color_commit_noarm(const struct intel_crtc_state * crtc_state)1174 void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state)
1175 {
1176 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1177
1178 if (dev_priv->display.funcs.color->color_commit_noarm)
1179 dev_priv->display.funcs.color->color_commit_noarm(crtc_state);
1180 }
1181
intel_color_commit_arm(const struct intel_crtc_state * crtc_state)1182 void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
1183 {
1184 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1185
1186 dev_priv->display.funcs.color->color_commit_arm(crtc_state);
1187 }
1188
intel_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1189 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1190 {
1191 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1192 struct intel_atomic_state *state =
1193 to_intel_atomic_state(new_crtc_state->uapi.state);
1194 const struct intel_crtc_state *old_crtc_state =
1195 intel_atomic_get_old_crtc_state(state, crtc);
1196
1197 return !old_crtc_state->hw.gamma_lut &&
1198 !old_crtc_state->hw.degamma_lut;
1199 }
1200
chv_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1201 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1202 {
1203 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1204 struct intel_atomic_state *state =
1205 to_intel_atomic_state(new_crtc_state->uapi.state);
1206 const struct intel_crtc_state *old_crtc_state =
1207 intel_atomic_get_old_crtc_state(state, crtc);
1208
1209 /*
1210 * CGM_PIPE_MODE is itself single buffered. We'd have to
1211 * somehow split it out from chv_load_luts() if we wanted
1212 * the ability to preload the CGM LUTs/CSC without tearing.
1213 */
1214 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1215 return false;
1216
1217 return !old_crtc_state->hw.gamma_lut;
1218 }
1219
glk_can_preload_luts(const struct intel_crtc_state * new_crtc_state)1220 static bool glk_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 * The hardware degamma is active whenever the pipe
1230 * CSC is active. Thus even if the old state has no
1231 * software degamma we need to avoid clobbering the
1232 * linear hardware degamma mid scanout.
1233 */
1234 return !old_crtc_state->csc_enable &&
1235 !old_crtc_state->hw.gamma_lut;
1236 }
1237
intel_color_check(struct intel_crtc_state * crtc_state)1238 int intel_color_check(struct intel_crtc_state *crtc_state)
1239 {
1240 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1241
1242 return dev_priv->display.funcs.color->color_check(crtc_state);
1243 }
1244
intel_color_get_config(struct intel_crtc_state * crtc_state)1245 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1246 {
1247 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1248
1249 if (dev_priv->display.funcs.color->read_luts)
1250 dev_priv->display.funcs.color->read_luts(crtc_state);
1251 }
1252
need_plane_update(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)1253 static bool need_plane_update(struct intel_plane *plane,
1254 const struct intel_crtc_state *crtc_state)
1255 {
1256 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1257
1258 /*
1259 * On pre-SKL the pipe gamma enable and pipe csc enable for
1260 * the pipe bottom color are configured via the primary plane.
1261 * We have to reconfigure that even if the plane is inactive.
1262 */
1263 return crtc_state->active_planes & BIT(plane->id) ||
1264 (DISPLAY_VER(dev_priv) < 9 &&
1265 plane->id == PLANE_PRIMARY);
1266 }
1267
1268 static int
intel_color_add_affected_planes(struct intel_crtc_state * new_crtc_state)1269 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1270 {
1271 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1272 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1273 struct intel_atomic_state *state =
1274 to_intel_atomic_state(new_crtc_state->uapi.state);
1275 const struct intel_crtc_state *old_crtc_state =
1276 intel_atomic_get_old_crtc_state(state, crtc);
1277 struct intel_plane *plane;
1278
1279 if (!new_crtc_state->hw.active ||
1280 drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
1281 return 0;
1282
1283 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1284 new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1285 return 0;
1286
1287 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
1288 struct intel_plane_state *plane_state;
1289
1290 if (!need_plane_update(plane, new_crtc_state))
1291 continue;
1292
1293 plane_state = intel_atomic_get_plane_state(state, plane);
1294 if (IS_ERR(plane_state))
1295 return PTR_ERR(plane_state);
1296
1297 new_crtc_state->update_planes |= BIT(plane->id);
1298 }
1299
1300 return 0;
1301 }
1302
check_lut_size(const struct drm_property_blob * lut,int expected)1303 static int check_lut_size(const struct drm_property_blob *lut, int expected)
1304 {
1305 int len;
1306
1307 if (!lut)
1308 return 0;
1309
1310 len = drm_color_lut_size(lut);
1311 if (len != expected) {
1312 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1313 len, expected);
1314 return -EINVAL;
1315 }
1316
1317 return 0;
1318 }
1319
check_luts(const struct intel_crtc_state * crtc_state)1320 static int check_luts(const struct intel_crtc_state *crtc_state)
1321 {
1322 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1323 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1324 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
1325 int gamma_length, degamma_length;
1326 u32 gamma_tests, degamma_tests;
1327
1328 /* Always allow legacy gamma LUT with no further checking. */
1329 if (crtc_state_is_legacy_gamma(crtc_state))
1330 return 0;
1331
1332 /* C8 relies on its palette being stored in the legacy LUT */
1333 if (crtc_state->c8_planes) {
1334 drm_dbg_kms(&dev_priv->drm,
1335 "C8 pixelformat requires the legacy LUT\n");
1336 return -EINVAL;
1337 }
1338
1339 degamma_length = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
1340 gamma_length = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1341 degamma_tests = INTEL_INFO(dev_priv)->display.color.degamma_lut_tests;
1342 gamma_tests = INTEL_INFO(dev_priv)->display.color.gamma_lut_tests;
1343
1344 if (check_lut_size(degamma_lut, degamma_length) ||
1345 check_lut_size(gamma_lut, gamma_length))
1346 return -EINVAL;
1347
1348 if (drm_color_lut_check(degamma_lut, degamma_tests) ||
1349 drm_color_lut_check(gamma_lut, gamma_tests))
1350 return -EINVAL;
1351
1352 return 0;
1353 }
1354
i9xx_gamma_mode(struct intel_crtc_state * crtc_state)1355 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
1356 {
1357 if (!crtc_state->gamma_enable ||
1358 crtc_state_is_legacy_gamma(crtc_state))
1359 return GAMMA_MODE_MODE_8BIT;
1360 else
1361 return GAMMA_MODE_MODE_10BIT; /* i965+ only */
1362 }
1363
i9xx_color_check(struct intel_crtc_state * crtc_state)1364 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1365 {
1366 int ret;
1367
1368 ret = check_luts(crtc_state);
1369 if (ret)
1370 return ret;
1371
1372 crtc_state->gamma_enable =
1373 crtc_state->hw.gamma_lut &&
1374 !crtc_state->c8_planes;
1375
1376 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1377
1378 ret = intel_color_add_affected_planes(crtc_state);
1379 if (ret)
1380 return ret;
1381
1382 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1383
1384 return 0;
1385 }
1386
chv_cgm_mode(const struct intel_crtc_state * crtc_state)1387 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1388 {
1389 u32 cgm_mode = 0;
1390
1391 if (crtc_state_is_legacy_gamma(crtc_state))
1392 return 0;
1393
1394 if (crtc_state->hw.degamma_lut)
1395 cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1396 if (crtc_state->hw.ctm)
1397 cgm_mode |= CGM_PIPE_MODE_CSC;
1398 if (crtc_state->hw.gamma_lut)
1399 cgm_mode |= CGM_PIPE_MODE_GAMMA;
1400
1401 return cgm_mode;
1402 }
1403
1404 /*
1405 * CHV color pipeline:
1406 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
1407 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
1408 *
1409 * We always bypass the WGC csc and use the CGM csc
1410 * instead since it has degamma and better precision.
1411 */
chv_color_check(struct intel_crtc_state * crtc_state)1412 static int chv_color_check(struct intel_crtc_state *crtc_state)
1413 {
1414 int ret;
1415
1416 ret = check_luts(crtc_state);
1417 if (ret)
1418 return ret;
1419
1420 /*
1421 * Pipe gamma will be used only for the legacy LUT.
1422 * Otherwise we bypass it and use the CGM gamma instead.
1423 */
1424 crtc_state->gamma_enable =
1425 crtc_state_is_legacy_gamma(crtc_state) &&
1426 !crtc_state->c8_planes;
1427
1428 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1429
1430 crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1431
1432 ret = intel_color_add_affected_planes(crtc_state);
1433 if (ret)
1434 return ret;
1435
1436 crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
1437
1438 return 0;
1439 }
1440
ilk_gamma_mode(const struct intel_crtc_state * crtc_state)1441 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1442 {
1443 if (!crtc_state->gamma_enable ||
1444 crtc_state_is_legacy_gamma(crtc_state))
1445 return GAMMA_MODE_MODE_8BIT;
1446 else
1447 return GAMMA_MODE_MODE_10BIT;
1448 }
1449
ilk_csc_mode(const struct intel_crtc_state * crtc_state)1450 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
1451 {
1452 /*
1453 * CSC comes after the LUT in RGB->YCbCr mode.
1454 * RGB->YCbCr needs the limited range offsets added to
1455 * the output. RGB limited range output is handled by
1456 * the hw automagically elsewhere.
1457 */
1458 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
1459 return CSC_BLACK_SCREEN_OFFSET;
1460
1461 return CSC_MODE_YUV_TO_RGB |
1462 CSC_POSITION_BEFORE_GAMMA;
1463 }
1464
ilk_color_check(struct intel_crtc_state * crtc_state)1465 static int ilk_color_check(struct intel_crtc_state *crtc_state)
1466 {
1467 int ret;
1468
1469 ret = check_luts(crtc_state);
1470 if (ret)
1471 return ret;
1472
1473 crtc_state->gamma_enable =
1474 crtc_state->hw.gamma_lut &&
1475 !crtc_state->c8_planes;
1476
1477 /*
1478 * We don't expose the ctm on ilk/snb currently, also RGB
1479 * limited range output is handled by the hw automagically.
1480 */
1481 crtc_state->csc_enable =
1482 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
1483
1484 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1485
1486 crtc_state->csc_mode = ilk_csc_mode(crtc_state);
1487
1488 ret = intel_color_add_affected_planes(crtc_state);
1489 if (ret)
1490 return ret;
1491
1492 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1493
1494 return 0;
1495 }
1496
ivb_gamma_mode(const struct intel_crtc_state * crtc_state)1497 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1498 {
1499 if (!crtc_state->gamma_enable ||
1500 crtc_state_is_legacy_gamma(crtc_state))
1501 return GAMMA_MODE_MODE_8BIT;
1502 else if (crtc_state->hw.gamma_lut &&
1503 crtc_state->hw.degamma_lut)
1504 return GAMMA_MODE_MODE_SPLIT;
1505 else
1506 return GAMMA_MODE_MODE_10BIT;
1507 }
1508
ivb_csc_mode(const struct intel_crtc_state * crtc_state)1509 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1510 {
1511 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1512
1513 /*
1514 * CSC comes after the LUT in degamma, RGB->YCbCr,
1515 * and RGB full->limited range mode.
1516 */
1517 if (crtc_state->hw.degamma_lut ||
1518 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1519 limited_color_range)
1520 return 0;
1521
1522 return CSC_POSITION_BEFORE_GAMMA;
1523 }
1524
ivb_color_check(struct intel_crtc_state * crtc_state)1525 static int ivb_color_check(struct intel_crtc_state *crtc_state)
1526 {
1527 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1528 bool limited_color_range = ilk_csc_limited_range(crtc_state);
1529 int ret;
1530
1531 ret = check_luts(crtc_state);
1532 if (ret)
1533 return ret;
1534
1535 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
1536 crtc_state->hw.ctm) {
1537 drm_dbg_kms(&dev_priv->drm,
1538 "YCBCR and CTM together are not possible\n");
1539 return -EINVAL;
1540 }
1541
1542 crtc_state->gamma_enable =
1543 (crtc_state->hw.gamma_lut ||
1544 crtc_state->hw.degamma_lut) &&
1545 !crtc_state->c8_planes;
1546
1547 crtc_state->csc_enable =
1548 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1549 crtc_state->hw.ctm || limited_color_range;
1550
1551 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1552
1553 crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1554
1555 ret = intel_color_add_affected_planes(crtc_state);
1556 if (ret)
1557 return ret;
1558
1559 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1560
1561 return 0;
1562 }
1563
glk_gamma_mode(const struct intel_crtc_state * crtc_state)1564 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1565 {
1566 if (!crtc_state->gamma_enable ||
1567 crtc_state_is_legacy_gamma(crtc_state))
1568 return GAMMA_MODE_MODE_8BIT;
1569 else
1570 return GAMMA_MODE_MODE_10BIT;
1571 }
1572
glk_color_check(struct intel_crtc_state * crtc_state)1573 static int glk_color_check(struct intel_crtc_state *crtc_state)
1574 {
1575 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1576 int ret;
1577
1578 ret = check_luts(crtc_state);
1579 if (ret)
1580 return ret;
1581
1582 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
1583 crtc_state->hw.ctm) {
1584 drm_dbg_kms(&dev_priv->drm,
1585 "YCBCR and CTM together are not possible\n");
1586 return -EINVAL;
1587 }
1588
1589 crtc_state->gamma_enable =
1590 crtc_state->hw.gamma_lut &&
1591 !crtc_state->c8_planes;
1592
1593 /* On GLK+ degamma LUT is controlled by csc_enable */
1594 crtc_state->csc_enable =
1595 crtc_state->hw.degamma_lut ||
1596 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1597 crtc_state->hw.ctm || crtc_state->limited_color_range;
1598
1599 crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1600
1601 crtc_state->csc_mode = 0;
1602
1603 ret = intel_color_add_affected_planes(crtc_state);
1604 if (ret)
1605 return ret;
1606
1607 crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
1608
1609 return 0;
1610 }
1611
icl_gamma_mode(const struct intel_crtc_state * crtc_state)1612 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1613 {
1614 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1615 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1616 u32 gamma_mode = 0;
1617
1618 if (crtc_state->hw.degamma_lut)
1619 gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1620
1621 if (crtc_state->hw.gamma_lut &&
1622 !crtc_state->c8_planes)
1623 gamma_mode |= POST_CSC_GAMMA_ENABLE;
1624
1625 if (!crtc_state->hw.gamma_lut ||
1626 crtc_state_is_legacy_gamma(crtc_state))
1627 gamma_mode |= GAMMA_MODE_MODE_8BIT;
1628 /*
1629 * Enable 10bit gamma for D13
1630 * ToDo: Extend to Logarithmic Gamma once the new UAPI
1631 * is accepted and implemented by a userspace consumer
1632 */
1633 else if (DISPLAY_VER(i915) >= 13)
1634 gamma_mode |= GAMMA_MODE_MODE_10BIT;
1635 else
1636 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
1637
1638 return gamma_mode;
1639 }
1640
icl_csc_mode(const struct intel_crtc_state * crtc_state)1641 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1642 {
1643 u32 csc_mode = 0;
1644
1645 if (crtc_state->hw.ctm)
1646 csc_mode |= ICL_CSC_ENABLE;
1647
1648 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1649 crtc_state->limited_color_range)
1650 csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1651
1652 return csc_mode;
1653 }
1654
icl_color_check(struct intel_crtc_state * crtc_state)1655 static int icl_color_check(struct intel_crtc_state *crtc_state)
1656 {
1657 int ret;
1658
1659 ret = check_luts(crtc_state);
1660 if (ret)
1661 return ret;
1662
1663 crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1664
1665 crtc_state->csc_mode = icl_csc_mode(crtc_state);
1666
1667 crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
1668
1669 return 0;
1670 }
1671
i9xx_gamma_precision(const struct intel_crtc_state * crtc_state)1672 static int i9xx_gamma_precision(const struct intel_crtc_state *crtc_state)
1673 {
1674 if (!crtc_state->gamma_enable)
1675 return 0;
1676
1677 switch (crtc_state->gamma_mode) {
1678 case GAMMA_MODE_MODE_8BIT:
1679 return 8;
1680 case GAMMA_MODE_MODE_10BIT:
1681 return 16;
1682 default:
1683 MISSING_CASE(crtc_state->gamma_mode);
1684 return 0;
1685 }
1686 }
1687
ilk_gamma_precision(const struct intel_crtc_state * crtc_state)1688 static int ilk_gamma_precision(const struct intel_crtc_state *crtc_state)
1689 {
1690 if (!crtc_state->gamma_enable)
1691 return 0;
1692
1693 if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
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 10;
1701 default:
1702 MISSING_CASE(crtc_state->gamma_mode);
1703 return 0;
1704 }
1705 }
1706
chv_gamma_precision(const struct intel_crtc_state * crtc_state)1707 static int chv_gamma_precision(const struct intel_crtc_state *crtc_state)
1708 {
1709 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1710 return 10;
1711 else
1712 return i9xx_gamma_precision(crtc_state);
1713 }
1714
glk_gamma_precision(const struct intel_crtc_state * crtc_state)1715 static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
1716 {
1717 if (!crtc_state->gamma_enable)
1718 return 0;
1719
1720 switch (crtc_state->gamma_mode) {
1721 case GAMMA_MODE_MODE_8BIT:
1722 return 8;
1723 case GAMMA_MODE_MODE_10BIT:
1724 return 10;
1725 default:
1726 MISSING_CASE(crtc_state->gamma_mode);
1727 return 0;
1728 }
1729 }
1730
icl_gamma_precision(const struct intel_crtc_state * crtc_state)1731 static int icl_gamma_precision(const struct intel_crtc_state *crtc_state)
1732 {
1733 if ((crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE) == 0)
1734 return 0;
1735
1736 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
1737 case GAMMA_MODE_MODE_8BIT:
1738 return 8;
1739 case GAMMA_MODE_MODE_10BIT:
1740 return 10;
1741 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
1742 return 16;
1743 default:
1744 MISSING_CASE(crtc_state->gamma_mode);
1745 return 0;
1746 }
1747 }
1748
intel_color_get_gamma_bit_precision(const struct intel_crtc_state * crtc_state)1749 int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
1750 {
1751 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1752 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1753
1754 if (HAS_GMCH(dev_priv)) {
1755 if (IS_CHERRYVIEW(dev_priv))
1756 return chv_gamma_precision(crtc_state);
1757 else
1758 return i9xx_gamma_precision(crtc_state);
1759 } else {
1760 if (DISPLAY_VER(dev_priv) >= 11)
1761 return icl_gamma_precision(crtc_state);
1762 else if (DISPLAY_VER(dev_priv) == 10)
1763 return glk_gamma_precision(crtc_state);
1764 else if (IS_IRONLAKE(dev_priv))
1765 return ilk_gamma_precision(crtc_state);
1766 }
1767
1768 return 0;
1769 }
1770
err_check(struct drm_color_lut * lut1,struct drm_color_lut * lut2,u32 err)1771 static bool err_check(struct drm_color_lut *lut1,
1772 struct drm_color_lut *lut2, u32 err)
1773 {
1774 return ((abs((long)lut2->red - lut1->red)) <= err) &&
1775 ((abs((long)lut2->blue - lut1->blue)) <= err) &&
1776 ((abs((long)lut2->green - lut1->green)) <= err);
1777 }
1778
intel_color_lut_entries_equal(struct drm_color_lut * lut1,struct drm_color_lut * lut2,int lut_size,u32 err)1779 static bool intel_color_lut_entries_equal(struct drm_color_lut *lut1,
1780 struct drm_color_lut *lut2,
1781 int lut_size, u32 err)
1782 {
1783 int i;
1784
1785 for (i = 0; i < lut_size; i++) {
1786 if (!err_check(&lut1[i], &lut2[i], err))
1787 return false;
1788 }
1789
1790 return true;
1791 }
1792
intel_color_lut_equal(struct drm_property_blob * blob1,struct drm_property_blob * blob2,u32 gamma_mode,u32 bit_precision)1793 bool intel_color_lut_equal(struct drm_property_blob *blob1,
1794 struct drm_property_blob *blob2,
1795 u32 gamma_mode, u32 bit_precision)
1796 {
1797 struct drm_color_lut *lut1, *lut2;
1798 int lut_size1, lut_size2;
1799 u32 err;
1800
1801 if (!blob1 != !blob2)
1802 return false;
1803
1804 if (!blob1)
1805 return true;
1806
1807 lut_size1 = drm_color_lut_size(blob1);
1808 lut_size2 = drm_color_lut_size(blob2);
1809
1810 /* check sw and hw lut size */
1811 if (lut_size1 != lut_size2)
1812 return false;
1813
1814 lut1 = blob1->data;
1815 lut2 = blob2->data;
1816
1817 err = 0xffff >> bit_precision;
1818
1819 /* check sw and hw lut entry to be equal */
1820 switch (gamma_mode & GAMMA_MODE_MODE_MASK) {
1821 case GAMMA_MODE_MODE_8BIT:
1822 case GAMMA_MODE_MODE_10BIT:
1823 if (!intel_color_lut_entries_equal(lut1, lut2,
1824 lut_size2, err))
1825 return false;
1826 break;
1827 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
1828 if (!intel_color_lut_entries_equal(lut1, lut2,
1829 9, err))
1830 return false;
1831 break;
1832 default:
1833 MISSING_CASE(gamma_mode);
1834 return false;
1835 }
1836
1837 return true;
1838 }
1839
i9xx_read_lut_8(struct intel_crtc * crtc)1840 static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)
1841 {
1842 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1843 enum pipe pipe = crtc->pipe;
1844 struct drm_property_blob *blob;
1845 struct drm_color_lut *lut;
1846 int i;
1847
1848 blob = drm_property_create_blob(&dev_priv->drm,
1849 sizeof(struct drm_color_lut) * LEGACY_LUT_LENGTH,
1850 NULL);
1851 if (IS_ERR(blob))
1852 return NULL;
1853
1854 lut = blob->data;
1855
1856 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
1857 u32 val = intel_de_read_fw(dev_priv, PALETTE(pipe, i));
1858
1859 i9xx_lut_8_pack(&lut[i], val);
1860 }
1861
1862 return blob;
1863 }
1864
i9xx_read_luts(struct intel_crtc_state * crtc_state)1865 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
1866 {
1867 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1868
1869 if (!crtc_state->gamma_enable)
1870 return;
1871
1872 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
1873 }
1874
i965_read_lut_10p6(struct intel_crtc * crtc)1875 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
1876 {
1877 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1878 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1879 enum pipe pipe = crtc->pipe;
1880 struct drm_property_blob *blob;
1881 struct drm_color_lut *lut;
1882
1883 blob = drm_property_create_blob(&dev_priv->drm,
1884 sizeof(struct drm_color_lut) * lut_size,
1885 NULL);
1886 if (IS_ERR(blob))
1887 return NULL;
1888
1889 lut = blob->data;
1890
1891 for (i = 0; i < lut_size - 1; i++) {
1892 u32 ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
1893 u32 udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
1894
1895 i965_lut_10p6_pack(&lut[i], ldw, udw);
1896 }
1897
1898 lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
1899 lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
1900 lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
1901
1902 return blob;
1903 }
1904
i965_read_luts(struct intel_crtc_state * crtc_state)1905 static void i965_read_luts(struct intel_crtc_state *crtc_state)
1906 {
1907 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1908
1909 if (!crtc_state->gamma_enable)
1910 return;
1911
1912 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
1913 crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
1914 else
1915 crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc);
1916 }
1917
chv_read_cgm_gamma(struct intel_crtc * crtc)1918 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
1919 {
1920 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1921 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1922 enum pipe pipe = crtc->pipe;
1923 struct drm_property_blob *blob;
1924 struct drm_color_lut *lut;
1925
1926 blob = drm_property_create_blob(&dev_priv->drm,
1927 sizeof(struct drm_color_lut) * lut_size,
1928 NULL);
1929 if (IS_ERR(blob))
1930 return NULL;
1931
1932 lut = blob->data;
1933
1934 for (i = 0; i < lut_size; i++) {
1935 u32 ldw = intel_de_read_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 0));
1936 u32 udw = intel_de_read_fw(dev_priv, CGM_PIPE_GAMMA(pipe, i, 1));
1937
1938 chv_cgm_gamma_pack(&lut[i], ldw, udw);
1939 }
1940
1941 return blob;
1942 }
1943
chv_read_luts(struct intel_crtc_state * crtc_state)1944 static void chv_read_luts(struct intel_crtc_state *crtc_state)
1945 {
1946 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1947
1948 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1949 crtc_state->hw.gamma_lut = chv_read_cgm_gamma(crtc);
1950 else
1951 i965_read_luts(crtc_state);
1952 }
1953
ilk_read_lut_8(struct intel_crtc * crtc)1954 static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc)
1955 {
1956 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1957 enum pipe pipe = crtc->pipe;
1958 struct drm_property_blob *blob;
1959 struct drm_color_lut *lut;
1960 int i;
1961
1962 blob = drm_property_create_blob(&dev_priv->drm,
1963 sizeof(struct drm_color_lut) * LEGACY_LUT_LENGTH,
1964 NULL);
1965 if (IS_ERR(blob))
1966 return NULL;
1967
1968 lut = blob->data;
1969
1970 for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
1971 u32 val = intel_de_read_fw(dev_priv, LGC_PALETTE(pipe, i));
1972
1973 i9xx_lut_8_pack(&lut[i], val);
1974 }
1975
1976 return blob;
1977 }
1978
ilk_read_lut_10(struct intel_crtc * crtc)1979 static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc)
1980 {
1981 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1982 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
1983 enum pipe pipe = crtc->pipe;
1984 struct drm_property_blob *blob;
1985 struct drm_color_lut *lut;
1986
1987 blob = drm_property_create_blob(&dev_priv->drm,
1988 sizeof(struct drm_color_lut) * lut_size,
1989 NULL);
1990 if (IS_ERR(blob))
1991 return NULL;
1992
1993 lut = blob->data;
1994
1995 for (i = 0; i < lut_size; i++) {
1996 u32 val = intel_de_read_fw(dev_priv, PREC_PALETTE(pipe, i));
1997
1998 ilk_lut_10_pack(&lut[i], val);
1999 }
2000
2001 return blob;
2002 }
2003
ilk_read_luts(struct intel_crtc_state * crtc_state)2004 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
2005 {
2006 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2007
2008 if (!crtc_state->gamma_enable)
2009 return;
2010
2011 if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
2012 return;
2013
2014 switch (crtc_state->gamma_mode) {
2015 case GAMMA_MODE_MODE_8BIT:
2016 crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
2017 break;
2018 case GAMMA_MODE_MODE_10BIT:
2019 crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc);
2020 break;
2021 default:
2022 MISSING_CASE(crtc_state->gamma_mode);
2023 break;
2024 }
2025 }
2026
2027 /* On BDW+ the index auto increment mode actually works */
bdw_read_lut_10(struct intel_crtc * crtc,u32 prec_index)2028 static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
2029 u32 prec_index)
2030 {
2031 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2032 int i, hw_lut_size = ivb_lut_10_size(prec_index);
2033 int lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
2034 enum pipe pipe = crtc->pipe;
2035 struct drm_property_blob *blob;
2036 struct drm_color_lut *lut;
2037
2038 drm_WARN_ON(&dev_priv->drm, lut_size != hw_lut_size);
2039
2040 blob = drm_property_create_blob(&dev_priv->drm,
2041 sizeof(struct drm_color_lut) * lut_size,
2042 NULL);
2043 if (IS_ERR(blob))
2044 return NULL;
2045
2046 lut = blob->data;
2047
2048 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
2049 prec_index | PAL_PREC_AUTO_INCREMENT);
2050
2051 for (i = 0; i < lut_size; i++) {
2052 u32 val = intel_de_read_fw(dev_priv, PREC_PAL_DATA(pipe));
2053
2054 ilk_lut_10_pack(&lut[i], val);
2055 }
2056
2057 intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe), 0);
2058
2059 return blob;
2060 }
2061
glk_read_luts(struct intel_crtc_state * crtc_state)2062 static void glk_read_luts(struct intel_crtc_state *crtc_state)
2063 {
2064 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2065
2066 if (!crtc_state->gamma_enable)
2067 return;
2068
2069 switch (crtc_state->gamma_mode) {
2070 case GAMMA_MODE_MODE_8BIT:
2071 crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
2072 break;
2073 case GAMMA_MODE_MODE_10BIT:
2074 crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
2075 break;
2076 default:
2077 MISSING_CASE(crtc_state->gamma_mode);
2078 break;
2079 }
2080 }
2081
2082 static struct drm_property_blob *
icl_read_lut_multi_segment(struct intel_crtc * crtc)2083 icl_read_lut_multi_segment(struct intel_crtc *crtc)
2084 {
2085 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2086 int i, lut_size = INTEL_INFO(dev_priv)->display.color.gamma_lut_size;
2087 enum pipe pipe = crtc->pipe;
2088 struct drm_property_blob *blob;
2089 struct drm_color_lut *lut;
2090
2091 blob = drm_property_create_blob(&dev_priv->drm,
2092 sizeof(struct drm_color_lut) * lut_size,
2093 NULL);
2094 if (IS_ERR(blob))
2095 return NULL;
2096
2097 lut = blob->data;
2098
2099 intel_de_write_fw(dev_priv, PREC_PAL_MULTI_SEG_INDEX(pipe),
2100 PAL_PREC_AUTO_INCREMENT);
2101
2102 for (i = 0; i < 9; i++) {
2103 u32 ldw = intel_de_read_fw(dev_priv, PREC_PAL_MULTI_SEG_DATA(pipe));
2104 u32 udw = intel_de_read_fw(dev_priv, PREC_PAL_MULTI_SEG_DATA(pipe));
2105
2106 icl_lut_multi_seg_pack(&lut[i], ldw, udw);
2107 }
2108
2109 intel_de_write_fw(dev_priv, PREC_PAL_MULTI_SEG_INDEX(pipe), 0);
2110
2111 /*
2112 * FIXME readouts from PAL_PREC_DATA register aren't giving
2113 * correct values in the case of fine and coarse segments.
2114 * Restricting readouts only for super fine segment as of now.
2115 */
2116
2117 return blob;
2118 }
2119
icl_read_luts(struct intel_crtc_state * crtc_state)2120 static void icl_read_luts(struct intel_crtc_state *crtc_state)
2121 {
2122 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2123
2124 if ((crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE) == 0)
2125 return;
2126
2127 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
2128 case GAMMA_MODE_MODE_8BIT:
2129 crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
2130 break;
2131 case GAMMA_MODE_MODE_10BIT:
2132 crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
2133 break;
2134 case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
2135 crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
2136 break;
2137 default:
2138 MISSING_CASE(crtc_state->gamma_mode);
2139 break;
2140 }
2141 }
2142
2143 static const struct intel_color_funcs chv_color_funcs = {
2144 .color_check = chv_color_check,
2145 .color_commit_arm = i9xx_color_commit_arm,
2146 .load_luts = chv_load_luts,
2147 .read_luts = chv_read_luts,
2148 };
2149
2150 static const struct intel_color_funcs i965_color_funcs = {
2151 .color_check = i9xx_color_check,
2152 .color_commit_arm = i9xx_color_commit_arm,
2153 .load_luts = i965_load_luts,
2154 .read_luts = i965_read_luts,
2155 };
2156
2157 static const struct intel_color_funcs i9xx_color_funcs = {
2158 .color_check = i9xx_color_check,
2159 .color_commit_arm = i9xx_color_commit_arm,
2160 .load_luts = i9xx_load_luts,
2161 .read_luts = i9xx_read_luts,
2162 };
2163
2164 static const struct intel_color_funcs icl_color_funcs = {
2165 .color_check = icl_color_check,
2166 .color_commit_noarm = icl_color_commit_noarm,
2167 .color_commit_arm = skl_color_commit_arm,
2168 .load_luts = icl_load_luts,
2169 .read_luts = icl_read_luts,
2170 };
2171
2172 static const struct intel_color_funcs glk_color_funcs = {
2173 .color_check = glk_color_check,
2174 .color_commit_noarm = ilk_color_commit_noarm,
2175 .color_commit_arm = skl_color_commit_arm,
2176 .load_luts = glk_load_luts,
2177 .read_luts = glk_read_luts,
2178 };
2179
2180 static const struct intel_color_funcs skl_color_funcs = {
2181 .color_check = ivb_color_check,
2182 .color_commit_noarm = ilk_color_commit_noarm,
2183 .color_commit_arm = skl_color_commit_arm,
2184 .load_luts = bdw_load_luts,
2185 .read_luts = NULL,
2186 };
2187
2188 static const struct intel_color_funcs bdw_color_funcs = {
2189 .color_check = ivb_color_check,
2190 .color_commit_noarm = ilk_color_commit_noarm,
2191 .color_commit_arm = hsw_color_commit_arm,
2192 .load_luts = bdw_load_luts,
2193 .read_luts = NULL,
2194 };
2195
2196 static const struct intel_color_funcs hsw_color_funcs = {
2197 .color_check = ivb_color_check,
2198 .color_commit_noarm = ilk_color_commit_noarm,
2199 .color_commit_arm = hsw_color_commit_arm,
2200 .load_luts = ivb_load_luts,
2201 .read_luts = NULL,
2202 };
2203
2204 static const struct intel_color_funcs ivb_color_funcs = {
2205 .color_check = ivb_color_check,
2206 .color_commit_noarm = ilk_color_commit_noarm,
2207 .color_commit_arm = ilk_color_commit_arm,
2208 .load_luts = ivb_load_luts,
2209 .read_luts = NULL,
2210 };
2211
2212 static const struct intel_color_funcs ilk_color_funcs = {
2213 .color_check = ilk_color_check,
2214 .color_commit_noarm = ilk_color_commit_noarm,
2215 .color_commit_arm = ilk_color_commit_arm,
2216 .load_luts = ilk_load_luts,
2217 .read_luts = ilk_read_luts,
2218 };
2219
intel_color_init(struct intel_crtc * crtc)2220 void intel_color_init(struct intel_crtc *crtc)
2221 {
2222 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2223 bool has_ctm = INTEL_INFO(dev_priv)->display.color.degamma_lut_size != 0;
2224
2225 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
2226
2227 if (HAS_GMCH(dev_priv)) {
2228 if (IS_CHERRYVIEW(dev_priv)) {
2229 dev_priv->display.funcs.color = &chv_color_funcs;
2230 } else if (DISPLAY_VER(dev_priv) >= 4) {
2231 dev_priv->display.funcs.color = &i965_color_funcs;
2232 } else {
2233 dev_priv->display.funcs.color = &i9xx_color_funcs;
2234 }
2235 } else {
2236 if (DISPLAY_VER(dev_priv) >= 11)
2237 dev_priv->display.funcs.color = &icl_color_funcs;
2238 else if (DISPLAY_VER(dev_priv) == 10)
2239 dev_priv->display.funcs.color = &glk_color_funcs;
2240 else if (DISPLAY_VER(dev_priv) == 9)
2241 dev_priv->display.funcs.color = &skl_color_funcs;
2242 else if (DISPLAY_VER(dev_priv) == 8)
2243 dev_priv->display.funcs.color = &bdw_color_funcs;
2244 else if (DISPLAY_VER(dev_priv) == 7) {
2245 if (IS_HASWELL(dev_priv))
2246 dev_priv->display.funcs.color = &hsw_color_funcs;
2247 else
2248 dev_priv->display.funcs.color = &ivb_color_funcs;
2249 } else
2250 dev_priv->display.funcs.color = &ilk_color_funcs;
2251 }
2252
2253 drm_crtc_enable_color_mgmt(&crtc->base,
2254 INTEL_INFO(dev_priv)->display.color.degamma_lut_size,
2255 has_ctm,
2256 INTEL_INFO(dev_priv)->display.color.gamma_lut_size);
2257 }
2258