1 /*
2  * Copyright © 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #include "i915_drv.h"
26 #include "i9xx_plane_regs.h"
27 #include "intel_color.h"
28 #include "intel_color_regs.h"
29 #include "intel_de.h"
30 #include "intel_display_types.h"
31 #include "intel_dsb.h"
32 #include "intel_vrr.h"
33 
34 struct intel_color_funcs {
35 	int (*color_check)(struct intel_atomic_state *state,
36 			   struct intel_crtc *crtc);
37 	/*
38 	 * Program non-arming double buffered color management registers
39 	 * before vblank evasion. The registers should then latch after
40 	 * the arming register is written (by color_commit_arm()) during
41 	 * the next vblank start, alongside any other double buffered
42 	 * registers involved with the same commit. This hook is optional.
43 	 */
44 	void (*color_commit_noarm)(struct intel_dsb *dsb,
45 				   const struct intel_crtc_state *crtc_state);
46 	/*
47 	 * Program arming double buffered color management registers
48 	 * during vblank evasion. The registers (and whatever other registers
49 	 * they arm that were written by color_commit_noarm) should then latch
50 	 * during the next vblank start, alongside any other double buffered
51 	 * registers involved with the same commit.
52 	 */
53 	void (*color_commit_arm)(struct intel_dsb *dsb,
54 				 const struct intel_crtc_state *crtc_state);
55 	/*
56 	 * Perform any extra tasks needed after all the
57 	 * double buffered registers have been latched.
58 	 */
59 	void (*color_post_update)(const struct intel_crtc_state *crtc_state);
60 	/*
61 	 * Load LUTs (and other single buffered color management
62 	 * registers). Will (hopefully) be called during the vblank
63 	 * following the latching of any double buffered registers
64 	 * involved with the same commit.
65 	 */
66 	void (*load_luts)(const struct intel_crtc_state *crtc_state);
67 	/*
68 	 * Read out the LUTs from the hardware into the software state.
69 	 * Used by eg. the hardware state checker.
70 	 */
71 	void (*read_luts)(struct intel_crtc_state *crtc_state);
72 	/*
73 	 * Compare the LUTs
74 	 */
75 	bool (*lut_equal)(const struct intel_crtc_state *crtc_state,
76 			  const struct drm_property_blob *blob1,
77 			  const struct drm_property_blob *blob2,
78 			  bool is_pre_csc_lut);
79 	/*
80 	 * Read out the CSCs (if any) from the hardware into the
81 	 * software state. Used by eg. the hardware state checker.
82 	 */
83 	void (*read_csc)(struct intel_crtc_state *crtc_state);
84 	/*
85 	 * Read config other than LUTs and CSCs, before them. Optional.
86 	 */
87 	void (*get_config)(struct intel_crtc_state *crtc_state);
88 };
89 
90 #define CTM_COEFF_SIGN	(1ULL << 63)
91 
92 #define CTM_COEFF_1_0	(1ULL << 32)
93 #define CTM_COEFF_2_0	(CTM_COEFF_1_0 << 1)
94 #define CTM_COEFF_4_0	(CTM_COEFF_2_0 << 1)
95 #define CTM_COEFF_8_0	(CTM_COEFF_4_0 << 1)
96 #define CTM_COEFF_0_5	(CTM_COEFF_1_0 >> 1)
97 #define CTM_COEFF_0_25	(CTM_COEFF_0_5 >> 1)
98 #define CTM_COEFF_0_125	(CTM_COEFF_0_25 >> 1)
99 
100 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
101 
102 #define CTM_COEFF_NEGATIVE(coeff)	(((coeff) & CTM_COEFF_SIGN) != 0)
103 #define CTM_COEFF_ABS(coeff)		((coeff) & (CTM_COEFF_SIGN - 1))
104 
105 #define LEGACY_LUT_LENGTH		256
106 
107 /*
108  * ILK+ csc matrix:
109  *
110  * |R/Cr|   | c0 c1 c2 |   ( |R/Cr|   |preoff0| )   |postoff0|
111  * |G/Y | = | c3 c4 c5 | x ( |G/Y | + |preoff1| ) + |postoff1|
112  * |B/Cb|   | c6 c7 c8 |   ( |B/Cb|   |preoff2| )   |postoff2|
113  *
114  * ILK/SNB don't have explicit post offsets, and instead
115  * CSC_MODE_YUV_TO_RGB and CSC_BLACK_SCREEN_OFFSET are used:
116  *  CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=0 -> 1/2, 0, 1/2
117  *  CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/2, 1/16, 1/2
118  *  CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=0 -> 0, 0, 0
119  *  CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/16, 1/16, 1/16
120  */
121 
122 /*
123  * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
124  * format). This macro takes the coefficient we want transformed and the
125  * number of fractional bits.
126  *
127  * We only have a 9 bits precision window which slides depending on the value
128  * of the CTM coefficient and we write the value from bit 3. We also round the
129  * value.
130  */
131 #define ILK_CSC_COEFF_FP(coeff, fbits)	\
132 	(clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
133 
134 #define ILK_CSC_COEFF_1_0 0x7800
135 #define ILK_CSC_COEFF_LIMITED_RANGE ((235 - 16) << (12 - 8)) /* exponent 0 */
136 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 << (12 - 8))
137 
138 static const struct intel_csc_matrix ilk_csc_matrix_identity = {
139 	.preoff = {},
140 	.coeff = {
141 		ILK_CSC_COEFF_1_0, 0, 0,
142 		0, ILK_CSC_COEFF_1_0, 0,
143 		0, 0, ILK_CSC_COEFF_1_0,
144 	},
145 	.postoff = {},
146 };
147 
148 /* Full range RGB -> limited range RGB matrix */
149 static const struct intel_csc_matrix ilk_csc_matrix_limited_range = {
150 	.preoff = {},
151 	.coeff = {
152 		ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
153 		0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
154 		0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
155 	},
156 	.postoff = {
157 		ILK_CSC_POSTOFF_LIMITED_RANGE,
158 		ILK_CSC_POSTOFF_LIMITED_RANGE,
159 		ILK_CSC_POSTOFF_LIMITED_RANGE,
160 	},
161 };
162 
163 /* BT.709 full range RGB -> limited range YCbCr matrix */
164 static const struct intel_csc_matrix ilk_csc_matrix_rgb_to_ycbcr = {
165 	.preoff = {},
166 	.coeff = {
167 		0x1e08, 0x9cc0, 0xb528,
168 		0x2ba8, 0x09d8, 0x37e8,
169 		0xbce8, 0x9ad8, 0x1e08,
170 	},
171 	.postoff = {
172 		0x0800, 0x0100, 0x0800,
173 	},
174 };
175 
intel_csc_clear(struct intel_csc_matrix * csc)176 static void intel_csc_clear(struct intel_csc_matrix *csc)
177 {
178 	memset(csc, 0, sizeof(*csc));
179 }
180 
lut_is_legacy(const struct drm_property_blob * lut)181 static bool lut_is_legacy(const struct drm_property_blob *lut)
182 {
183 	return lut && drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
184 }
185 
186 /*
187  * When using limited range, multiply the matrix given by userspace by
188  * the matrix that we would use for the limited range.
189  */
ctm_mult_by_limited(u64 * result,const u64 * input)190 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
191 {
192 	int i;
193 
194 	for (i = 0; i < 9; i++) {
195 		u64 user_coeff = input[i];
196 		u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
197 		u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
198 					  CTM_COEFF_4_0 - 1) >> 2;
199 
200 		/*
201 		 * By scaling every co-efficient with limited range (16-235)
202 		 * vs full range (0-255) the final o/p will be scaled down to
203 		 * fit in the limited range supported by the panel.
204 		 */
205 		result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
206 		result[i] |= user_coeff & CTM_COEFF_SIGN;
207 	}
208 
209 	return result;
210 }
211 
ilk_update_pipe_csc(struct intel_dsb * dsb,struct intel_crtc * crtc,const struct intel_csc_matrix * csc)212 static void ilk_update_pipe_csc(struct intel_dsb *dsb,
213 				struct intel_crtc *crtc,
214 				const struct intel_csc_matrix *csc)
215 {
216 	struct intel_display *display = to_intel_display(crtc->base.dev);
217 	enum pipe pipe = crtc->pipe;
218 
219 	intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_HI(pipe),
220 			   csc->preoff[0]);
221 	intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_ME(pipe),
222 			   csc->preoff[1]);
223 	intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_LO(pipe),
224 			   csc->preoff[2]);
225 
226 	intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RY_GY(pipe),
227 			   csc->coeff[0] << 16 | csc->coeff[1]);
228 	intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BY(pipe),
229 			   csc->coeff[2] << 16);
230 
231 	intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RU_GU(pipe),
232 			   csc->coeff[3] << 16 | csc->coeff[4]);
233 	intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BU(pipe),
234 			   csc->coeff[5] << 16);
235 
236 	intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RV_GV(pipe),
237 			   csc->coeff[6] << 16 | csc->coeff[7]);
238 	intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BV(pipe),
239 			   csc->coeff[8] << 16);
240 
241 	if (DISPLAY_VER(display) < 7)
242 		return;
243 
244 	intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_HI(pipe),
245 			   csc->postoff[0]);
246 	intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_ME(pipe),
247 			   csc->postoff[1]);
248 	intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_LO(pipe),
249 			   csc->postoff[2]);
250 }
251 
ilk_read_pipe_csc(struct intel_crtc * crtc,struct intel_csc_matrix * csc)252 static void ilk_read_pipe_csc(struct intel_crtc *crtc,
253 			      struct intel_csc_matrix *csc)
254 {
255 	struct intel_display *display = to_intel_display(crtc);
256 	enum pipe pipe = crtc->pipe;
257 	u32 tmp;
258 
259 	csc->preoff[0] = intel_de_read_fw(display, PIPE_CSC_PREOFF_HI(pipe));
260 	csc->preoff[1] = intel_de_read_fw(display, PIPE_CSC_PREOFF_ME(pipe));
261 	csc->preoff[2] = intel_de_read_fw(display, PIPE_CSC_PREOFF_LO(pipe));
262 
263 	tmp = intel_de_read_fw(display, PIPE_CSC_COEFF_RY_GY(pipe));
264 	csc->coeff[0] = tmp >> 16;
265 	csc->coeff[1] = tmp & 0xffff;
266 	tmp = intel_de_read_fw(display, PIPE_CSC_COEFF_BY(pipe));
267 	csc->coeff[2] = tmp >> 16;
268 
269 	tmp = intel_de_read_fw(display, PIPE_CSC_COEFF_RU_GU(pipe));
270 	csc->coeff[3] = tmp >> 16;
271 	csc->coeff[4] = tmp & 0xffff;
272 	tmp = intel_de_read_fw(display, PIPE_CSC_COEFF_BU(pipe));
273 	csc->coeff[5] = tmp >> 16;
274 
275 	tmp = intel_de_read_fw(display, PIPE_CSC_COEFF_RV_GV(pipe));
276 	csc->coeff[6] = tmp >> 16;
277 	csc->coeff[7] = tmp & 0xffff;
278 	tmp = intel_de_read_fw(display, PIPE_CSC_COEFF_BV(pipe));
279 	csc->coeff[8] = tmp >> 16;
280 
281 	if (DISPLAY_VER(display) < 7)
282 		return;
283 
284 	csc->postoff[0] = intel_de_read_fw(display, PIPE_CSC_POSTOFF_HI(pipe));
285 	csc->postoff[1] = intel_de_read_fw(display, PIPE_CSC_POSTOFF_ME(pipe));
286 	csc->postoff[2] = intel_de_read_fw(display, PIPE_CSC_POSTOFF_LO(pipe));
287 }
288 
ilk_read_csc(struct intel_crtc_state * crtc_state)289 static void ilk_read_csc(struct intel_crtc_state *crtc_state)
290 {
291 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
292 
293 	if (crtc_state->csc_enable)
294 		ilk_read_pipe_csc(crtc, &crtc_state->csc);
295 }
296 
skl_read_csc(struct intel_crtc_state * crtc_state)297 static void skl_read_csc(struct intel_crtc_state *crtc_state)
298 {
299 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
300 
301 	/*
302 	 * Display WA #1184: skl,glk
303 	 * Wa_1406463849: icl
304 	 *
305 	 * Danger! On SKL-ICL *reads* from the CSC coeff/offset registers
306 	 * will disarm an already armed CSC double buffer update.
307 	 * So this must not be called while armed. Fortunately the state checker
308 	 * readout happens only after the update has been already been latched.
309 	 *
310 	 * On earlier and later platforms only writes to said registers will
311 	 * disarm the update. This is considered normal behavior and also
312 	 * happens with various other hardware units.
313 	 */
314 	if (crtc_state->csc_enable)
315 		ilk_read_pipe_csc(crtc, &crtc_state->csc);
316 }
317 
icl_update_output_csc(struct intel_dsb * dsb,struct intel_crtc * crtc,const struct intel_csc_matrix * csc)318 static void icl_update_output_csc(struct intel_dsb *dsb,
319 				  struct intel_crtc *crtc,
320 				  const struct intel_csc_matrix *csc)
321 {
322 	struct intel_display *display = to_intel_display(crtc->base.dev);
323 	enum pipe pipe = crtc->pipe;
324 
325 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_HI(pipe),
326 			   csc->preoff[0]);
327 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_ME(pipe),
328 			   csc->preoff[1]);
329 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_LO(pipe),
330 			   csc->preoff[2]);
331 
332 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
333 			   csc->coeff[0] << 16 | csc->coeff[1]);
334 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
335 			   csc->coeff[2] << 16);
336 
337 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
338 			   csc->coeff[3] << 16 | csc->coeff[4]);
339 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
340 			   csc->coeff[5] << 16);
341 
342 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
343 			   csc->coeff[6] << 16 | csc->coeff[7]);
344 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
345 			   csc->coeff[8] << 16);
346 
347 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe),
348 			   csc->postoff[0]);
349 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe),
350 			   csc->postoff[1]);
351 	intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe),
352 			   csc->postoff[2]);
353 }
354 
icl_read_output_csc(struct intel_crtc * crtc,struct intel_csc_matrix * csc)355 static void icl_read_output_csc(struct intel_crtc *crtc,
356 				struct intel_csc_matrix *csc)
357 {
358 	struct intel_display *display = to_intel_display(crtc);
359 	enum pipe pipe = crtc->pipe;
360 	u32 tmp;
361 
362 	csc->preoff[0] = intel_de_read_fw(display, PIPE_CSC_OUTPUT_PREOFF_HI(pipe));
363 	csc->preoff[1] = intel_de_read_fw(display, PIPE_CSC_OUTPUT_PREOFF_ME(pipe));
364 	csc->preoff[2] = intel_de_read_fw(display, PIPE_CSC_OUTPUT_PREOFF_LO(pipe));
365 
366 	tmp = intel_de_read_fw(display, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe));
367 	csc->coeff[0] = tmp >> 16;
368 	csc->coeff[1] = tmp & 0xffff;
369 	tmp = intel_de_read_fw(display, PIPE_CSC_OUTPUT_COEFF_BY(pipe));
370 	csc->coeff[2] = tmp >> 16;
371 
372 	tmp = intel_de_read_fw(display, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe));
373 	csc->coeff[3] = tmp >> 16;
374 	csc->coeff[4] = tmp & 0xffff;
375 	tmp = intel_de_read_fw(display, PIPE_CSC_OUTPUT_COEFF_BU(pipe));
376 	csc->coeff[5] = tmp >> 16;
377 
378 	tmp = intel_de_read_fw(display, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe));
379 	csc->coeff[6] = tmp >> 16;
380 	csc->coeff[7] = tmp & 0xffff;
381 	tmp = intel_de_read_fw(display, PIPE_CSC_OUTPUT_COEFF_BV(pipe));
382 	csc->coeff[8] = tmp >> 16;
383 
384 	csc->postoff[0] = intel_de_read_fw(display, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe));
385 	csc->postoff[1] = intel_de_read_fw(display, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe));
386 	csc->postoff[2] = intel_de_read_fw(display, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe));
387 }
388 
icl_read_csc(struct intel_crtc_state * crtc_state)389 static void icl_read_csc(struct intel_crtc_state *crtc_state)
390 {
391 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
392 
393 	/*
394 	 * Wa_1406463849: icl
395 	 *
396 	 * See skl_read_csc()
397 	 */
398 	if (crtc_state->csc_mode & ICL_CSC_ENABLE)
399 		ilk_read_pipe_csc(crtc, &crtc_state->csc);
400 
401 	if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE)
402 		icl_read_output_csc(crtc, &crtc_state->output_csc);
403 }
404 
ilk_limited_range(const struct intel_crtc_state * crtc_state)405 static bool ilk_limited_range(const struct intel_crtc_state *crtc_state)
406 {
407 	struct intel_display *display = to_intel_display(crtc_state);
408 	struct drm_i915_private *i915 = to_i915(display->drm);
409 
410 	/* icl+ have dedicated output CSC */
411 	if (DISPLAY_VER(display) >= 11)
412 		return false;
413 
414 	/* pre-hsw have TRANSCONF_COLOR_RANGE_SELECT */
415 	if (DISPLAY_VER(display) < 7 || IS_IVYBRIDGE(i915))
416 		return false;
417 
418 	return crtc_state->limited_color_range;
419 }
420 
ilk_lut_limited_range(const struct intel_crtc_state * crtc_state)421 static bool ilk_lut_limited_range(const struct intel_crtc_state *crtc_state)
422 {
423 	struct intel_display *display = to_intel_display(crtc_state);
424 
425 	if (!ilk_limited_range(crtc_state))
426 		return false;
427 
428 	if (crtc_state->c8_planes)
429 		return false;
430 
431 	if (DISPLAY_VER(display) == 10)
432 		return crtc_state->hw.gamma_lut;
433 	else
434 		return crtc_state->hw.gamma_lut &&
435 			(crtc_state->hw.degamma_lut || crtc_state->hw.ctm);
436 }
437 
ilk_csc_limited_range(const struct intel_crtc_state * crtc_state)438 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
439 {
440 	if (!ilk_limited_range(crtc_state))
441 		return false;
442 
443 	return !ilk_lut_limited_range(crtc_state);
444 }
445 
ilk_csc_copy(struct intel_display * display,struct intel_csc_matrix * dst,const struct intel_csc_matrix * src)446 static void ilk_csc_copy(struct intel_display *display,
447 			 struct intel_csc_matrix *dst,
448 			 const struct intel_csc_matrix *src)
449 {
450 	*dst = *src;
451 
452 	if (DISPLAY_VER(display) < 7)
453 		memset(dst->postoff, 0, sizeof(dst->postoff));
454 }
455 
ilk_csc_convert_ctm(const struct intel_crtc_state * crtc_state,struct intel_csc_matrix * csc,bool limited_color_range)456 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
457 				struct intel_csc_matrix *csc,
458 				bool limited_color_range)
459 {
460 	struct intel_display *display = to_intel_display(crtc_state);
461 	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
462 	const u64 *input;
463 	u64 temp[9];
464 	int i;
465 
466 	/* for preoff/postoff */
467 	if (limited_color_range)
468 		ilk_csc_copy(display, csc, &ilk_csc_matrix_limited_range);
469 	else
470 		ilk_csc_copy(display, csc, &ilk_csc_matrix_identity);
471 
472 	if (limited_color_range)
473 		input = ctm_mult_by_limited(temp, ctm->matrix);
474 	else
475 		input = ctm->matrix;
476 
477 	/*
478 	 * Convert fixed point S31.32 input to format supported by the
479 	 * hardware.
480 	 */
481 	for (i = 0; i < 9; i++) {
482 		u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
483 
484 		/*
485 		 * Clamp input value to min/max supported by
486 		 * hardware.
487 		 */
488 		abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
489 
490 		csc->coeff[i] = 0;
491 
492 		/* sign bit */
493 		if (CTM_COEFF_NEGATIVE(input[i]))
494 			csc->coeff[i] |= 1 << 15;
495 
496 		if (abs_coeff < CTM_COEFF_0_125)
497 			csc->coeff[i] |= (3 << 12) |
498 				ILK_CSC_COEFF_FP(abs_coeff, 12);
499 		else if (abs_coeff < CTM_COEFF_0_25)
500 			csc->coeff[i] |= (2 << 12) |
501 				ILK_CSC_COEFF_FP(abs_coeff, 11);
502 		else if (abs_coeff < CTM_COEFF_0_5)
503 			csc->coeff[i] |= (1 << 12) |
504 				ILK_CSC_COEFF_FP(abs_coeff, 10);
505 		else if (abs_coeff < CTM_COEFF_1_0)
506 			csc->coeff[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
507 		else if (abs_coeff < CTM_COEFF_2_0)
508 			csc->coeff[i] |= (7 << 12) |
509 				ILK_CSC_COEFF_FP(abs_coeff, 8);
510 		else
511 			csc->coeff[i] |= (6 << 12) |
512 				ILK_CSC_COEFF_FP(abs_coeff, 7);
513 	}
514 }
515 
ilk_assign_csc(struct intel_crtc_state * crtc_state)516 static void ilk_assign_csc(struct intel_crtc_state *crtc_state)
517 {
518 	struct intel_display *display = to_intel_display(crtc_state);
519 	struct drm_i915_private *i915 = to_i915(display->drm);
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, !IS_GEMINILAKE(i915));
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_vblank)
1343 		intel_dsb_reg_write(crtc_state->dsb_color_vblank, 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_vblank)
1354 		intel_dsb_reg_write_indexed(crtc_state->dsb_color_vblank, 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_vblank)
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_vblank)
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_prepare_commit(struct intel_atomic_state * state,struct intel_crtc * crtc)1968 void intel_color_prepare_commit(struct intel_atomic_state *state,
1969 				struct intel_crtc *crtc)
1970 {
1971 	struct intel_display *display = to_intel_display(state);
1972 	struct intel_crtc_state *crtc_state =
1973 		intel_atomic_get_new_crtc_state(state, crtc);
1974 
1975 	if (!crtc_state->hw.active ||
1976 	    intel_crtc_needs_modeset(crtc_state))
1977 		return;
1978 
1979 	if (!intel_crtc_needs_color_update(crtc_state))
1980 		return;
1981 
1982 	if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
1983 		return;
1984 
1985 	crtc_state->dsb_color_vblank = intel_dsb_prepare(state, crtc, INTEL_DSB_1, 1024);
1986 	if (!crtc_state->dsb_color_vblank)
1987 		return;
1988 
1989 	display->funcs.color->load_luts(crtc_state);
1990 
1991 	if (crtc_state->use_dsb) {
1992 		intel_vrr_send_push(crtc_state->dsb_color_vblank, crtc_state);
1993 		intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank);
1994 		intel_vrr_check_push_sent(crtc_state->dsb_color_vblank, crtc_state);
1995 		intel_dsb_interrupt(crtc_state->dsb_color_vblank);
1996 	}
1997 
1998 	intel_dsb_finish(crtc_state->dsb_color_vblank);
1999 }
2000 
intel_color_cleanup_commit(struct intel_crtc_state * crtc_state)2001 void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
2002 {
2003 	if (crtc_state->dsb_color_vblank) {
2004 		intel_dsb_cleanup(crtc_state->dsb_color_vblank);
2005 		crtc_state->dsb_color_vblank = NULL;
2006 	}
2007 }
2008 
intel_color_wait_commit(const struct intel_crtc_state * crtc_state)2009 void intel_color_wait_commit(const struct intel_crtc_state *crtc_state)
2010 {
2011 	if (crtc_state->dsb_color_vblank)
2012 		intel_dsb_wait(crtc_state->dsb_color_vblank);
2013 }
2014 
intel_color_uses_dsb(const struct intel_crtc_state * crtc_state)2015 bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
2016 {
2017 	return crtc_state->dsb_color_vblank;
2018 }
2019 
intel_can_preload_luts(struct intel_atomic_state * state,struct intel_crtc * crtc)2020 static bool intel_can_preload_luts(struct intel_atomic_state *state,
2021 				   struct intel_crtc *crtc)
2022 {
2023 	const struct intel_crtc_state *old_crtc_state =
2024 		intel_atomic_get_old_crtc_state(state, crtc);
2025 
2026 	return !old_crtc_state->post_csc_lut &&
2027 		!old_crtc_state->pre_csc_lut;
2028 }
2029 
vlv_can_preload_luts(struct intel_atomic_state * state,struct intel_crtc * crtc)2030 static bool vlv_can_preload_luts(struct intel_atomic_state *state,
2031 				 struct intel_crtc *crtc)
2032 {
2033 	const struct intel_crtc_state *old_crtc_state =
2034 		intel_atomic_get_old_crtc_state(state, crtc);
2035 
2036 	return !old_crtc_state->wgc_enable &&
2037 		!old_crtc_state->post_csc_lut;
2038 }
2039 
chv_can_preload_luts(struct intel_atomic_state * state,struct intel_crtc * crtc)2040 static bool chv_can_preload_luts(struct intel_atomic_state *state,
2041 				 struct intel_crtc *crtc)
2042 {
2043 	const struct intel_crtc_state *old_crtc_state =
2044 		intel_atomic_get_old_crtc_state(state, crtc);
2045 	const struct intel_crtc_state *new_crtc_state =
2046 		intel_atomic_get_new_crtc_state(state, crtc);
2047 
2048 	/*
2049 	 * CGM_PIPE_MODE is itself single buffered. We'd have to
2050 	 * somehow split it out from chv_load_luts() if we wanted
2051 	 * the ability to preload the CGM LUTs/CSC without tearing.
2052 	 */
2053 	if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
2054 		return false;
2055 
2056 	return vlv_can_preload_luts(state, crtc);
2057 }
2058 
intel_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2059 int intel_color_check(struct intel_atomic_state *state,
2060 		      struct intel_crtc *crtc)
2061 {
2062 	struct intel_display *display = to_intel_display(state);
2063 	const struct intel_crtc_state *old_crtc_state =
2064 		intel_atomic_get_old_crtc_state(state, crtc);
2065 	struct intel_crtc_state *new_crtc_state =
2066 		intel_atomic_get_new_crtc_state(state, crtc);
2067 
2068 	/*
2069 	 * May need to update pipe gamma enable bits
2070 	 * when C8 planes are getting enabled/disabled.
2071 	 */
2072 	if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes)
2073 		new_crtc_state->uapi.color_mgmt_changed = true;
2074 
2075 	if (!intel_crtc_needs_color_update(new_crtc_state))
2076 		return 0;
2077 
2078 	return display->funcs.color->color_check(state, crtc);
2079 }
2080 
intel_color_get_config(struct intel_crtc_state * crtc_state)2081 void intel_color_get_config(struct intel_crtc_state *crtc_state)
2082 {
2083 	struct intel_display *display = to_intel_display(crtc_state);
2084 
2085 	display->funcs.color->get_config(crtc_state);
2086 
2087 	display->funcs.color->read_luts(crtc_state);
2088 
2089 	if (display->funcs.color->read_csc)
2090 		display->funcs.color->read_csc(crtc_state);
2091 }
2092 
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)2093 bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state,
2094 			   const struct drm_property_blob *blob1,
2095 			   const struct drm_property_blob *blob2,
2096 			   bool is_pre_csc_lut)
2097 {
2098 	struct intel_display *display = to_intel_display(crtc_state);
2099 
2100 	/*
2101 	 * FIXME c8_planes readout missing thus
2102 	 * .read_luts() doesn't read out post_csc_lut.
2103 	 */
2104 	if (!is_pre_csc_lut && crtc_state->c8_planes)
2105 		return true;
2106 
2107 	return display->funcs.color->lut_equal(crtc_state, blob1, blob2,
2108 					       is_pre_csc_lut);
2109 }
2110 
need_plane_update(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)2111 static bool need_plane_update(struct intel_plane *plane,
2112 			      const struct intel_crtc_state *crtc_state)
2113 {
2114 	struct intel_display *display = to_intel_display(plane);
2115 
2116 	/*
2117 	 * On pre-SKL the pipe gamma enable and pipe csc enable for
2118 	 * the pipe bottom color are configured via the primary plane.
2119 	 * We have to reconfigure that even if the plane is inactive.
2120 	 */
2121 	return crtc_state->active_planes & BIT(plane->id) ||
2122 		(DISPLAY_VER(display) < 9 && plane->id == PLANE_PRIMARY);
2123 }
2124 
2125 static int
intel_color_add_affected_planes(struct intel_atomic_state * state,struct intel_crtc * crtc)2126 intel_color_add_affected_planes(struct intel_atomic_state *state,
2127 				struct intel_crtc *crtc)
2128 {
2129 	struct intel_display *display = to_intel_display(state);
2130 	const struct intel_crtc_state *old_crtc_state =
2131 		intel_atomic_get_old_crtc_state(state, crtc);
2132 	struct intel_crtc_state *new_crtc_state =
2133 		intel_atomic_get_new_crtc_state(state, crtc);
2134 	struct intel_plane *plane;
2135 
2136 	if (!new_crtc_state->hw.active ||
2137 	    intel_crtc_needs_modeset(new_crtc_state))
2138 		return 0;
2139 
2140 	if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
2141 	    new_crtc_state->csc_enable == old_crtc_state->csc_enable)
2142 		return 0;
2143 
2144 	for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
2145 		struct intel_plane_state *plane_state;
2146 
2147 		if (!need_plane_update(plane, new_crtc_state))
2148 			continue;
2149 
2150 		plane_state = intel_atomic_get_plane_state(state, plane);
2151 		if (IS_ERR(plane_state))
2152 			return PTR_ERR(plane_state);
2153 
2154 		new_crtc_state->update_planes |= BIT(plane->id);
2155 		new_crtc_state->async_flip_planes = 0;
2156 		new_crtc_state->do_async_flip = false;
2157 
2158 		/* plane control register changes blocked by CxSR */
2159 		if (HAS_GMCH(display))
2160 			new_crtc_state->disable_cxsr = true;
2161 	}
2162 
2163 	return 0;
2164 }
2165 
intel_gamma_lut_tests(const struct intel_crtc_state * crtc_state)2166 static u32 intel_gamma_lut_tests(const struct intel_crtc_state *crtc_state)
2167 {
2168 	struct intel_display *display = to_intel_display(crtc_state);
2169 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
2170 
2171 	if (lut_is_legacy(gamma_lut))
2172 		return 0;
2173 
2174 	return DISPLAY_INFO(display)->color.gamma_lut_tests;
2175 }
2176 
intel_degamma_lut_tests(const struct intel_crtc_state * crtc_state)2177 static u32 intel_degamma_lut_tests(const struct intel_crtc_state *crtc_state)
2178 {
2179 	struct intel_display *display = to_intel_display(crtc_state);
2180 
2181 	return DISPLAY_INFO(display)->color.degamma_lut_tests;
2182 }
2183 
intel_gamma_lut_size(const struct intel_crtc_state * crtc_state)2184 static int intel_gamma_lut_size(const struct intel_crtc_state *crtc_state)
2185 {
2186 	struct intel_display *display = to_intel_display(crtc_state);
2187 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
2188 
2189 	if (lut_is_legacy(gamma_lut))
2190 		return LEGACY_LUT_LENGTH;
2191 
2192 	return DISPLAY_INFO(display)->color.gamma_lut_size;
2193 }
2194 
intel_degamma_lut_size(const struct intel_crtc_state * crtc_state)2195 static u32 intel_degamma_lut_size(const struct intel_crtc_state *crtc_state)
2196 {
2197 	struct intel_display *display = to_intel_display(crtc_state);
2198 
2199 	return DISPLAY_INFO(display)->color.degamma_lut_size;
2200 }
2201 
check_lut_size(struct intel_crtc * crtc,const char * lut_name,const struct drm_property_blob * lut,int expected)2202 static int check_lut_size(struct intel_crtc *crtc, const char *lut_name,
2203 			  const struct drm_property_blob *lut, int expected)
2204 {
2205 	struct intel_display *display = to_intel_display(crtc);
2206 	int len;
2207 
2208 	if (!lut)
2209 		return 0;
2210 
2211 	len = drm_color_lut_size(lut);
2212 	if (len != expected) {
2213 		drm_dbg_kms(display->drm,
2214 			    "[CRTC:%d:%s] Invalid %s LUT size; got %d, expected %d\n",
2215 			    crtc->base.base.id, crtc->base.name, lut_name, len, expected);
2216 		return -EINVAL;
2217 	}
2218 
2219 	return 0;
2220 }
2221 
_check_luts(const struct intel_crtc_state * crtc_state,u32 degamma_tests,u32 gamma_tests)2222 static int _check_luts(const struct intel_crtc_state *crtc_state,
2223 		       u32 degamma_tests, u32 gamma_tests)
2224 {
2225 	struct intel_display *display = to_intel_display(crtc_state);
2226 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2227 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
2228 	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
2229 	int gamma_length, degamma_length;
2230 
2231 	/* C8 relies on its palette being stored in the legacy LUT */
2232 	if (crtc_state->c8_planes && !lut_is_legacy(crtc_state->hw.gamma_lut)) {
2233 		drm_dbg_kms(display->drm,
2234 			    "[CRTC:%d:%s] C8 pixelformat requires the legacy LUT\n",
2235 			    crtc->base.base.id, crtc->base.name);
2236 		return -EINVAL;
2237 	}
2238 
2239 	degamma_length = intel_degamma_lut_size(crtc_state);
2240 	gamma_length = intel_gamma_lut_size(crtc_state);
2241 
2242 	if (check_lut_size(crtc, "degamma", degamma_lut, degamma_length) ||
2243 	    check_lut_size(crtc, "gamma", gamma_lut, gamma_length))
2244 		return -EINVAL;
2245 
2246 	if (drm_color_lut_check(degamma_lut, degamma_tests) ||
2247 	    drm_color_lut_check(gamma_lut, gamma_tests))
2248 		return -EINVAL;
2249 
2250 	return 0;
2251 }
2252 
check_luts(const struct intel_crtc_state * crtc_state)2253 static int check_luts(const struct intel_crtc_state *crtc_state)
2254 {
2255 	return _check_luts(crtc_state,
2256 			   intel_degamma_lut_tests(crtc_state),
2257 			   intel_gamma_lut_tests(crtc_state));
2258 }
2259 
i9xx_gamma_mode(struct intel_crtc_state * crtc_state)2260 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
2261 {
2262 	if (!crtc_state->gamma_enable ||
2263 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2264 		return GAMMA_MODE_MODE_8BIT;
2265 	else
2266 		return GAMMA_MODE_MODE_10BIT;
2267 }
2268 
i9xx_lut_10_diff(u16 a,u16 b)2269 static int i9xx_lut_10_diff(u16 a, u16 b)
2270 {
2271 	return drm_color_lut_extract(a, 10) -
2272 		drm_color_lut_extract(b, 10);
2273 }
2274 
i9xx_check_lut_10(struct intel_crtc * crtc,const struct drm_property_blob * blob)2275 static int i9xx_check_lut_10(struct intel_crtc *crtc,
2276 			     const struct drm_property_blob *blob)
2277 {
2278 	struct intel_display *display = to_intel_display(crtc);
2279 	const struct drm_color_lut *lut = blob->data;
2280 	int lut_size = drm_color_lut_size(blob);
2281 	const struct drm_color_lut *a = &lut[lut_size - 2];
2282 	const struct drm_color_lut *b = &lut[lut_size - 1];
2283 
2284 	if (i9xx_lut_10_diff(b->red, a->red) > 0x7f ||
2285 	    i9xx_lut_10_diff(b->green, a->green) > 0x7f ||
2286 	    i9xx_lut_10_diff(b->blue, a->blue) > 0x7f) {
2287 		drm_dbg_kms(display->drm,
2288 			    "[CRTC:%d:%s] Last gamma LUT entry exceeds max slope\n",
2289 			    crtc->base.base.id, crtc->base.name);
2290 		return -EINVAL;
2291 	}
2292 
2293 	return 0;
2294 }
2295 
intel_color_assert_luts(const struct intel_crtc_state * crtc_state)2296 void intel_color_assert_luts(const struct intel_crtc_state *crtc_state)
2297 {
2298 	struct intel_display *display = to_intel_display(crtc_state);
2299 
2300 	/* make sure {pre,post}_csc_lut were correctly assigned */
2301 	if (DISPLAY_VER(display) >= 11 || HAS_GMCH(display)) {
2302 		drm_WARN_ON(display->drm,
2303 			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut);
2304 		drm_WARN_ON(display->drm,
2305 			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2306 	} else if (DISPLAY_VER(display) == 10) {
2307 		drm_WARN_ON(display->drm,
2308 			    crtc_state->post_csc_lut == crtc_state->hw.gamma_lut &&
2309 			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2310 			    crtc_state->pre_csc_lut != display->color.glk_linear_degamma_lut);
2311 		drm_WARN_ON(display->drm,
2312 			    !ilk_lut_limited_range(crtc_state) &&
2313 			    crtc_state->post_csc_lut != NULL &&
2314 			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2315 	} else if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT) {
2316 		drm_WARN_ON(display->drm,
2317 			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2318 			    crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut);
2319 		drm_WARN_ON(display->drm,
2320 			    !ilk_lut_limited_range(crtc_state) &&
2321 			    crtc_state->post_csc_lut != crtc_state->hw.degamma_lut &&
2322 			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2323 	}
2324 }
2325 
intel_assign_luts(struct intel_crtc_state * crtc_state)2326 static void intel_assign_luts(struct intel_crtc_state *crtc_state)
2327 {
2328 	drm_property_replace_blob(&crtc_state->pre_csc_lut,
2329 				  crtc_state->hw.degamma_lut);
2330 	drm_property_replace_blob(&crtc_state->post_csc_lut,
2331 				  crtc_state->hw.gamma_lut);
2332 }
2333 
i9xx_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2334 static int i9xx_color_check(struct intel_atomic_state *state,
2335 			    struct intel_crtc *crtc)
2336 {
2337 	struct intel_display *display = to_intel_display(state);
2338 	struct intel_crtc_state *crtc_state =
2339 		intel_atomic_get_new_crtc_state(state, crtc);
2340 	int ret;
2341 
2342 	ret = check_luts(crtc_state);
2343 	if (ret)
2344 		return ret;
2345 
2346 	crtc_state->gamma_enable =
2347 		crtc_state->hw.gamma_lut &&
2348 		!crtc_state->c8_planes;
2349 
2350 	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2351 
2352 	if (DISPLAY_VER(display) < 4 &&
2353 	    crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT) {
2354 		ret = i9xx_check_lut_10(crtc, crtc_state->hw.gamma_lut);
2355 		if (ret)
2356 			return ret;
2357 	}
2358 
2359 	ret = intel_color_add_affected_planes(state, crtc);
2360 	if (ret)
2361 		return ret;
2362 
2363 	intel_assign_luts(crtc_state);
2364 
2365 	crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
2366 
2367 	return 0;
2368 }
2369 
2370 /*
2371  * VLV color pipeline:
2372  * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2373  */
vlv_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2374 static int vlv_color_check(struct intel_atomic_state *state,
2375 			   struct intel_crtc *crtc)
2376 {
2377 	struct intel_crtc_state *crtc_state =
2378 		intel_atomic_get_new_crtc_state(state, crtc);
2379 	int ret;
2380 
2381 	ret = check_luts(crtc_state);
2382 	if (ret)
2383 		return ret;
2384 
2385 	crtc_state->gamma_enable =
2386 		crtc_state->hw.gamma_lut &&
2387 		!crtc_state->c8_planes;
2388 
2389 	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2390 
2391 	crtc_state->wgc_enable = crtc_state->hw.ctm;
2392 
2393 	ret = intel_color_add_affected_planes(state, crtc);
2394 	if (ret)
2395 		return ret;
2396 
2397 	intel_assign_luts(crtc_state);
2398 
2399 	vlv_assign_csc(crtc_state);
2400 
2401 	crtc_state->preload_luts = vlv_can_preload_luts(state, crtc);
2402 
2403 	return 0;
2404 }
2405 
chv_cgm_mode(const struct intel_crtc_state * crtc_state)2406 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
2407 {
2408 	u32 cgm_mode = 0;
2409 
2410 	if (crtc_state->hw.degamma_lut)
2411 		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
2412 	if (crtc_state->hw.ctm)
2413 		cgm_mode |= CGM_PIPE_MODE_CSC;
2414 	if (crtc_state->hw.gamma_lut &&
2415 	    !lut_is_legacy(crtc_state->hw.gamma_lut))
2416 		cgm_mode |= CGM_PIPE_MODE_GAMMA;
2417 
2418 	/*
2419 	 * Toggling the CGM CSC on/off outside of the tiny window
2420 	 * between start of vblank and frame start causes underruns.
2421 	 * Always enable the CGM CSC as a workaround.
2422 	 */
2423 	cgm_mode |= CGM_PIPE_MODE_CSC;
2424 
2425 	return cgm_mode;
2426 }
2427 
2428 /*
2429  * CHV color pipeline:
2430  * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
2431  * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2432  *
2433  * We always bypass the WGC csc and use the CGM csc
2434  * instead since it has degamma and better precision.
2435  */
chv_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2436 static int chv_color_check(struct intel_atomic_state *state,
2437 			   struct intel_crtc *crtc)
2438 {
2439 	struct intel_crtc_state *crtc_state =
2440 		intel_atomic_get_new_crtc_state(state, crtc);
2441 	int ret;
2442 
2443 	ret = check_luts(crtc_state);
2444 	if (ret)
2445 		return ret;
2446 
2447 	/*
2448 	 * Pipe gamma will be used only for the legacy LUT.
2449 	 * Otherwise we bypass it and use the CGM gamma instead.
2450 	 */
2451 	crtc_state->gamma_enable =
2452 		lut_is_legacy(crtc_state->hw.gamma_lut) &&
2453 		!crtc_state->c8_planes;
2454 
2455 	crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
2456 
2457 	crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
2458 
2459 	/*
2460 	 * We always bypass the WGC CSC and use the CGM CSC
2461 	 * instead since it has degamma and better precision.
2462 	 */
2463 	crtc_state->wgc_enable = false;
2464 
2465 	ret = intel_color_add_affected_planes(state, crtc);
2466 	if (ret)
2467 		return ret;
2468 
2469 	intel_assign_luts(crtc_state);
2470 
2471 	chv_assign_csc(crtc_state);
2472 
2473 	crtc_state->preload_luts = chv_can_preload_luts(state, crtc);
2474 
2475 	return 0;
2476 }
2477 
ilk_gamma_enable(const struct intel_crtc_state * crtc_state)2478 static bool ilk_gamma_enable(const struct intel_crtc_state *crtc_state)
2479 {
2480 	return (crtc_state->hw.gamma_lut ||
2481 		crtc_state->hw.degamma_lut) &&
2482 		!crtc_state->c8_planes;
2483 }
2484 
ilk_csc_enable(const struct intel_crtc_state * crtc_state)2485 static bool ilk_csc_enable(const struct intel_crtc_state *crtc_state)
2486 {
2487 	return crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2488 		ilk_csc_limited_range(crtc_state) ||
2489 		crtc_state->hw.ctm;
2490 }
2491 
ilk_gamma_mode(const struct intel_crtc_state * crtc_state)2492 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
2493 {
2494 	if (!crtc_state->gamma_enable ||
2495 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2496 		return GAMMA_MODE_MODE_8BIT;
2497 	else
2498 		return GAMMA_MODE_MODE_10BIT;
2499 }
2500 
ilk_csc_mode(const struct intel_crtc_state * crtc_state)2501 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
2502 {
2503 	/*
2504 	 * CSC comes after the LUT in RGB->YCbCr mode.
2505 	 * RGB->YCbCr needs the limited range offsets added to
2506 	 * the output. RGB limited range output is handled by
2507 	 * the hw automagically elsewhere.
2508 	 */
2509 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
2510 		return CSC_BLACK_SCREEN_OFFSET;
2511 
2512 	if (crtc_state->hw.degamma_lut)
2513 		return CSC_MODE_YUV_TO_RGB;
2514 
2515 	return CSC_MODE_YUV_TO_RGB |
2516 		CSC_POSITION_BEFORE_GAMMA;
2517 }
2518 
ilk_assign_luts(struct intel_crtc_state * crtc_state)2519 static int ilk_assign_luts(struct intel_crtc_state *crtc_state)
2520 {
2521 	struct intel_display *display = to_intel_display(crtc_state);
2522 
2523 	if (ilk_lut_limited_range(crtc_state)) {
2524 		struct drm_property_blob *gamma_lut;
2525 
2526 		gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut,
2527 					       drm_color_lut_size(crtc_state->hw.gamma_lut),
2528 					       true);
2529 		if (IS_ERR(gamma_lut))
2530 			return PTR_ERR(gamma_lut);
2531 
2532 		drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2533 
2534 		drm_property_blob_put(gamma_lut);
2535 
2536 		drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2537 
2538 		return 0;
2539 	}
2540 
2541 	if (crtc_state->hw.degamma_lut ||
2542 	    crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
2543 		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2544 					  crtc_state->hw.degamma_lut);
2545 		drm_property_replace_blob(&crtc_state->post_csc_lut,
2546 					  crtc_state->hw.gamma_lut);
2547 	} else {
2548 		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2549 					  crtc_state->hw.gamma_lut);
2550 		drm_property_replace_blob(&crtc_state->post_csc_lut,
2551 					  NULL);
2552 	}
2553 
2554 	return 0;
2555 }
2556 
ilk_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2557 static int ilk_color_check(struct intel_atomic_state *state,
2558 			   struct intel_crtc *crtc)
2559 {
2560 	struct intel_display *display = to_intel_display(state);
2561 	struct intel_crtc_state *crtc_state =
2562 		intel_atomic_get_new_crtc_state(state, crtc);
2563 	int ret;
2564 
2565 	ret = check_luts(crtc_state);
2566 	if (ret)
2567 		return ret;
2568 
2569 	if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2570 		drm_dbg_kms(display->drm,
2571 			    "[CRTC:%d:%s] Degamma and gamma together are not possible\n",
2572 			    crtc->base.base.id, crtc->base.name);
2573 		return -EINVAL;
2574 	}
2575 
2576 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2577 	    crtc_state->hw.ctm) {
2578 		drm_dbg_kms(display->drm,
2579 			    "[CRTC:%d:%s] YCbCr and CTM together are not possible\n",
2580 			    crtc->base.base.id, crtc->base.name);
2581 		return -EINVAL;
2582 	}
2583 
2584 	crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2585 
2586 	crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2587 
2588 	crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
2589 
2590 	crtc_state->csc_mode = ilk_csc_mode(crtc_state);
2591 
2592 	ret = intel_color_add_affected_planes(state, crtc);
2593 	if (ret)
2594 		return ret;
2595 
2596 	ret = ilk_assign_luts(crtc_state);
2597 	if (ret)
2598 		return ret;
2599 
2600 	ilk_assign_csc(crtc_state);
2601 
2602 	crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
2603 
2604 	return 0;
2605 }
2606 
ivb_gamma_mode(const struct intel_crtc_state * crtc_state)2607 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
2608 {
2609 	if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut)
2610 		return GAMMA_MODE_MODE_SPLIT;
2611 
2612 	return ilk_gamma_mode(crtc_state);
2613 }
2614 
ivb_csc_mode(const struct intel_crtc_state * crtc_state)2615 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
2616 {
2617 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
2618 
2619 	/*
2620 	 * CSC comes after the LUT in degamma, RGB->YCbCr,
2621 	 * and RGB full->limited range mode.
2622 	 */
2623 	if (crtc_state->hw.degamma_lut ||
2624 	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2625 	    limited_color_range)
2626 		return 0;
2627 
2628 	return CSC_POSITION_BEFORE_GAMMA;
2629 }
2630 
ivb_assign_luts(struct intel_crtc_state * crtc_state)2631 static int ivb_assign_luts(struct intel_crtc_state *crtc_state)
2632 {
2633 	struct intel_display *display = to_intel_display(crtc_state);
2634 	struct drm_property_blob *degamma_lut, *gamma_lut;
2635 
2636 	if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT)
2637 		return ilk_assign_luts(crtc_state);
2638 
2639 	drm_WARN_ON(display->drm, drm_color_lut_size(crtc_state->hw.degamma_lut) != 1024);
2640 	drm_WARN_ON(display->drm, drm_color_lut_size(crtc_state->hw.gamma_lut) != 1024);
2641 
2642 	degamma_lut = create_resized_lut(display, crtc_state->hw.degamma_lut, 512,
2643 					 false);
2644 	if (IS_ERR(degamma_lut))
2645 		return PTR_ERR(degamma_lut);
2646 
2647 	gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut, 512,
2648 				       ilk_lut_limited_range(crtc_state));
2649 	if (IS_ERR(gamma_lut)) {
2650 		drm_property_blob_put(degamma_lut);
2651 		return PTR_ERR(gamma_lut);
2652 	}
2653 
2654 	drm_property_replace_blob(&crtc_state->pre_csc_lut, degamma_lut);
2655 	drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2656 
2657 	drm_property_blob_put(degamma_lut);
2658 	drm_property_blob_put(gamma_lut);
2659 
2660 	return 0;
2661 }
2662 
ivb_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2663 static int ivb_color_check(struct intel_atomic_state *state,
2664 			   struct intel_crtc *crtc)
2665 {
2666 	struct intel_display *display = to_intel_display(state);
2667 	struct intel_crtc_state *crtc_state =
2668 		intel_atomic_get_new_crtc_state(state, crtc);
2669 	int ret;
2670 
2671 	ret = check_luts(crtc_state);
2672 	if (ret)
2673 		return ret;
2674 
2675 	if (crtc_state->c8_planes && crtc_state->hw.degamma_lut) {
2676 		drm_dbg_kms(display->drm,
2677 			    "[CRTC:%d:%s] C8 pixelformat and degamma together are not possible\n",
2678 			    crtc->base.base.id, crtc->base.name);
2679 		return -EINVAL;
2680 	}
2681 
2682 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2683 	    crtc_state->hw.ctm) {
2684 		drm_dbg_kms(display->drm,
2685 			    "[CRTC:%d:%s] YCbCr and CTM together are not possible\n",
2686 			    crtc->base.base.id, crtc->base.name);
2687 		return -EINVAL;
2688 	}
2689 
2690 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2691 	    crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2692 		drm_dbg_kms(display->drm,
2693 			    "[CRTC:%d:%s] YCbCr and degamma+gamma together are not possible\n",
2694 			    crtc->base.base.id, crtc->base.name);
2695 		return -EINVAL;
2696 	}
2697 
2698 	crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2699 
2700 	crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2701 
2702 	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
2703 
2704 	crtc_state->csc_mode = ivb_csc_mode(crtc_state);
2705 
2706 	ret = intel_color_add_affected_planes(state, crtc);
2707 	if (ret)
2708 		return ret;
2709 
2710 	ret = ivb_assign_luts(crtc_state);
2711 	if (ret)
2712 		return ret;
2713 
2714 	ilk_assign_csc(crtc_state);
2715 
2716 	crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
2717 
2718 	return 0;
2719 }
2720 
glk_gamma_mode(const struct intel_crtc_state * crtc_state)2721 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
2722 {
2723 	if (!crtc_state->gamma_enable ||
2724 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2725 		return GAMMA_MODE_MODE_8BIT;
2726 	else
2727 		return GAMMA_MODE_MODE_10BIT;
2728 }
2729 
glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state * crtc_state)2730 static bool glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state *crtc_state)
2731 {
2732 	return crtc_state->hw.gamma_lut &&
2733 		!crtc_state->c8_planes &&
2734 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
2735 }
2736 
glk_assign_luts(struct intel_crtc_state * crtc_state)2737 static int glk_assign_luts(struct intel_crtc_state *crtc_state)
2738 {
2739 	struct intel_display *display = to_intel_display(crtc_state);
2740 
2741 	if (glk_use_pre_csc_lut_for_gamma(crtc_state)) {
2742 		struct drm_property_blob *gamma_lut;
2743 
2744 		gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut,
2745 					       DISPLAY_INFO(display)->color.degamma_lut_size,
2746 					       false);
2747 		if (IS_ERR(gamma_lut))
2748 			return PTR_ERR(gamma_lut);
2749 
2750 		drm_property_replace_blob(&crtc_state->pre_csc_lut, gamma_lut);
2751 		drm_property_replace_blob(&crtc_state->post_csc_lut, NULL);
2752 
2753 		drm_property_blob_put(gamma_lut);
2754 
2755 		return 0;
2756 	}
2757 
2758 	if (ilk_lut_limited_range(crtc_state)) {
2759 		struct drm_property_blob *gamma_lut;
2760 
2761 		gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut,
2762 					       drm_color_lut_size(crtc_state->hw.gamma_lut),
2763 					       true);
2764 		if (IS_ERR(gamma_lut))
2765 			return PTR_ERR(gamma_lut);
2766 
2767 		drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2768 
2769 		drm_property_blob_put(gamma_lut);
2770 	} else {
2771 		drm_property_replace_blob(&crtc_state->post_csc_lut, crtc_state->hw.gamma_lut);
2772 	}
2773 
2774 	drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2775 
2776 	/*
2777 	 * On GLK+ both pipe CSC and degamma LUT are controlled
2778 	 * by csc_enable. Hence for the cases where the CSC is
2779 	 * needed but degamma LUT is not we need to load a
2780 	 * linear degamma LUT.
2781 	 */
2782 	if (crtc_state->csc_enable && !crtc_state->pre_csc_lut)
2783 		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2784 					  display->color.glk_linear_degamma_lut);
2785 
2786 	return 0;
2787 }
2788 
glk_check_luts(const struct intel_crtc_state * crtc_state)2789 static int glk_check_luts(const struct intel_crtc_state *crtc_state)
2790 {
2791 	u32 degamma_tests = intel_degamma_lut_tests(crtc_state);
2792 	u32 gamma_tests = intel_gamma_lut_tests(crtc_state);
2793 
2794 	if (glk_use_pre_csc_lut_for_gamma(crtc_state))
2795 		gamma_tests |= degamma_tests;
2796 
2797 	return _check_luts(crtc_state, degamma_tests, gamma_tests);
2798 }
2799 
glk_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2800 static int glk_color_check(struct intel_atomic_state *state,
2801 			   struct intel_crtc *crtc)
2802 {
2803 	struct intel_display *display = to_intel_display(state);
2804 	struct intel_crtc_state *crtc_state =
2805 		intel_atomic_get_new_crtc_state(state, crtc);
2806 	int ret;
2807 
2808 	ret = glk_check_luts(crtc_state);
2809 	if (ret)
2810 		return ret;
2811 
2812 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2813 	    crtc_state->hw.ctm) {
2814 		drm_dbg_kms(display->drm,
2815 			    "[CRTC:%d:%s] YCbCr and CTM together are not possible\n",
2816 			    crtc->base.base.id, crtc->base.name);
2817 		return -EINVAL;
2818 	}
2819 
2820 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2821 	    crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2822 		drm_dbg_kms(display->drm,
2823 			    "[CRTC:%d:%s] YCbCr and degamma+gamma together are not possible\n",
2824 			    crtc->base.base.id, crtc->base.name);
2825 		return -EINVAL;
2826 	}
2827 
2828 	crtc_state->gamma_enable =
2829 		!glk_use_pre_csc_lut_for_gamma(crtc_state) &&
2830 		crtc_state->hw.gamma_lut &&
2831 		!crtc_state->c8_planes;
2832 
2833 	/* On GLK+ degamma LUT is controlled by csc_enable */
2834 	crtc_state->csc_enable =
2835 		glk_use_pre_csc_lut_for_gamma(crtc_state) ||
2836 		crtc_state->hw.degamma_lut ||
2837 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2838 		crtc_state->hw.ctm || ilk_csc_limited_range(crtc_state);
2839 
2840 	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
2841 
2842 	crtc_state->csc_mode = 0;
2843 
2844 	ret = intel_color_add_affected_planes(state, crtc);
2845 	if (ret)
2846 		return ret;
2847 
2848 	ret = glk_assign_luts(crtc_state);
2849 	if (ret)
2850 		return ret;
2851 
2852 	ilk_assign_csc(crtc_state);
2853 
2854 	crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
2855 
2856 	return 0;
2857 }
2858 
icl_gamma_mode(const struct intel_crtc_state * crtc_state)2859 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
2860 {
2861 	struct intel_display *display = to_intel_display(crtc_state);
2862 	u32 gamma_mode = 0;
2863 
2864 	if (crtc_state->hw.degamma_lut)
2865 		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
2866 
2867 	if (crtc_state->hw.gamma_lut &&
2868 	    !crtc_state->c8_planes)
2869 		gamma_mode |= POST_CSC_GAMMA_ENABLE;
2870 
2871 	if (!crtc_state->hw.gamma_lut ||
2872 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2873 		gamma_mode |= GAMMA_MODE_MODE_8BIT;
2874 	/*
2875 	 * Enable 10bit gamma for D13
2876 	 * ToDo: Extend to Logarithmic Gamma once the new UAPI
2877 	 * is accepted and implemented by a userspace consumer
2878 	 */
2879 	else if (DISPLAY_VER(display) >= 13)
2880 		gamma_mode |= GAMMA_MODE_MODE_10BIT;
2881 	else
2882 		gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEG;
2883 
2884 	return gamma_mode;
2885 }
2886 
icl_csc_mode(const struct intel_crtc_state * crtc_state)2887 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
2888 {
2889 	u32 csc_mode = 0;
2890 
2891 	if (crtc_state->hw.ctm)
2892 		csc_mode |= ICL_CSC_ENABLE;
2893 
2894 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2895 	    crtc_state->limited_color_range)
2896 		csc_mode |= ICL_OUTPUT_CSC_ENABLE;
2897 
2898 	return csc_mode;
2899 }
2900 
icl_color_check(struct intel_atomic_state * state,struct intel_crtc * crtc)2901 static int icl_color_check(struct intel_atomic_state *state,
2902 			   struct intel_crtc *crtc)
2903 {
2904 	struct intel_crtc_state *crtc_state =
2905 		intel_atomic_get_new_crtc_state(state, crtc);
2906 	int ret;
2907 
2908 	ret = check_luts(crtc_state);
2909 	if (ret)
2910 		return ret;
2911 
2912 	crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
2913 
2914 	crtc_state->csc_mode = icl_csc_mode(crtc_state);
2915 
2916 	intel_assign_luts(crtc_state);
2917 
2918 	icl_assign_csc(crtc_state);
2919 
2920 	crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
2921 
2922 	return 0;
2923 }
2924 
i9xx_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2925 static int i9xx_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2926 {
2927 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2928 		return 0;
2929 
2930 	switch (crtc_state->gamma_mode) {
2931 	case GAMMA_MODE_MODE_8BIT:
2932 		return 8;
2933 	case GAMMA_MODE_MODE_10BIT:
2934 		return 10;
2935 	default:
2936 		MISSING_CASE(crtc_state->gamma_mode);
2937 		return 0;
2938 	}
2939 }
2940 
i9xx_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2941 static int i9xx_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2942 {
2943 	return 0;
2944 }
2945 
i965_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2946 static int i965_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2947 {
2948 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2949 		return 0;
2950 
2951 	switch (crtc_state->gamma_mode) {
2952 	case GAMMA_MODE_MODE_8BIT:
2953 		return 8;
2954 	case GAMMA_MODE_MODE_10BIT:
2955 		return 16;
2956 	default:
2957 		MISSING_CASE(crtc_state->gamma_mode);
2958 		return 0;
2959 	}
2960 }
2961 
ilk_gamma_mode_precision(u32 gamma_mode)2962 static int ilk_gamma_mode_precision(u32 gamma_mode)
2963 {
2964 	switch (gamma_mode) {
2965 	case GAMMA_MODE_MODE_8BIT:
2966 		return 8;
2967 	case GAMMA_MODE_MODE_10BIT:
2968 		return 10;
2969 	default:
2970 		MISSING_CASE(gamma_mode);
2971 		return 0;
2972 	}
2973 }
2974 
ilk_has_post_csc_lut(const struct intel_crtc_state * crtc_state)2975 static bool ilk_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2976 {
2977 	if (crtc_state->c8_planes)
2978 		return true;
2979 
2980 	return crtc_state->gamma_enable &&
2981 		(crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) != 0;
2982 }
2983 
ilk_has_pre_csc_lut(const struct intel_crtc_state * crtc_state)2984 static bool ilk_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2985 {
2986 	return crtc_state->gamma_enable &&
2987 		(crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0;
2988 }
2989 
ilk_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)2990 static int ilk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2991 {
2992 	if (!ilk_has_post_csc_lut(crtc_state))
2993 		return 0;
2994 
2995 	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2996 }
2997 
ilk_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)2998 static int ilk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2999 {
3000 	if (!ilk_has_pre_csc_lut(crtc_state))
3001 		return 0;
3002 
3003 	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
3004 }
3005 
ivb_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)3006 static int ivb_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3007 {
3008 	if (crtc_state->gamma_enable &&
3009 	    crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
3010 		return 10;
3011 
3012 	return ilk_post_csc_lut_precision(crtc_state);
3013 }
3014 
ivb_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)3015 static int ivb_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3016 {
3017 	if (crtc_state->gamma_enable &&
3018 	    crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
3019 		return 10;
3020 
3021 	return ilk_pre_csc_lut_precision(crtc_state);
3022 }
3023 
chv_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)3024 static int chv_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3025 {
3026 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
3027 		return 10;
3028 
3029 	return i965_post_csc_lut_precision(crtc_state);
3030 }
3031 
chv_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)3032 static int chv_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3033 {
3034 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
3035 		return 14;
3036 
3037 	return 0;
3038 }
3039 
glk_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)3040 static int glk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3041 {
3042 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3043 		return 0;
3044 
3045 	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
3046 }
3047 
glk_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)3048 static int glk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3049 {
3050 	if (!crtc_state->csc_enable)
3051 		return 0;
3052 
3053 	return 16;
3054 }
3055 
icl_has_post_csc_lut(const struct intel_crtc_state * crtc_state)3056 static bool icl_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
3057 {
3058 	if (crtc_state->c8_planes)
3059 		return true;
3060 
3061 	return crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE;
3062 }
3063 
icl_has_pre_csc_lut(const struct intel_crtc_state * crtc_state)3064 static bool icl_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
3065 {
3066 	return crtc_state->gamma_mode & PRE_CSC_GAMMA_ENABLE;
3067 }
3068 
icl_post_csc_lut_precision(const struct intel_crtc_state * crtc_state)3069 static int icl_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3070 {
3071 	if (!icl_has_post_csc_lut(crtc_state))
3072 		return 0;
3073 
3074 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
3075 	case GAMMA_MODE_MODE_8BIT:
3076 		return 8;
3077 	case GAMMA_MODE_MODE_10BIT:
3078 		return 10;
3079 	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
3080 		return 16;
3081 	default:
3082 		MISSING_CASE(crtc_state->gamma_mode);
3083 		return 0;
3084 	}
3085 }
3086 
icl_pre_csc_lut_precision(const struct intel_crtc_state * crtc_state)3087 static int icl_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
3088 {
3089 	if (!icl_has_pre_csc_lut(crtc_state))
3090 		return 0;
3091 
3092 	return 16;
3093 }
3094 
err_check(const struct drm_color_lut * lut1,const struct drm_color_lut * lut2,u32 err)3095 static bool err_check(const struct drm_color_lut *lut1,
3096 		      const struct drm_color_lut *lut2, u32 err)
3097 {
3098 	return ((abs((long)lut2->red - lut1->red)) <= err) &&
3099 		((abs((long)lut2->blue - lut1->blue)) <= err) &&
3100 		((abs((long)lut2->green - lut1->green)) <= err);
3101 }
3102 
intel_lut_entries_equal(const struct drm_color_lut * lut1,const struct drm_color_lut * lut2,int lut_size,u32 err)3103 static bool intel_lut_entries_equal(const struct drm_color_lut *lut1,
3104 				    const struct drm_color_lut *lut2,
3105 				    int lut_size, u32 err)
3106 {
3107 	int i;
3108 
3109 	for (i = 0; i < lut_size; i++) {
3110 		if (!err_check(&lut1[i], &lut2[i], err))
3111 			return false;
3112 	}
3113 
3114 	return true;
3115 }
3116 
intel_lut_equal(const struct drm_property_blob * blob1,const struct drm_property_blob * blob2,int check_size,int precision)3117 static bool intel_lut_equal(const struct drm_property_blob *blob1,
3118 			    const struct drm_property_blob *blob2,
3119 			    int check_size, int precision)
3120 {
3121 	const struct drm_color_lut *lut1, *lut2;
3122 	int lut_size1, lut_size2;
3123 	u32 err;
3124 
3125 	if (!blob1 != !blob2)
3126 		return false;
3127 
3128 	if (!blob1 != !precision)
3129 		return false;
3130 
3131 	if (!blob1)
3132 		return true;
3133 
3134 	lut_size1 = drm_color_lut_size(blob1);
3135 	lut_size2 = drm_color_lut_size(blob2);
3136 
3137 	if (lut_size1 != lut_size2)
3138 		return false;
3139 
3140 	if (check_size > lut_size1)
3141 		return false;
3142 
3143 	lut1 = blob1->data;
3144 	lut2 = blob2->data;
3145 
3146 	err = 0xffff >> precision;
3147 
3148 	if (!check_size)
3149 		check_size = lut_size1;
3150 
3151 	return intel_lut_entries_equal(lut1, lut2, check_size, err);
3152 }
3153 
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)3154 static bool i9xx_lut_equal(const struct intel_crtc_state *crtc_state,
3155 			   const struct drm_property_blob *blob1,
3156 			   const struct drm_property_blob *blob2,
3157 			   bool is_pre_csc_lut)
3158 {
3159 	int check_size = 0;
3160 
3161 	if (is_pre_csc_lut)
3162 		return intel_lut_equal(blob1, blob2, 0,
3163 				       i9xx_pre_csc_lut_precision(crtc_state));
3164 
3165 	/* 10bit mode last entry is implicit, just skip it */
3166 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT)
3167 		check_size = 128;
3168 
3169 	return intel_lut_equal(blob1, blob2, check_size,
3170 			       i9xx_post_csc_lut_precision(crtc_state));
3171 }
3172 
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)3173 static bool i965_lut_equal(const struct intel_crtc_state *crtc_state,
3174 			   const struct drm_property_blob *blob1,
3175 			   const struct drm_property_blob *blob2,
3176 			   bool is_pre_csc_lut)
3177 {
3178 	if (is_pre_csc_lut)
3179 		return intel_lut_equal(blob1, blob2, 0,
3180 				       i9xx_pre_csc_lut_precision(crtc_state));
3181 	else
3182 		return intel_lut_equal(blob1, blob2, 0,
3183 				       i965_post_csc_lut_precision(crtc_state));
3184 }
3185 
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)3186 static bool chv_lut_equal(const struct intel_crtc_state *crtc_state,
3187 			  const struct drm_property_blob *blob1,
3188 			  const struct drm_property_blob *blob2,
3189 			  bool is_pre_csc_lut)
3190 {
3191 	if (is_pre_csc_lut)
3192 		return intel_lut_equal(blob1, blob2, 0,
3193 				       chv_pre_csc_lut_precision(crtc_state));
3194 	else
3195 		return intel_lut_equal(blob1, blob2, 0,
3196 				       chv_post_csc_lut_precision(crtc_state));
3197 }
3198 
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)3199 static bool ilk_lut_equal(const struct intel_crtc_state *crtc_state,
3200 			  const struct drm_property_blob *blob1,
3201 			  const struct drm_property_blob *blob2,
3202 			  bool is_pre_csc_lut)
3203 {
3204 	if (is_pre_csc_lut)
3205 		return intel_lut_equal(blob1, blob2, 0,
3206 				       ilk_pre_csc_lut_precision(crtc_state));
3207 	else
3208 		return intel_lut_equal(blob1, blob2, 0,
3209 				       ilk_post_csc_lut_precision(crtc_state));
3210 }
3211 
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)3212 static bool ivb_lut_equal(const struct intel_crtc_state *crtc_state,
3213 			  const struct drm_property_blob *blob1,
3214 			  const struct drm_property_blob *blob2,
3215 			  bool is_pre_csc_lut)
3216 {
3217 	if (is_pre_csc_lut)
3218 		return intel_lut_equal(blob1, blob2, 0,
3219 				       ivb_pre_csc_lut_precision(crtc_state));
3220 	else
3221 		return intel_lut_equal(blob1, blob2, 0,
3222 				       ivb_post_csc_lut_precision(crtc_state));
3223 }
3224 
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)3225 static bool glk_lut_equal(const struct intel_crtc_state *crtc_state,
3226 			  const struct drm_property_blob *blob1,
3227 			  const struct drm_property_blob *blob2,
3228 			  bool is_pre_csc_lut)
3229 {
3230 	if (is_pre_csc_lut)
3231 		return intel_lut_equal(blob1, blob2, 0,
3232 				       glk_pre_csc_lut_precision(crtc_state));
3233 	else
3234 		return intel_lut_equal(blob1, blob2, 0,
3235 				       glk_post_csc_lut_precision(crtc_state));
3236 }
3237 
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)3238 static bool icl_lut_equal(const struct intel_crtc_state *crtc_state,
3239 			  const struct drm_property_blob *blob1,
3240 			  const struct drm_property_blob *blob2,
3241 			  bool is_pre_csc_lut)
3242 {
3243 	int check_size = 0;
3244 
3245 	if (is_pre_csc_lut)
3246 		return intel_lut_equal(blob1, blob2, 0,
3247 				       icl_pre_csc_lut_precision(crtc_state));
3248 
3249 	/* hw readout broken except for the super fine segment :( */
3250 	if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) ==
3251 	    GAMMA_MODE_MODE_12BIT_MULTI_SEG)
3252 		check_size = 9;
3253 
3254 	return intel_lut_equal(blob1, blob2, check_size,
3255 			       icl_post_csc_lut_precision(crtc_state));
3256 }
3257 
i9xx_read_lut_8(struct intel_crtc * crtc)3258 static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)
3259 {
3260 	struct intel_display *display = to_intel_display(crtc);
3261 	enum pipe pipe = crtc->pipe;
3262 	struct drm_property_blob *blob;
3263 	struct drm_color_lut *lut;
3264 	int i;
3265 
3266 	blob = drm_property_create_blob(display->drm,
3267 					sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3268 					NULL);
3269 	if (IS_ERR(blob))
3270 		return NULL;
3271 
3272 	lut = blob->data;
3273 
3274 	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3275 		u32 val = intel_de_read_fw(display,
3276 					   PALETTE(display, pipe, i));
3277 
3278 		i9xx_lut_8_pack(&lut[i], val);
3279 	}
3280 
3281 	return blob;
3282 }
3283 
i9xx_read_lut_10(struct intel_crtc * crtc)3284 static struct drm_property_blob *i9xx_read_lut_10(struct intel_crtc *crtc)
3285 {
3286 	struct intel_display *display = to_intel_display(crtc);
3287 	u32 lut_size = DISPLAY_INFO(display)->color.gamma_lut_size;
3288 	enum pipe pipe = crtc->pipe;
3289 	struct drm_property_blob *blob;
3290 	struct drm_color_lut *lut;
3291 	u32 ldw, udw;
3292 	int i;
3293 
3294 	blob = drm_property_create_blob(display->drm,
3295 					lut_size * sizeof(lut[0]), NULL);
3296 	if (IS_ERR(blob))
3297 		return NULL;
3298 
3299 	lut = blob->data;
3300 
3301 	for (i = 0; i < lut_size - 1; i++) {
3302 		ldw = intel_de_read_fw(display,
3303 				       PALETTE(display, pipe, 2 * i + 0));
3304 		udw = intel_de_read_fw(display,
3305 				       PALETTE(display, pipe, 2 * i + 1));
3306 
3307 		i9xx_lut_10_pack(&lut[i], ldw, udw);
3308 	}
3309 
3310 	i9xx_lut_10_pack_slope(&lut[i], ldw, udw);
3311 
3312 	return blob;
3313 }
3314 
i9xx_read_luts(struct intel_crtc_state * crtc_state)3315 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
3316 {
3317 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3318 
3319 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3320 		return;
3321 
3322 	switch (crtc_state->gamma_mode) {
3323 	case GAMMA_MODE_MODE_8BIT:
3324 		crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3325 		break;
3326 	case GAMMA_MODE_MODE_10BIT:
3327 		crtc_state->post_csc_lut = i9xx_read_lut_10(crtc);
3328 		break;
3329 	default:
3330 		MISSING_CASE(crtc_state->gamma_mode);
3331 		break;
3332 	}
3333 }
3334 
i965_read_lut_10p6(struct intel_crtc * crtc)3335 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
3336 {
3337 	struct intel_display *display = to_intel_display(crtc);
3338 	int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size;
3339 	enum pipe pipe = crtc->pipe;
3340 	struct drm_property_blob *blob;
3341 	struct drm_color_lut *lut;
3342 
3343 	blob = drm_property_create_blob(display->drm,
3344 					sizeof(lut[0]) * lut_size,
3345 					NULL);
3346 	if (IS_ERR(blob))
3347 		return NULL;
3348 
3349 	lut = blob->data;
3350 
3351 	for (i = 0; i < lut_size - 1; i++) {
3352 		u32 ldw = intel_de_read_fw(display,
3353 					   PALETTE(display, pipe, 2 * i + 0));
3354 		u32 udw = intel_de_read_fw(display,
3355 					   PALETTE(display, pipe, 2 * i + 1));
3356 
3357 		i965_lut_10p6_pack(&lut[i], ldw, udw);
3358 	}
3359 
3360 	lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(display, PIPEGCMAX(display, pipe, 0)));
3361 	lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(display, PIPEGCMAX(display, pipe, 1)));
3362 	lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(display, PIPEGCMAX(display, pipe, 2)));
3363 
3364 	return blob;
3365 }
3366 
i965_read_luts(struct intel_crtc_state * crtc_state)3367 static void i965_read_luts(struct intel_crtc_state *crtc_state)
3368 {
3369 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3370 
3371 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3372 		return;
3373 
3374 	switch (crtc_state->gamma_mode) {
3375 	case GAMMA_MODE_MODE_8BIT:
3376 		crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3377 		break;
3378 	case GAMMA_MODE_MODE_10BIT:
3379 		crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
3380 		break;
3381 	default:
3382 		MISSING_CASE(crtc_state->gamma_mode);
3383 		break;
3384 	}
3385 }
3386 
chv_read_cgm_degamma(struct intel_crtc * crtc)3387 static struct drm_property_blob *chv_read_cgm_degamma(struct intel_crtc *crtc)
3388 {
3389 	struct intel_display *display = to_intel_display(crtc);
3390 	int i, lut_size = DISPLAY_INFO(display)->color.degamma_lut_size;
3391 	enum pipe pipe = crtc->pipe;
3392 	struct drm_property_blob *blob;
3393 	struct drm_color_lut *lut;
3394 
3395 	blob = drm_property_create_blob(display->drm,
3396 					sizeof(lut[0]) * lut_size,
3397 					NULL);
3398 	if (IS_ERR(blob))
3399 		return NULL;
3400 
3401 	lut = blob->data;
3402 
3403 	for (i = 0; i < lut_size; i++) {
3404 		u32 ldw = intel_de_read_fw(display, CGM_PIPE_DEGAMMA(pipe, i, 0));
3405 		u32 udw = intel_de_read_fw(display, CGM_PIPE_DEGAMMA(pipe, i, 1));
3406 
3407 		chv_cgm_degamma_pack(&lut[i], ldw, udw);
3408 	}
3409 
3410 	return blob;
3411 }
3412 
chv_read_cgm_gamma(struct intel_crtc * crtc)3413 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
3414 {
3415 	struct intel_display *display = to_intel_display(crtc);
3416 	int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size;
3417 	enum pipe pipe = crtc->pipe;
3418 	struct drm_property_blob *blob;
3419 	struct drm_color_lut *lut;
3420 
3421 	blob = drm_property_create_blob(display->drm,
3422 					sizeof(lut[0]) * lut_size,
3423 					NULL);
3424 	if (IS_ERR(blob))
3425 		return NULL;
3426 
3427 	lut = blob->data;
3428 
3429 	for (i = 0; i < lut_size; i++) {
3430 		u32 ldw = intel_de_read_fw(display, CGM_PIPE_GAMMA(pipe, i, 0));
3431 		u32 udw = intel_de_read_fw(display, CGM_PIPE_GAMMA(pipe, i, 1));
3432 
3433 		chv_cgm_gamma_pack(&lut[i], ldw, udw);
3434 	}
3435 
3436 	return blob;
3437 }
3438 
chv_get_config(struct intel_crtc_state * crtc_state)3439 static void chv_get_config(struct intel_crtc_state *crtc_state)
3440 {
3441 	struct intel_display *display = to_intel_display(crtc_state);
3442 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3443 
3444 	crtc_state->cgm_mode = intel_de_read(display, CGM_PIPE_MODE(crtc->pipe));
3445 
3446 	i9xx_get_config(crtc_state);
3447 }
3448 
chv_read_luts(struct intel_crtc_state * crtc_state)3449 static void chv_read_luts(struct intel_crtc_state *crtc_state)
3450 {
3451 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3452 
3453 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
3454 		crtc_state->pre_csc_lut = chv_read_cgm_degamma(crtc);
3455 
3456 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
3457 		crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
3458 	else
3459 		i965_read_luts(crtc_state);
3460 }
3461 
ilk_read_lut_8(struct intel_crtc * crtc)3462 static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc)
3463 {
3464 	struct intel_display *display = to_intel_display(crtc);
3465 	enum pipe pipe = crtc->pipe;
3466 	struct drm_property_blob *blob;
3467 	struct drm_color_lut *lut;
3468 	int i;
3469 
3470 	blob = drm_property_create_blob(display->drm,
3471 					sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3472 					NULL);
3473 	if (IS_ERR(blob))
3474 		return NULL;
3475 
3476 	lut = blob->data;
3477 
3478 	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3479 		u32 val = intel_de_read_fw(display, LGC_PALETTE(pipe, i));
3480 
3481 		i9xx_lut_8_pack(&lut[i], val);
3482 	}
3483 
3484 	return blob;
3485 }
3486 
ilk_read_lut_10(struct intel_crtc * crtc)3487 static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc)
3488 {
3489 	struct intel_display *display = to_intel_display(crtc);
3490 	int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size;
3491 	enum pipe pipe = crtc->pipe;
3492 	struct drm_property_blob *blob;
3493 	struct drm_color_lut *lut;
3494 
3495 	blob = drm_property_create_blob(display->drm,
3496 					sizeof(lut[0]) * lut_size,
3497 					NULL);
3498 	if (IS_ERR(blob))
3499 		return NULL;
3500 
3501 	lut = blob->data;
3502 
3503 	for (i = 0; i < lut_size; i++) {
3504 		u32 val = intel_de_read_fw(display, PREC_PALETTE(pipe, i));
3505 
3506 		ilk_lut_10_pack(&lut[i], val);
3507 	}
3508 
3509 	return blob;
3510 }
3511 
ilk_get_config(struct intel_crtc_state * crtc_state)3512 static void ilk_get_config(struct intel_crtc_state *crtc_state)
3513 {
3514 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3515 
3516 	crtc_state->csc_mode = ilk_read_csc_mode(crtc);
3517 
3518 	i9xx_get_config(crtc_state);
3519 }
3520 
ilk_read_luts(struct intel_crtc_state * crtc_state)3521 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
3522 {
3523 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3524 	struct drm_property_blob **blob =
3525 		ilk_has_post_csc_lut(crtc_state) ?
3526 		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3527 
3528 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3529 		return;
3530 
3531 	switch (crtc_state->gamma_mode) {
3532 	case GAMMA_MODE_MODE_8BIT:
3533 		*blob = ilk_read_lut_8(crtc);
3534 		break;
3535 	case GAMMA_MODE_MODE_10BIT:
3536 		*blob = ilk_read_lut_10(crtc);
3537 		break;
3538 	default:
3539 		MISSING_CASE(crtc_state->gamma_mode);
3540 		break;
3541 	}
3542 }
3543 
3544 /*
3545  * IVB/HSW Bspec / PAL_PREC_INDEX:
3546  * "Restriction : Index auto increment mode is not
3547  *  supported and must not be enabled."
3548  */
ivb_read_lut_10(struct intel_crtc * crtc,u32 prec_index)3549 static struct drm_property_blob *ivb_read_lut_10(struct intel_crtc *crtc,
3550 						 u32 prec_index)
3551 {
3552 	struct intel_display *display = to_intel_display(crtc);
3553 	int i, lut_size = ivb_lut_10_size(prec_index);
3554 	enum pipe pipe = crtc->pipe;
3555 	struct drm_property_blob *blob;
3556 	struct drm_color_lut *lut;
3557 
3558 	blob = drm_property_create_blob(display->drm,
3559 					sizeof(lut[0]) * lut_size,
3560 					NULL);
3561 	if (IS_ERR(blob))
3562 		return NULL;
3563 
3564 	lut = blob->data;
3565 
3566 	for (i = 0; i < lut_size; i++) {
3567 		u32 val;
3568 
3569 		intel_de_write_fw(display, PREC_PAL_INDEX(pipe),
3570 				  prec_index + i);
3571 		val = intel_de_read_fw(display, PREC_PAL_DATA(pipe));
3572 
3573 		ilk_lut_10_pack(&lut[i], val);
3574 	}
3575 
3576 	intel_de_write_fw(display, PREC_PAL_INDEX(pipe),
3577 			  PAL_PREC_INDEX_VALUE(0));
3578 
3579 	return blob;
3580 }
3581 
ivb_read_luts(struct intel_crtc_state * crtc_state)3582 static void ivb_read_luts(struct intel_crtc_state *crtc_state)
3583 {
3584 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3585 	struct drm_property_blob **blob =
3586 		ilk_has_post_csc_lut(crtc_state) ?
3587 		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3588 
3589 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3590 		return;
3591 
3592 	switch (crtc_state->gamma_mode) {
3593 	case GAMMA_MODE_MODE_8BIT:
3594 		*blob = ilk_read_lut_8(crtc);
3595 		break;
3596 	case GAMMA_MODE_MODE_SPLIT:
3597 		crtc_state->pre_csc_lut =
3598 			ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3599 					PAL_PREC_INDEX_VALUE(0));
3600 		crtc_state->post_csc_lut =
3601 			ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3602 					PAL_PREC_INDEX_VALUE(512));
3603 		break;
3604 	case GAMMA_MODE_MODE_10BIT:
3605 		*blob = ivb_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3606 		break;
3607 	default:
3608 		MISSING_CASE(crtc_state->gamma_mode);
3609 		break;
3610 	}
3611 }
3612 
3613 /* On BDW+ the index auto increment mode actually works */
bdw_read_lut_10(struct intel_crtc * crtc,u32 prec_index)3614 static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
3615 						 u32 prec_index)
3616 {
3617 	struct intel_display *display = to_intel_display(crtc);
3618 	int i, lut_size = ivb_lut_10_size(prec_index);
3619 	enum pipe pipe = crtc->pipe;
3620 	struct drm_property_blob *blob;
3621 	struct drm_color_lut *lut;
3622 
3623 	blob = drm_property_create_blob(display->drm,
3624 					sizeof(lut[0]) * lut_size,
3625 					NULL);
3626 	if (IS_ERR(blob))
3627 		return NULL;
3628 
3629 	lut = blob->data;
3630 
3631 	intel_de_write_fw(display, PREC_PAL_INDEX(pipe),
3632 			  prec_index);
3633 	intel_de_write_fw(display, PREC_PAL_INDEX(pipe),
3634 			  PAL_PREC_AUTO_INCREMENT |
3635 			  prec_index);
3636 
3637 	for (i = 0; i < lut_size; i++) {
3638 		u32 val = intel_de_read_fw(display, PREC_PAL_DATA(pipe));
3639 
3640 		ilk_lut_10_pack(&lut[i], val);
3641 	}
3642 
3643 	intel_de_write_fw(display, PREC_PAL_INDEX(pipe),
3644 			  PAL_PREC_INDEX_VALUE(0));
3645 
3646 	return blob;
3647 }
3648 
bdw_read_luts(struct intel_crtc_state * crtc_state)3649 static void bdw_read_luts(struct intel_crtc_state *crtc_state)
3650 {
3651 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3652 	struct drm_property_blob **blob =
3653 		ilk_has_post_csc_lut(crtc_state) ?
3654 		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3655 
3656 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3657 		return;
3658 
3659 	switch (crtc_state->gamma_mode) {
3660 	case GAMMA_MODE_MODE_8BIT:
3661 		*blob = ilk_read_lut_8(crtc);
3662 		break;
3663 	case GAMMA_MODE_MODE_SPLIT:
3664 		crtc_state->pre_csc_lut =
3665 			bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3666 					PAL_PREC_INDEX_VALUE(0));
3667 		crtc_state->post_csc_lut =
3668 			bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3669 					PAL_PREC_INDEX_VALUE(512));
3670 		break;
3671 	case GAMMA_MODE_MODE_10BIT:
3672 		*blob = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3673 		break;
3674 	default:
3675 		MISSING_CASE(crtc_state->gamma_mode);
3676 		break;
3677 	}
3678 }
3679 
glk_read_degamma_lut(struct intel_crtc * crtc)3680 static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc)
3681 {
3682 	struct intel_display *display = to_intel_display(crtc);
3683 	int i, lut_size = DISPLAY_INFO(display)->color.degamma_lut_size;
3684 	enum pipe pipe = crtc->pipe;
3685 	struct drm_property_blob *blob;
3686 	struct drm_color_lut *lut;
3687 
3688 	blob = drm_property_create_blob(display->drm,
3689 					sizeof(lut[0]) * lut_size,
3690 					NULL);
3691 	if (IS_ERR(blob))
3692 		return NULL;
3693 
3694 	lut = blob->data;
3695 
3696 	/*
3697 	 * When setting the auto-increment bit, the hardware seems to
3698 	 * ignore the index bits, so we need to reset it to index 0
3699 	 * separately.
3700 	 */
3701 	intel_de_write_fw(display, PRE_CSC_GAMC_INDEX(pipe),
3702 			  PRE_CSC_GAMC_INDEX_VALUE(0));
3703 	intel_de_write_fw(display, PRE_CSC_GAMC_INDEX(pipe),
3704 			  PRE_CSC_GAMC_AUTO_INCREMENT |
3705 			  PRE_CSC_GAMC_INDEX_VALUE(0));
3706 
3707 	for (i = 0; i < lut_size; i++) {
3708 		u32 val = intel_de_read_fw(display, PRE_CSC_GAMC_DATA(pipe));
3709 
3710 		if (DISPLAY_VER(display) >= 14)
3711 			mtl_degamma_lut_pack(&lut[i], val);
3712 		else
3713 			glk_degamma_lut_pack(&lut[i], val);
3714 	}
3715 
3716 	intel_de_write_fw(display, PRE_CSC_GAMC_INDEX(pipe),
3717 			  PRE_CSC_GAMC_INDEX_VALUE(0));
3718 
3719 	return blob;
3720 }
3721 
glk_read_luts(struct intel_crtc_state * crtc_state)3722 static void glk_read_luts(struct intel_crtc_state *crtc_state)
3723 {
3724 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3725 
3726 	if (crtc_state->csc_enable)
3727 		crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3728 
3729 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3730 		return;
3731 
3732 	switch (crtc_state->gamma_mode) {
3733 	case GAMMA_MODE_MODE_8BIT:
3734 		crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3735 		break;
3736 	case GAMMA_MODE_MODE_10BIT:
3737 		crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3738 		break;
3739 	default:
3740 		MISSING_CASE(crtc_state->gamma_mode);
3741 		break;
3742 	}
3743 }
3744 
3745 static struct drm_property_blob *
icl_read_lut_multi_segment(struct intel_crtc * crtc)3746 icl_read_lut_multi_segment(struct intel_crtc *crtc)
3747 {
3748 	struct intel_display *display = to_intel_display(crtc);
3749 	int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size;
3750 	enum pipe pipe = crtc->pipe;
3751 	struct drm_property_blob *blob;
3752 	struct drm_color_lut *lut;
3753 
3754 	blob = drm_property_create_blob(display->drm,
3755 					sizeof(lut[0]) * lut_size,
3756 					NULL);
3757 	if (IS_ERR(blob))
3758 		return NULL;
3759 
3760 	lut = blob->data;
3761 
3762 	intel_de_write_fw(display, PREC_PAL_MULTI_SEG_INDEX(pipe),
3763 			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3764 	intel_de_write_fw(display, PREC_PAL_MULTI_SEG_INDEX(pipe),
3765 			  PAL_PREC_MULTI_SEG_AUTO_INCREMENT |
3766 			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3767 
3768 	for (i = 0; i < 9; i++) {
3769 		u32 ldw = intel_de_read_fw(display, PREC_PAL_MULTI_SEG_DATA(pipe));
3770 		u32 udw = intel_de_read_fw(display, PREC_PAL_MULTI_SEG_DATA(pipe));
3771 
3772 		ilk_lut_12p4_pack(&lut[i], ldw, udw);
3773 	}
3774 
3775 	intel_de_write_fw(display, PREC_PAL_MULTI_SEG_INDEX(pipe),
3776 			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3777 
3778 	/*
3779 	 * FIXME readouts from PAL_PREC_DATA register aren't giving
3780 	 * correct values in the case of fine and coarse segments.
3781 	 * Restricting readouts only for super fine segment as of now.
3782 	 */
3783 
3784 	return blob;
3785 }
3786 
icl_read_luts(struct intel_crtc_state * crtc_state)3787 static void icl_read_luts(struct intel_crtc_state *crtc_state)
3788 {
3789 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3790 
3791 	if (icl_has_pre_csc_lut(crtc_state))
3792 		crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3793 
3794 	if (!icl_has_post_csc_lut(crtc_state))
3795 		return;
3796 
3797 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
3798 	case GAMMA_MODE_MODE_8BIT:
3799 		crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3800 		break;
3801 	case GAMMA_MODE_MODE_10BIT:
3802 		crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3803 		break;
3804 	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
3805 		crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
3806 		break;
3807 	default:
3808 		MISSING_CASE(crtc_state->gamma_mode);
3809 		break;
3810 	}
3811 }
3812 
3813 static const struct intel_color_funcs chv_color_funcs = {
3814 	.color_check = chv_color_check,
3815 	.color_commit_arm = i9xx_color_commit_arm,
3816 	.load_luts = chv_load_luts,
3817 	.read_luts = chv_read_luts,
3818 	.lut_equal = chv_lut_equal,
3819 	.read_csc = chv_read_csc,
3820 	.get_config = chv_get_config,
3821 };
3822 
3823 static const struct intel_color_funcs vlv_color_funcs = {
3824 	.color_check = vlv_color_check,
3825 	.color_commit_arm = i9xx_color_commit_arm,
3826 	.load_luts = vlv_load_luts,
3827 	.read_luts = i965_read_luts,
3828 	.lut_equal = i965_lut_equal,
3829 	.read_csc = vlv_read_csc,
3830 	.get_config = i9xx_get_config,
3831 };
3832 
3833 static const struct intel_color_funcs i965_color_funcs = {
3834 	.color_check = i9xx_color_check,
3835 	.color_commit_arm = i9xx_color_commit_arm,
3836 	.load_luts = i965_load_luts,
3837 	.read_luts = i965_read_luts,
3838 	.lut_equal = i965_lut_equal,
3839 	.get_config = i9xx_get_config,
3840 };
3841 
3842 static const struct intel_color_funcs i9xx_color_funcs = {
3843 	.color_check = i9xx_color_check,
3844 	.color_commit_arm = i9xx_color_commit_arm,
3845 	.load_luts = i9xx_load_luts,
3846 	.read_luts = i9xx_read_luts,
3847 	.lut_equal = i9xx_lut_equal,
3848 	.get_config = i9xx_get_config,
3849 };
3850 
3851 static const struct intel_color_funcs tgl_color_funcs = {
3852 	.color_check = icl_color_check,
3853 	.color_commit_noarm = icl_color_commit_noarm,
3854 	.color_commit_arm = icl_color_commit_arm,
3855 	.load_luts = icl_load_luts,
3856 	.read_luts = icl_read_luts,
3857 	.lut_equal = icl_lut_equal,
3858 	.read_csc = icl_read_csc,
3859 	.get_config = skl_get_config,
3860 };
3861 
3862 static const struct intel_color_funcs icl_color_funcs = {
3863 	.color_check = icl_color_check,
3864 	.color_commit_noarm = icl_color_commit_noarm,
3865 	.color_commit_arm = icl_color_commit_arm,
3866 	.color_post_update = icl_color_post_update,
3867 	.load_luts = icl_load_luts,
3868 	.read_luts = icl_read_luts,
3869 	.lut_equal = icl_lut_equal,
3870 	.read_csc = icl_read_csc,
3871 	.get_config = skl_get_config,
3872 };
3873 
3874 static const struct intel_color_funcs glk_color_funcs = {
3875 	.color_check = glk_color_check,
3876 	.color_commit_noarm = skl_color_commit_noarm,
3877 	.color_commit_arm = skl_color_commit_arm,
3878 	.load_luts = glk_load_luts,
3879 	.read_luts = glk_read_luts,
3880 	.lut_equal = glk_lut_equal,
3881 	.read_csc = skl_read_csc,
3882 	.get_config = skl_get_config,
3883 };
3884 
3885 static const struct intel_color_funcs skl_color_funcs = {
3886 	.color_check = ivb_color_check,
3887 	.color_commit_noarm = skl_color_commit_noarm,
3888 	.color_commit_arm = skl_color_commit_arm,
3889 	.load_luts = bdw_load_luts,
3890 	.read_luts = bdw_read_luts,
3891 	.lut_equal = ivb_lut_equal,
3892 	.read_csc = skl_read_csc,
3893 	.get_config = skl_get_config,
3894 };
3895 
3896 static const struct intel_color_funcs bdw_color_funcs = {
3897 	.color_check = ivb_color_check,
3898 	.color_commit_noarm = ilk_color_commit_noarm,
3899 	.color_commit_arm = hsw_color_commit_arm,
3900 	.load_luts = bdw_load_luts,
3901 	.read_luts = bdw_read_luts,
3902 	.lut_equal = ivb_lut_equal,
3903 	.read_csc = ilk_read_csc,
3904 	.get_config = hsw_get_config,
3905 };
3906 
3907 static const struct intel_color_funcs hsw_color_funcs = {
3908 	.color_check = ivb_color_check,
3909 	.color_commit_noarm = ilk_color_commit_noarm,
3910 	.color_commit_arm = hsw_color_commit_arm,
3911 	.load_luts = ivb_load_luts,
3912 	.read_luts = ivb_read_luts,
3913 	.lut_equal = ivb_lut_equal,
3914 	.read_csc = ilk_read_csc,
3915 	.get_config = hsw_get_config,
3916 };
3917 
3918 static const struct intel_color_funcs ivb_color_funcs = {
3919 	.color_check = ivb_color_check,
3920 	.color_commit_noarm = ilk_color_commit_noarm,
3921 	.color_commit_arm = ilk_color_commit_arm,
3922 	.load_luts = ivb_load_luts,
3923 	.read_luts = ivb_read_luts,
3924 	.lut_equal = ivb_lut_equal,
3925 	.read_csc = ilk_read_csc,
3926 	.get_config = ilk_get_config,
3927 };
3928 
3929 static const struct intel_color_funcs ilk_color_funcs = {
3930 	.color_check = ilk_color_check,
3931 	.color_commit_noarm = ilk_color_commit_noarm,
3932 	.color_commit_arm = ilk_color_commit_arm,
3933 	.load_luts = ilk_load_luts,
3934 	.read_luts = ilk_read_luts,
3935 	.lut_equal = ilk_lut_equal,
3936 	.read_csc = ilk_read_csc,
3937 	.get_config = ilk_get_config,
3938 };
3939 
intel_color_crtc_init(struct intel_crtc * crtc)3940 void intel_color_crtc_init(struct intel_crtc *crtc)
3941 {
3942 	struct intel_display *display = to_intel_display(crtc);
3943 	int degamma_lut_size, gamma_lut_size;
3944 	bool has_ctm;
3945 
3946 	drm_mode_crtc_set_gamma_size(&crtc->base, 256);
3947 
3948 	gamma_lut_size = DISPLAY_INFO(display)->color.gamma_lut_size;
3949 	degamma_lut_size = DISPLAY_INFO(display)->color.degamma_lut_size;
3950 	has_ctm = DISPLAY_VER(display) >= 5;
3951 
3952 	/*
3953 	 * "DPALETTE_A: NOTE: The 8-bit (non-10-bit) mode is the
3954 	 *  only mode supported by Alviso and Grantsdale."
3955 	 *
3956 	 * Actually looks like this affects all of gen3.
3957 	 * Confirmed on alv,cst,pnv. Mobile gen2 parts (alm,mgm)
3958 	 * are confirmed not to suffer from this restriction.
3959 	 */
3960 	if (DISPLAY_VER(display) == 3 && crtc->pipe == PIPE_A)
3961 		gamma_lut_size = 256;
3962 
3963 	drm_crtc_enable_color_mgmt(&crtc->base, degamma_lut_size,
3964 				   has_ctm, gamma_lut_size);
3965 }
3966 
intel_color_init(struct intel_display * display)3967 int intel_color_init(struct intel_display *display)
3968 {
3969 	struct drm_property_blob *blob;
3970 
3971 	if (DISPLAY_VER(display) != 10)
3972 		return 0;
3973 
3974 	blob = create_linear_lut(display,
3975 				 DISPLAY_INFO(display)->color.degamma_lut_size);
3976 	if (IS_ERR(blob))
3977 		return PTR_ERR(blob);
3978 
3979 	display->color.glk_linear_degamma_lut = blob;
3980 
3981 	return 0;
3982 }
3983 
intel_color_init_hooks(struct intel_display * display)3984 void intel_color_init_hooks(struct intel_display *display)
3985 {
3986 	struct drm_i915_private *i915 = to_i915(display->drm);
3987 
3988 	if (HAS_GMCH(display)) {
3989 		if (IS_CHERRYVIEW(i915))
3990 			display->funcs.color = &chv_color_funcs;
3991 		else if (IS_VALLEYVIEW(i915))
3992 			display->funcs.color = &vlv_color_funcs;
3993 		else if (DISPLAY_VER(display) >= 4)
3994 			display->funcs.color = &i965_color_funcs;
3995 		else
3996 			display->funcs.color = &i9xx_color_funcs;
3997 	} else {
3998 		if (DISPLAY_VER(display) >= 12)
3999 			display->funcs.color = &tgl_color_funcs;
4000 		else if (DISPLAY_VER(display) == 11)
4001 			display->funcs.color = &icl_color_funcs;
4002 		else if (DISPLAY_VER(display) == 10)
4003 			display->funcs.color = &glk_color_funcs;
4004 		else if (DISPLAY_VER(display) == 9)
4005 			display->funcs.color = &skl_color_funcs;
4006 		else if (DISPLAY_VER(display) == 8)
4007 			display->funcs.color = &bdw_color_funcs;
4008 		else if (IS_HASWELL(i915))
4009 			display->funcs.color = &hsw_color_funcs;
4010 		else if (DISPLAY_VER(display) == 7)
4011 			display->funcs.color = &ivb_color_funcs;
4012 		else
4013 			display->funcs.color = &ilk_color_funcs;
4014 	}
4015 }
4016