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