intel_vdsc.c revision 1.2
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright �� 2018 Intel Corporation
4 *
5 * Author: Gaurav K Singh <gaurav.k.singh@intel.com>
6 *         Manasi Navare <manasi.d.navare@intel.com>
7 */
8
9#include "i915_drv.h"
10#include "intel_display_types.h"
11#include "intel_dsi.h"
12#include "intel_vdsc.h"
13
14enum ROW_INDEX_BPP {
15	ROW_INDEX_6BPP = 0,
16	ROW_INDEX_8BPP,
17	ROW_INDEX_10BPP,
18	ROW_INDEX_12BPP,
19	ROW_INDEX_15BPP,
20	MAX_ROW_INDEX
21};
22
23enum COLUMN_INDEX_BPC {
24	COLUMN_INDEX_8BPC = 0,
25	COLUMN_INDEX_10BPC,
26	COLUMN_INDEX_12BPC,
27	COLUMN_INDEX_14BPC,
28	COLUMN_INDEX_16BPC,
29	MAX_COLUMN_INDEX
30};
31
32/* From DSC_v1.11 spec, rc_parameter_Set syntax element typically constant */
33static const u16 rc_buf_thresh[] = {
34	896, 1792, 2688, 3584, 4480, 5376, 6272, 6720, 7168, 7616,
35	7744, 7872, 8000, 8064
36};
37
38struct rc_parameters {
39	u16 initial_xmit_delay;
40	u8 first_line_bpg_offset;
41	u16 initial_offset;
42	u8 flatness_min_qp;
43	u8 flatness_max_qp;
44	u8 rc_quant_incr_limit0;
45	u8 rc_quant_incr_limit1;
46	struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES];
47};
48
49/*
50 * Selected Rate Control Related Parameter Recommended Values
51 * from DSC_v1.11 spec & C Model release: DSC_model_20161212
52 */
53static const struct rc_parameters rc_parameters[][MAX_COLUMN_INDEX] = {
54{
55	/* 6BPP/8BPC */
56	{ 768, 15, 6144, 3, 13, 11, 11, {
57		{ 0, 4, 0 }, { 1, 6, -2 }, { 3, 8, -2 }, { 4, 8, -4 },
58		{ 5, 9, -6 }, { 5, 9, -6 }, { 6, 9, -6 }, { 6, 10, -8 },
59		{ 7, 11, -8 }, { 8, 12, -10 }, { 9, 12, -10 }, { 10, 12, -12 },
60		{ 10, 12, -12 }, { 11, 12, -12 }, { 13, 14, -12 }
61		}
62	},
63	/* 6BPP/10BPC */
64	{ 768, 15, 6144, 7, 17, 15, 15, {
65		{ 0, 8, 0 }, { 3, 10, -2 }, { 7, 12, -2 }, { 8, 12, -4 },
66		{ 9, 13, -6 }, { 9, 13, -6 }, { 10, 13, -6 }, { 10, 14, -8 },
67		{ 11, 15, -8 }, { 12, 16, -10 }, { 13, 16, -10 },
68		{ 14, 16, -12 }, { 14, 16, -12 }, { 15, 16, -12 },
69		{ 17, 18, -12 }
70		}
71	},
72	/* 6BPP/12BPC */
73	{ 768, 15, 6144, 11, 21, 19, 19, {
74		{ 0, 12, 0 }, { 5, 14, -2 }, { 11, 16, -2 }, { 12, 16, -4 },
75		{ 13, 17, -6 }, { 13, 17, -6 }, { 14, 17, -6 }, { 14, 18, -8 },
76		{ 15, 19, -8 }, { 16, 20, -10 }, { 17, 20, -10 },
77		{ 18, 20, -12 }, { 18, 20, -12 }, { 19, 20, -12 },
78		{ 21, 22, -12 }
79		}
80	},
81	/* 6BPP/14BPC */
82	{ 768, 15, 6144, 15, 25, 23, 27, {
83		{ 0, 16, 0 }, { 7, 18, -2 }, { 15, 20, -2 }, { 16, 20, -4 },
84		{ 17, 21, -6 }, { 17, 21, -6 }, { 18, 21, -6 }, { 18, 22, -8 },
85		{ 19, 23, -8 }, { 20, 24, -10 }, { 21, 24, -10 },
86		{ 22, 24, -12 }, { 22, 24, -12 }, { 23, 24, -12 },
87		{ 25, 26, -12 }
88		}
89	},
90	/* 6BPP/16BPC */
91	{ 768, 15, 6144, 19, 29, 27, 27, {
92		{ 0, 20, 0 }, { 9, 22, -2 }, { 19, 24, -2 }, { 20, 24, -4 },
93		{ 21, 25, -6 }, { 21, 25, -6 }, { 22, 25, -6 }, { 22, 26, -8 },
94		{ 23, 27, -8 }, { 24, 28, -10 }, { 25, 28, -10 },
95		{ 26, 28, -12 }, { 26, 28, -12 }, { 27, 28, -12 },
96		{ 29, 30, -12 }
97		}
98	},
99},
100{
101	/* 8BPP/8BPC */
102	{ 512, 12, 6144, 3, 12, 11, 11, {
103		{ 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
104		{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
105		{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 }, { 5, 12, -12 },
106		{ 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
107		}
108	},
109	/* 8BPP/10BPC */
110	{ 512, 12, 6144, 7, 16, 15, 15, {
111		{ 0, 4, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 },
112		{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
113		{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 },
114		{ 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
115		}
116	},
117	/* 8BPP/12BPC */
118	{ 512, 12, 6144, 11, 20, 19, 19, {
119		{ 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 },
120		{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
121		{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 },
122		{ 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 },
123		{ 21, 23, -12 }
124		}
125	},
126	/* 8BPP/14BPC */
127	{ 512, 12, 6144, 15, 24, 23, 23, {
128		{ 0, 12, 0 }, { 5, 13, 0 }, { 11, 15, 0 }, { 12, 17, -2 },
129		{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
130		{ 15, 21, -8 }, { 15, 22, -10 }, { 17, 22, -10 },
131		{ 17, 23, -12 }, { 17, 23, -12 }, { 21, 24, -12 },
132		{ 24, 25, -12 }
133		}
134	},
135	/* 8BPP/16BPC */
136	{ 512, 12, 6144, 19, 28, 27, 27, {
137		{ 0, 12, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 15, 20, -2 },
138		{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
139		{ 19, 25, -8 }, { 19, 26, -10 }, { 21, 26, -10 },
140		{ 21, 27, -12 }, { 21, 27, -12 }, { 25, 28, -12 },
141		{ 28, 29, -12 }
142		}
143	},
144},
145{
146	/* 10BPP/8BPC */
147	{ 410, 15, 5632, 3, 12, 11, 11, {
148		{ 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 },
149		{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
150		{ 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 10, -10 },
151		{ 5, 11, -12 }, { 7, 11, -12 }, { 11, 12, -12 }
152		}
153	},
154	/* 10BPP/10BPC */
155	{ 410, 15, 5632, 7, 16, 15, 15, {
156		{ 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 },
157		{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
158		{ 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 14, -10 },
159		{ 9, 15, -12 }, { 11, 15, -12 }, { 15, 16, -12 }
160		}
161	},
162	/* 10BPP/12BPC */
163	{ 410, 15, 5632, 11, 20, 19, 19, {
164		{ 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 },
165		{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
166		{ 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 },
167		{ 13, 18, -10 }, { 13, 19, -12 }, { 15, 19, -12 },
168		{ 19, 20, -12 }
169		}
170	},
171	/* 10BPP/14BPC */
172	{ 410, 15, 5632, 15, 24, 23, 23, {
173		{ 0, 11, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 13, 18, -2 },
174		{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
175		{ 15, 21, -8 }, { 15, 21, -10 }, { 17, 22, -10 },
176		{ 17, 22, -10 }, { 17, 23, -12 }, { 19, 23, -12 },
177		{ 23, 24, -12 }
178		}
179	},
180	/* 10BPP/16BPC */
181	{ 410, 15, 5632, 19, 28, 27, 27, {
182		{ 0, 11, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 16, 20, -2 },
183		{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
184		{ 19, 25, -8 }, { 19, 25, -10 }, { 21, 26, -10 },
185		{ 21, 26, -10 }, { 21, 27, -12 }, { 23, 27, -12 },
186		{ 27, 28, -12 }
187		}
188	},
189},
190{
191	/* 12BPP/8BPC */
192	{ 341, 15, 2048, 3, 12, 11, 11, {
193		{ 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
194		{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
195		{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 },
196		{ 5, 12, -12 }, { 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
197		}
198	},
199	/* 12BPP/10BPC */
200	{ 341, 15, 2048, 7, 16, 15, 15, {
201		{ 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 },
202		{ 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
203		{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 },
204		{ 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
205		}
206	},
207	/* 12BPP/12BPC */
208	{ 341, 15, 2048, 11, 20, 19, 19, {
209		{ 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 },
210		{ 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
211		{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 },
212		{ 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 },
213		{ 21, 23, -12 }
214		}
215	},
216	/* 12BPP/14BPC */
217	{ 341, 15, 2048, 15, 24, 23, 23, {
218		{ 0, 6, 2 }, { 7, 10, 0 }, { 9, 13, 0 }, { 11, 16, -2 },
219		{ 14, 17, -4 }, { 15, 18, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
220		{ 15, 20, -8 }, { 15, 21, -10 }, { 17, 21, -10 },
221		{ 17, 21, -12 }, { 17, 21, -12 }, { 19, 22, -12 },
222		{ 22, 23, -12 }
223		}
224	},
225	/* 12BPP/16BPC */
226	{ 341, 15, 2048, 19, 28, 27, 27, {
227		{ 0, 6, 2 }, { 6, 11, 0 }, { 11, 15, 0 }, { 14, 18, -2 },
228		{ 18, 21, -4 }, { 19, 22, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
229		{ 19, 24, -8 }, { 19, 25, -10 }, { 21, 25, -10 },
230		{ 21, 25, -12 }, { 21, 25, -12 }, { 23, 26, -12 },
231		{ 26, 27, -12 }
232		}
233	},
234},
235{
236	/* 15BPP/8BPC */
237	{ 273, 15, 2048, 3, 12, 11, 11, {
238		{ 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 },
239		{ 1, 2, 2 }, { 1, 3, 0 }, { 1, 3, -2 }, { 2, 4, -4 },
240		{ 2, 5, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 4, 7, -10 },
241		{ 5, 7, -12 }, { 7, 8, -12 }, { 8, 9, -12 }
242		}
243	},
244	/* 15BPP/10BPC */
245	{ 273, 15, 2048, 7, 16, 15, 15, {
246		{ 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 },
247		{ 5, 6, 2 }, { 5, 7, 0 }, { 5, 7, -2 }, { 6, 8, -4 },
248		{ 6, 9, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 8, 11, -10 },
249		{ 9, 11, -12 }, { 11, 12, -12 }, { 12, 13, -12 }
250		}
251	},
252	/* 15BPP/12BPC */
253	{ 273, 15, 2048, 11, 20, 19, 19, {
254		{ 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 },
255		{ 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 },
256		{ 11, 13, -6 }, { 11, 13, -8 }, { 12, 14, -10 },
257		{ 13, 15, -10 }, { 13, 15, -12 }, { 15, 16, -12 },
258		{ 16, 17, -12 }
259		}
260	},
261	/* 15BPP/14BPC */
262	{ 273, 15, 2048, 15, 24, 23, 23, {
263		{ 0, 4, 10 }, { 3, 8, 8 }, { 6, 11, 6 }, { 9, 14, 4 },
264		{ 13, 15, 2 }, { 13, 15, 0 }, { 13, 16, -2 }, { 14, 16, -4 },
265		{ 15, 17, -6 }, { 15, 17, -8 }, { 16, 18, -10 },
266		{ 17, 19, -10 }, { 17, 19, -12 }, { 19, 20, -12 },
267		{ 20, 21, -12 }
268		}
269	},
270	/* 15BPP/16BPC */
271	{ 273, 15, 2048, 19, 28, 27, 27, {
272		{ 0, 4, 10 }, { 4, 9, 8 }, { 8, 13, 6 }, { 12, 17, 4 },
273		{ 17, 19, 2 }, { 17, 20, 0 }, { 17, 20, -2 }, { 18, 20, -4 },
274		{ 19, 21, -6 }, { 19, 21, -8 }, { 20, 22, -10 },
275		{ 21, 23, -10 }, { 21, 23, -12 }, { 23, 24, -12 },
276		{ 24, 25, -12 }
277		}
278	}
279}
280
281};
282
283static int get_row_index_for_rc_params(u16 compressed_bpp)
284{
285	switch (compressed_bpp) {
286	case 6:
287		return ROW_INDEX_6BPP;
288	case 8:
289		return ROW_INDEX_8BPP;
290	case 10:
291		return ROW_INDEX_10BPP;
292	case 12:
293		return ROW_INDEX_12BPP;
294	case 15:
295		return ROW_INDEX_15BPP;
296	default:
297		return -EINVAL;
298	}
299}
300
301static int get_column_index_for_rc_params(u8 bits_per_component)
302{
303	switch (bits_per_component) {
304	case 8:
305		return COLUMN_INDEX_8BPC;
306	case 10:
307		return COLUMN_INDEX_10BPC;
308	case 12:
309		return COLUMN_INDEX_12BPC;
310	case 14:
311		return COLUMN_INDEX_14BPC;
312	case 16:
313		return COLUMN_INDEX_16BPC;
314	default:
315		return -EINVAL;
316	}
317}
318
319static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
320						 u8 bits_per_component)
321{
322	int row_index, column_index;
323
324	row_index = get_row_index_for_rc_params(compressed_bpp);
325	if (row_index < 0)
326		return NULL;
327
328	column_index = get_column_index_for_rc_params(bits_per_component);
329	if (column_index < 0)
330		return NULL;
331
332	return &rc_parameters[row_index][column_index];
333}
334
335bool intel_dsc_source_support(struct intel_encoder *encoder,
336			      const struct intel_crtc_state *crtc_state)
337{
338	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
339	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
340	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
341	enum pipe pipe = crtc->pipe;
342
343	if (!INTEL_INFO(i915)->display.has_dsc)
344		return false;
345
346	/* On TGL, DSC is supported on all Pipes */
347	if (INTEL_GEN(i915) >= 12)
348		return true;
349
350	if (INTEL_GEN(i915) >= 10 &&
351	    (pipe != PIPE_A ||
352	     (cpu_transcoder == TRANSCODER_EDP ||
353	      cpu_transcoder == TRANSCODER_DSI_0 ||
354	      cpu_transcoder == TRANSCODER_DSI_1)))
355		return true;
356
357	return false;
358}
359
360static bool is_pipe_dsc(const struct intel_crtc_state *crtc_state)
361{
362	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
363	const struct drm_i915_private *i915 = to_i915(crtc->base.dev);
364	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
365
366	if (INTEL_GEN(i915) >= 12)
367		return true;
368
369	if (cpu_transcoder == TRANSCODER_EDP ||
370	    cpu_transcoder == TRANSCODER_DSI_0 ||
371	    cpu_transcoder == TRANSCODER_DSI_1)
372		return false;
373
374	/* There's no pipe A DSC engine on ICL */
375	drm_WARN_ON(&i915->drm, crtc->pipe == PIPE_A);
376
377	return true;
378}
379
380int intel_dsc_compute_params(struct intel_encoder *encoder,
381			     struct intel_crtc_state *pipe_config)
382{
383	struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config;
384	u16 compressed_bpp = pipe_config->dsc.compressed_bpp;
385	const struct rc_parameters *rc_params;
386	u8 i = 0;
387
388	vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
389	vdsc_cfg->pic_height = pipe_config->hw.adjusted_mode.crtc_vdisplay;
390	vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
391					     pipe_config->dsc.slice_count);
392
393	/* Gen 11 does not support YCbCr */
394	vdsc_cfg->simple_422 = false;
395	/* Gen 11 does not support VBR */
396	vdsc_cfg->vbr_enable = false;
397
398	/* Gen 11 only supports integral values of bpp */
399	vdsc_cfg->bits_per_pixel = compressed_bpp << 4;
400	vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3;
401
402	for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
403		/*
404		 * six 0s are appended to the lsb of each threshold value
405		 * internally in h/w.
406		 * Only 8 bits are allowed for programming RcBufThreshold
407		 */
408		vdsc_cfg->rc_buf_thresh[i] = rc_buf_thresh[i] >> 6;
409	}
410
411	/*
412	 * For 6bpp, RC Buffer threshold 12 and 13 need a different value
413	 * as per C Model
414	 */
415	if (compressed_bpp == 6) {
416		vdsc_cfg->rc_buf_thresh[12] = 0x7C;
417		vdsc_cfg->rc_buf_thresh[13] = 0x7D;
418	}
419
420	rc_params = get_rc_params(compressed_bpp, vdsc_cfg->bits_per_component);
421	if (!rc_params)
422		return -EINVAL;
423
424	vdsc_cfg->first_line_bpg_offset = rc_params->first_line_bpg_offset;
425	vdsc_cfg->initial_xmit_delay = rc_params->initial_xmit_delay;
426	vdsc_cfg->initial_offset = rc_params->initial_offset;
427	vdsc_cfg->flatness_min_qp = rc_params->flatness_min_qp;
428	vdsc_cfg->flatness_max_qp = rc_params->flatness_max_qp;
429	vdsc_cfg->rc_quant_incr_limit0 = rc_params->rc_quant_incr_limit0;
430	vdsc_cfg->rc_quant_incr_limit1 = rc_params->rc_quant_incr_limit1;
431
432	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
433		vdsc_cfg->rc_range_params[i].range_min_qp =
434			rc_params->rc_range_params[i].range_min_qp;
435		vdsc_cfg->rc_range_params[i].range_max_qp =
436			rc_params->rc_range_params[i].range_max_qp;
437		/*
438		 * Range BPG Offset uses 2's complement and is only a 6 bits. So
439		 * mask it to get only 6 bits.
440		 */
441		vdsc_cfg->rc_range_params[i].range_bpg_offset =
442			rc_params->rc_range_params[i].range_bpg_offset &
443			DSC_RANGE_BPG_OFFSET_MASK;
444	}
445
446	/*
447	 * BitsPerComponent value determines mux_word_size:
448	 * When BitsPerComponent is 12bpc, muxWordSize will be equal to 64 bits
449	 * When BitsPerComponent is 8 or 10bpc, muxWordSize will be equal to
450	 * 48 bits
451	 */
452	if (vdsc_cfg->bits_per_component == 8 ||
453	    vdsc_cfg->bits_per_component == 10)
454		vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
455	else if (vdsc_cfg->bits_per_component == 12)
456		vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
457
458	/* RC_MODEL_SIZE is a constant across all configurations */
459	vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
460	/* InitialScaleValue is a 6 bit value with 3 fractional bits (U3.3) */
461	vdsc_cfg->initial_scale_value = (vdsc_cfg->rc_model_size << 3) /
462		(vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset);
463
464	return 0;
465}
466
467enum intel_display_power_domain
468intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
469{
470	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
471	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
472	enum pipe pipe = crtc->pipe;
473
474	/*
475	 * VDSC/joining uses a separate power well, PW2, and requires
476	 * POWER_DOMAIN_TRANSCODER_VDSC_PW2 power domain in two cases:
477	 *
478	 *  - ICL eDP/DSI transcoder
479	 *  - Gen12+ (except RKL) pipe A
480	 *
481	 * For any other pipe, VDSC/joining uses the power well associated with
482	 * the pipe in use. Hence another reference on the pipe power domain
483	 * will suffice. (Except no VDSC/joining on ICL pipe A.)
484	 */
485	if (INTEL_GEN(i915) >= 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A)
486		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
487	else if (is_pipe_dsc(crtc_state))
488		return POWER_DOMAIN_PIPE(pipe);
489	else
490		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
491}
492
493static void intel_dsc_pps_configure(struct intel_encoder *encoder,
494				    const struct intel_crtc_state *crtc_state)
495{
496	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
497	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
498	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
499	enum pipe pipe = crtc->pipe;
500	u32 pps_val = 0;
501	u32 rc_buf_thresh_dword[4];
502	u32 rc_range_params_dword[8];
503	u8 num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;
504	int i = 0;
505
506	/* Populate PICTURE_PARAMETER_SET_0 registers */
507	pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
508		DSC_VER_MIN_SHIFT |
509		vdsc_cfg->bits_per_component << DSC_BPC_SHIFT |
510		vdsc_cfg->line_buf_depth << DSC_LINE_BUF_DEPTH_SHIFT;
511	if (vdsc_cfg->block_pred_enable)
512		pps_val |= DSC_BLOCK_PREDICTION;
513	if (vdsc_cfg->convert_rgb)
514		pps_val |= DSC_COLOR_SPACE_CONVERSION;
515	if (vdsc_cfg->simple_422)
516		pps_val |= DSC_422_ENABLE;
517	if (vdsc_cfg->vbr_enable)
518		pps_val |= DSC_VBR_ENABLE;
519	drm_info(&dev_priv->drm, "PPS0 = 0x%08x\n", pps_val);
520	if (!is_pipe_dsc(crtc_state)) {
521		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_0,
522			       pps_val);
523		/*
524		 * If 2 VDSC instances are needed, configure PPS for second
525		 * VDSC
526		 */
527		if (crtc_state->dsc.dsc_split)
528			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_0,
529				       pps_val);
530	} else {
531		intel_de_write(dev_priv,
532			       ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe),
533			       pps_val);
534		if (crtc_state->dsc.dsc_split)
535			intel_de_write(dev_priv,
536				       ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe),
537				       pps_val);
538	}
539
540	/* Populate PICTURE_PARAMETER_SET_1 registers */
541	pps_val = 0;
542	pps_val |= DSC_BPP(vdsc_cfg->bits_per_pixel);
543	drm_info(&dev_priv->drm, "PPS1 = 0x%08x\n", pps_val);
544	if (!is_pipe_dsc(crtc_state)) {
545		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_1,
546			       pps_val);
547		/*
548		 * If 2 VDSC instances are needed, configure PPS for second
549		 * VDSC
550		 */
551		if (crtc_state->dsc.dsc_split)
552			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_1,
553				       pps_val);
554	} else {
555		intel_de_write(dev_priv,
556			       ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe),
557			       pps_val);
558		if (crtc_state->dsc.dsc_split)
559			intel_de_write(dev_priv,
560				       ICL_DSC1_PICTURE_PARAMETER_SET_1(pipe),
561				       pps_val);
562	}
563
564	/* Populate PICTURE_PARAMETER_SET_2 registers */
565	pps_val = 0;
566	pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) |
567		DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
568	drm_info(&dev_priv->drm, "PPS2 = 0x%08x\n", pps_val);
569	if (!is_pipe_dsc(crtc_state)) {
570		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_2,
571			       pps_val);
572		/*
573		 * If 2 VDSC instances are needed, configure PPS for second
574		 * VDSC
575		 */
576		if (crtc_state->dsc.dsc_split)
577			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_2,
578				       pps_val);
579	} else {
580		intel_de_write(dev_priv,
581			       ICL_DSC0_PICTURE_PARAMETER_SET_2(pipe),
582			       pps_val);
583		if (crtc_state->dsc.dsc_split)
584			intel_de_write(dev_priv,
585				       ICL_DSC1_PICTURE_PARAMETER_SET_2(pipe),
586				       pps_val);
587	}
588
589	/* Populate PICTURE_PARAMETER_SET_3 registers */
590	pps_val = 0;
591	pps_val |= DSC_SLICE_HEIGHT(vdsc_cfg->slice_height) |
592		DSC_SLICE_WIDTH(vdsc_cfg->slice_width);
593	drm_info(&dev_priv->drm, "PPS3 = 0x%08x\n", pps_val);
594	if (!is_pipe_dsc(crtc_state)) {
595		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_3,
596			       pps_val);
597		/*
598		 * If 2 VDSC instances are needed, configure PPS for second
599		 * VDSC
600		 */
601		if (crtc_state->dsc.dsc_split)
602			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_3,
603				       pps_val);
604	} else {
605		intel_de_write(dev_priv,
606			       ICL_DSC0_PICTURE_PARAMETER_SET_3(pipe),
607			       pps_val);
608		if (crtc_state->dsc.dsc_split)
609			intel_de_write(dev_priv,
610				       ICL_DSC1_PICTURE_PARAMETER_SET_3(pipe),
611				       pps_val);
612	}
613
614	/* Populate PICTURE_PARAMETER_SET_4 registers */
615	pps_val = 0;
616	pps_val |= DSC_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) |
617		DSC_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay);
618	drm_info(&dev_priv->drm, "PPS4 = 0x%08x\n", pps_val);
619	if (!is_pipe_dsc(crtc_state)) {
620		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_4,
621			       pps_val);
622		/*
623		 * If 2 VDSC instances are needed, configure PPS for second
624		 * VDSC
625		 */
626		if (crtc_state->dsc.dsc_split)
627			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_4,
628				       pps_val);
629	} else {
630		intel_de_write(dev_priv,
631			       ICL_DSC0_PICTURE_PARAMETER_SET_4(pipe),
632			       pps_val);
633		if (crtc_state->dsc.dsc_split)
634			intel_de_write(dev_priv,
635				       ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe),
636				       pps_val);
637	}
638
639	/* Populate PICTURE_PARAMETER_SET_5 registers */
640	pps_val = 0;
641	pps_val |= DSC_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) |
642		DSC_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval);
643	drm_info(&dev_priv->drm, "PPS5 = 0x%08x\n", pps_val);
644	if (!is_pipe_dsc(crtc_state)) {
645		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_5,
646			       pps_val);
647		/*
648		 * If 2 VDSC instances are needed, configure PPS for second
649		 * VDSC
650		 */
651		if (crtc_state->dsc.dsc_split)
652			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_5,
653				       pps_val);
654	} else {
655		intel_de_write(dev_priv,
656			       ICL_DSC0_PICTURE_PARAMETER_SET_5(pipe),
657			       pps_val);
658		if (crtc_state->dsc.dsc_split)
659			intel_de_write(dev_priv,
660				       ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe),
661				       pps_val);
662	}
663
664	/* Populate PICTURE_PARAMETER_SET_6 registers */
665	pps_val = 0;
666	pps_val |= DSC_INITIAL_SCALE_VALUE(vdsc_cfg->initial_scale_value) |
667		DSC_FIRST_LINE_BPG_OFFSET(vdsc_cfg->first_line_bpg_offset) |
668		DSC_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) |
669		DSC_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp);
670	drm_info(&dev_priv->drm, "PPS6 = 0x%08x\n", pps_val);
671	if (!is_pipe_dsc(crtc_state)) {
672		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_6,
673			       pps_val);
674		/*
675		 * If 2 VDSC instances are needed, configure PPS for second
676		 * VDSC
677		 */
678		if (crtc_state->dsc.dsc_split)
679			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_6,
680				       pps_val);
681	} else {
682		intel_de_write(dev_priv,
683			       ICL_DSC0_PICTURE_PARAMETER_SET_6(pipe),
684			       pps_val);
685		if (crtc_state->dsc.dsc_split)
686			intel_de_write(dev_priv,
687				       ICL_DSC1_PICTURE_PARAMETER_SET_6(pipe),
688				       pps_val);
689	}
690
691	/* Populate PICTURE_PARAMETER_SET_7 registers */
692	pps_val = 0;
693	pps_val |= DSC_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) |
694		DSC_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset);
695	drm_info(&dev_priv->drm, "PPS7 = 0x%08x\n", pps_val);
696	if (!is_pipe_dsc(crtc_state)) {
697		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_7,
698			       pps_val);
699		/*
700		 * If 2 VDSC instances are needed, configure PPS for second
701		 * VDSC
702		 */
703		if (crtc_state->dsc.dsc_split)
704			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_7,
705				       pps_val);
706	} else {
707		intel_de_write(dev_priv,
708			       ICL_DSC0_PICTURE_PARAMETER_SET_7(pipe),
709			       pps_val);
710		if (crtc_state->dsc.dsc_split)
711			intel_de_write(dev_priv,
712				       ICL_DSC1_PICTURE_PARAMETER_SET_7(pipe),
713				       pps_val);
714	}
715
716	/* Populate PICTURE_PARAMETER_SET_8 registers */
717	pps_val = 0;
718	pps_val |= DSC_FINAL_OFFSET(vdsc_cfg->final_offset) |
719		DSC_INITIAL_OFFSET(vdsc_cfg->initial_offset);
720	drm_info(&dev_priv->drm, "PPS8 = 0x%08x\n", pps_val);
721	if (!is_pipe_dsc(crtc_state)) {
722		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_8,
723			       pps_val);
724		/*
725		 * If 2 VDSC instances are needed, configure PPS for second
726		 * VDSC
727		 */
728		if (crtc_state->dsc.dsc_split)
729			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_8,
730				       pps_val);
731	} else {
732		intel_de_write(dev_priv,
733			       ICL_DSC0_PICTURE_PARAMETER_SET_8(pipe),
734			       pps_val);
735		if (crtc_state->dsc.dsc_split)
736			intel_de_write(dev_priv,
737				       ICL_DSC1_PICTURE_PARAMETER_SET_8(pipe),
738				       pps_val);
739	}
740
741	/* Populate PICTURE_PARAMETER_SET_9 registers */
742	pps_val = 0;
743	pps_val |= DSC_RC_MODEL_SIZE(DSC_RC_MODEL_SIZE_CONST) |
744		DSC_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST);
745	drm_info(&dev_priv->drm, "PPS9 = 0x%08x\n", pps_val);
746	if (!is_pipe_dsc(crtc_state)) {
747		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_9,
748			       pps_val);
749		/*
750		 * If 2 VDSC instances are needed, configure PPS for second
751		 * VDSC
752		 */
753		if (crtc_state->dsc.dsc_split)
754			intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_9,
755				       pps_val);
756	} else {
757		intel_de_write(dev_priv,
758			       ICL_DSC0_PICTURE_PARAMETER_SET_9(pipe),
759			       pps_val);
760		if (crtc_state->dsc.dsc_split)
761			intel_de_write(dev_priv,
762				       ICL_DSC1_PICTURE_PARAMETER_SET_9(pipe),
763				       pps_val);
764	}
765
766	/* Populate PICTURE_PARAMETER_SET_10 registers */
767	pps_val = 0;
768	pps_val |= DSC_RC_QUANT_INC_LIMIT0(vdsc_cfg->rc_quant_incr_limit0) |
769		DSC_RC_QUANT_INC_LIMIT1(vdsc_cfg->rc_quant_incr_limit1) |
770		DSC_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) |
771		DSC_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST);
772	drm_info(&dev_priv->drm, "PPS10 = 0x%08x\n", pps_val);
773	if (!is_pipe_dsc(crtc_state)) {
774		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_10,
775			       pps_val);
776		/*
777		 * If 2 VDSC instances are needed, configure PPS for second
778		 * VDSC
779		 */
780		if (crtc_state->dsc.dsc_split)
781			intel_de_write(dev_priv,
782				       DSCC_PICTURE_PARAMETER_SET_10, pps_val);
783	} else {
784		intel_de_write(dev_priv,
785			       ICL_DSC0_PICTURE_PARAMETER_SET_10(pipe),
786			       pps_val);
787		if (crtc_state->dsc.dsc_split)
788			intel_de_write(dev_priv,
789				       ICL_DSC1_PICTURE_PARAMETER_SET_10(pipe),
790				       pps_val);
791	}
792
793	/* Populate Picture parameter set 16 */
794	pps_val = 0;
795	pps_val |= DSC_SLICE_CHUNK_SIZE(vdsc_cfg->slice_chunk_size) |
796		DSC_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) /
797				   vdsc_cfg->slice_width) |
798		DSC_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height /
799					vdsc_cfg->slice_height);
800	drm_info(&dev_priv->drm, "PPS16 = 0x%08x\n", pps_val);
801	if (!is_pipe_dsc(crtc_state)) {
802		intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_16,
803			       pps_val);
804		/*
805		 * If 2 VDSC instances are needed, configure PPS for second
806		 * VDSC
807		 */
808		if (crtc_state->dsc.dsc_split)
809			intel_de_write(dev_priv,
810				       DSCC_PICTURE_PARAMETER_SET_16, pps_val);
811	} else {
812		intel_de_write(dev_priv,
813			       ICL_DSC0_PICTURE_PARAMETER_SET_16(pipe),
814			       pps_val);
815		if (crtc_state->dsc.dsc_split)
816			intel_de_write(dev_priv,
817				       ICL_DSC1_PICTURE_PARAMETER_SET_16(pipe),
818				       pps_val);
819	}
820
821	/* Populate the RC_BUF_THRESH registers */
822	memset(rc_buf_thresh_dword, 0, sizeof(rc_buf_thresh_dword));
823	for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
824		rc_buf_thresh_dword[i / 4] |=
825			(u32)(vdsc_cfg->rc_buf_thresh[i] <<
826			      BITS_PER_BYTE * (i % 4));
827		drm_info(&dev_priv->drm, " RC_BUF_THRESH%d = 0x%08x\n", i,
828			 rc_buf_thresh_dword[i / 4]);
829	}
830	if (!is_pipe_dsc(crtc_state)) {
831		intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0,
832			       rc_buf_thresh_dword[0]);
833		intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0_UDW,
834			       rc_buf_thresh_dword[1]);
835		intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1,
836			       rc_buf_thresh_dword[2]);
837		intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1_UDW,
838			       rc_buf_thresh_dword[3]);
839		if (crtc_state->dsc.dsc_split) {
840			intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0,
841				       rc_buf_thresh_dword[0]);
842			intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0_UDW,
843				       rc_buf_thresh_dword[1]);
844			intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1,
845				       rc_buf_thresh_dword[2]);
846			intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1_UDW,
847				       rc_buf_thresh_dword[3]);
848		}
849	} else {
850		intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0(pipe),
851			       rc_buf_thresh_dword[0]);
852		intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe),
853			       rc_buf_thresh_dword[1]);
854		intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1(pipe),
855			       rc_buf_thresh_dword[2]);
856		intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),
857			       rc_buf_thresh_dword[3]);
858		if (crtc_state->dsc.dsc_split) {
859			intel_de_write(dev_priv,
860				       ICL_DSC1_RC_BUF_THRESH_0(pipe),
861				       rc_buf_thresh_dword[0]);
862			intel_de_write(dev_priv,
863				       ICL_DSC1_RC_BUF_THRESH_0_UDW(pipe),
864				       rc_buf_thresh_dword[1]);
865			intel_de_write(dev_priv,
866				       ICL_DSC1_RC_BUF_THRESH_1(pipe),
867				       rc_buf_thresh_dword[2]);
868			intel_de_write(dev_priv,
869				       ICL_DSC1_RC_BUF_THRESH_1_UDW(pipe),
870				       rc_buf_thresh_dword[3]);
871		}
872	}
873
874	/* Populate the RC_RANGE_PARAMETERS registers */
875	memset(rc_range_params_dword, 0, sizeof(rc_range_params_dword));
876	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
877		rc_range_params_dword[i / 2] |=
878			(u32)(((vdsc_cfg->rc_range_params[i].range_bpg_offset <<
879				RC_BPG_OFFSET_SHIFT) |
880			       (vdsc_cfg->rc_range_params[i].range_max_qp <<
881				RC_MAX_QP_SHIFT) |
882			       (vdsc_cfg->rc_range_params[i].range_min_qp <<
883				RC_MIN_QP_SHIFT)) << 16 * (i % 2));
884		drm_info(&dev_priv->drm, " RC_RANGE_PARAM_%d = 0x%08x\n", i,
885			 rc_range_params_dword[i / 2]);
886	}
887	if (!is_pipe_dsc(crtc_state)) {
888		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0,
889			       rc_range_params_dword[0]);
890		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0_UDW,
891			       rc_range_params_dword[1]);
892		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1,
893			       rc_range_params_dword[2]);
894		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1_UDW,
895			       rc_range_params_dword[3]);
896		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2,
897			       rc_range_params_dword[4]);
898		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2_UDW,
899			       rc_range_params_dword[5]);
900		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3,
901			       rc_range_params_dword[6]);
902		intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3_UDW,
903			       rc_range_params_dword[7]);
904		if (crtc_state->dsc.dsc_split) {
905			intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_0,
906				       rc_range_params_dword[0]);
907			intel_de_write(dev_priv,
908				       DSCC_RC_RANGE_PARAMETERS_0_UDW,
909				       rc_range_params_dword[1]);
910			intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_1,
911				       rc_range_params_dword[2]);
912			intel_de_write(dev_priv,
913				       DSCC_RC_RANGE_PARAMETERS_1_UDW,
914				       rc_range_params_dword[3]);
915			intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_2,
916				       rc_range_params_dword[4]);
917			intel_de_write(dev_priv,
918				       DSCC_RC_RANGE_PARAMETERS_2_UDW,
919				       rc_range_params_dword[5]);
920			intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_3,
921				       rc_range_params_dword[6]);
922			intel_de_write(dev_priv,
923				       DSCC_RC_RANGE_PARAMETERS_3_UDW,
924				       rc_range_params_dword[7]);
925		}
926	} else {
927		intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe),
928			       rc_range_params_dword[0]);
929		intel_de_write(dev_priv,
930			       ICL_DSC0_RC_RANGE_PARAMETERS_0_UDW(pipe),
931			       rc_range_params_dword[1]);
932		intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe),
933			       rc_range_params_dword[2]);
934		intel_de_write(dev_priv,
935			       ICL_DSC0_RC_RANGE_PARAMETERS_1_UDW(pipe),
936			       rc_range_params_dword[3]);
937		intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe),
938			       rc_range_params_dword[4]);
939		intel_de_write(dev_priv,
940			       ICL_DSC0_RC_RANGE_PARAMETERS_2_UDW(pipe),
941			       rc_range_params_dword[5]);
942		intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe),
943			       rc_range_params_dword[6]);
944		intel_de_write(dev_priv,
945			       ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe),
946			       rc_range_params_dword[7]);
947		if (crtc_state->dsc.dsc_split) {
948			intel_de_write(dev_priv,
949				       ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe),
950				       rc_range_params_dword[0]);
951			intel_de_write(dev_priv,
952				       ICL_DSC1_RC_RANGE_PARAMETERS_0_UDW(pipe),
953				       rc_range_params_dword[1]);
954			intel_de_write(dev_priv,
955				       ICL_DSC1_RC_RANGE_PARAMETERS_1(pipe),
956				       rc_range_params_dword[2]);
957			intel_de_write(dev_priv,
958				       ICL_DSC1_RC_RANGE_PARAMETERS_1_UDW(pipe),
959				       rc_range_params_dword[3]);
960			intel_de_write(dev_priv,
961				       ICL_DSC1_RC_RANGE_PARAMETERS_2(pipe),
962				       rc_range_params_dword[4]);
963			intel_de_write(dev_priv,
964				       ICL_DSC1_RC_RANGE_PARAMETERS_2_UDW(pipe),
965				       rc_range_params_dword[5]);
966			intel_de_write(dev_priv,
967				       ICL_DSC1_RC_RANGE_PARAMETERS_3(pipe),
968				       rc_range_params_dword[6]);
969			intel_de_write(dev_priv,
970				       ICL_DSC1_RC_RANGE_PARAMETERS_3_UDW(pipe),
971				       rc_range_params_dword[7]);
972		}
973	}
974}
975
976void intel_dsc_get_config(struct intel_encoder *encoder,
977			  struct intel_crtc_state *crtc_state)
978{
979	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
980	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
981	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
982	enum pipe pipe = crtc->pipe;
983	enum intel_display_power_domain power_domain;
984	intel_wakeref_t wakeref;
985	u32 dss_ctl1, dss_ctl2, val;
986
987	if (!intel_dsc_source_support(encoder, crtc_state))
988		return;
989
990	power_domain = intel_dsc_power_domain(crtc_state);
991
992	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
993	if (!wakeref)
994		return;
995
996	if (!is_pipe_dsc(crtc_state)) {
997		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
998		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
999	} else {
1000		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
1001		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
1002	}
1003
1004	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
1005	if (!crtc_state->dsc.compression_enable)
1006		goto out;
1007
1008	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
1009		(dss_ctl1 & JOINER_ENABLE);
1010
1011	/* FIXME: add more state readout as needed */
1012
1013	/* PPS1 */
1014	if (!is_pipe_dsc(crtc_state))
1015		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
1016	else
1017		val = intel_de_read(dev_priv,
1018				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
1019	vdsc_cfg->bits_per_pixel = val;
1020	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
1021out:
1022	intel_display_power_put(dev_priv, power_domain, wakeref);
1023}
1024
1025static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
1026				    const struct intel_crtc_state *crtc_state)
1027{
1028	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
1029	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
1030	struct mipi_dsi_device *dsi;
1031	struct drm_dsc_picture_parameter_set pps;
1032	enum port port;
1033
1034	drm_dsc_pps_payload_pack(&pps, vdsc_cfg);
1035
1036	for_each_dsi_port(port, intel_dsi->ports) {
1037		dsi = intel_dsi->dsi_hosts[port]->device;
1038
1039		mipi_dsi_picture_parameter_set(dsi, &pps);
1040		mipi_dsi_compression_mode(dsi, true);
1041	}
1042}
1043
1044static void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
1045				   const struct intel_crtc_state *crtc_state)
1046{
1047	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1048	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1049	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
1050	struct drm_dsc_pps_infoframe dp_dsc_pps_sdp;
1051
1052	/* Prepare DP SDP PPS header as per DP 1.4 spec, Table 2-123 */
1053	drm_dsc_dp_pps_header_init(&dp_dsc_pps_sdp.pps_header);
1054
1055	/* Fill the PPS payload bytes as per DSC spec 1.2 Table 4-1 */
1056	drm_dsc_pps_payload_pack(&dp_dsc_pps_sdp.pps_payload, vdsc_cfg);
1057
1058	dig_port->write_infoframe(encoder, crtc_state,
1059				  DP_SDP_PPS, &dp_dsc_pps_sdp,
1060				  sizeof(dp_dsc_pps_sdp));
1061}
1062
1063void intel_dsc_enable(struct intel_encoder *encoder,
1064		      const struct intel_crtc_state *crtc_state)
1065{
1066	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1067	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1068	enum pipe pipe = crtc->pipe;
1069	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
1070	u32 dss_ctl1_val = 0;
1071	u32 dss_ctl2_val = 0;
1072
1073	if (!crtc_state->dsc.compression_enable)
1074		return;
1075
1076	/* Enable Power wells for VDSC/joining */
1077	intel_display_power_get(dev_priv,
1078				intel_dsc_power_domain(crtc_state));
1079
1080	intel_dsc_pps_configure(encoder, crtc_state);
1081
1082	if (encoder->type == INTEL_OUTPUT_DSI)
1083		intel_dsc_dsi_pps_write(encoder, crtc_state);
1084	else
1085		intel_dsc_dp_pps_write(encoder, crtc_state);
1086
1087	if (!is_pipe_dsc(crtc_state)) {
1088		dss_ctl1_reg = DSS_CTL1;
1089		dss_ctl2_reg = DSS_CTL2;
1090	} else {
1091		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
1092		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
1093	}
1094	dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
1095	if (crtc_state->dsc.dsc_split) {
1096		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
1097		dss_ctl1_val |= JOINER_ENABLE;
1098	}
1099	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
1100	intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
1101}
1102
1103void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
1104{
1105	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
1106	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1107	enum pipe pipe = crtc->pipe;
1108	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
1109	u32 dss_ctl1_val = 0, dss_ctl2_val = 0;
1110
1111	if (!old_crtc_state->dsc.compression_enable)
1112		return;
1113
1114	if (!is_pipe_dsc(old_crtc_state)) {
1115		dss_ctl1_reg = DSS_CTL1;
1116		dss_ctl2_reg = DSS_CTL2;
1117	} else {
1118		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
1119		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
1120	}
1121	dss_ctl1_val = intel_de_read(dev_priv, dss_ctl1_reg);
1122	if (dss_ctl1_val & JOINER_ENABLE)
1123		dss_ctl1_val &= ~JOINER_ENABLE;
1124	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
1125
1126	dss_ctl2_val = intel_de_read(dev_priv, dss_ctl2_reg);
1127	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE ||
1128	    dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE)
1129		dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE |
1130				  RIGHT_BRANCH_VDSC_ENABLE);
1131	intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
1132
1133	/* Disable Power wells for VDSC/joining */
1134	intel_display_power_put_unchecked(dev_priv,
1135					  intel_dsc_power_domain(old_crtc_state));
1136}
1137