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