1/* SPDX-License-Identifier: MIT */ 2/* Copyright 2024 Advanced Micro Devices, Inc. */ 3#include "resource.h" 4#include "dcn351_fpu.h" 5#include "dcn31/dcn31_resource.h" 6#include "dcn32/dcn32_resource.h" 7#include "dcn35/dcn35_resource.h" 8#include "dcn351/dcn351_resource.h" 9#include "dml/dcn31/dcn31_fpu.h" 10#include "dml/dcn35/dcn35_fpu.h" 11#include "dml/dml_inline_defs.h" 12 13#include "link.h" 14 15#define DC_LOGGER_INIT(logger) 16 17struct _vcs_dpi_ip_params_st dcn3_51_ip = { 18 .VBlankNomDefaultUS = 668, 19 .gpuvm_enable = 1, 20 .gpuvm_max_page_table_levels = 1, 21 .hostvm_enable = 1, 22 .hostvm_max_page_table_levels = 2, 23 .rob_buffer_size_kbytes = 64, 24 .det_buffer_size_kbytes = 1536, 25 .config_return_buffer_size_in_kbytes = 1792, 26 .compressed_buffer_segment_size_in_kbytes = 64, 27 .meta_fifo_size_in_kentries = 32, 28 .zero_size_buffer_entries = 512, 29 .compbuf_reserved_space_64b = 256, 30 .compbuf_reserved_space_zs = 64, 31 .dpp_output_buffer_pixels = 2560,/*not used*/ 32 .opp_output_buffer_lines = 1,/*not used*/ 33 .pixel_chunk_size_kbytes = 8, 34 //.alpha_pixel_chunk_size_kbytes = 4;/*new*/ 35 //.min_pixel_chunk_size_bytes = 1024;/*new*/ 36 .meta_chunk_size_kbytes = 2, 37 .min_meta_chunk_size_bytes = 256, 38 .writeback_chunk_size_kbytes = 8, 39 .ptoi_supported = false, 40 .num_dsc = 4, 41 .maximum_dsc_bits_per_component = 12,/*delta from 10*/ 42 .dsc422_native_support = true,/*delta from false*/ 43 .is_line_buffer_bpp_fixed = true,/*new*/ 44 .line_buffer_fixed_bpp = 32,/*delta from 48*/ 45 .line_buffer_size_bits = 986880,/*delta from 789504*/ 46 .max_line_buffer_lines = 32,/*delta from 12*/ 47 .writeback_interface_buffer_size_kbytes = 90, 48 .max_num_dpp = 4, 49 .max_num_otg = 4, 50 .max_num_hdmi_frl_outputs = 1, 51 .max_num_wb = 1, 52 /*.max_num_hdmi_frl_outputs = 1; new in dml2*/ 53 /*.max_num_dp2p0_outputs = 2; new in dml2*/ 54 /*.max_num_dp2p0_streams = 4; new in dml2*/ 55 .max_dchub_pscl_bw_pix_per_clk = 4, 56 .max_pscl_lb_bw_pix_per_clk = 2, 57 .max_lb_vscl_bw_pix_per_clk = 4, 58 .max_vscl_hscl_bw_pix_per_clk = 4, 59 .max_hscl_ratio = 6, 60 .max_vscl_ratio = 6, 61 .max_hscl_taps = 8, 62 .max_vscl_taps = 8, 63 .dpte_buffer_size_in_pte_reqs_luma = 68,/*changed from 64,*/ 64 .dpte_buffer_size_in_pte_reqs_chroma = 36,/*changed from 34*/ 65 /*.dcc_meta_buffer_size_bytes = 6272; new to dml2*/ 66 .dispclk_ramp_margin_percent = 1.11,/*delta from 1*/ 67 /*.dppclk_delay_subtotal = 47; 68 .dppclk_delay_scl = 50; 69 .dppclk_delay_scl_lb_only = 16; 70 .dppclk_delay_cnvc_formatter = 28; 71 .dppclk_delay_cnvc_cursor = 6; 72 .dispclk_delay_subtotal = 125;*/ /*new to dml2*/ 73 .max_inter_dcn_tile_repeaters = 8, 74 .cursor_buffer_size = 16, 75 .cursor_chunk_size = 2, 76 .writeback_line_buffer_buffer_size = 0, 77 .writeback_min_hscl_ratio = 1, 78 .writeback_min_vscl_ratio = 1, 79 .writeback_max_hscl_ratio = 1, 80 .writeback_max_vscl_ratio = 1, 81 .writeback_max_hscl_taps = 1, 82 .writeback_max_vscl_taps = 1, 83 .dppclk_delay_subtotal = 47, /* changed from 46,*/ 84 .dppclk_delay_scl = 50, 85 .dppclk_delay_scl_lb_only = 16, 86 .dppclk_delay_cnvc_formatter = 28,/*changed from 27,*/ 87 .dppclk_delay_cnvc_cursor = 6, 88 .dispclk_delay_subtotal = 125, /*changed from 119,*/ 89 .dynamic_metadata_vm_enabled = false, 90 .odm_combine_4to1_supported = false, 91 .dcc_supported = true, 92// .config_return_buffer_segment_size_in_kbytes = 64;/*required, hard coded in dml2_translate_ip_params*/ 93 94}; 95 96struct _vcs_dpi_soc_bounding_box_st dcn3_51_soc = { 97 /*TODO: correct dispclk/dppclk voltage level determination*/ 98 .clock_limits = { 99 { 100 .state = 0, 101 .dcfclk_mhz = 400.0, 102 .fabricclk_mhz = 400.0, 103 .socclk_mhz = 600.0, 104 .dram_speed_mts = 3200.0, 105 .dispclk_mhz = 600.0, 106 .dppclk_mhz = 600.0, 107 .phyclk_mhz = 600.0, 108 .phyclk_d18_mhz = 667.0, 109 .dscclk_mhz = 200.0, 110 .dtbclk_mhz = 600.0, 111 }, 112 { 113 .state = 1, 114 .dcfclk_mhz = 600.0, 115 .fabricclk_mhz = 1000.0, 116 .socclk_mhz = 733.0, 117 .dram_speed_mts = 6400.0, 118 .dispclk_mhz = 800.0, 119 .dppclk_mhz = 800.0, 120 .phyclk_mhz = 810.0, 121 .phyclk_d18_mhz = 667.0, 122 .dscclk_mhz = 266.7, 123 .dtbclk_mhz = 600.0, 124 }, 125 { 126 .state = 2, 127 .dcfclk_mhz = 738.0, 128 .fabricclk_mhz = 1200.0, 129 .socclk_mhz = 880.0, 130 .dram_speed_mts = 7500.0, 131 .dispclk_mhz = 800.0, 132 .dppclk_mhz = 800.0, 133 .phyclk_mhz = 810.0, 134 .phyclk_d18_mhz = 667.0, 135 .dscclk_mhz = 266.7, 136 .dtbclk_mhz = 600.0, 137 }, 138 { 139 .state = 3, 140 .dcfclk_mhz = 800.0, 141 .fabricclk_mhz = 1400.0, 142 .socclk_mhz = 978.0, 143 .dram_speed_mts = 7500.0, 144 .dispclk_mhz = 960.0, 145 .dppclk_mhz = 960.0, 146 .phyclk_mhz = 810.0, 147 .phyclk_d18_mhz = 667.0, 148 .dscclk_mhz = 320.0, 149 .dtbclk_mhz = 600.0, 150 }, 151 { 152 .state = 4, 153 .dcfclk_mhz = 873.0, 154 .fabricclk_mhz = 1600.0, 155 .socclk_mhz = 1100.0, 156 .dram_speed_mts = 8533.0, 157 .dispclk_mhz = 1066.7, 158 .dppclk_mhz = 1066.7, 159 .phyclk_mhz = 810.0, 160 .phyclk_d18_mhz = 667.0, 161 .dscclk_mhz = 355.6, 162 .dtbclk_mhz = 600.0, 163 }, 164 { 165 .state = 5, 166 .dcfclk_mhz = 960.0, 167 .fabricclk_mhz = 1700.0, 168 .socclk_mhz = 1257.0, 169 .dram_speed_mts = 8533.0, 170 .dispclk_mhz = 1200.0, 171 .dppclk_mhz = 1200.0, 172 .phyclk_mhz = 810.0, 173 .phyclk_d18_mhz = 667.0, 174 .dscclk_mhz = 400.0, 175 .dtbclk_mhz = 600.0, 176 }, 177 { 178 .state = 6, 179 .dcfclk_mhz = 1067.0, 180 .fabricclk_mhz = 1850.0, 181 .socclk_mhz = 1257.0, 182 .dram_speed_mts = 8533.0, 183 .dispclk_mhz = 1371.4, 184 .dppclk_mhz = 1371.4, 185 .phyclk_mhz = 810.0, 186 .phyclk_d18_mhz = 667.0, 187 .dscclk_mhz = 457.1, 188 .dtbclk_mhz = 600.0, 189 }, 190 { 191 .state = 7, 192 .dcfclk_mhz = 1200.0, 193 .fabricclk_mhz = 2000.0, 194 .socclk_mhz = 1467.0, 195 .dram_speed_mts = 8533.0, 196 .dispclk_mhz = 1600.0, 197 .dppclk_mhz = 1600.0, 198 .phyclk_mhz = 810.0, 199 .phyclk_d18_mhz = 667.0, 200 .dscclk_mhz = 533.3, 201 .dtbclk_mhz = 600.0, 202 }, 203 }, 204 .num_states = 8, 205 .sr_exit_time_us = 28.0, 206 .sr_enter_plus_exit_time_us = 30.0, 207 .sr_exit_z8_time_us = 250.0, 208 .sr_enter_plus_exit_z8_time_us = 350.0, 209 .fclk_change_latency_us = 24.0, 210 .usr_retraining_latency_us = 2, 211 .writeback_latency_us = 12.0, 212 213 .dram_channel_width_bytes = 4,/*not exist in dml2*/ 214 .round_trip_ping_latency_dcfclk_cycles = 106,/*not exist in dml2*/ 215 .urgent_latency_pixel_data_only_us = 4.0, 216 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, 217 .urgent_latency_vm_data_only_us = 4.0, 218 .dram_clock_change_latency_us = 11.72, 219 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 220 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 221 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 222 223 .pct_ideal_sdp_bw_after_urgent = 80.0, 224 .pct_ideal_fabric_bw_after_urgent = 80.0, /*new to dml2*/ 225 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0, 226 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, 227 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0, 228 .max_avg_sdp_bw_use_normal_percent = 60.0, 229 .max_avg_dram_bw_use_normal_percent = 60.0, 230 .fabric_datapath_to_dcn_data_return_bytes = 32, 231 .return_bus_width_bytes = 64, 232 .downspread_percent = 0.38, 233 .dcn_downspread_percent = 0.5, 234 .gpuvm_min_page_size_bytes = 4096, 235 .hostvm_min_page_size_bytes = 4096, 236 .do_urgent_latency_adjustment = 0, 237 .urgent_latency_adjustment_fabric_clock_component_us = 0, 238 .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, 239 .num_chans = 4, 240 .dram_clock_change_latency_us = 11.72, 241 .dispclk_dppclk_vco_speed_mhz = 2400.0, 242}; 243 244/* 245 * dcn351_update_bw_bounding_box 246 * 247 * This would override some dcn3_51 ip_or_soc initial parameters hardcoded from 248 * spreadsheet with actual values as per dGPU SKU: 249 * - with passed few options from dc->config 250 * - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might 251 * need to get it from PM FW) 252 * - with passed latency values (passed in ns units) in dc-> bb override for 253 * debugging purposes 254 * - with passed latencies from VBIOS (in 100_ns units) if available for 255 * certain dGPU SKU 256 * - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU 257 * of the same ASIC) 258 * - clocks levels with passed clk_table entries from Clk Mgr as reported by PM 259 * FW for different clocks (which might differ for certain dGPU SKU of the 260 * same ASIC) 261 */ 262void dcn351_update_bw_bounding_box_fpu(struct dc *dc, 263 struct clk_bw_params *bw_params) 264{ 265 unsigned int i, closest_clk_lvl; 266 int j; 267 struct clk_limit_table *clk_table = &bw_params->clk_table; 268 struct _vcs_dpi_voltage_scaling_st *clock_limits = 269 dc->scratch.update_bw_bounding_box.clock_limits; 270 int max_dispclk_mhz = 0, max_dppclk_mhz = 0; 271 272 dc_assert_fp_enabled(); 273 274 dcn3_51_ip.max_num_otg = 275 dc->res_pool->res_cap->num_timing_generator; 276 dcn3_51_ip.max_num_dpp = dc->res_pool->pipe_count; 277 dcn3_51_soc.num_chans = bw_params->num_channels; 278 279 ASSERT(clk_table->num_entries); 280 281 /* Prepass to find max clocks independent of voltage level. */ 282 for (i = 0; i < clk_table->num_entries; ++i) { 283 if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) 284 max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; 285 if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) 286 max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; 287 } 288 289 for (i = 0; i < clk_table->num_entries; i++) { 290 /* loop backwards*/ 291 for (closest_clk_lvl = 0, j = dcn3_51_soc.num_states - 1; 292 j >= 0; j--) { 293 if (dcn3_51_soc.clock_limits[j].dcfclk_mhz <= 294 clk_table->entries[i].dcfclk_mhz) { 295 closest_clk_lvl = j; 296 break; 297 } 298 } 299 if (clk_table->num_entries == 1) { 300 /*smu gives one DPM level, let's take the highest one*/ 301 closest_clk_lvl = dcn3_51_soc.num_states - 1; 302 } 303 304 clock_limits[i].state = i; 305 306 /* Clocks dependent on voltage level. */ 307 clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; 308 if (clk_table->num_entries == 1 && 309 clock_limits[i].dcfclk_mhz < 310 dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { 311 /*SMU fix not released yet*/ 312 clock_limits[i].dcfclk_mhz = 313 dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz; 314 } 315 316 clock_limits[i].fabricclk_mhz = 317 clk_table->entries[i].fclk_mhz; 318 clock_limits[i].socclk_mhz = 319 clk_table->entries[i].socclk_mhz; 320 321 if (clk_table->entries[i].memclk_mhz && 322 clk_table->entries[i].wck_ratio) 323 clock_limits[i].dram_speed_mts = 324 clk_table->entries[i].memclk_mhz * 2 * 325 clk_table->entries[i].wck_ratio; 326 327 /* Clocks independent of voltage level. */ 328 clock_limits[i].dispclk_mhz = max_dispclk_mhz ? 329 max_dispclk_mhz : 330 dcn3_51_soc.clock_limits[closest_clk_lvl].dispclk_mhz; 331 332 clock_limits[i].dppclk_mhz = max_dppclk_mhz ? 333 max_dppclk_mhz : 334 dcn3_51_soc.clock_limits[closest_clk_lvl].dppclk_mhz; 335 336 clock_limits[i].dram_bw_per_chan_gbps = 337 dcn3_51_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; 338 clock_limits[i].dscclk_mhz = 339 dcn3_51_soc.clock_limits[closest_clk_lvl].dscclk_mhz; 340 clock_limits[i].dtbclk_mhz = 341 dcn3_51_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; 342 clock_limits[i].phyclk_d18_mhz = 343 dcn3_51_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; 344 clock_limits[i].phyclk_mhz = 345 dcn3_51_soc.clock_limits[closest_clk_lvl].phyclk_mhz; 346 } 347 348 memcpy(dcn3_51_soc.clock_limits, clock_limits, 349 sizeof(dcn3_51_soc.clock_limits)); 350 351 if (clk_table->num_entries) 352 dcn3_51_soc.num_states = clk_table->num_entries; 353 354 if (max_dispclk_mhz) { 355 dcn3_51_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; 356 dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; 357 } 358 if ((int)(dcn3_51_soc.dram_clock_change_latency_us * 1000) 359 != dc->debug.dram_clock_change_latency_ns 360 && dc->debug.dram_clock_change_latency_ns) { 361 dcn3_51_soc.dram_clock_change_latency_us = 362 dc->debug.dram_clock_change_latency_ns / 1000.0; 363 } 364 365 if (dc->bb_overrides.dram_clock_change_latency_ns > 0) 366 dcn3_51_soc.dram_clock_change_latency_us = 367 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 368 369 if (dc->bb_overrides.sr_exit_time_ns > 0) 370 dcn3_51_soc.sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0; 371 372 if (dc->bb_overrides.sr_enter_plus_exit_time_ns > 0) 373 dcn3_51_soc.sr_enter_plus_exit_time_us = 374 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; 375 376 if (dc->bb_overrides.sr_exit_z8_time_ns > 0) 377 dcn3_51_soc.sr_exit_z8_time_us = dc->bb_overrides.sr_exit_z8_time_ns / 1000.0; 378 379 if (dc->bb_overrides.sr_enter_plus_exit_z8_time_ns > 0) 380 dcn3_51_soc.sr_enter_plus_exit_z8_time_us = 381 dc->bb_overrides.sr_enter_plus_exit_z8_time_ns / 1000.0; 382 383 /*temp till dml2 fully work without dml1*/ 384 dml_init_instance(&dc->dml, &dcn3_51_soc, &dcn3_51_ip, 385 DML_PROJECT_DCN31); 386 387 /*copy to dml2, before dml2_create*/ 388 if (clk_table->num_entries > 2) { 389 390 for (i = 0; i < clk_table->num_entries; i++) { 391 dc->dml2_options.bbox_overrides.clks_table.num_states = 392 clk_table->num_entries; 393 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz = 394 clock_limits[i].dcfclk_mhz; 395 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz = 396 clock_limits[i].fabricclk_mhz; 397 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz = 398 clock_limits[i].dispclk_mhz; 399 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz = 400 clock_limits[i].dppclk_mhz; 401 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz = 402 clock_limits[i].socclk_mhz; 403 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz = 404 clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio; 405 dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz = 406 clock_limits[i].dtbclk_mhz; 407 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels = 408 clk_table->num_entries; 409 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels = 410 clk_table->num_entries; 411 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels = 412 clk_table->num_entries; 413 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels = 414 clk_table->num_entries; 415 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels = 416 clk_table->num_entries; 417 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels = 418 clk_table->num_entries; 419 dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dtbclk_levels = 420 clk_table->num_entries; 421 } 422 } 423 424 /* Update latency values */ 425 dc->dml2_options.bbox_overrides.dram_clock_change_latency_us = dcn3_51_soc.dram_clock_change_latency_us; 426 427 dc->dml2_options.bbox_overrides.sr_exit_latency_us = dcn3_51_soc.sr_exit_time_us; 428 dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us = dcn3_51_soc.sr_enter_plus_exit_time_us; 429 430 dc->dml2_options.bbox_overrides.sr_exit_z8_time_us = dcn3_51_soc.sr_exit_z8_time_us; 431 dc->dml2_options.bbox_overrides.sr_enter_plus_exit_z8_time_us = dcn3_51_soc.sr_enter_plus_exit_z8_time_us; 432} 433 434static bool is_dual_plane(enum surface_pixel_format format) 435{ 436 return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || 437 format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA; 438} 439 440/* 441 * micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing 442 * 443 * @param: num_us: number of microseconds 444 * @return: number of vertical lines. If exact number of vertical lines is not found then 445 * it will round up to next number of lines to guarantee num_us 446 */ 447static unsigned int micro_sec_to_vert_lines(unsigned int num_us, struct dc_crtc_timing *timing) 448{ 449 unsigned int num_lines = 0; 450 unsigned int lines_time_in_ns = 1000.0 * 451 (((float)timing->h_total * 1000.0) / 452 ((float)timing->pix_clk_100hz / 10.0)); 453 454 num_lines = dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0); 455 456 return num_lines; 457} 458 459static unsigned int get_vertical_back_porch(struct dc_crtc_timing *timing) 460{ 461 unsigned int v_active = 0, v_blank = 0, v_back_porch = 0; 462 463 v_active = timing->v_border_top + timing->v_addressable + timing->v_border_bottom; 464 v_blank = timing->v_total - v_active; 465 v_back_porch = v_blank - timing->v_front_porch - timing->v_sync_width; 466 467 return v_back_porch; 468} 469 470int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc, 471 struct dc_state *context, 472 display_e2e_pipe_params_st *pipes, 473 bool fast_validate) 474{ 475 int i, pipe_cnt; 476 struct resource_context *res_ctx = &context->res_ctx; 477 struct pipe_ctx *pipe; 478 bool upscaled = false; 479 const unsigned int max_allowed_vblank_nom = 1023; 480 481 dcn31_populate_dml_pipes_from_context(dc, context, pipes, 482 fast_validate); 483 484 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { 485 struct dc_crtc_timing *timing; 486 unsigned int num_lines = 0; 487 unsigned int v_back_porch = 0; 488 489 if (!res_ctx->pipe_ctx[i].stream) 490 continue; 491 492 pipe = &res_ctx->pipe_ctx[i]; 493 timing = &pipe->stream->timing; 494 495 num_lines = micro_sec_to_vert_lines(dcn3_51_ip.VBlankNomDefaultUS, timing); 496 v_back_porch = get_vertical_back_porch(timing); 497 498 if (pipe->stream->adjust.v_total_max == 499 pipe->stream->adjust.v_total_min && 500 pipe->stream->adjust.v_total_min > timing->v_total) { 501 pipes[pipe_cnt].pipe.dest.vtotal = 502 pipe->stream->adjust.v_total_min; 503 pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - 504 pipes[pipe_cnt].pipe.dest.vactive; 505 } 506 507 pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; 508 pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines); 509 // vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2) 510 // + 2 is because 511 // 1 -> VStartup_start should be 1 line before VSync 512 // 1 -> always reserve 1 line between start of vblank to vstartup signal 513 pipes[pipe_cnt].pipe.dest.vblank_nom = 514 max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2); 515 pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom); 516 517 if (pipe->plane_state && 518 (pipe->plane_state->src_rect.height < 519 pipe->plane_state->dst_rect.height || 520 pipe->plane_state->src_rect.width < 521 pipe->plane_state->dst_rect.width)) 522 upscaled = true; 523 524 /* 525 * Immediate flip can be set dynamically after enabling the 526 * plane. We need to require support for immediate flip or 527 * underflow can be intermittently experienced depending on peak 528 * b/w requirements. 529 */ 530 pipes[pipe_cnt].pipe.src.immediate_flip = true; 531 532 pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; 533 534 DC_FP_START(); 535 dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt); 536 DC_FP_END(); 537 538 pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; 539 pipes[pipe_cnt].pipe.src.dcc_rate = 3; 540 pipes[pipe_cnt].dout.dsc_input_bpc = 0; 541 pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; 542 543 if (pipes[pipe_cnt].dout.dsc_enable) { 544 switch (timing->display_color_depth) { 545 case COLOR_DEPTH_888: 546 pipes[pipe_cnt].dout.dsc_input_bpc = 8; 547 break; 548 case COLOR_DEPTH_101010: 549 pipes[pipe_cnt].dout.dsc_input_bpc = 10; 550 break; 551 case COLOR_DEPTH_121212: 552 pipes[pipe_cnt].dout.dsc_input_bpc = 12; 553 break; 554 default: 555 ASSERT(0); 556 break; 557 } 558 } 559 560 pipe_cnt++; 561 } 562 563 context->bw_ctx.dml.ip.det_buffer_size_kbytes = 384;/*per guide*/ 564 dc->config.enable_4to1MPC = false; 565 566 if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) { 567 if (is_dual_plane(pipe->plane_state->format) 568 && pipe->plane_state->src_rect.width <= 1920 && 569 pipe->plane_state->src_rect.height <= 1080) { 570 dc->config.enable_4to1MPC = true; 571 } else if (!is_dual_plane(pipe->plane_state->format) && 572 pipe->plane_state->src_rect.width <= 5120) { 573 /* 574 * Limit to 5k max to avoid forced pipe split when there 575 * is not enough detile for swath 576 */ 577 context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192; 578 pipes[0].pipe.src.unbounded_req_mode = true; 579 } 580 } else if (context->stream_count >= 581 dc->debug.crb_alloc_policy_min_disp_count && 582 dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) { 583 context->bw_ctx.dml.ip.det_buffer_size_kbytes = 584 dc->debug.crb_alloc_policy * 64; 585 } else if (context->stream_count >= 3 && upscaled) { 586 context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192; 587 } 588 589 for (i = 0; i < dc->res_pool->pipe_count; i++) { 590 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 591 592 if (!pipe->stream) 593 continue; 594 595 if (pipe->stream->signal == SIGNAL_TYPE_EDP && 596 dc->debug.seamless_boot_odm_combine && 597 pipe->stream->apply_seamless_boot_optimization) { 598 599 if (pipe->stream->apply_boot_odm_mode == 600 dm_odm_combine_policy_2to1) { 601 context->bw_ctx.dml.vba.ODMCombinePolicy = 602 dm_odm_combine_policy_2to1; 603 break; 604 } 605 } 606 } 607 608 return pipe_cnt; 609} 610 611void dcn351_decide_zstate_support(struct dc *dc, struct dc_state *context) 612{ 613 enum dcn_zstate_support_state support = DCN_ZSTATE_SUPPORT_DISALLOW; 614 unsigned int i, plane_count = 0; 615 616 for (i = 0; i < dc->res_pool->pipe_count; i++) { 617 if (context->res_ctx.pipe_ctx[i].plane_state) 618 plane_count++; 619 } 620 621 /*dcn351 does not support z9/z10*/ 622 if (context->stream_count == 0 || plane_count == 0) { 623 support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY; 624 } else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { 625 struct dc_link *link = context->streams[0]->sink->link; 626 bool is_pwrseq0 = link && link->link_index == 0; 627 bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 || 628 link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr); 629 bool is_replay = link && link->replay_settings.replay_feature_enabled; 630 int minmum_z8_residency = 631 dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; 632 bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; 633 634 /*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/ 635 if (is_pwrseq0 && (is_psr || is_replay)) 636 support = allow_z8 ? allow_z8 : DCN_ZSTATE_SUPPORT_DISALLOW; 637 } 638 context->bw_ctx.bw.dcn.clk.zstate_support = support; 639} 640