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