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 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
dml21_populate_dml_init_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config,const struct dc * in_dc)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
calc_max_hardware_v_total(const struct dc_stream_state * stream)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
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)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
populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg * output,struct dc_stream_state * stream,const struct pipe_ctx * pipe)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
populate_dml21_stream_overrides_from_stream_state(struct dml2_stream_parameters * stream_desc,struct dc_stream_state * stream,struct dc_stream_status * stream_status)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
gfx_addr3_to_dml2_swizzle_mode(enum swizzle_mode_addr3_values addr3_mode)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
gfx9_to_dml2_swizzle_mode(enum swizzle_mode_values gfx9_mode)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
populate_dml21_dummy_surface_cfg(struct dml2_surface_cfg * surface,const struct dc_stream_state * stream)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
populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters * plane,const struct dc_stream_state * stream,const struct dml2_soc_bb * soc_bb)392 static void populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters *plane,
393 const struct dc_stream_state *stream,
394 const struct dml2_soc_bb *soc_bb)
395 {
396 unsigned int width, height;
397
398 if (stream->timing.h_addressable > 3840)
399 width = 3840;
400 else
401 width = stream->timing.h_addressable; // 4K max
402
403 if (stream->timing.v_addressable > 2160)
404 height = 2160;
405 else
406 height = stream->timing.v_addressable; // 4K max
407
408 plane->cursor.cursor_bpp = 32;
409
410 plane->cursor.cursor_width = 256;
411 plane->cursor.num_cursors = 1;
412
413 plane->composition.viewport.plane0.width = width;
414 plane->composition.viewport.plane0.height = height;
415 plane->composition.viewport.plane1.width = 0;
416 plane->composition.viewport.plane1.height = 0;
417
418 plane->composition.viewport.stationary = false;
419 plane->composition.viewport.plane0.x_start = 0;
420 plane->composition.viewport.plane0.y_start = 0;
421 plane->composition.viewport.plane1.x_start = 0;
422 plane->composition.viewport.plane1.y_start = 0;
423
424 plane->composition.scaler_info.enabled = false;
425 plane->composition.rotation_angle = dml2_rotation_0;
426 plane->composition.scaler_info.plane0.h_ratio = 1.0;
427 plane->composition.scaler_info.plane0.v_ratio = 1.0;
428 plane->composition.scaler_info.plane1.h_ratio = 0;
429 plane->composition.scaler_info.plane1.v_ratio = 0;
430 plane->composition.scaler_info.plane0.h_taps = 1;
431 plane->composition.scaler_info.plane0.v_taps = 1;
432 plane->composition.scaler_info.plane1.h_taps = 0;
433 plane->composition.scaler_info.plane1.v_taps = 0;
434 plane->composition.scaler_info.rect_out_width = width;
435 plane->pixel_format = dml2_444_32;
436
437 plane->dynamic_meta_data.enable = false;
438 plane->overrides.gpuvm_min_page_size_kbytes = soc_bb->gpuvm_min_page_size_kbytes;
439 plane->overrides.hostvm_min_page_size_kbytes = soc_bb->hostvm_min_page_size_kbytes;
440 }
441
populate_dml21_surface_config_from_plane_state(const struct dc * in_dc,struct dml2_surface_cfg * surface,const struct dc_plane_state * plane_state)442 static void populate_dml21_surface_config_from_plane_state(
443 const struct dc *in_dc,
444 struct dml2_surface_cfg *surface,
445 const struct dc_plane_state *plane_state)
446 {
447 (void)in_dc;
448 surface->plane0.pitch = plane_state->plane_size.surface_pitch;
449 surface->plane1.pitch = plane_state->plane_size.chroma_pitch;
450 surface->plane0.height = plane_state->plane_size.surface_size.height;
451 surface->plane0.width = plane_state->plane_size.surface_size.width;
452 surface->plane1.height = plane_state->plane_size.chroma_size.height;
453 surface->plane1.width = plane_state->plane_size.chroma_size.width;
454 surface->dcc.enable = plane_state->dcc.enable;
455 surface->dcc.informative.dcc_rate_plane0 = 1.0;
456 surface->dcc.informative.dcc_rate_plane1 = 1.0;
457 surface->dcc.informative.fraction_of_zero_size_request_plane0 = plane_state->dcc.independent_64b_blks;
458 surface->dcc.informative.fraction_of_zero_size_request_plane1 = plane_state->dcc.independent_64b_blks_c;
459 surface->dcc.plane0.pitch = plane_state->dcc.meta_pitch;
460 surface->dcc.plane1.pitch = plane_state->dcc.meta_pitch_c;
461
462 // Update swizzle / array mode based on the gfx_format
463 switch (plane_state->tiling_info.gfxversion) {
464 case DcGfxVersion7:
465 case DcGfxVersion8:
466 break;
467 case DcGfxVersion9:
468 case DcGfxVersion10:
469 case DcGfxVersion11:
470 surface->tiling = gfx9_to_dml2_swizzle_mode(plane_state->tiling_info.gfx9.swizzle);
471 break;
472 case DcGfxAddr3:
473 surface->tiling = gfx_addr3_to_dml2_swizzle_mode(plane_state->tiling_info.gfx_addr3.swizzle);
474 break;
475 }
476 }
477
get_scaler_data_for_plane(struct dml2_context * dml_ctx,const struct dc_plane_state * in,const struct dc_state * context)478 static const struct scaler_data *get_scaler_data_for_plane(
479 struct dml2_context *dml_ctx,
480 const struct dc_plane_state *in,
481 const struct dc_state *context)
482 {
483 int i;
484 struct pipe_ctx *temp_pipe = &dml_ctx->v21.scratch.temp_pipe;
485
486 memset(temp_pipe, 0, sizeof(struct pipe_ctx));
487
488 for (i = 0; i < MAX_PIPES; i++) {
489 const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
490
491 if (pipe->plane_state == in && !pipe->prev_odm_pipe) {
492 temp_pipe->stream = pipe->stream;
493 temp_pipe->plane_state = pipe->plane_state;
494 temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;
495 temp_pipe->stream_res = pipe->stream_res;
496 temp_pipe->dsc_padding_params.dsc_hactive_padding = pipe->dsc_padding_params.dsc_hactive_padding;
497 temp_pipe->dsc_padding_params.dsc_htotal_padding = pipe->dsc_padding_params.dsc_htotal_padding;
498 temp_pipe->dsc_padding_params.dsc_pix_clk_100hz = pipe->dsc_padding_params.dsc_pix_clk_100hz;
499 dml_ctx->config.callbacks.build_scaling_params(temp_pipe);
500 break;
501 }
502 }
503
504 ASSERT(i < MAX_PIPES);
505 return &temp_pipe->plane_res.scl_data;
506 }
507
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,const struct dml2_soc_bb * soc_bb)508 static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dml_ctx,
509 struct dml2_plane_parameters *plane, const struct dc_plane_state *plane_state,
510 const struct dc_state *context, unsigned int stream_index, const struct dml2_soc_bb *soc_bb)
511 {
512 const struct scaler_data *scaler_data = get_scaler_data_for_plane(dml_ctx, plane_state, context);
513 struct dc_stream_state *stream = context->streams[stream_index];
514
515 plane->cursor.cursor_bpp = 32;
516 plane->cursor.cursor_width = 256;
517 plane->cursor.num_cursors = 1;
518
519 switch (plane_state->format) {
520 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
521 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
522 plane->pixel_format = dml2_420_8;
523 break;
524 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
525 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
526 plane->pixel_format = dml2_420_10;
527 break;
528 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
529 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
530 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
531 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
532 plane->pixel_format = dml2_444_64;
533 break;
534 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
535 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
536 plane->pixel_format = dml2_444_16;
537 break;
538 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
539 plane->pixel_format = dml2_444_8;
540 break;
541 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
542 plane->pixel_format = dml2_rgbe_alpha;
543 break;
544 default:
545 plane->pixel_format = dml2_444_32;
546 break;
547 }
548
549 plane->composition.viewport.plane0.height = scaler_data->viewport.height;
550 plane->composition.viewport.plane0.width = scaler_data->viewport.width;
551 plane->composition.viewport.plane1.height = scaler_data->viewport_c.height;
552 plane->composition.viewport.plane1.width = scaler_data->viewport_c.width;
553 plane->composition.viewport.plane0.x_start = scaler_data->viewport.x;
554 plane->composition.viewport.plane0.y_start = scaler_data->viewport.y;
555 plane->composition.viewport.plane1.x_start = scaler_data->viewport_c.x;
556 plane->composition.viewport.plane1.y_start = scaler_data->viewport_c.y;
557 plane->composition.viewport.stationary = false;
558 plane->composition.scaler_info.enabled = scaler_data->ratios.horz.value != dc_fixpt_one.value ||
559 scaler_data->ratios.horz_c.value != dc_fixpt_one.value ||
560 scaler_data->ratios.vert.value != dc_fixpt_one.value ||
561 scaler_data->ratios.vert_c.value != dc_fixpt_one.value;
562
563 if (!scaler_data->taps.h_taps) {
564 /* Above logic determines scaling should be enabled even when there are no taps for
565 * certain cases. Hence do corrective active and disable scaling.
566 */
567 plane->composition.scaler_info.enabled = false;
568 } else if ((plane_state->ctx->dc->config.use_spl == true) &&
569 (plane->composition.scaler_info.enabled == false)) {
570 /* To enable sharpener for 1:1, scaler must be enabled. If use_spl is set, then
571 * allow case where ratio is 1 but taps > 1
572 */
573 if ((scaler_data->taps.h_taps > 1) || (scaler_data->taps.v_taps > 1) ||
574 (scaler_data->taps.h_taps_c > 1) || (scaler_data->taps.v_taps_c > 1))
575 plane->composition.scaler_info.enabled = true;
576 }
577
578 /* always_scale is only used for debug purposes not used in production but has to be
579 * maintained for certain complainces. */
580 if (plane_state->ctx->dc->debug.always_scale == true) {
581 plane->composition.scaler_info.enabled = true;
582 }
583
584 if (plane->composition.scaler_info.enabled == false) {
585 plane->composition.scaler_info.plane0.h_ratio = 1.0;
586 plane->composition.scaler_info.plane0.v_ratio = 1.0;
587 plane->composition.scaler_info.plane1.h_ratio = 1.0;
588 plane->composition.scaler_info.plane1.v_ratio = 1.0;
589 } else {
590 plane->composition.scaler_info.plane0.h_ratio = (double)scaler_data->ratios.horz.value / (1ULL << 32);
591 plane->composition.scaler_info.plane0.v_ratio = (double)scaler_data->ratios.vert.value / (1ULL << 32);
592 plane->composition.scaler_info.plane1.h_ratio = (double)scaler_data->ratios.horz_c.value / (1ULL << 32);
593 plane->composition.scaler_info.plane1.v_ratio = (double)scaler_data->ratios.vert_c.value / (1ULL << 32);
594 }
595
596 if (!scaler_data->taps.h_taps) {
597 plane->composition.scaler_info.plane0.h_taps = 1;
598 plane->composition.scaler_info.plane1.h_taps = 1;
599 } else {
600 plane->composition.scaler_info.plane0.h_taps = scaler_data->taps.h_taps;
601 plane->composition.scaler_info.plane1.h_taps = scaler_data->taps.h_taps_c;
602 }
603 if (!scaler_data->taps.v_taps) {
604 plane->composition.scaler_info.plane0.v_taps = 1;
605 plane->composition.scaler_info.plane1.v_taps = 1;
606 } else {
607 plane->composition.scaler_info.plane0.v_taps = scaler_data->taps.v_taps;
608 plane->composition.scaler_info.plane1.v_taps = scaler_data->taps.v_taps_c;
609 }
610
611 plane->composition.viewport.stationary = false;
612
613 if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
614 plane->tdlut.setup_for_tdlut = true;
615
616 switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.layout) {
617 case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
618 case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
619 plane->tdlut.tdlut_addressing_mode = dml2_tdlut_sw_linear;
620 break;
621 case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
622 plane->tdlut.tdlut_addressing_mode = dml2_tdlut_simple_linear;
623 break;
624 }
625
626 switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.size) {
627 case DC_CM2_GPU_MEM_SIZE_171717:
628 plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube;
629 break;
630 case DC_CM2_GPU_MEM_SIZE_333333:
631 plane->tdlut.tdlut_width_mode = dml2_tdlut_width_33_cube;
632 break;
633 // handling when use case and HW support available
634 case DC_CM2_GPU_MEM_SIZE_454545:
635 case DC_CM2_GPU_MEM_SIZE_656565:
636 break;
637 case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
638 default:
639 //plane->tdlut.tdlut_width_mode = dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined
640 break;
641 }
642 }
643
644 plane->tdlut.setup_for_tdlut |= dml_ctx->config.force_tdlut_enable;
645
646 plane->dynamic_meta_data.enable = false;
647 plane->dynamic_meta_data.lines_before_active_required = 0;
648 plane->dynamic_meta_data.transmitted_bytes = 0;
649
650 plane->composition.scaler_info.rect_out_width = plane_state->dst_rect.width;
651 plane->composition.rotation_angle = (enum dml2_rotation_angle) plane_state->rotation;
652 plane->stream_index = stream_index;
653
654 plane->overrides.gpuvm_min_page_size_kbytes = soc_bb->gpuvm_min_page_size_kbytes;
655 plane->overrides.hostvm_min_page_size_kbytes = soc_bb->hostvm_min_page_size_kbytes;
656
657 plane->immediate_flip = plane_state->flip_immediate;
658
659 plane->composition.rect_out_height_spans_vactive =
660 plane_state->dst_rect.height >= stream->src.height &&
661 stream->dst.height >= stream->timing.v_addressable;
662 }
663
664 //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)665 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)
666 {
667 int i, j;
668
669 if (!plane_id)
670 return false;
671
672 for (i = 0; i < context->stream_count; i++) {
673 if (context->streams[i]->stream_id == stream_id) {
674 for (j = 0; j < context->stream_status[i].plane_count; j++) {
675 if (context->stream_status[i].plane_states[j] == plane) {
676 *plane_id = (i << 16) | j;
677 return true;
678 }
679 }
680 }
681 }
682
683 return false;
684 }
685
map_stream_to_dml21_display_cfg(const struct dml2_context * dml_ctx,const struct dc_stream_state * stream)686 static unsigned int map_stream_to_dml21_display_cfg(const struct dml2_context *dml_ctx, const struct dc_stream_state *stream)
687 {
688 int i = 0;
689 int location = -1;
690
691 for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
692 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) {
693 location = i;
694 break;
695 }
696 }
697
698 return location;
699 }
700
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)701 unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id,
702 const struct dc_plane_state *plane, const struct dc_state *context)
703 {
704 unsigned int plane_id;
705 int i = 0;
706 int location = -1;
707
708 if (!dml21_wrapper_get_plane_id(context, stream_id, plane, &plane_id)) {
709 ASSERT(false);
710 return UINT_MAX;
711 }
712
713 for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
714 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) {
715 location = i;
716 break;
717 }
718 }
719
720 return location;
721 }
722
dml21_force_pstate_method_to_uclk_state_change_strategy(enum dml2_force_pstate_methods force_pstate_method)723 static enum dml2_uclk_pstate_change_strategy dml21_force_pstate_method_to_uclk_state_change_strategy(enum dml2_force_pstate_methods force_pstate_method)
724 {
725 enum dml2_uclk_pstate_change_strategy val = dml2_uclk_pstate_change_strategy_auto;
726
727 switch (force_pstate_method) {
728 case dml2_force_pstate_method_vactive:
729 val = dml2_uclk_pstate_change_strategy_force_vactive;
730 break;
731 case dml2_force_pstate_method_vblank:
732 val = dml2_uclk_pstate_change_strategy_force_vblank;
733 break;
734 case dml2_force_pstate_method_drr:
735 val = dml2_uclk_pstate_change_strategy_force_drr;
736 break;
737 case dml2_force_pstate_method_subvp:
738 val = dml2_uclk_pstate_change_strategy_force_mall_svp;
739 break;
740 case dml2_force_pstate_method_auto:
741 default:
742 val = dml2_uclk_pstate_change_strategy_auto;
743 }
744
745 return val;
746 }
747
dml21_map_dc_state_into_dml_display_cfg(const struct dc * in_dc,struct dc_state * context,struct dml2_context * dml_ctx)748 bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_state *context, struct dml2_context *dml_ctx)
749 {
750 int stream_index, plane_index;
751 int disp_cfg_stream_location, disp_cfg_plane_location;
752 struct dml2_display_cfg *dml_dispcfg = &dml_ctx->v21.display_config;
753 unsigned int plane_count = 0;
754
755 memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
756
757 dml_dispcfg->gpuvm_enable = dml_ctx->config.gpuvm_enable;
758 if (dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels)
759 dml_dispcfg->gpuvm_max_page_table_levels = dml_ctx->v21.dml_init.soc_bb.gpuvm_max_page_table_levels;
760 else
761 dml_dispcfg->gpuvm_max_page_table_levels = 4;
762 dml_dispcfg->hostvm_enable = dml_ctx->config.hostvm_enable;
763 dml_dispcfg->hostvm_max_non_cached_page_table_levels = dml_ctx->v21.dml_init.soc_bb.hostvm_max_non_cached_page_table_levels;
764 dml_dispcfg->minimize_det_reallocation = true;
765 dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;
766
767 if (in_dc->debug.disable_unbounded_requesting) {
768 dml_dispcfg->overrides.hw.force_unbounded_requesting.enable = true;
769 dml_dispcfg->overrides.hw.force_unbounded_requesting.value = false;
770 }
771
772 for (stream_index = 0; stream_index < context->stream_count; stream_index++) {
773 disp_cfg_stream_location = map_stream_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]);
774
775 if (disp_cfg_stream_location < 0)
776 disp_cfg_stream_location = dml_dispcfg->num_streams++;
777
778 ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
779 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);
780 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]);
781 populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location], context->streams[stream_index], &context->stream_status[stream_index]);
782
783 dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.fclk_pstate = dml2_twait_budgeting_setting_if_needed;
784 dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.uclk_pstate = dml2_twait_budgeting_setting_if_needed;
785 dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.stutter_enter_exit = dml2_twait_budgeting_setting_if_needed;
786
787 dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[disp_cfg_stream_location] = context->streams[stream_index]->stream_id;
788 dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[disp_cfg_stream_location] = true;
789
790 if (context->stream_status[stream_index].plane_count == 0) {
791 disp_cfg_plane_location = dml_dispcfg->num_planes++;
792 populate_dml21_dummy_surface_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->streams[stream_index]);
793 populate_dml21_dummy_plane_cfg(
794 &dml_dispcfg->plane_descriptors[disp_cfg_plane_location],
795 context->streams[stream_index], &dml_ctx->v21.dml_init.soc_bb);
796 dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
797 } else {
798 for (plane_index = 0; plane_index < context->stream_status[stream_index].plane_count; plane_index++) {
799 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);
800
801 if (disp_cfg_plane_location < 0)
802 disp_cfg_plane_location = dml_dispcfg->num_planes++;
803
804 ASSERT(disp_cfg_plane_location >= 0 && disp_cfg_plane_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
805
806 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]);
807 populate_dml21_plane_config_from_plane_state(
808 dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location],
809 context->stream_status[stream_index].plane_states[plane_index],
810 context, stream_index, &dml_ctx->v21.dml_init.soc_bb);
811 dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
812
813 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]))
814 dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
815
816 /* apply forced pstate policy */
817 if (dml_ctx->config.pmo.force_pstate_method_enable) {
818 dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy =
819 dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]);
820 }
821
822 plane_count++;
823 }
824 }
825 }
826
827 if (plane_count == 0) {
828 dml_dispcfg->overrides.all_streams_blanked = true;
829 }
830
831 return true;
832 }
833
dml21_copy_clocks_to_dc_state(struct dml2_context * in_ctx,struct dc_state * context)834 void dml21_copy_clocks_to_dc_state(struct dml2_context *in_ctx, struct dc_state *context)
835 {
836 /* TODO these should be the max of active, svp prefetch and idle should be tracked seperately */
837 context->bw_ctx.bw.dcn.clk.dispclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dispclk_khz;
838 context->bw_ctx.bw.dcn.clk.dcfclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.dcfclk_khz;
839 context->bw_ctx.bw.dcn.clk.dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.uclk_khz;
840 context->bw_ctx.bw.dcn.clk.fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.fclk_khz;
841 context->bw_ctx.bw.dcn.clk.idle_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.uclk_khz;
842 context->bw_ctx.bw.dcn.clk.idle_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.fclk_khz;
843 context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.deepsleep_dcfclk_khz;
844 context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = in_ctx->v21.mode_programming.programming->fclk_pstate_supported;
845 context->bw_ctx.bw.dcn.clk.p_state_change_support = in_ctx->v21.mode_programming.programming->uclk_pstate_supported;
846 context->bw_ctx.bw.dcn.clk.dtbclk_en = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz > 0;
847 context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz;
848 context->bw_ctx.bw.dcn.clk.socclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.socclk_khz;
849 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;
850 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;
851 context->bw_ctx.bw.dcn.clk.stutter_efficiency.base_efficiency = in_ctx->v21.mode_programming.programming->stutter.base_percent_efficiency;
852 context->bw_ctx.bw.dcn.clk.stutter_efficiency.low_power_efficiency = in_ctx->v21.mode_programming.programming->stutter.low_power_percent_efficiency;
853 context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_efficiency = in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_efficiency;
854 context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_period = in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_period;
855 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*/
856 }
857
wm_set_index_to_dc_wm_set(union dcn_watermark_set * watermarks,const enum dml2_dchub_watermark_reg_set_index wm_index)858 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)
859 {
860 struct dml2_dchub_watermark_regs *wm_regs = NULL;
861
862 switch (wm_index) {
863 case DML2_DCHUB_WATERMARK_SET_A:
864 wm_regs = &watermarks->dcn4x.a;
865 break;
866 case DML2_DCHUB_WATERMARK_SET_B:
867 wm_regs = &watermarks->dcn4x.b;
868 break;
869 case DML2_DCHUB_WATERMARK_SET_C:
870 wm_regs = &watermarks->dcn4x.c;
871 break;
872 case DML2_DCHUB_WATERMARK_SET_D:
873 wm_regs = &watermarks->dcn4x.d;
874 break;
875 case DML2_DCHUB_WATERMARK_SET_NUM:
876 default:
877 /* invalid wm set index */
878 wm_regs = NULL;
879 }
880
881 return wm_regs;
882 }
883
dml21_extract_watermark_sets(const struct dc * in_dc,union dcn_watermark_set * watermarks,struct dml2_context * in_ctx)884 void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_set *watermarks, struct dml2_context *in_ctx)
885 {
886 (void)in_dc;
887 const struct dml2_display_cfg_programming *programming = in_ctx->v21.mode_programming.programming;
888
889 unsigned int wm_index;
890
891 /* copy watermark sets from DML */
892 for (wm_index = 0; wm_index < programming->global_regs.num_watermark_sets; wm_index++) {
893 struct dml2_dchub_watermark_regs *wm_regs = wm_set_index_to_dc_wm_set(watermarks, wm_index);
894
895 if (wm_regs)
896 memcpy(wm_regs,
897 &programming->global_regs.wm_regs[wm_index],
898 sizeof(struct dml2_dchub_watermark_regs));
899 }
900 }
901
dml21_map_hw_resources(struct dml2_context * dml_ctx)902 void dml21_map_hw_resources(struct dml2_context *dml_ctx)
903 {
904 unsigned int i = 0;
905
906 for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
907 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];
908 dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[i] = true;
909 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];
910 dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id_valid[i] = true;
911 }
912
913 }
914
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)915 void dml21_get_pipe_mcache_config(
916 struct dc_state *context,
917 struct pipe_ctx *pipe_ctx,
918 struct dml2_per_plane_programming *pln_prog,
919 struct dml2_pipe_configuration_descriptor *mcache_pipe_config)
920 {
921 (void)context;
922 mcache_pipe_config->plane0.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x;
923 mcache_pipe_config->plane0.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width;
924
925 mcache_pipe_config->plane1.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport_c.x;
926 mcache_pipe_config->plane1.viewport_width = pipe_ctx->plane_res.scl_data.viewport_c.width;
927
928 mcache_pipe_config->plane1_enabled =
929 dml21_is_plane1_enabled(pln_prog->plane_descriptor->pixel_format);
930 }
931
dml21_set_dc_p_state_type(struct pipe_ctx * pipe_ctx,struct dml2_per_stream_programming * stream_programming,bool sub_vp_enabled)932 void dml21_set_dc_p_state_type(
933 struct pipe_ctx *pipe_ctx,
934 struct dml2_per_stream_programming *stream_programming,
935 bool sub_vp_enabled)
936 {
937 switch (stream_programming->uclk_pstate_method) {
938 case dml2_pstate_method_vactive:
939 case dml2_pstate_method_fw_vactive_drr:
940 pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
941 break;
942 case dml2_pstate_method_vblank:
943 case dml2_pstate_method_fw_vblank_drr:
944 if (sub_vp_enabled)
945 pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
946 else
947 pipe_ctx->p_state_type = P_STATE_V_BLANK;
948 break;
949 case dml2_pstate_method_fw_svp:
950 case dml2_pstate_method_fw_svp_drr:
951 pipe_ctx->p_state_type = P_STATE_SUB_VP;
952 break;
953 case dml2_pstate_method_fw_drr:
954 if (sub_vp_enabled)
955 pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
956 else
957 pipe_ctx->p_state_type = P_STATE_FPO;
958 break;
959 default:
960 pipe_ctx->p_state_type = P_STATE_UNKNOWN;
961 break;
962 }
963 }
964
dml21_init_min_clocks_for_dc_state(struct dml2_context * in_ctx,struct dc_state * context)965 void dml21_init_min_clocks_for_dc_state(struct dml2_context *in_ctx, struct dc_state *context)
966 {
967 unsigned int lowest_dpm_state_index = 0;
968 struct dc_clocks *min_clocks = &context->bw_ctx.bw.dcn.clk;
969
970 min_clocks->dispclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dispclk.clk_values_khz[lowest_dpm_state_index];
971 min_clocks->dppclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dppclk.clk_values_khz[lowest_dpm_state_index];
972 min_clocks->dcfclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dcfclk.clk_values_khz[lowest_dpm_state_index];
973 min_clocks->dramclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.uclk.clk_values_khz[lowest_dpm_state_index];
974 min_clocks->fclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.fclk.clk_values_khz[lowest_dpm_state_index];
975 min_clocks->idle_dramclk_khz = 0;
976 min_clocks->idle_fclk_khz = 0;
977 min_clocks->dcfclk_deep_sleep_khz = 0;
978 min_clocks->fclk_p_state_change_support = true;
979 min_clocks->p_state_change_support = true;
980 min_clocks->dtbclk_en = false;
981 min_clocks->ref_dtbclk_khz = 0;
982 min_clocks->socclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.socclk.clk_values_khz[lowest_dpm_state_index];
983 min_clocks->subvp_prefetch_dramclk_khz = 0;
984 min_clocks->subvp_prefetch_fclk_khz = 0;
985 min_clocks->phyclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.phyclk.clk_values_khz[lowest_dpm_state_index];
986 min_clocks->stutter_efficiency.base_efficiency = 1;
987 min_clocks->stutter_efficiency.low_power_efficiency = 1;
988 min_clocks->stutter_efficiency.z8_stutter_efficiency = 1;
989 min_clocks->stutter_efficiency.z8_stutter_period = 100000;
990 min_clocks->zstate_support = DCN_ZSTATE_SUPPORT_ALLOW;
991 }
992
993