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
32struct 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
133static 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 */
144static 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 */
159static 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
171static void intel_csc_clear(struct intel_csc_matrix *csc)
172{
173	memset(csc, 0, sizeof(*csc));
174}
175
176static 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 */
185static 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
207static 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
240static 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
277static 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
285static 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
306static 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
336static 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
370static 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
386static 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
401static 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
418static 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
426static 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
436static 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
496static 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
528static 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
536static 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
565static 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
576static 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 */
603static 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
613static 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
635static 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
664static 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
672static 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 */
695static 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
707static 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
715static 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
733static 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
760static 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
768static 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 */
786static 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
796static 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
803static 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) */
811static u32 _i9xx_lut_10_ldw(u16 a)
812{
813	return drm_color_lut_extract(a, 10) & 0xff;
814}
815
816static 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) */
824static 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
844static 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
851static 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
866static 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) */
884static 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) */
892static 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
899static 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
909static 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
915static 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
922static 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) */
930static 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) */
938static 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
945static 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
955static 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
968static 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
984static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
985{
986	ilk_load_csc_matrix(crtc_state);
987}
988
989static 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
995static 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
1007static 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
1019static 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
1026static 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
1033static 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
1050static 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
1060static 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
1078static 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
1106static 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
1125static 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
1147static struct drm_property_blob *
1148create_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
1173static 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
1181static struct drm_property_blob *
1182create_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
1216static 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
1234static 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
1250static 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
1268static 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
1288static 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
1306static 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
1317static 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
1346static 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
1359static 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
1378static 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 */
1391static 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 */
1416static 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
1443static 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
1454static 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
1465static 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
1493static 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
1521static 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
1529static u32 glk_degamma_lut(const struct drm_color_lut *color)
1530{
1531	return color->green;
1532}
1533
1534static 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
1540static u32 mtl_degamma_lut(const struct drm_color_lut *color)
1541{
1542	return drm_color_lut_extract(color->green, 24);
1543}
1544
1545static 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
1552static 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
1600static 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
1623static void
1624ivb_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
1636static void
1637icl_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
1671static void
1672icl_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
1735static 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
1764static 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
1774static 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
1780static 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
1785static 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
1792static 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
1808static 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
1814static 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
1819static 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
1826static 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
1842static 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
1864void 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
1874void 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
1882void 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
1892void 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
1900void 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
1921void 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
1930void 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
1936bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
1937{
1938	return crtc_state->dsb;
1939}
1940
1941static 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
1953static 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
1965static 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
1984int 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
1991void 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
2004bool 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
2022static 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
2037static int
2038intel_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
2078static 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
2089static 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
2096static 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
2107static 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
2114static int check_lut_size(struct drm_i915_private *i915,
2115			  const struct drm_property_blob *lut, int expected)
2116{
2117	int len;
2118
2119	if (!lut)
2120		return 0;
2121
2122	len = drm_color_lut_size(lut);
2123	if (len != expected) {
2124		drm_dbg_kms(&i915->drm, "Invalid LUT size; got %d, expected %d\n",
2125			    len, expected);
2126		return -EINVAL;
2127	}
2128
2129	return 0;
2130}
2131
2132static int _check_luts(const struct intel_crtc_state *crtc_state,
2133		       u32 degamma_tests, u32 gamma_tests)
2134{
2135	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2136	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
2137	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
2138	int gamma_length, degamma_length;
2139
2140	/* C8 relies on its palette being stored in the legacy LUT */
2141	if (crtc_state->c8_planes && !lut_is_legacy(crtc_state->hw.gamma_lut)) {
2142		drm_dbg_kms(&i915->drm,
2143			    "C8 pixelformat requires the legacy LUT\n");
2144		return -EINVAL;
2145	}
2146
2147	degamma_length = intel_degamma_lut_size(crtc_state);
2148	gamma_length = intel_gamma_lut_size(crtc_state);
2149
2150	if (check_lut_size(i915, degamma_lut, degamma_length) ||
2151	    check_lut_size(i915, gamma_lut, gamma_length))
2152		return -EINVAL;
2153
2154	if (drm_color_lut_check(degamma_lut, degamma_tests) ||
2155	    drm_color_lut_check(gamma_lut, gamma_tests))
2156		return -EINVAL;
2157
2158	return 0;
2159}
2160
2161static int check_luts(const struct intel_crtc_state *crtc_state)
2162{
2163	return _check_luts(crtc_state,
2164			   intel_degamma_lut_tests(crtc_state),
2165			   intel_gamma_lut_tests(crtc_state));
2166}
2167
2168static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
2169{
2170	if (!crtc_state->gamma_enable ||
2171	    lut_is_legacy(crtc_state->hw.gamma_lut))
2172		return GAMMA_MODE_MODE_8BIT;
2173	else
2174		return GAMMA_MODE_MODE_10BIT;
2175}
2176
2177static int i9xx_lut_10_diff(u16 a, u16 b)
2178{
2179	return drm_color_lut_extract(a, 10) -
2180		drm_color_lut_extract(b, 10);
2181}
2182
2183static int i9xx_check_lut_10(struct drm_i915_private *dev_priv,
2184			     const struct drm_property_blob *blob)
2185{
2186	const struct drm_color_lut *lut = blob->data;
2187	int lut_size = drm_color_lut_size(blob);
2188	const struct drm_color_lut *a = &lut[lut_size - 2];
2189	const struct drm_color_lut *b = &lut[lut_size - 1];
2190
2191	if (i9xx_lut_10_diff(b->red, a->red) > 0x7f ||
2192	    i9xx_lut_10_diff(b->green, a->green) > 0x7f ||
2193	    i9xx_lut_10_diff(b->blue, a->blue) > 0x7f) {
2194		drm_dbg_kms(&dev_priv->drm, "Last gamma LUT entry exceeds max slope\n");
2195		return -EINVAL;
2196	}
2197
2198	return 0;
2199}
2200
2201void intel_color_assert_luts(const struct intel_crtc_state *crtc_state)
2202{
2203	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2204
2205	/* make sure {pre,post}_csc_lut were correctly assigned */
2206	if (DISPLAY_VER(i915) >= 11 || HAS_GMCH(i915)) {
2207		drm_WARN_ON(&i915->drm,
2208			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut);
2209		drm_WARN_ON(&i915->drm,
2210			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2211	} else if (DISPLAY_VER(i915) == 10) {
2212		drm_WARN_ON(&i915->drm,
2213			    crtc_state->post_csc_lut == crtc_state->hw.gamma_lut &&
2214			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2215			    crtc_state->pre_csc_lut != i915->display.color.glk_linear_degamma_lut);
2216		drm_WARN_ON(&i915->drm,
2217			    !ilk_lut_limited_range(crtc_state) &&
2218			    crtc_state->post_csc_lut != NULL &&
2219			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2220	} else if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT) {
2221		drm_WARN_ON(&i915->drm,
2222			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2223			    crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut);
2224		drm_WARN_ON(&i915->drm,
2225			    !ilk_lut_limited_range(crtc_state) &&
2226			    crtc_state->post_csc_lut != crtc_state->hw.degamma_lut &&
2227			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2228	}
2229}
2230
2231static void intel_assign_luts(struct intel_crtc_state *crtc_state)
2232{
2233	drm_property_replace_blob(&crtc_state->pre_csc_lut,
2234				  crtc_state->hw.degamma_lut);
2235	drm_property_replace_blob(&crtc_state->post_csc_lut,
2236				  crtc_state->hw.gamma_lut);
2237}
2238
2239static int i9xx_color_check(struct intel_crtc_state *crtc_state)
2240{
2241	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2242	int ret;
2243
2244	ret = check_luts(crtc_state);
2245	if (ret)
2246		return ret;
2247
2248	crtc_state->gamma_enable =
2249		crtc_state->hw.gamma_lut &&
2250		!crtc_state->c8_planes;
2251
2252	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2253
2254	if (DISPLAY_VER(i915) < 4 &&
2255	    crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT) {
2256		ret = i9xx_check_lut_10(i915, crtc_state->hw.gamma_lut);
2257		if (ret)
2258			return ret;
2259	}
2260
2261	ret = intel_color_add_affected_planes(crtc_state);
2262	if (ret)
2263		return ret;
2264
2265	intel_assign_luts(crtc_state);
2266
2267	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2268
2269	return 0;
2270}
2271
2272/*
2273 * VLV color pipeline:
2274 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2275 */
2276static int vlv_color_check(struct intel_crtc_state *crtc_state)
2277{
2278	int ret;
2279
2280	ret = check_luts(crtc_state);
2281	if (ret)
2282		return ret;
2283
2284	crtc_state->gamma_enable =
2285		crtc_state->hw.gamma_lut &&
2286		!crtc_state->c8_planes;
2287
2288	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2289
2290	crtc_state->wgc_enable = crtc_state->hw.ctm;
2291
2292	ret = intel_color_add_affected_planes(crtc_state);
2293	if (ret)
2294		return ret;
2295
2296	intel_assign_luts(crtc_state);
2297
2298	vlv_assign_csc(crtc_state);
2299
2300	crtc_state->preload_luts = vlv_can_preload_luts(crtc_state);
2301
2302	return 0;
2303}
2304
2305static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
2306{
2307	u32 cgm_mode = 0;
2308
2309	if (crtc_state->hw.degamma_lut)
2310		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
2311	if (crtc_state->hw.ctm)
2312		cgm_mode |= CGM_PIPE_MODE_CSC;
2313	if (crtc_state->hw.gamma_lut &&
2314	    !lut_is_legacy(crtc_state->hw.gamma_lut))
2315		cgm_mode |= CGM_PIPE_MODE_GAMMA;
2316
2317	/*
2318	 * Toggling the CGM CSC on/off outside of the tiny window
2319	 * between start of vblank and frame start causes underruns.
2320	 * Always enable the CGM CSC as a workaround.
2321	 */
2322	cgm_mode |= CGM_PIPE_MODE_CSC;
2323
2324	return cgm_mode;
2325}
2326
2327/*
2328 * CHV color pipeline:
2329 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
2330 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2331 *
2332 * We always bypass the WGC csc and use the CGM csc
2333 * instead since it has degamma and better precision.
2334 */
2335static int chv_color_check(struct intel_crtc_state *crtc_state)
2336{
2337	int ret;
2338
2339	ret = check_luts(crtc_state);
2340	if (ret)
2341		return ret;
2342
2343	/*
2344	 * Pipe gamma will be used only for the legacy LUT.
2345	 * Otherwise we bypass it and use the CGM gamma instead.
2346	 */
2347	crtc_state->gamma_enable =
2348		lut_is_legacy(crtc_state->hw.gamma_lut) &&
2349		!crtc_state->c8_planes;
2350
2351	crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
2352
2353	crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
2354
2355	/*
2356	 * We always bypass the WGC CSC and use the CGM CSC
2357	 * instead since it has degamma and better precision.
2358	 */
2359	crtc_state->wgc_enable = false;
2360
2361	ret = intel_color_add_affected_planes(crtc_state);
2362	if (ret)
2363		return ret;
2364
2365	intel_assign_luts(crtc_state);
2366
2367	chv_assign_csc(crtc_state);
2368
2369	crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
2370
2371	return 0;
2372}
2373
2374static bool ilk_gamma_enable(const struct intel_crtc_state *crtc_state)
2375{
2376	return (crtc_state->hw.gamma_lut ||
2377		crtc_state->hw.degamma_lut) &&
2378		!crtc_state->c8_planes;
2379}
2380
2381static bool ilk_csc_enable(const struct intel_crtc_state *crtc_state)
2382{
2383	return crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2384		ilk_csc_limited_range(crtc_state) ||
2385		crtc_state->hw.ctm;
2386}
2387
2388static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
2389{
2390	if (!crtc_state->gamma_enable ||
2391	    lut_is_legacy(crtc_state->hw.gamma_lut))
2392		return GAMMA_MODE_MODE_8BIT;
2393	else
2394		return GAMMA_MODE_MODE_10BIT;
2395}
2396
2397static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
2398{
2399	/*
2400	 * CSC comes after the LUT in RGB->YCbCr mode.
2401	 * RGB->YCbCr needs the limited range offsets added to
2402	 * the output. RGB limited range output is handled by
2403	 * the hw automagically elsewhere.
2404	 */
2405	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
2406		return CSC_BLACK_SCREEN_OFFSET;
2407
2408	if (crtc_state->hw.degamma_lut)
2409		return CSC_MODE_YUV_TO_RGB;
2410
2411	return CSC_MODE_YUV_TO_RGB |
2412		CSC_POSITION_BEFORE_GAMMA;
2413}
2414
2415static int ilk_assign_luts(struct intel_crtc_state *crtc_state)
2416{
2417	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2418
2419	if (ilk_lut_limited_range(crtc_state)) {
2420		struct drm_property_blob *gamma_lut;
2421
2422		gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2423					       drm_color_lut_size(crtc_state->hw.gamma_lut),
2424					       true);
2425		if (IS_ERR(gamma_lut))
2426			return PTR_ERR(gamma_lut);
2427
2428		drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2429
2430		drm_property_blob_put(gamma_lut);
2431
2432		drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2433
2434		return 0;
2435	}
2436
2437	if (crtc_state->hw.degamma_lut ||
2438	    crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
2439		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2440					  crtc_state->hw.degamma_lut);
2441		drm_property_replace_blob(&crtc_state->post_csc_lut,
2442					  crtc_state->hw.gamma_lut);
2443	} else {
2444		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2445					  crtc_state->hw.gamma_lut);
2446		drm_property_replace_blob(&crtc_state->post_csc_lut,
2447					  NULL);
2448	}
2449
2450	return 0;
2451}
2452
2453static int ilk_color_check(struct intel_crtc_state *crtc_state)
2454{
2455	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2456	int ret;
2457
2458	ret = check_luts(crtc_state);
2459	if (ret)
2460		return ret;
2461
2462	if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2463		drm_dbg_kms(&i915->drm,
2464			    "Degamma and gamma together are not possible\n");
2465		return -EINVAL;
2466	}
2467
2468	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2469	    crtc_state->hw.ctm) {
2470		drm_dbg_kms(&i915->drm,
2471			    "YCbCr and CTM together are not possible\n");
2472		return -EINVAL;
2473	}
2474
2475	crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2476
2477	crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2478
2479	crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
2480
2481	crtc_state->csc_mode = ilk_csc_mode(crtc_state);
2482
2483	ret = intel_color_add_affected_planes(crtc_state);
2484	if (ret)
2485		return ret;
2486
2487	ret = ilk_assign_luts(crtc_state);
2488	if (ret)
2489		return ret;
2490
2491	ilk_assign_csc(crtc_state);
2492
2493	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2494
2495	return 0;
2496}
2497
2498static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
2499{
2500	if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut)
2501		return GAMMA_MODE_MODE_SPLIT;
2502
2503	return ilk_gamma_mode(crtc_state);
2504}
2505
2506static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
2507{
2508	bool limited_color_range = ilk_csc_limited_range(crtc_state);
2509
2510	/*
2511	 * CSC comes after the LUT in degamma, RGB->YCbCr,
2512	 * and RGB full->limited range mode.
2513	 */
2514	if (crtc_state->hw.degamma_lut ||
2515	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2516	    limited_color_range)
2517		return 0;
2518
2519	return CSC_POSITION_BEFORE_GAMMA;
2520}
2521
2522static int ivb_assign_luts(struct intel_crtc_state *crtc_state)
2523{
2524	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2525	struct drm_property_blob *degamma_lut, *gamma_lut;
2526
2527	if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT)
2528		return ilk_assign_luts(crtc_state);
2529
2530	drm_WARN_ON(&i915->drm, drm_color_lut_size(crtc_state->hw.degamma_lut) != 1024);
2531	drm_WARN_ON(&i915->drm, drm_color_lut_size(crtc_state->hw.gamma_lut) != 1024);
2532
2533	degamma_lut = create_resized_lut(i915, crtc_state->hw.degamma_lut, 512,
2534					 false);
2535	if (IS_ERR(degamma_lut))
2536		return PTR_ERR(degamma_lut);
2537
2538	gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut, 512,
2539				       ilk_lut_limited_range(crtc_state));
2540	if (IS_ERR(gamma_lut)) {
2541		drm_property_blob_put(degamma_lut);
2542		return PTR_ERR(gamma_lut);
2543	}
2544
2545	drm_property_replace_blob(&crtc_state->pre_csc_lut, degamma_lut);
2546	drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2547
2548	drm_property_blob_put(degamma_lut);
2549	drm_property_blob_put(gamma_lut);
2550
2551	return 0;
2552}
2553
2554static int ivb_color_check(struct intel_crtc_state *crtc_state)
2555{
2556	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2557	int ret;
2558
2559	ret = check_luts(crtc_state);
2560	if (ret)
2561		return ret;
2562
2563	if (crtc_state->c8_planes && crtc_state->hw.degamma_lut) {
2564		drm_dbg_kms(&i915->drm,
2565			    "C8 pixelformat and degamma together are not possible\n");
2566		return -EINVAL;
2567	}
2568
2569	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2570	    crtc_state->hw.ctm) {
2571		drm_dbg_kms(&i915->drm,
2572			    "YCbCr and CTM together are not possible\n");
2573		return -EINVAL;
2574	}
2575
2576	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2577	    crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2578		drm_dbg_kms(&i915->drm,
2579			    "YCbCr and degamma+gamma together are not possible\n");
2580		return -EINVAL;
2581	}
2582
2583	crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2584
2585	crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2586
2587	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
2588
2589	crtc_state->csc_mode = ivb_csc_mode(crtc_state);
2590
2591	ret = intel_color_add_affected_planes(crtc_state);
2592	if (ret)
2593		return ret;
2594
2595	ret = ivb_assign_luts(crtc_state);
2596	if (ret)
2597		return ret;
2598
2599	ilk_assign_csc(crtc_state);
2600
2601	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2602
2603	return 0;
2604}
2605
2606static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
2607{
2608	if (!crtc_state->gamma_enable ||
2609	    lut_is_legacy(crtc_state->hw.gamma_lut))
2610		return GAMMA_MODE_MODE_8BIT;
2611	else
2612		return GAMMA_MODE_MODE_10BIT;
2613}
2614
2615static bool glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state *crtc_state)
2616{
2617	return crtc_state->hw.gamma_lut &&
2618		!crtc_state->c8_planes &&
2619		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
2620}
2621
2622static int glk_assign_luts(struct intel_crtc_state *crtc_state)
2623{
2624	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2625
2626	if (glk_use_pre_csc_lut_for_gamma(crtc_state)) {
2627		struct drm_property_blob *gamma_lut;
2628
2629		gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2630					       DISPLAY_INFO(i915)->color.degamma_lut_size,
2631					       false);
2632		if (IS_ERR(gamma_lut))
2633			return PTR_ERR(gamma_lut);
2634
2635		drm_property_replace_blob(&crtc_state->pre_csc_lut, gamma_lut);
2636		drm_property_replace_blob(&crtc_state->post_csc_lut, NULL);
2637
2638		drm_property_blob_put(gamma_lut);
2639
2640		return 0;
2641	}
2642
2643	if (ilk_lut_limited_range(crtc_state)) {
2644		struct drm_property_blob *gamma_lut;
2645
2646		gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2647					       drm_color_lut_size(crtc_state->hw.gamma_lut),
2648					       true);
2649		if (IS_ERR(gamma_lut))
2650			return PTR_ERR(gamma_lut);
2651
2652		drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2653
2654		drm_property_blob_put(gamma_lut);
2655	} else {
2656		drm_property_replace_blob(&crtc_state->post_csc_lut, crtc_state->hw.gamma_lut);
2657	}
2658
2659	drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2660
2661	/*
2662	 * On GLK+ both pipe CSC and degamma LUT are controlled
2663	 * by csc_enable. Hence for the cases where the CSC is
2664	 * needed but degamma LUT is not we need to load a
2665	 * linear degamma LUT.
2666	 */
2667	if (crtc_state->csc_enable && !crtc_state->pre_csc_lut)
2668		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2669					  i915->display.color.glk_linear_degamma_lut);
2670
2671	return 0;
2672}
2673
2674static int glk_check_luts(const struct intel_crtc_state *crtc_state)
2675{
2676	u32 degamma_tests = intel_degamma_lut_tests(crtc_state);
2677	u32 gamma_tests = intel_gamma_lut_tests(crtc_state);
2678
2679	if (glk_use_pre_csc_lut_for_gamma(crtc_state))
2680		gamma_tests |= degamma_tests;
2681
2682	return _check_luts(crtc_state, degamma_tests, gamma_tests);
2683}
2684
2685static int glk_color_check(struct intel_crtc_state *crtc_state)
2686{
2687	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2688	int ret;
2689
2690	ret = glk_check_luts(crtc_state);
2691	if (ret)
2692		return ret;
2693
2694	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2695	    crtc_state->hw.ctm) {
2696		drm_dbg_kms(&i915->drm,
2697			    "YCbCr and CTM together are not possible\n");
2698		return -EINVAL;
2699	}
2700
2701	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2702	    crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2703		drm_dbg_kms(&i915->drm,
2704			    "YCbCr and degamma+gamma together are not possible\n");
2705		return -EINVAL;
2706	}
2707
2708	crtc_state->gamma_enable =
2709		!glk_use_pre_csc_lut_for_gamma(crtc_state) &&
2710		crtc_state->hw.gamma_lut &&
2711		!crtc_state->c8_planes;
2712
2713	/* On GLK+ degamma LUT is controlled by csc_enable */
2714	crtc_state->csc_enable =
2715		glk_use_pre_csc_lut_for_gamma(crtc_state) ||
2716		crtc_state->hw.degamma_lut ||
2717		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2718		crtc_state->hw.ctm || ilk_csc_limited_range(crtc_state);
2719
2720	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
2721
2722	crtc_state->csc_mode = 0;
2723
2724	ret = intel_color_add_affected_planes(crtc_state);
2725	if (ret)
2726		return ret;
2727
2728	ret = glk_assign_luts(crtc_state);
2729	if (ret)
2730		return ret;
2731
2732	ilk_assign_csc(crtc_state);
2733
2734	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2735
2736	return 0;
2737}
2738
2739static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
2740{
2741	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2742	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2743	u32 gamma_mode = 0;
2744
2745	if (crtc_state->hw.degamma_lut)
2746		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
2747
2748	if (crtc_state->hw.gamma_lut &&
2749	    !crtc_state->c8_planes)
2750		gamma_mode |= POST_CSC_GAMMA_ENABLE;
2751
2752	if (!crtc_state->hw.gamma_lut ||
2753	    lut_is_legacy(crtc_state->hw.gamma_lut))
2754		gamma_mode |= GAMMA_MODE_MODE_8BIT;
2755	/*
2756	 * Enable 10bit gamma for D13
2757	 * ToDo: Extend to Logarithmic Gamma once the new UAPI
2758	 * is accepted and implemented by a userspace consumer
2759	 */
2760	else if (DISPLAY_VER(i915) >= 13)
2761		gamma_mode |= GAMMA_MODE_MODE_10BIT;
2762	else
2763		gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEG;
2764
2765	return gamma_mode;
2766}
2767
2768static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
2769{
2770	u32 csc_mode = 0;
2771
2772	if (crtc_state->hw.ctm)
2773		csc_mode |= ICL_CSC_ENABLE;
2774
2775	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2776	    crtc_state->limited_color_range)
2777		csc_mode |= ICL_OUTPUT_CSC_ENABLE;
2778
2779	return csc_mode;
2780}
2781
2782static int icl_color_check(struct intel_crtc_state *crtc_state)
2783{
2784	int ret;
2785
2786	ret = check_luts(crtc_state);
2787	if (ret)
2788		return ret;
2789
2790	crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
2791
2792	crtc_state->csc_mode = icl_csc_mode(crtc_state);
2793
2794	intel_assign_luts(crtc_state);
2795
2796	icl_assign_csc(crtc_state);
2797
2798	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2799
2800	return 0;
2801}
2802
2803static int i9xx_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2804{
2805	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2806		return 0;
2807
2808	switch (crtc_state->gamma_mode) {
2809	case GAMMA_MODE_MODE_8BIT:
2810		return 8;
2811	case GAMMA_MODE_MODE_10BIT:
2812		return 10;
2813	default:
2814		MISSING_CASE(crtc_state->gamma_mode);
2815		return 0;
2816	}
2817}
2818
2819static int i9xx_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2820{
2821	return 0;
2822}
2823
2824static int i965_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2825{
2826	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2827		return 0;
2828
2829	switch (crtc_state->gamma_mode) {
2830	case GAMMA_MODE_MODE_8BIT:
2831		return 8;
2832	case GAMMA_MODE_MODE_10BIT:
2833		return 16;
2834	default:
2835		MISSING_CASE(crtc_state->gamma_mode);
2836		return 0;
2837	}
2838}
2839
2840static int ilk_gamma_mode_precision(u32 gamma_mode)
2841{
2842	switch (gamma_mode) {
2843	case GAMMA_MODE_MODE_8BIT:
2844		return 8;
2845	case GAMMA_MODE_MODE_10BIT:
2846		return 10;
2847	default:
2848		MISSING_CASE(gamma_mode);
2849		return 0;
2850	}
2851}
2852
2853static bool ilk_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2854{
2855	if (crtc_state->c8_planes)
2856		return true;
2857
2858	return crtc_state->gamma_enable &&
2859		(crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) != 0;
2860}
2861
2862static bool ilk_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2863{
2864	return crtc_state->gamma_enable &&
2865		(crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0;
2866}
2867
2868static int ilk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2869{
2870	if (!ilk_has_post_csc_lut(crtc_state))
2871		return 0;
2872
2873	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2874}
2875
2876static int ilk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2877{
2878	if (!ilk_has_pre_csc_lut(crtc_state))
2879		return 0;
2880
2881	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2882}
2883
2884static int ivb_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2885{
2886	if (crtc_state->gamma_enable &&
2887	    crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
2888		return 10;
2889
2890	return ilk_post_csc_lut_precision(crtc_state);
2891}
2892
2893static int ivb_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2894{
2895	if (crtc_state->gamma_enable &&
2896	    crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
2897		return 10;
2898
2899	return ilk_pre_csc_lut_precision(crtc_state);
2900}
2901
2902static int chv_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2903{
2904	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
2905		return 10;
2906
2907	return i965_post_csc_lut_precision(crtc_state);
2908}
2909
2910static int chv_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2911{
2912	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
2913		return 14;
2914
2915	return 0;
2916}
2917
2918static int glk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2919{
2920	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2921		return 0;
2922
2923	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2924}
2925
2926static int glk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2927{
2928	if (!crtc_state->csc_enable)
2929		return 0;
2930
2931	return 16;
2932}
2933
2934static bool icl_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2935{
2936	if (crtc_state->c8_planes)
2937		return true;
2938
2939	return crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE;
2940}
2941
2942static bool icl_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2943{
2944	return crtc_state->gamma_mode & PRE_CSC_GAMMA_ENABLE;
2945}
2946
2947static int icl_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2948{
2949	if (!icl_has_post_csc_lut(crtc_state))
2950		return 0;
2951
2952	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
2953	case GAMMA_MODE_MODE_8BIT:
2954		return 8;
2955	case GAMMA_MODE_MODE_10BIT:
2956		return 10;
2957	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
2958		return 16;
2959	default:
2960		MISSING_CASE(crtc_state->gamma_mode);
2961		return 0;
2962	}
2963}
2964
2965static int icl_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2966{
2967	if (!icl_has_pre_csc_lut(crtc_state))
2968		return 0;
2969
2970	return 16;
2971}
2972
2973static bool err_check(const struct drm_color_lut *lut1,
2974		      const struct drm_color_lut *lut2, u32 err)
2975{
2976	return ((abs((long)lut2->red - lut1->red)) <= err) &&
2977		((abs((long)lut2->blue - lut1->blue)) <= err) &&
2978		((abs((long)lut2->green - lut1->green)) <= err);
2979}
2980
2981static bool intel_lut_entries_equal(const struct drm_color_lut *lut1,
2982				    const struct drm_color_lut *lut2,
2983				    int lut_size, u32 err)
2984{
2985	int i;
2986
2987	for (i = 0; i < lut_size; i++) {
2988		if (!err_check(&lut1[i], &lut2[i], err))
2989			return false;
2990	}
2991
2992	return true;
2993}
2994
2995static bool intel_lut_equal(const struct drm_property_blob *blob1,
2996			    const struct drm_property_blob *blob2,
2997			    int check_size, int precision)
2998{
2999	const struct drm_color_lut *lut1, *lut2;
3000	int lut_size1, lut_size2;
3001	u32 err;
3002
3003	if (!blob1 != !blob2)
3004		return false;
3005
3006	if (!blob1 != !precision)
3007		return false;
3008
3009	if (!blob1)
3010		return true;
3011
3012	lut_size1 = drm_color_lut_size(blob1);
3013	lut_size2 = drm_color_lut_size(blob2);
3014
3015	if (lut_size1 != lut_size2)
3016		return false;
3017
3018	if (check_size > lut_size1)
3019		return false;
3020
3021	lut1 = blob1->data;
3022	lut2 = blob2->data;
3023
3024	err = 0xffff >> precision;
3025
3026	if (!check_size)
3027		check_size = lut_size1;
3028
3029	return intel_lut_entries_equal(lut1, lut2, check_size, err);
3030}
3031
3032static bool i9xx_lut_equal(const struct intel_crtc_state *crtc_state,
3033			   const struct drm_property_blob *blob1,
3034			   const struct drm_property_blob *blob2,
3035			   bool is_pre_csc_lut)
3036{
3037	int check_size = 0;
3038
3039	if (is_pre_csc_lut)
3040		return intel_lut_equal(blob1, blob2, 0,
3041				       i9xx_pre_csc_lut_precision(crtc_state));
3042
3043	/* 10bit mode last entry is implicit, just skip it */
3044	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT)
3045		check_size = 128;
3046
3047	return intel_lut_equal(blob1, blob2, check_size,
3048			       i9xx_post_csc_lut_precision(crtc_state));
3049}
3050
3051static bool i965_lut_equal(const struct intel_crtc_state *crtc_state,
3052			   const struct drm_property_blob *blob1,
3053			   const struct drm_property_blob *blob2,
3054			   bool is_pre_csc_lut)
3055{
3056	if (is_pre_csc_lut)
3057		return intel_lut_equal(blob1, blob2, 0,
3058				       i9xx_pre_csc_lut_precision(crtc_state));
3059	else
3060		return intel_lut_equal(blob1, blob2, 0,
3061				       i965_post_csc_lut_precision(crtc_state));
3062}
3063
3064static bool chv_lut_equal(const struct intel_crtc_state *crtc_state,
3065			  const struct drm_property_blob *blob1,
3066			  const struct drm_property_blob *blob2,
3067			  bool is_pre_csc_lut)
3068{
3069	if (is_pre_csc_lut)
3070		return intel_lut_equal(blob1, blob2, 0,
3071				       chv_pre_csc_lut_precision(crtc_state));
3072	else
3073		return intel_lut_equal(blob1, blob2, 0,
3074				       chv_post_csc_lut_precision(crtc_state));
3075}
3076
3077static bool ilk_lut_equal(const struct intel_crtc_state *crtc_state,
3078			  const struct drm_property_blob *blob1,
3079			  const struct drm_property_blob *blob2,
3080			  bool is_pre_csc_lut)
3081{
3082	if (is_pre_csc_lut)
3083		return intel_lut_equal(blob1, blob2, 0,
3084				       ilk_pre_csc_lut_precision(crtc_state));
3085	else
3086		return intel_lut_equal(blob1, blob2, 0,
3087				       ilk_post_csc_lut_precision(crtc_state));
3088}
3089
3090static bool ivb_lut_equal(const struct intel_crtc_state *crtc_state,
3091			  const struct drm_property_blob *blob1,
3092			  const struct drm_property_blob *blob2,
3093			  bool is_pre_csc_lut)
3094{
3095	if (is_pre_csc_lut)
3096		return intel_lut_equal(blob1, blob2, 0,
3097				       ivb_pre_csc_lut_precision(crtc_state));
3098	else
3099		return intel_lut_equal(blob1, blob2, 0,
3100				       ivb_post_csc_lut_precision(crtc_state));
3101}
3102
3103static bool glk_lut_equal(const struct intel_crtc_state *crtc_state,
3104			  const struct drm_property_blob *blob1,
3105			  const struct drm_property_blob *blob2,
3106			  bool is_pre_csc_lut)
3107{
3108	if (is_pre_csc_lut)
3109		return intel_lut_equal(blob1, blob2, 0,
3110				       glk_pre_csc_lut_precision(crtc_state));
3111	else
3112		return intel_lut_equal(blob1, blob2, 0,
3113				       glk_post_csc_lut_precision(crtc_state));
3114}
3115
3116static bool icl_lut_equal(const struct intel_crtc_state *crtc_state,
3117			  const struct drm_property_blob *blob1,
3118			  const struct drm_property_blob *blob2,
3119			  bool is_pre_csc_lut)
3120{
3121	int check_size = 0;
3122
3123	if (is_pre_csc_lut)
3124		return intel_lut_equal(blob1, blob2, 0,
3125				       icl_pre_csc_lut_precision(crtc_state));
3126
3127	/* hw readout broken except for the super fine segment :( */
3128	if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) ==
3129	    GAMMA_MODE_MODE_12BIT_MULTI_SEG)
3130		check_size = 9;
3131
3132	return intel_lut_equal(blob1, blob2, check_size,
3133			       icl_post_csc_lut_precision(crtc_state));
3134}
3135
3136static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)
3137{
3138	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3139	enum pipe pipe = crtc->pipe;
3140	struct drm_property_blob *blob;
3141	struct drm_color_lut *lut;
3142	int i;
3143
3144	blob = drm_property_create_blob(&dev_priv->drm,
3145					sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3146					NULL);
3147	if (IS_ERR(blob))
3148		return NULL;
3149
3150	lut = blob->data;
3151
3152	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3153		u32 val = intel_de_read_fw(dev_priv, PALETTE(pipe, i));
3154
3155		i9xx_lut_8_pack(&lut[i], val);
3156	}
3157
3158	return blob;
3159}
3160
3161static struct drm_property_blob *i9xx_read_lut_10(struct intel_crtc *crtc)
3162{
3163	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3164	u32 lut_size = DISPLAY_INFO(dev_priv)->color.gamma_lut_size;
3165	enum pipe pipe = crtc->pipe;
3166	struct drm_property_blob *blob;
3167	struct drm_color_lut *lut;
3168	u32 ldw, udw;
3169	int i;
3170
3171	blob = drm_property_create_blob(&dev_priv->drm,
3172					lut_size * sizeof(lut[0]), NULL);
3173	if (IS_ERR(blob))
3174		return NULL;
3175
3176	lut = blob->data;
3177
3178	for (i = 0; i < lut_size - 1; i++) {
3179		ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
3180		udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
3181
3182		i9xx_lut_10_pack(&lut[i], ldw, udw);
3183	}
3184
3185	i9xx_lut_10_pack_slope(&lut[i], ldw, udw);
3186
3187	return blob;
3188}
3189
3190static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
3191{
3192	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3193
3194	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3195		return;
3196
3197	switch (crtc_state->gamma_mode) {
3198	case GAMMA_MODE_MODE_8BIT:
3199		crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3200		break;
3201	case GAMMA_MODE_MODE_10BIT:
3202		crtc_state->post_csc_lut = i9xx_read_lut_10(crtc);
3203		break;
3204	default:
3205		MISSING_CASE(crtc_state->gamma_mode);
3206		break;
3207	}
3208}
3209
3210static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
3211{
3212	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3213	int i, lut_size = DISPLAY_INFO(dev_priv)->color.gamma_lut_size;
3214	enum pipe pipe = crtc->pipe;
3215	struct drm_property_blob *blob;
3216	struct drm_color_lut *lut;
3217
3218	blob = drm_property_create_blob(&dev_priv->drm,
3219					sizeof(lut[0]) * lut_size,
3220					NULL);
3221	if (IS_ERR(blob))
3222		return NULL;
3223
3224	lut = blob->data;
3225
3226	for (i = 0; i < lut_size - 1; i++) {
3227		u32 ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
3228		u32 udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
3229
3230		i965_lut_10p6_pack(&lut[i], ldw, udw);
3231	}
3232
3233	lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
3234	lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
3235	lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
3236
3237	return blob;
3238}
3239
3240static void i965_read_luts(struct intel_crtc_state *crtc_state)
3241{
3242	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3243
3244	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3245		return;
3246
3247	switch (crtc_state->gamma_mode) {
3248	case GAMMA_MODE_MODE_8BIT:
3249		crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3250		break;
3251	case GAMMA_MODE_MODE_10BIT:
3252		crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
3253		break;
3254	default:
3255		MISSING_CASE(crtc_state->gamma_mode);
3256		break;
3257	}
3258}
3259
3260static struct drm_property_blob *chv_read_cgm_degamma(struct intel_crtc *crtc)
3261{
3262	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3263	int i, lut_size = DISPLAY_INFO(dev_priv)->color.degamma_lut_size;
3264	enum pipe pipe = crtc->pipe;
3265	struct drm_property_blob *blob;
3266	struct drm_color_lut *lut;
3267
3268	blob = drm_property_create_blob(&dev_priv->drm,
3269					sizeof(lut[0]) * lut_size,
3270					NULL);
3271	if (IS_ERR(blob))
3272		return NULL;
3273
3274	lut = blob->data;
3275
3276	for (i = 0; i < lut_size; i++) {
3277		u32 ldw = intel_de_read_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 0));
3278		u32 udw = intel_de_read_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 1));
3279
3280		chv_cgm_degamma_pack(&lut[i], ldw, udw);
3281	}
3282
3283	return blob;
3284}
3285
3286static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
3287{
3288	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3289	int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3290	enum pipe pipe = crtc->pipe;
3291	struct drm_property_blob *blob;
3292	struct drm_color_lut *lut;
3293
3294	blob = drm_property_create_blob(&i915->drm,
3295					sizeof(lut[0]) * lut_size,
3296					NULL);
3297	if (IS_ERR(blob))
3298		return NULL;
3299
3300	lut = blob->data;
3301
3302	for (i = 0; i < lut_size; i++) {
3303		u32 ldw = intel_de_read_fw(i915, CGM_PIPE_GAMMA(pipe, i, 0));
3304		u32 udw = intel_de_read_fw(i915, CGM_PIPE_GAMMA(pipe, i, 1));
3305
3306		chv_cgm_gamma_pack(&lut[i], ldw, udw);
3307	}
3308
3309	return blob;
3310}
3311
3312static void chv_get_config(struct intel_crtc_state *crtc_state)
3313{
3314	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3315	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3316
3317	crtc_state->cgm_mode = intel_de_read(i915, CGM_PIPE_MODE(crtc->pipe));
3318
3319	i9xx_get_config(crtc_state);
3320}
3321
3322static void chv_read_luts(struct intel_crtc_state *crtc_state)
3323{
3324	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3325
3326	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
3327		crtc_state->pre_csc_lut = chv_read_cgm_degamma(crtc);
3328
3329	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
3330		crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
3331	else
3332		i965_read_luts(crtc_state);
3333}
3334
3335static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc)
3336{
3337	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3338	enum pipe pipe = crtc->pipe;
3339	struct drm_property_blob *blob;
3340	struct drm_color_lut *lut;
3341	int i;
3342
3343	blob = drm_property_create_blob(&i915->drm,
3344					sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3345					NULL);
3346	if (IS_ERR(blob))
3347		return NULL;
3348
3349	lut = blob->data;
3350
3351	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3352		u32 val = intel_de_read_fw(i915, LGC_PALETTE(pipe, i));
3353
3354		i9xx_lut_8_pack(&lut[i], val);
3355	}
3356
3357	return blob;
3358}
3359
3360static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc)
3361{
3362	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3363	int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3364	enum pipe pipe = crtc->pipe;
3365	struct drm_property_blob *blob;
3366	struct drm_color_lut *lut;
3367
3368	blob = drm_property_create_blob(&i915->drm,
3369					sizeof(lut[0]) * lut_size,
3370					NULL);
3371	if (IS_ERR(blob))
3372		return NULL;
3373
3374	lut = blob->data;
3375
3376	for (i = 0; i < lut_size; i++) {
3377		u32 val = intel_de_read_fw(i915, PREC_PALETTE(pipe, i));
3378
3379		ilk_lut_10_pack(&lut[i], val);
3380	}
3381
3382	return blob;
3383}
3384
3385static void ilk_get_config(struct intel_crtc_state *crtc_state)
3386{
3387	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3388
3389	crtc_state->csc_mode = ilk_read_csc_mode(crtc);
3390
3391	i9xx_get_config(crtc_state);
3392}
3393
3394static void ilk_read_luts(struct intel_crtc_state *crtc_state)
3395{
3396	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3397	struct drm_property_blob **blob =
3398		ilk_has_post_csc_lut(crtc_state) ?
3399		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3400
3401	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3402		return;
3403
3404	switch (crtc_state->gamma_mode) {
3405	case GAMMA_MODE_MODE_8BIT:
3406		*blob = ilk_read_lut_8(crtc);
3407		break;
3408	case GAMMA_MODE_MODE_10BIT:
3409		*blob = ilk_read_lut_10(crtc);
3410		break;
3411	default:
3412		MISSING_CASE(crtc_state->gamma_mode);
3413		break;
3414	}
3415}
3416
3417/*
3418 * IVB/HSW Bspec / PAL_PREC_INDEX:
3419 * "Restriction : Index auto increment mode is not
3420 *  supported and must not be enabled."
3421 */
3422static struct drm_property_blob *ivb_read_lut_10(struct intel_crtc *crtc,
3423						 u32 prec_index)
3424{
3425	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3426	int i, lut_size = ivb_lut_10_size(prec_index);
3427	enum pipe pipe = crtc->pipe;
3428	struct drm_property_blob *blob;
3429	struct drm_color_lut *lut;
3430
3431	blob = drm_property_create_blob(&dev_priv->drm,
3432					sizeof(lut[0]) * lut_size,
3433					NULL);
3434	if (IS_ERR(blob))
3435		return NULL;
3436
3437	lut = blob->data;
3438
3439	for (i = 0; i < lut_size; i++) {
3440		u32 val;
3441
3442		intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
3443				  prec_index + i);
3444		val = intel_de_read_fw(dev_priv, PREC_PAL_DATA(pipe));
3445
3446		ilk_lut_10_pack(&lut[i], val);
3447	}
3448
3449	intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
3450			  PAL_PREC_INDEX_VALUE(0));
3451
3452	return blob;
3453}
3454
3455static void ivb_read_luts(struct intel_crtc_state *crtc_state)
3456{
3457	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3458	struct drm_property_blob **blob =
3459		ilk_has_post_csc_lut(crtc_state) ?
3460		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3461
3462	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3463		return;
3464
3465	switch (crtc_state->gamma_mode) {
3466	case GAMMA_MODE_MODE_8BIT:
3467		*blob = ilk_read_lut_8(crtc);
3468		break;
3469	case GAMMA_MODE_MODE_SPLIT:
3470		crtc_state->pre_csc_lut =
3471			ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3472					PAL_PREC_INDEX_VALUE(0));
3473		crtc_state->post_csc_lut =
3474			ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3475					PAL_PREC_INDEX_VALUE(512));
3476		break;
3477	case GAMMA_MODE_MODE_10BIT:
3478		*blob = ivb_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3479		break;
3480	default:
3481		MISSING_CASE(crtc_state->gamma_mode);
3482		break;
3483	}
3484}
3485
3486/* On BDW+ the index auto increment mode actually works */
3487static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
3488						 u32 prec_index)
3489{
3490	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3491	int i, lut_size = ivb_lut_10_size(prec_index);
3492	enum pipe pipe = crtc->pipe;
3493	struct drm_property_blob *blob;
3494	struct drm_color_lut *lut;
3495
3496	blob = drm_property_create_blob(&i915->drm,
3497					sizeof(lut[0]) * lut_size,
3498					NULL);
3499	if (IS_ERR(blob))
3500		return NULL;
3501
3502	lut = blob->data;
3503
3504	intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3505			  prec_index);
3506	intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3507			  PAL_PREC_AUTO_INCREMENT |
3508			  prec_index);
3509
3510	for (i = 0; i < lut_size; i++) {
3511		u32 val = intel_de_read_fw(i915, PREC_PAL_DATA(pipe));
3512
3513		ilk_lut_10_pack(&lut[i], val);
3514	}
3515
3516	intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3517			  PAL_PREC_INDEX_VALUE(0));
3518
3519	return blob;
3520}
3521
3522static void bdw_read_luts(struct intel_crtc_state *crtc_state)
3523{
3524	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3525	struct drm_property_blob **blob =
3526		ilk_has_post_csc_lut(crtc_state) ?
3527		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3528
3529	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3530		return;
3531
3532	switch (crtc_state->gamma_mode) {
3533	case GAMMA_MODE_MODE_8BIT:
3534		*blob = ilk_read_lut_8(crtc);
3535		break;
3536	case GAMMA_MODE_MODE_SPLIT:
3537		crtc_state->pre_csc_lut =
3538			bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3539					PAL_PREC_INDEX_VALUE(0));
3540		crtc_state->post_csc_lut =
3541			bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3542					PAL_PREC_INDEX_VALUE(512));
3543		break;
3544	case GAMMA_MODE_MODE_10BIT:
3545		*blob = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3546		break;
3547	default:
3548		MISSING_CASE(crtc_state->gamma_mode);
3549		break;
3550	}
3551}
3552
3553static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc)
3554{
3555	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3556	int i, lut_size = DISPLAY_INFO(dev_priv)->color.degamma_lut_size;
3557	enum pipe pipe = crtc->pipe;
3558	struct drm_property_blob *blob;
3559	struct drm_color_lut *lut;
3560
3561	blob = drm_property_create_blob(&dev_priv->drm,
3562					sizeof(lut[0]) * lut_size,
3563					NULL);
3564	if (IS_ERR(blob))
3565		return NULL;
3566
3567	lut = blob->data;
3568
3569	/*
3570	 * When setting the auto-increment bit, the hardware seems to
3571	 * ignore the index bits, so we need to reset it to index 0
3572	 * separately.
3573	 */
3574	intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3575			  PRE_CSC_GAMC_INDEX_VALUE(0));
3576	intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3577			  PRE_CSC_GAMC_AUTO_INCREMENT |
3578			  PRE_CSC_GAMC_INDEX_VALUE(0));
3579
3580	for (i = 0; i < lut_size; i++) {
3581		u32 val = intel_de_read_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe));
3582
3583		if (DISPLAY_VER(dev_priv) >= 14)
3584			mtl_degamma_lut_pack(&lut[i], val);
3585		else
3586			glk_degamma_lut_pack(&lut[i], val);
3587	}
3588
3589	intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3590			  PRE_CSC_GAMC_INDEX_VALUE(0));
3591
3592	return blob;
3593}
3594
3595static void glk_read_luts(struct intel_crtc_state *crtc_state)
3596{
3597	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3598
3599	if (crtc_state->csc_enable)
3600		crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3601
3602	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3603		return;
3604
3605	switch (crtc_state->gamma_mode) {
3606	case GAMMA_MODE_MODE_8BIT:
3607		crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3608		break;
3609	case GAMMA_MODE_MODE_10BIT:
3610		crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3611		break;
3612	default:
3613		MISSING_CASE(crtc_state->gamma_mode);
3614		break;
3615	}
3616}
3617
3618static struct drm_property_blob *
3619icl_read_lut_multi_segment(struct intel_crtc *crtc)
3620{
3621	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3622	int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3623	enum pipe pipe = crtc->pipe;
3624	struct drm_property_blob *blob;
3625	struct drm_color_lut *lut;
3626
3627	blob = drm_property_create_blob(&i915->drm,
3628					sizeof(lut[0]) * lut_size,
3629					NULL);
3630	if (IS_ERR(blob))
3631		return NULL;
3632
3633	lut = blob->data;
3634
3635	intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3636			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3637	intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3638			  PAL_PREC_MULTI_SEG_AUTO_INCREMENT |
3639			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3640
3641	for (i = 0; i < 9; i++) {
3642		u32 ldw = intel_de_read_fw(i915, PREC_PAL_MULTI_SEG_DATA(pipe));
3643		u32 udw = intel_de_read_fw(i915, PREC_PAL_MULTI_SEG_DATA(pipe));
3644
3645		ilk_lut_12p4_pack(&lut[i], ldw, udw);
3646	}
3647
3648	intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3649			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3650
3651	/*
3652	 * FIXME readouts from PAL_PREC_DATA register aren't giving
3653	 * correct values in the case of fine and coarse segments.
3654	 * Restricting readouts only for super fine segment as of now.
3655	 */
3656
3657	return blob;
3658}
3659
3660static void icl_read_luts(struct intel_crtc_state *crtc_state)
3661{
3662	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3663
3664	if (icl_has_pre_csc_lut(crtc_state))
3665		crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3666
3667	if (!icl_has_post_csc_lut(crtc_state))
3668		return;
3669
3670	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
3671	case GAMMA_MODE_MODE_8BIT:
3672		crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3673		break;
3674	case GAMMA_MODE_MODE_10BIT:
3675		crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3676		break;
3677	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
3678		crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
3679		break;
3680	default:
3681		MISSING_CASE(crtc_state->gamma_mode);
3682		break;
3683	}
3684}
3685
3686static const struct intel_color_funcs chv_color_funcs = {
3687	.color_check = chv_color_check,
3688	.color_commit_arm = i9xx_color_commit_arm,
3689	.load_luts = chv_load_luts,
3690	.read_luts = chv_read_luts,
3691	.lut_equal = chv_lut_equal,
3692	.read_csc = chv_read_csc,
3693	.get_config = chv_get_config,
3694};
3695
3696static const struct intel_color_funcs vlv_color_funcs = {
3697	.color_check = vlv_color_check,
3698	.color_commit_arm = i9xx_color_commit_arm,
3699	.load_luts = vlv_load_luts,
3700	.read_luts = i965_read_luts,
3701	.lut_equal = i965_lut_equal,
3702	.read_csc = vlv_read_csc,
3703	.get_config = i9xx_get_config,
3704};
3705
3706static const struct intel_color_funcs i965_color_funcs = {
3707	.color_check = i9xx_color_check,
3708	.color_commit_arm = i9xx_color_commit_arm,
3709	.load_luts = i965_load_luts,
3710	.read_luts = i965_read_luts,
3711	.lut_equal = i965_lut_equal,
3712	.get_config = i9xx_get_config,
3713};
3714
3715static const struct intel_color_funcs i9xx_color_funcs = {
3716	.color_check = i9xx_color_check,
3717	.color_commit_arm = i9xx_color_commit_arm,
3718	.load_luts = i9xx_load_luts,
3719	.read_luts = i9xx_read_luts,
3720	.lut_equal = i9xx_lut_equal,
3721	.get_config = i9xx_get_config,
3722};
3723
3724static const struct intel_color_funcs tgl_color_funcs = {
3725	.color_check = icl_color_check,
3726	.color_commit_noarm = icl_color_commit_noarm,
3727	.color_commit_arm = icl_color_commit_arm,
3728	.load_luts = icl_load_luts,
3729	.read_luts = icl_read_luts,
3730	.lut_equal = icl_lut_equal,
3731	.read_csc = icl_read_csc,
3732	.get_config = skl_get_config,
3733};
3734
3735static const struct intel_color_funcs icl_color_funcs = {
3736	.color_check = icl_color_check,
3737	.color_commit_noarm = icl_color_commit_noarm,
3738	.color_commit_arm = icl_color_commit_arm,
3739	.color_post_update = icl_color_post_update,
3740	.load_luts = icl_load_luts,
3741	.read_luts = icl_read_luts,
3742	.lut_equal = icl_lut_equal,
3743	.read_csc = icl_read_csc,
3744	.get_config = skl_get_config,
3745};
3746
3747static const struct intel_color_funcs glk_color_funcs = {
3748	.color_check = glk_color_check,
3749	.color_commit_noarm = skl_color_commit_noarm,
3750	.color_commit_arm = skl_color_commit_arm,
3751	.load_luts = glk_load_luts,
3752	.read_luts = glk_read_luts,
3753	.lut_equal = glk_lut_equal,
3754	.read_csc = skl_read_csc,
3755	.get_config = skl_get_config,
3756};
3757
3758static const struct intel_color_funcs skl_color_funcs = {
3759	.color_check = ivb_color_check,
3760	.color_commit_noarm = skl_color_commit_noarm,
3761	.color_commit_arm = skl_color_commit_arm,
3762	.load_luts = bdw_load_luts,
3763	.read_luts = bdw_read_luts,
3764	.lut_equal = ivb_lut_equal,
3765	.read_csc = skl_read_csc,
3766	.get_config = skl_get_config,
3767};
3768
3769static const struct intel_color_funcs bdw_color_funcs = {
3770	.color_check = ivb_color_check,
3771	.color_commit_noarm = ilk_color_commit_noarm,
3772	.color_commit_arm = hsw_color_commit_arm,
3773	.load_luts = bdw_load_luts,
3774	.read_luts = bdw_read_luts,
3775	.lut_equal = ivb_lut_equal,
3776	.read_csc = ilk_read_csc,
3777	.get_config = hsw_get_config,
3778};
3779
3780static const struct intel_color_funcs hsw_color_funcs = {
3781	.color_check = ivb_color_check,
3782	.color_commit_noarm = ilk_color_commit_noarm,
3783	.color_commit_arm = hsw_color_commit_arm,
3784	.load_luts = ivb_load_luts,
3785	.read_luts = ivb_read_luts,
3786	.lut_equal = ivb_lut_equal,
3787	.read_csc = ilk_read_csc,
3788	.get_config = hsw_get_config,
3789};
3790
3791static const struct intel_color_funcs ivb_color_funcs = {
3792	.color_check = ivb_color_check,
3793	.color_commit_noarm = ilk_color_commit_noarm,
3794	.color_commit_arm = ilk_color_commit_arm,
3795	.load_luts = ivb_load_luts,
3796	.read_luts = ivb_read_luts,
3797	.lut_equal = ivb_lut_equal,
3798	.read_csc = ilk_read_csc,
3799	.get_config = ilk_get_config,
3800};
3801
3802static const struct intel_color_funcs ilk_color_funcs = {
3803	.color_check = ilk_color_check,
3804	.color_commit_noarm = ilk_color_commit_noarm,
3805	.color_commit_arm = ilk_color_commit_arm,
3806	.load_luts = ilk_load_luts,
3807	.read_luts = ilk_read_luts,
3808	.lut_equal = ilk_lut_equal,
3809	.read_csc = ilk_read_csc,
3810	.get_config = ilk_get_config,
3811};
3812
3813void intel_color_crtc_init(struct intel_crtc *crtc)
3814{
3815	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3816	int degamma_lut_size, gamma_lut_size;
3817	bool has_ctm;
3818
3819	drm_mode_crtc_set_gamma_size(&crtc->base, 256);
3820
3821	gamma_lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3822	degamma_lut_size = DISPLAY_INFO(i915)->color.degamma_lut_size;
3823	has_ctm = DISPLAY_VER(i915) >= 5;
3824
3825	/*
3826	 * "DPALETTE_A: NOTE: The 8-bit (non-10-bit) mode is the
3827	 *  only mode supported by Alviso and Grantsdale."
3828	 *
3829	 * Actually looks like this affects all of gen3.
3830	 * Confirmed on alv,cst,pnv. Mobile gen2 parts (alm,mgm)
3831	 * are confirmed not to suffer from this restriction.
3832	 */
3833	if (DISPLAY_VER(i915) == 3 && crtc->pipe == PIPE_A)
3834		gamma_lut_size = 256;
3835
3836	drm_crtc_enable_color_mgmt(&crtc->base, degamma_lut_size,
3837				   has_ctm, gamma_lut_size);
3838}
3839
3840int intel_color_init(struct drm_i915_private *i915)
3841{
3842	struct drm_property_blob *blob;
3843
3844	if (DISPLAY_VER(i915) != 10)
3845		return 0;
3846
3847	blob = create_linear_lut(i915,
3848				 DISPLAY_INFO(i915)->color.degamma_lut_size);
3849	if (IS_ERR(blob))
3850		return PTR_ERR(blob);
3851
3852	i915->display.color.glk_linear_degamma_lut = blob;
3853
3854	return 0;
3855}
3856
3857void intel_color_init_hooks(struct drm_i915_private *i915)
3858{
3859	if (HAS_GMCH(i915)) {
3860		if (IS_CHERRYVIEW(i915))
3861			i915->display.funcs.color = &chv_color_funcs;
3862		else if (IS_VALLEYVIEW(i915))
3863			i915->display.funcs.color = &vlv_color_funcs;
3864		else if (DISPLAY_VER(i915) >= 4)
3865			i915->display.funcs.color = &i965_color_funcs;
3866		else
3867			i915->display.funcs.color = &i9xx_color_funcs;
3868	} else {
3869		if (DISPLAY_VER(i915) >= 12)
3870			i915->display.funcs.color = &tgl_color_funcs;
3871		else if (DISPLAY_VER(i915) == 11)
3872			i915->display.funcs.color = &icl_color_funcs;
3873		else if (DISPLAY_VER(i915) == 10)
3874			i915->display.funcs.color = &glk_color_funcs;
3875		else if (DISPLAY_VER(i915) == 9)
3876			i915->display.funcs.color = &skl_color_funcs;
3877		else if (DISPLAY_VER(i915) == 8)
3878			i915->display.funcs.color = &bdw_color_funcs;
3879		else if (IS_HASWELL(i915))
3880			i915->display.funcs.color = &hsw_color_funcs;
3881		else if (DISPLAY_VER(i915) == 7)
3882			i915->display.funcs.color = &ivb_color_funcs;
3883		else
3884			i915->display.funcs.color = &ilk_color_funcs;
3885	}
3886}
3887