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