xref: /linux/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c (revision 3722df98c2e724121c40ea7ad59988262dbdb98f)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4 
5 #include "dml21_wrapper.h"
6 #include "dml2_core_dcn4_calcs.h"
7 #include "dml2_internal_shared_types.h"
8 #include "dml2_internal_types.h"
9 #include "dml21_utils.h"
10 #include "dml21_translation_helper.h"
11 #include "soc_and_ip_translator.h"
12 
13 static void dml21_populate_pmo_options(struct dml2_pmo_options *pmo_options,
14 		const struct dc *in_dc,
15 		const struct dml2_configuration_options *config)
16 {
17 	bool disable_fams2 = !in_dc->debug.fams2_config.bits.enable;
18 
19 	/* ODM options */
20 	pmo_options->disable_dyn_odm = !config->minimize_dispclk_using_odm;
21 	pmo_options->disable_dyn_odm_for_multi_stream = true;
22 	pmo_options->disable_dyn_odm_for_stream_with_svp = true;
23 
24 	pmo_options->disable_vblank = ((in_dc->debug.dml21_disable_pstate_method_mask >> 1) & 1);
25 
26 	/* NOTE: DRR and SubVP Require FAMS2 */
27 	pmo_options->disable_svp = ((in_dc->debug.dml21_disable_pstate_method_mask >> 2) & 1) ||
28 			in_dc->debug.force_disable_subvp ||
29 			disable_fams2;
30 	pmo_options->disable_drr_clamped = ((in_dc->debug.dml21_disable_pstate_method_mask >> 3) & 1) ||
31 			disable_fams2;
32 	pmo_options->disable_drr_var = ((in_dc->debug.dml21_disable_pstate_method_mask >> 4) & 1) ||
33 			disable_fams2;
34 	pmo_options->disable_fams2 = disable_fams2;
35 
36 	pmo_options->disable_drr_var_when_var_active = in_dc->debug.disable_fams_gaming == INGAME_FAMS_DISABLE ||
37 			in_dc->debug.disable_fams_gaming == INGAME_FAMS_MULTI_DISP_CLAMPED_ONLY;
38 	pmo_options->disable_drr_clamped_when_var_active = in_dc->debug.disable_fams_gaming == INGAME_FAMS_DISABLE;
39 }
40 
41 static enum dml2_project_id dml21_dcn_revision_to_dml2_project_id(enum dce_version dcn_version)
42 {
43 	enum dml2_project_id project_id;
44 	switch (dcn_version) {
45 	case DCN_VERSION_4_01:
46 		project_id = dml2_project_dcn4x_stage2_auto_drr_svp;
47 		break;
48 	case DCN_VERSION_4_2:
49 		project_id = dml2_project_dcn42;
50 		break;
51 	default:
52 		project_id = dml2_project_invalid;
53 		DC_ERR("unsupported dcn version for DML21!");
54 		break;
55 	}
56 
57 	return project_id;
58 }
59 
60 void dml21_populate_dml_init_params(struct dml2_initialize_instance_in_out *dml_init,
61 		const struct dml2_configuration_options *config,
62 		const struct dc *in_dc)
63 {
64 	dml_init->options.project_id = dml21_dcn_revision_to_dml2_project_id(in_dc->ctx->dce_version);
65 
66 	if (config->use_native_soc_bb_construction) {
67 		in_dc->soc_and_ip_translator->translator_funcs->get_soc_bb(&dml_init->soc_bb, in_dc, config);
68 		in_dc->soc_and_ip_translator->translator_funcs->get_ip_caps(&dml_init->ip_caps);
69 	} else {
70 		dml_init->soc_bb = config->external_socbb_ip_params->soc_bb;
71 		dml_init->ip_caps = config->external_socbb_ip_params->ip_params;
72 	}
73 
74 	dml21_populate_pmo_options(&dml_init->options.pmo_options, in_dc, config);
75 }
76 
77 static unsigned int calc_max_hardware_v_total(const struct dc_stream_state *stream)
78 {
79 	unsigned int max_hw_v_total = stream->ctx->dc->caps.max_v_total;
80 
81 	if (stream->ctx->dc->caps.vtotal_limited_by_fp2) {
82 		max_hw_v_total -= stream->timing.v_front_porch + 1;
83 	}
84 
85 	return max_hw_v_total;
86 }
87 
88 static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cfg *timing,
89 		struct dc_stream_state *stream,
90 		struct pipe_ctx *pipe_ctx,
91 		struct dml2_context *dml_ctx)
92 {
93 	unsigned int hblank_start, vblank_start;
94 	uint64_t min_hardware_refresh_in_uhz;
95 	uint32_t pix_clk_100hz;
96 
97 	timing->h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right + pipe_ctx->dsc_padding_params.dsc_hactive_padding;
98 	timing->v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
99 	timing->h_front_porch = stream->timing.h_front_porch;
100 	timing->v_front_porch = stream->timing.v_front_porch;
101 	timing->pixel_clock_khz = stream->timing.pix_clk_100hz / 10;
102 	if (pipe_ctx->dsc_padding_params.dsc_hactive_padding != 0)
103 		timing->pixel_clock_khz = pipe_ctx->dsc_padding_params.dsc_pix_clk_100hz / 10;
104 	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
105 		timing->pixel_clock_khz *= 2;
106 	timing->h_total = stream->timing.h_total + pipe_ctx->dsc_padding_params.dsc_htotal_padding;
107 	timing->v_total = stream->timing.v_total;
108 	timing->h_sync_width = stream->timing.h_sync_width;
109 	timing->interlaced = (stream->timing.flags.INTERLACE != 0);
110 
111 	hblank_start = stream->timing.h_total - stream->timing.h_front_porch;
112 
113 	timing->h_blank_end = hblank_start - stream->timing.h_addressable - pipe_ctx->dsc_padding_params.dsc_hactive_padding
114 		- stream->timing.h_border_left - stream->timing.h_border_right;
115 
116 	if (hblank_start < stream->timing.h_addressable)
117 		timing->h_blank_end = 0;
118 
119 	vblank_start = stream->timing.v_total - stream->timing.v_front_porch;
120 
121 	timing->v_blank_end = vblank_start - stream->timing.v_addressable
122 		- stream->timing.v_border_top - stream->timing.v_border_bottom;
123 
124 	timing->drr_config.enabled = stream->ignore_msa_timing_param;
125 	timing->drr_config.drr_active_variable = stream->vrr_active_variable;
126 	timing->drr_config.drr_active_fixed = stream->vrr_active_fixed;
127 	timing->drr_config.disallowed = !stream->allow_freesync;
128 
129 	/* limit min refresh rate to DC cap */
130 	min_hardware_refresh_in_uhz = stream->timing.min_refresh_in_uhz;
131 	if (stream->ctx->dc->caps.max_v_total != 0) {
132 		if (pipe_ctx->dsc_padding_params.dsc_hactive_padding != 0) {
133 			pix_clk_100hz = pipe_ctx->dsc_padding_params.dsc_pix_clk_100hz;
134 		} else {
135 			pix_clk_100hz = stream->timing.pix_clk_100hz;
136 		}
137 		min_hardware_refresh_in_uhz = div64_u64((pix_clk_100hz * 100000000ULL),
138 				(timing->h_total * (long long)calc_max_hardware_v_total(stream)));
139 	}
140 
141 	{
142 		uint64_t min_refresh = max((uint64_t)stream->timing.min_refresh_in_uhz, min_hardware_refresh_in_uhz);
143 		ASSERT(min_refresh <= ULONG_MAX);
144 		timing->drr_config.min_refresh_uhz = (unsigned long)min_refresh;
145 	}
146 
147 	if (dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase &&
148 			stream->ctx->dc->config.enable_fpo_flicker_detection == 1)
149 		timing->drr_config.max_instant_vtotal_delta = dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase(stream, false);
150 	else
151 		timing->drr_config.max_instant_vtotal_delta = 0;
152 
153 	if (stream->timing.flags.DSC) {
154 		timing->dsc.enable = dml2_dsc_enable;
155 		timing->dsc.overrides.num_slices = stream->timing.dsc_cfg.num_slices_h;
156 		timing->dsc.dsc_compressed_bpp_x16 = stream->timing.dsc_cfg.bits_per_pixel;
157 	} else
158 		timing->dsc.enable = dml2_dsc_disable;
159 
160 	switch (stream->timing.display_color_depth) {
161 	case COLOR_DEPTH_666:
162 		timing->bpc = 6;
163 		break;
164 	case COLOR_DEPTH_888:
165 		timing->bpc = 8;
166 		break;
167 	case COLOR_DEPTH_101010:
168 		timing->bpc = 10;
169 		break;
170 	case COLOR_DEPTH_121212:
171 		timing->bpc = 12;
172 		break;
173 	case COLOR_DEPTH_141414:
174 		timing->bpc = 14;
175 		break;
176 	case COLOR_DEPTH_161616:
177 		timing->bpc = 16;
178 		break;
179 	case COLOR_DEPTH_999:
180 		timing->bpc = 9;
181 		break;
182 	case COLOR_DEPTH_111111:
183 		timing->bpc = 11;
184 		break;
185 	default:
186 		timing->bpc = 8;
187 		break;
188 	}
189 
190 	timing->vblank_nom = timing->v_total - timing->v_active;
191 }
192 
193 static void populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg *output,
194 		struct dc_stream_state *stream, const struct pipe_ctx *pipe)
195 {
196 	output->output_dp_lane_count = 4;
197 
198 	switch (stream->signal) {
199 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
200 	case SIGNAL_TYPE_DISPLAY_PORT:
201 		output->output_encoder = dml2_dp;
202 		if (check_dp2p0_output_encoder(pipe))
203 			output->output_encoder = dml2_dp2p0;
204 		break;
205 	case SIGNAL_TYPE_EDP:
206 		output->output_encoder = dml2_edp;
207 		break;
208 	case SIGNAL_TYPE_HDMI_TYPE_A:
209 	case SIGNAL_TYPE_DVI_SINGLE_LINK:
210 	case SIGNAL_TYPE_DVI_DUAL_LINK:
211 		output->output_encoder = dml2_hdmi;
212 		break;
213 	default:
214 			output->output_encoder = dml2_dp;
215 	}
216 
217 	switch (stream->timing.pixel_encoding) {
218 	case PIXEL_ENCODING_RGB:
219 	case PIXEL_ENCODING_YCBCR444:
220 		output->output_format = dml2_444;
221 		break;
222 	case PIXEL_ENCODING_YCBCR420:
223 		output->output_format = dml2_420;
224 		break;
225 	case PIXEL_ENCODING_YCBCR422:
226 		if (stream->timing.flags.DSC && !stream->timing.dsc_cfg.ycbcr422_simple)
227 			output->output_format = dml2_n422;
228 		else
229 			output->output_format = dml2_s422;
230 		break;
231 	default:
232 		output->output_format = dml2_444;
233 		break;
234 	}
235 
236 	switch (stream->signal) {
237 	case SIGNAL_TYPE_NONE:
238 	case SIGNAL_TYPE_DVI_SINGLE_LINK:
239 	case SIGNAL_TYPE_DVI_DUAL_LINK:
240 	case SIGNAL_TYPE_HDMI_TYPE_A:
241 	case SIGNAL_TYPE_LVDS:
242 	case SIGNAL_TYPE_RGB:
243 	case SIGNAL_TYPE_DISPLAY_PORT:
244 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
245 	case SIGNAL_TYPE_EDP:
246 	case SIGNAL_TYPE_VIRTUAL:
247 	default:
248 		output->output_dp_link_rate = dml2_dp_rate_na;
249 		break;
250 	}
251 
252 	output->audio_sample_layout = stream->audio_info.modes->sample_size;
253 	output->audio_sample_rate = stream->audio_info.modes->max_bit_rate;
254 	output->output_disabled = true;
255 
256 	//TODO : New to DML2.1. How do we populate this ?
257 	// output->validate_output
258 }
259 
260 static void populate_dml21_stream_overrides_from_stream_state(
261 		struct dml2_stream_parameters *stream_desc,
262 		struct dc_stream_state *stream,
263 		struct dc_stream_status *stream_status)
264 {
265 	switch (stream->debug.force_odm_combine_segments) {
266 	case 0:
267 		stream_desc->overrides.odm_mode = dml2_odm_mode_auto;
268 		break;
269 	case 1:
270 		stream_desc->overrides.odm_mode = dml2_odm_mode_bypass;
271 		break;
272 	case 2:
273 		stream_desc->overrides.odm_mode = dml2_odm_mode_combine_2to1;
274 		break;
275 	case 3:
276 		stream_desc->overrides.odm_mode = dml2_odm_mode_combine_3to1;
277 		break;
278 	case 4:
279 		stream_desc->overrides.odm_mode = dml2_odm_mode_combine_4to1;
280 		break;
281 	default:
282 		stream_desc->overrides.odm_mode =  dml2_odm_mode_auto;
283 		break;
284 	}
285 	if (!stream->ctx->dc->debug.enable_single_display_2to1_odm_policy ||
286 			stream->debug.force_odm_combine_segments > 0)
287 		stream_desc->overrides.disable_dynamic_odm = true;
288 	stream_desc->overrides.disable_subvp = stream->ctx->dc->debug.force_disable_subvp ||
289 			stream->hw_cursor_req ||
290 			stream_status->mall_stream_config.cursor_size_limit_subvp;
291 }
292 
293 static enum dml2_swizzle_mode gfx_addr3_to_dml2_swizzle_mode(enum swizzle_mode_addr3_values addr3_mode)
294 {
295 	enum dml2_swizzle_mode dml2_mode = dml2_sw_linear;
296 
297 	switch (addr3_mode) {
298 	case DC_ADDR3_SW_LINEAR:
299 		dml2_mode = dml2_sw_linear;
300 		break;
301 	case DC_ADDR3_SW_256B_2D:
302 		dml2_mode = dml2_sw_256b_2d;
303 		break;
304 	case DC_ADDR3_SW_4KB_2D:
305 		dml2_mode = dml2_sw_4kb_2d;
306 		break;
307 	case DC_ADDR3_SW_64KB_2D:
308 		dml2_mode = dml2_sw_64kb_2d;
309 		break;
310 	case DC_ADDR3_SW_256KB_2D:
311 		dml2_mode = dml2_sw_256kb_2d;
312 		break;
313 	default:
314 		/* invalid swizzle mode for DML2.1 */
315 		ASSERT(false);
316 		dml2_mode = dml2_sw_linear;
317 	}
318 
319 	return dml2_mode;
320 }
321 
322 static enum dml2_swizzle_mode gfx9_to_dml2_swizzle_mode(enum swizzle_mode_values gfx9_mode)
323 {
324 	enum dml2_swizzle_mode dml2_mode = dml2_sw_64kb_2d;
325 
326 	switch (gfx9_mode) {
327 	case DC_SW_LINEAR:
328 		dml2_mode = dml2_sw_linear;
329 		break;
330 	case DC_SW_256_D:
331 	case DC_SW_256_R:
332 		dml2_mode = dml2_sw_256b_2d;
333 		break;
334 	case DC_SW_4KB_D:
335 	case DC_SW_4KB_R:
336 	case DC_SW_4KB_R_X:
337 		dml2_mode = dml2_sw_4kb_2d;
338 		break;
339 	case DC_SW_64KB_D:
340 	case DC_SW_64KB_D_X:
341 	case DC_SW_64KB_R:
342 	case DC_SW_64KB_R_X:
343 		dml2_mode = dml2_sw_64kb_2d;
344 		break;
345 	case DC_SW_256B_S:
346 	case DC_SW_4KB_S:
347 	case DC_SW_64KB_S:
348 	case DC_SW_VAR_S:
349 	case DC_SW_VAR_D:
350 	case DC_SW_VAR_R:
351 	case DC_SW_64KB_S_T:
352 	case DC_SW_64KB_D_T:
353 	case DC_SW_4KB_S_X:
354 	case DC_SW_4KB_D_X:
355 	case DC_SW_64KB_S_X:
356 	case DC_SW_VAR_S_X:
357 	case DC_SW_VAR_D_X:
358 	case DC_SW_VAR_R_X:
359 	default:
360 		/*
361 		 * invalid swizzle mode for DML2.1. This could happen because
362 		 * DML21 is not intended to be used by N-1 in production. To
363 		 * properly filter out unsupported swizzle modes, we will need
364 		 * to fix capability reporting when DML2.1 is used for N-1 in
365 		 * dc. So DML will only receive DML21 supported swizzle modes.
366 		 * This implementation is not added and has a low value because
367 		 * the supported swizzle modes should already cover most of our
368 		 * N-1 test cases.
369 		 */
370 		return dml2_sw_64kb_2d;
371 	}
372 
373 	return dml2_mode;
374 }
375 
376 static void populate_dml21_dummy_surface_cfg(struct dml2_surface_cfg *surface, const struct dc_stream_state *stream)
377 {
378 	surface->plane0.width = stream->timing.h_addressable;
379 	surface->plane0.height = stream->timing.v_addressable;
380 	surface->plane1.width = stream->timing.h_addressable;
381 	surface->plane1.height = stream->timing.v_addressable;
382 	surface->plane0.pitch = ((surface->plane0.width + 127) / 128) * 128;
383 	surface->plane1.pitch = 0;
384 	surface->dcc.enable = false;
385 	surface->dcc.informative.dcc_rate_plane0 = 1.0;
386 	surface->dcc.informative.dcc_rate_plane1 = 1.0;
387 	surface->dcc.informative.fraction_of_zero_size_request_plane0 = 0;
388 	surface->dcc.informative.fraction_of_zero_size_request_plane1 = 0;
389 	surface->tiling = dml2_sw_64kb_2d;
390 }
391 
392 static void populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters *plane, const struct dc_stream_state *stream)
393 {
394 	unsigned int width, height;
395 
396 	if (stream->timing.h_addressable > 3840)
397 		width = 3840;
398 	else
399 		width = stream->timing.h_addressable;	// 4K max
400 
401 	if (stream->timing.v_addressable > 2160)
402 		height = 2160;
403 	else
404 		height = stream->timing.v_addressable;	// 4K max
405 
406 	plane->cursor.cursor_bpp = 32;
407 
408 	plane->cursor.cursor_width = 256;
409 	plane->cursor.num_cursors = 1;
410 
411 	plane->composition.viewport.plane0.width = width;
412 	plane->composition.viewport.plane0.height = height;
413 	plane->composition.viewport.plane1.width = 0;
414 	plane->composition.viewport.plane1.height = 0;
415 
416 	plane->composition.viewport.stationary = false;
417 	plane->composition.viewport.plane0.x_start = 0;
418 	plane->composition.viewport.plane0.y_start = 0;
419 	plane->composition.viewport.plane1.x_start = 0;
420 	plane->composition.viewport.plane1.y_start = 0;
421 
422 	plane->composition.scaler_info.enabled = false;
423 	plane->composition.rotation_angle = dml2_rotation_0;
424 	plane->composition.scaler_info.plane0.h_ratio = 1.0;
425 	plane->composition.scaler_info.plane0.v_ratio = 1.0;
426 	plane->composition.scaler_info.plane1.h_ratio = 0;
427 	plane->composition.scaler_info.plane1.v_ratio = 0;
428 	plane->composition.scaler_info.plane0.h_taps = 1;
429 	plane->composition.scaler_info.plane0.v_taps = 1;
430 	plane->composition.scaler_info.plane1.h_taps = 0;
431 	plane->composition.scaler_info.plane1.v_taps = 0;
432 	plane->composition.scaler_info.rect_out_width = width;
433 	plane->pixel_format = dml2_444_32;
434 
435 	plane->dynamic_meta_data.enable = false;
436 	plane->overrides.gpuvm_min_page_size_kbytes = 256;
437 }
438 
439 static void populate_dml21_surface_config_from_plane_state(
440 		const struct dc *in_dc,
441 		struct dml2_surface_cfg *surface,
442 		const struct dc_plane_state *plane_state)
443 {
444 	surface->plane0.pitch = plane_state->plane_size.surface_pitch;
445 	surface->plane1.pitch = plane_state->plane_size.chroma_pitch;
446 	surface->plane0.height = plane_state->plane_size.surface_size.height;
447 	surface->plane0.width = plane_state->plane_size.surface_size.width;
448 	surface->plane1.height = plane_state->plane_size.chroma_size.height;
449 	surface->plane1.width = plane_state->plane_size.chroma_size.width;
450 	surface->dcc.enable = plane_state->dcc.enable;
451 	surface->dcc.informative.dcc_rate_plane0 = 1.0;
452 	surface->dcc.informative.dcc_rate_plane1 = 1.0;
453 	surface->dcc.informative.fraction_of_zero_size_request_plane0 = plane_state->dcc.independent_64b_blks;
454 	surface->dcc.informative.fraction_of_zero_size_request_plane1 = plane_state->dcc.independent_64b_blks_c;
455 	surface->dcc.plane0.pitch = plane_state->dcc.meta_pitch;
456 	surface->dcc.plane1.pitch = plane_state->dcc.meta_pitch_c;
457 
458 	// Update swizzle / array mode based on the gfx_format
459 	switch (plane_state->tiling_info.gfxversion) {
460 	case DcGfxVersion7:
461 	case DcGfxVersion8:
462 		break;
463 	case DcGfxVersion9:
464 	case DcGfxVersion10:
465 	case DcGfxVersion11:
466 		surface->tiling = gfx9_to_dml2_swizzle_mode(plane_state->tiling_info.gfx9.swizzle);
467 		break;
468 	case DcGfxAddr3:
469 		surface->tiling = gfx_addr3_to_dml2_swizzle_mode(plane_state->tiling_info.gfx_addr3.swizzle);
470 		break;
471 	}
472 }
473 
474 static const struct scaler_data *get_scaler_data_for_plane(
475 		struct dml2_context *dml_ctx,
476 		const struct dc_plane_state *in,
477 		const struct dc_state *context)
478 {
479 	int i;
480 	struct pipe_ctx *temp_pipe = &dml_ctx->v21.scratch.temp_pipe;
481 
482 	memset(temp_pipe, 0, sizeof(struct pipe_ctx));
483 
484 	for (i = 0; i < MAX_PIPES; i++)	{
485 		const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
486 
487 		if (pipe->plane_state == in && !pipe->prev_odm_pipe) {
488 			temp_pipe->stream = pipe->stream;
489 			temp_pipe->plane_state = pipe->plane_state;
490 			temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;
491 			temp_pipe->stream_res = pipe->stream_res;
492 			temp_pipe->dsc_padding_params.dsc_hactive_padding = pipe->dsc_padding_params.dsc_hactive_padding;
493 			temp_pipe->dsc_padding_params.dsc_htotal_padding = pipe->dsc_padding_params.dsc_htotal_padding;
494 			temp_pipe->dsc_padding_params.dsc_pix_clk_100hz = pipe->dsc_padding_params.dsc_pix_clk_100hz;
495 			dml_ctx->config.callbacks.build_scaling_params(temp_pipe);
496 			break;
497 		}
498 	}
499 
500 	ASSERT(i < MAX_PIPES);
501 	return &temp_pipe->plane_res.scl_data;
502 }
503 
504 static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dml_ctx,
505 		struct dml2_plane_parameters *plane, const struct dc_plane_state *plane_state,
506 		const struct dc_state *context, unsigned int stream_index)
507 {
508 	const struct scaler_data *scaler_data = get_scaler_data_for_plane(dml_ctx, plane_state, context);
509 	struct dc_stream_state *stream = context->streams[stream_index];
510 
511 	plane->cursor.cursor_bpp = 32;
512 	plane->cursor.cursor_width = 256;
513 	plane->cursor.num_cursors = 1;
514 
515 	switch (plane_state->format) {
516 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
517 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
518 		plane->pixel_format = dml2_420_8;
519 		break;
520 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
521 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
522 		plane->pixel_format = dml2_420_10;
523 		break;
524 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
525 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
526 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
527 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
528 		plane->pixel_format = dml2_444_64;
529 		break;
530 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
531 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
532 		plane->pixel_format = dml2_444_16;
533 		break;
534 	case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
535 		plane->pixel_format = dml2_444_8;
536 		break;
537 	case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
538 		plane->pixel_format = dml2_rgbe_alpha;
539 		break;
540 	default:
541 		plane->pixel_format = dml2_444_32;
542 		break;
543 	}
544 
545 	plane->composition.viewport.plane0.height = scaler_data->viewport.height;
546 	plane->composition.viewport.plane0.width = scaler_data->viewport.width;
547 	plane->composition.viewport.plane1.height = scaler_data->viewport_c.height;
548 	plane->composition.viewport.plane1.width = scaler_data->viewport_c.width;
549 	plane->composition.viewport.plane0.x_start = scaler_data->viewport.x;
550 	plane->composition.viewport.plane0.y_start = scaler_data->viewport.y;
551 	plane->composition.viewport.plane1.x_start = scaler_data->viewport_c.x;
552 	plane->composition.viewport.plane1.y_start = scaler_data->viewport_c.y;
553 	plane->composition.viewport.stationary = false;
554 	plane->composition.scaler_info.enabled = scaler_data->ratios.horz.value != dc_fixpt_one.value ||
555 		scaler_data->ratios.horz_c.value != dc_fixpt_one.value ||
556 		scaler_data->ratios.vert.value != dc_fixpt_one.value ||
557 		scaler_data->ratios.vert_c.value != dc_fixpt_one.value;
558 
559 	if (!scaler_data->taps.h_taps) {
560 		/* Above logic determines scaling should be enabled even when there are no taps for
561 		 * certain cases. Hence do corrective active and disable scaling.
562 		 */
563 		plane->composition.scaler_info.enabled = false;
564 	} else if ((plane_state->ctx->dc->config.use_spl == true) &&
565 		(plane->composition.scaler_info.enabled == false)) {
566 		/* To enable sharpener for 1:1, scaler must be enabled.  If use_spl is set, then
567 		 *  allow case where ratio is 1 but taps > 1
568 		 */
569 		if ((scaler_data->taps.h_taps > 1) || (scaler_data->taps.v_taps > 1) ||
570 			(scaler_data->taps.h_taps_c > 1) || (scaler_data->taps.v_taps_c > 1))
571 			plane->composition.scaler_info.enabled = true;
572 	}
573 
574 	/* always_scale is only used for debug purposes not used in production but has to be
575 	 * maintained for certain complainces. */
576 	if (plane_state->ctx->dc->debug.always_scale == true) {
577 		plane->composition.scaler_info.enabled = true;
578 	}
579 
580 	if (plane->composition.scaler_info.enabled == false) {
581 		plane->composition.scaler_info.plane0.h_ratio = 1.0;
582 		plane->composition.scaler_info.plane0.v_ratio = 1.0;
583 		plane->composition.scaler_info.plane1.h_ratio = 1.0;
584 		plane->composition.scaler_info.plane1.v_ratio = 1.0;
585 	} else {
586 		plane->composition.scaler_info.plane0.h_ratio = (double)scaler_data->ratios.horz.value / (1ULL << 32);
587 		plane->composition.scaler_info.plane0.v_ratio = (double)scaler_data->ratios.vert.value / (1ULL << 32);
588 		plane->composition.scaler_info.plane1.h_ratio = (double)scaler_data->ratios.horz_c.value / (1ULL << 32);
589 		plane->composition.scaler_info.plane1.v_ratio = (double)scaler_data->ratios.vert_c.value / (1ULL << 32);
590 	}
591 
592 	if (!scaler_data->taps.h_taps) {
593 		plane->composition.scaler_info.plane0.h_taps = 1;
594 		plane->composition.scaler_info.plane1.h_taps = 1;
595 	} else {
596 		plane->composition.scaler_info.plane0.h_taps = scaler_data->taps.h_taps;
597 		plane->composition.scaler_info.plane1.h_taps = scaler_data->taps.h_taps_c;
598 	}
599 	if (!scaler_data->taps.v_taps) {
600 		plane->composition.scaler_info.plane0.v_taps = 1;
601 		plane->composition.scaler_info.plane1.v_taps = 1;
602 	} else {
603 		plane->composition.scaler_info.plane0.v_taps = scaler_data->taps.v_taps;
604 		plane->composition.scaler_info.plane1.v_taps = scaler_data->taps.v_taps_c;
605 	}
606 
607 	plane->composition.viewport.stationary = false;
608 
609 	if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
610 		plane->tdlut.setup_for_tdlut = true;
611 
612 		switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.layout) {
613 		case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
614 		case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
615 			plane->tdlut.tdlut_addressing_mode = dml2_tdlut_sw_linear;
616 			break;
617 		case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
618 			plane->tdlut.tdlut_addressing_mode = dml2_tdlut_simple_linear;
619 			break;
620 		}
621 
622 		switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.size) {
623 		case DC_CM2_GPU_MEM_SIZE_171717:
624 			plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube;
625 			break;
626 		case DC_CM2_GPU_MEM_SIZE_333333:
627 			plane->tdlut.tdlut_width_mode = dml2_tdlut_width_33_cube;
628 			break;
629 		// handling when use case and HW support available
630 		case DC_CM2_GPU_MEM_SIZE_454545:
631 		case DC_CM2_GPU_MEM_SIZE_656565:
632 			break;
633 		case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
634 		default:
635 			//plane->tdlut.tdlut_width_mode = dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined
636 			break;
637 		}
638 	}
639 
640 	plane->tdlut.setup_for_tdlut |= dml_ctx->config.force_tdlut_enable;
641 
642 	plane->dynamic_meta_data.enable = false;
643 	plane->dynamic_meta_data.lines_before_active_required = 0;
644 	plane->dynamic_meta_data.transmitted_bytes = 0;
645 
646 	plane->composition.scaler_info.rect_out_width = plane_state->dst_rect.width;
647 	plane->composition.rotation_angle = (enum dml2_rotation_angle) plane_state->rotation;
648 	plane->stream_index = stream_index;
649 
650 	plane->overrides.gpuvm_min_page_size_kbytes = 256;
651 
652 	plane->immediate_flip = plane_state->flip_immediate;
653 
654 	plane->composition.rect_out_height_spans_vactive =
655 		plane_state->dst_rect.height >= stream->src.height &&
656 		stream->dst.height >= stream->timing.v_addressable;
657 }
658 
659 //TODO : Could be possibly moved to a common helper layer.
660 static bool dml21_wrapper_get_plane_id(const struct dc_state *context, unsigned int stream_id, const struct dc_plane_state *plane, unsigned int *plane_id)
661 {
662 	int i, j;
663 
664 	if (!plane_id)
665 		return false;
666 
667 	for (i = 0; i < context->stream_count; i++) {
668 		if (context->streams[i]->stream_id == stream_id) {
669 			for (j = 0; j < context->stream_status[i].plane_count; j++) {
670 				if (context->stream_status[i].plane_states[j] == plane) {
671 					*plane_id = (i << 16) | j;
672 					return true;
673 				}
674 			}
675 		}
676 	}
677 
678 	return false;
679 }
680 
681 static unsigned int map_stream_to_dml21_display_cfg(const struct dml2_context *dml_ctx, const struct dc_stream_state *stream)
682 {
683 	int i = 0;
684 	int location = -1;
685 
686 	for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
687 		if (dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[i] && dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[i] == stream->stream_id) {
688 			location = i;
689 			break;
690 		}
691 	}
692 
693 	return location;
694 }
695 
696 unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id,
697 		const struct dc_plane_state *plane, const struct dc_state *context)
698 {
699 	unsigned int plane_id;
700 	int i = 0;
701 	int location = -1;
702 
703 	if (!dml21_wrapper_get_plane_id(context, stream_id, plane, &plane_id)) {
704 		ASSERT(false);
705 		return UINT_MAX;
706 	}
707 
708 	for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
709 		if (dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[i] && dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[i] == plane_id) {
710 			location = i;
711 			break;
712 		}
713 	}
714 
715 	return location;
716 }
717 
718 static enum dml2_uclk_pstate_change_strategy dml21_force_pstate_method_to_uclk_state_change_strategy(enum dml2_force_pstate_methods force_pstate_method)
719 {
720 	enum dml2_uclk_pstate_change_strategy val = dml2_uclk_pstate_change_strategy_auto;
721 
722 	switch (force_pstate_method) {
723 	case dml2_force_pstate_method_vactive:
724 		val = dml2_uclk_pstate_change_strategy_force_vactive;
725 		break;
726 	case dml2_force_pstate_method_vblank:
727 		val = dml2_uclk_pstate_change_strategy_force_vblank;
728 		break;
729 	case dml2_force_pstate_method_drr:
730 		val = dml2_uclk_pstate_change_strategy_force_drr;
731 		break;
732 	case dml2_force_pstate_method_subvp:
733 		val = dml2_uclk_pstate_change_strategy_force_mall_svp;
734 		break;
735 	case dml2_force_pstate_method_auto:
736 	default:
737 		val = dml2_uclk_pstate_change_strategy_auto;
738 	}
739 
740 	return val;
741 }
742 
743 bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_state *context, struct dml2_context *dml_ctx)
744 {
745 	int stream_index, plane_index;
746 	int disp_cfg_stream_location, disp_cfg_plane_location;
747 	struct dml2_display_cfg *dml_dispcfg = &dml_ctx->v21.display_config;
748 	unsigned int plane_count = 0;
749 
750 	memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
751 
752 	dml_dispcfg->gpuvm_enable = dml_ctx->config.gpuvm_enable;
753 	if (dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels)
754 		dml_dispcfg->gpuvm_max_page_table_levels = dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels;
755 	else
756 		dml_dispcfg->gpuvm_max_page_table_levels = 4;
757 	dml_dispcfg->hostvm_enable = dml_ctx->config.hostvm_enable;
758 	dml_dispcfg->hostvm_max_non_cached_page_table_levels = dml_ctx->v21.dml_init.soc_bb.hostvm_max_non_cached_page_table_levels;
759 	dml_dispcfg->minimize_det_reallocation = true;
760 	dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;
761 
762 	if (in_dc->debug.disable_unbounded_requesting) {
763 		dml_dispcfg->overrides.hw.force_unbounded_requesting.enable = true;
764 		dml_dispcfg->overrides.hw.force_unbounded_requesting.value = false;
765 	}
766 
767 	for (stream_index = 0; stream_index < context->stream_count; stream_index++) {
768 		disp_cfg_stream_location = map_stream_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]);
769 
770 		if (disp_cfg_stream_location < 0)
771 			disp_cfg_stream_location = dml_dispcfg->num_streams++;
772 
773 		ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
774 		populate_dml21_timing_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, context->streams[stream_index], &context->res_ctx.pipe_ctx[stream_index], dml_ctx);
775 		populate_dml21_output_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].output, context->streams[stream_index], &context->res_ctx.pipe_ctx[stream_index]);
776 		populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location], context->streams[stream_index], &context->stream_status[stream_index]);
777 
778 		dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.fclk_pstate = dml2_twait_budgeting_setting_if_needed;
779 		dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.uclk_pstate = dml2_twait_budgeting_setting_if_needed;
780 		dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.stutter_enter_exit = dml2_twait_budgeting_setting_if_needed;
781 
782 		dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[disp_cfg_stream_location] = context->streams[stream_index]->stream_id;
783 		dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[disp_cfg_stream_location] = true;
784 
785 		if (context->stream_status[stream_index].plane_count == 0) {
786 			disp_cfg_plane_location = dml_dispcfg->num_planes++;
787 			populate_dml21_dummy_surface_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->streams[stream_index]);
788 			populate_dml21_dummy_plane_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->streams[stream_index]);
789 			dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
790 		} else {
791 			for (plane_index = 0; plane_index < context->stream_status[stream_index].plane_count; plane_index++) {
792 				disp_cfg_plane_location = map_plane_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], context);
793 
794 				if (disp_cfg_plane_location < 0)
795 					disp_cfg_plane_location = dml_dispcfg->num_planes++;
796 
797 				ASSERT(disp_cfg_plane_location >= 0 && disp_cfg_plane_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
798 
799 				populate_dml21_surface_config_from_plane_state(in_dc, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->stream_status[stream_index].plane_states[plane_index]);
800 				populate_dml21_plane_config_from_plane_state(dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->stream_status[stream_index].plane_states[plane_index], context, stream_index);
801 				dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
802 
803 				if (dml21_wrapper_get_plane_id(context, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
804 					dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
805 
806 				/* apply forced pstate policy */
807 				if (dml_ctx->config.pmo.force_pstate_method_enable) {
808 					dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy =
809 							dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]);
810 				}
811 
812 				plane_count++;
813 			}
814 		}
815 	}
816 
817 	if (plane_count == 0) {
818 		dml_dispcfg->overrides.all_streams_blanked = true;
819 	}
820 
821 	return true;
822 }
823 
824 void dml21_copy_clocks_to_dc_state(struct dml2_context *in_ctx, struct dc_state *context)
825 {
826 	/* TODO these should be the max of active, svp prefetch and idle should be tracked seperately */
827 	context->bw_ctx.bw.dcn.clk.dispclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dispclk_khz;
828 	context->bw_ctx.bw.dcn.clk.dcfclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.dcfclk_khz;
829 	context->bw_ctx.bw.dcn.clk.dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.uclk_khz;
830 	context->bw_ctx.bw.dcn.clk.fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.fclk_khz;
831 	context->bw_ctx.bw.dcn.clk.idle_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.uclk_khz;
832 	context->bw_ctx.bw.dcn.clk.idle_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.fclk_khz;
833 	context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.deepsleep_dcfclk_khz;
834 	context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = in_ctx->v21.mode_programming.programming->fclk_pstate_supported;
835 	context->bw_ctx.bw.dcn.clk.p_state_change_support = in_ctx->v21.mode_programming.programming->uclk_pstate_supported;
836 	context->bw_ctx.bw.dcn.clk.dtbclk_en = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz > 0;
837 	context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz;
838 	context->bw_ctx.bw.dcn.clk.socclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.socclk_khz;
839 	context->bw_ctx.bw.dcn.clk.subvp_prefetch_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.uclk_khz;
840 	context->bw_ctx.bw.dcn.clk.subvp_prefetch_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz;
841 	context->bw_ctx.bw.dcn.clk.stutter_efficiency.base_efficiency = in_ctx->v21.mode_programming.programming->stutter.base_percent_efficiency;
842 	context->bw_ctx.bw.dcn.clk.stutter_efficiency.low_power_efficiency = in_ctx->v21.mode_programming.programming->stutter.low_power_percent_efficiency;
843 	context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_efficiency = in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_efficiency;
844 	context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_period = in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_period;
845 	context->bw_ctx.bw.dcn.clk.zstate_support = in_ctx->v21.mode_programming.programming->z8_stutter.supported_in_blank; /*ignore meets_eco since it is not used*/
846 }
847 
848 static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_watermark_set *watermarks, const enum dml2_dchub_watermark_reg_set_index wm_index)
849 {
850 	struct dml2_dchub_watermark_regs *wm_regs = NULL;
851 
852 	switch (wm_index) {
853 	case DML2_DCHUB_WATERMARK_SET_A:
854 		wm_regs = &watermarks->dcn4x.a;
855 		break;
856 	case DML2_DCHUB_WATERMARK_SET_B:
857 		wm_regs = &watermarks->dcn4x.b;
858 		break;
859 	case DML2_DCHUB_WATERMARK_SET_C:
860 		wm_regs = &watermarks->dcn4x.c;
861 		break;
862 	case DML2_DCHUB_WATERMARK_SET_D:
863 		wm_regs = &watermarks->dcn4x.d;
864 		break;
865 	case DML2_DCHUB_WATERMARK_SET_NUM:
866 	default:
867 		/* invalid wm set index */
868 		wm_regs = NULL;
869 	}
870 
871 	return wm_regs;
872 }
873 
874 void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_set *watermarks, struct dml2_context *in_ctx)
875 {
876 	const struct dml2_display_cfg_programming *programming = in_ctx->v21.mode_programming.programming;
877 
878 	unsigned int wm_index;
879 
880 	/* copy watermark sets from DML */
881 	for (wm_index = 0; wm_index < programming->global_regs.num_watermark_sets; wm_index++) {
882 		struct dml2_dchub_watermark_regs *wm_regs = wm_set_index_to_dc_wm_set(watermarks, wm_index);
883 
884 		if (wm_regs)
885 			memcpy(wm_regs,
886 				&programming->global_regs.wm_regs[wm_index],
887 				sizeof(struct dml2_dchub_watermark_regs));
888 	}
889 }
890 
891 void dml21_map_hw_resources(struct dml2_context *dml_ctx)
892 {
893 	unsigned int i = 0;
894 
895 	for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
896 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id[i] = dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[i];
897 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[i] = true;
898 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id[i] = dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[i];
899 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id_valid[i] = true;
900 	}
901 
902 }
903 
904 void dml21_get_pipe_mcache_config(
905 	struct dc_state *context,
906 	struct pipe_ctx *pipe_ctx,
907 	struct dml2_per_plane_programming *pln_prog,
908 	struct dml2_pipe_configuration_descriptor *mcache_pipe_config)
909 {
910 	mcache_pipe_config->plane0.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x;
911 	mcache_pipe_config->plane0.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width;
912 
913 	mcache_pipe_config->plane1.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport_c.x;
914 	mcache_pipe_config->plane1.viewport_width = pipe_ctx->plane_res.scl_data.viewport_c.width;
915 
916 	mcache_pipe_config->plane1_enabled =
917 			dml21_is_plane1_enabled(pln_prog->plane_descriptor->pixel_format);
918 }
919 
920 void dml21_set_dc_p_state_type(
921 		struct pipe_ctx *pipe_ctx,
922 		struct dml2_per_stream_programming *stream_programming,
923 		bool sub_vp_enabled)
924 {
925 	switch (stream_programming->uclk_pstate_method) {
926 	case dml2_pstate_method_vactive:
927 	case dml2_pstate_method_fw_vactive_drr:
928 		pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
929 		break;
930 	case dml2_pstate_method_vblank:
931 	case dml2_pstate_method_fw_vblank_drr:
932 		if (sub_vp_enabled)
933 			pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
934 		else
935 			pipe_ctx->p_state_type = P_STATE_V_BLANK;
936 		break;
937 	case dml2_pstate_method_fw_svp:
938 	case dml2_pstate_method_fw_svp_drr:
939 		pipe_ctx->p_state_type = P_STATE_SUB_VP;
940 		break;
941 	case dml2_pstate_method_fw_drr:
942 		if (sub_vp_enabled)
943 			pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
944 		else
945 			pipe_ctx->p_state_type = P_STATE_FPO;
946 		break;
947 	default:
948 		pipe_ctx->p_state_type = P_STATE_UNKNOWN;
949 		break;
950 	}
951 }
952 
953 void dml21_init_min_clocks_for_dc_state(struct dml2_context *in_ctx, struct dc_state *context)
954 {
955 	unsigned int lowest_dpm_state_index = 0;
956 	struct dc_clocks *min_clocks = &context->bw_ctx.bw.dcn.clk;
957 
958 	min_clocks->dispclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dispclk.clk_values_khz[lowest_dpm_state_index];
959 	min_clocks->dppclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dppclk.clk_values_khz[lowest_dpm_state_index];
960 	min_clocks->dcfclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dcfclk.clk_values_khz[lowest_dpm_state_index];
961 	min_clocks->dramclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.uclk.clk_values_khz[lowest_dpm_state_index];
962 	min_clocks->fclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.fclk.clk_values_khz[lowest_dpm_state_index];
963 	min_clocks->idle_dramclk_khz = 0;
964 	min_clocks->idle_fclk_khz = 0;
965 	min_clocks->dcfclk_deep_sleep_khz = 0;
966 	min_clocks->fclk_p_state_change_support = true;
967 	min_clocks->p_state_change_support = true;
968 	min_clocks->dtbclk_en = false;
969 	min_clocks->ref_dtbclk_khz = 0;
970 	min_clocks->socclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.socclk.clk_values_khz[lowest_dpm_state_index];
971 	min_clocks->subvp_prefetch_dramclk_khz = 0;
972 	min_clocks->subvp_prefetch_fclk_khz = 0;
973 	min_clocks->phyclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.phyclk.clk_values_khz[lowest_dpm_state_index];
974 	min_clocks->stutter_efficiency.base_efficiency = 1;
975 	min_clocks->stutter_efficiency.low_power_efficiency = 1;
976 	min_clocks->stutter_efficiency.z8_stutter_efficiency = 1;
977 	min_clocks->stutter_efficiency.z8_stutter_period = 100000;
978 	min_clocks->zstate_support = DCN_ZSTATE_SUPPORT_ALLOW;
979 }
980 
981