2562 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright 2021 Advanced Micro Devices, Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: AMD24 *25 */26 27#include "resource.h"28#include "clk_mgr.h"29#include "dchubbub.h"30#include "dcn20/dcn20_resource.h"31#include "dcn21/dcn21_resource.h"32#include "clk_mgr/dcn21/rn_clk_mgr.h"33 34#include "link.h"35#include "dcn20_fpu.h"36#include "dc_state_priv.h"37 38#define DC_LOGGER \39 dc->ctx->logger40#define DC_LOGGER_INIT(logger)41 42#ifndef MAX43#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))44#endif45#ifndef MIN46#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))47#endif48 49/* Constant */50#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */51 52/**53 * DOC: DCN2x FPU manipulation Overview54 *55 * The DCN architecture relies on FPU operations, which require special56 * compilation flags and the use of kernel_fpu_begin/end functions; ideally, we57 * want to avoid spreading FPU access across multiple files. With this idea in58 * mind, this file aims to centralize all DCN20 and DCN2.1 (DCN2x) functions59 * that require FPU access in a single place. Code in this file follows the60 * following code pattern:61 *62 * 1. Functions that use FPU operations should be isolated in static functions.63 * 2. The FPU functions should have the noinline attribute to ensure anything64 * that deals with FP register is contained within this call.65 * 3. All function that needs to be accessed outside this file requires a66 * public interface that not uses any FPU reference.67 * 4. Developers **must not** use DC_FP_START/END in this file, but they need68 * to ensure that the caller invokes it before access any function available69 * in this file. For this reason, public functions in this file must invoke70 * dc_assert_fp_enabled();71 *72 * Let's expand a little bit more the idea in the code pattern. To fully73 * isolate FPU operations in a single place, we must avoid situations where74 * compilers spill FP values to registers due to FP enable in a specific C75 * file. Note that even if we isolate all FPU functions in a single file and76 * call its interface from other files, the compiler might enable the use of77 * FPU before we call DC_FP_START. Nevertheless, it is the programmer's78 * responsibility to invoke DC_FP_START/END in the correct place. To highlight79 * situations where developers forgot to use the FP protection before calling80 * the DC FPU interface functions, we introduce a helper that checks if the81 * function is invoked under FP protection. If not, it will trigger a kernel82 * warning.83 */84 85struct _vcs_dpi_ip_params_st dcn2_0_ip = {86 .odm_capable = 1,87 .gpuvm_enable = 0,88 .hostvm_enable = 0,89 .gpuvm_max_page_table_levels = 4,90 .hostvm_max_page_table_levels = 4,91 .hostvm_cached_page_table_levels = 0,92 .pte_group_size_bytes = 2048,93 .num_dsc = 6,94 .rob_buffer_size_kbytes = 168,95 .det_buffer_size_kbytes = 164,96 .dpte_buffer_size_in_pte_reqs_luma = 84,97 .pde_proc_buffer_size_64k_reqs = 48,98 .dpp_output_buffer_pixels = 2560,99 .opp_output_buffer_lines = 1,100 .pixel_chunk_size_kbytes = 8,101 .pte_chunk_size_kbytes = 2,102 .meta_chunk_size_kbytes = 2,103 .writeback_chunk_size_kbytes = 2,104 .line_buffer_size_bits = 789504,105 .is_line_buffer_bpp_fixed = 0,106 .line_buffer_fixed_bpp = 0,107 .dcc_supported = true,108 .max_line_buffer_lines = 12,109 .writeback_luma_buffer_size_kbytes = 12,110 .writeback_chroma_buffer_size_kbytes = 8,111 .writeback_chroma_line_buffer_width_pixels = 4,112 .writeback_max_hscl_ratio = 1,113 .writeback_max_vscl_ratio = 1,114 .writeback_min_hscl_ratio = 1,115 .writeback_min_vscl_ratio = 1,116 .writeback_max_hscl_taps = 12,117 .writeback_max_vscl_taps = 12,118 .writeback_line_buffer_luma_buffer_size = 0,119 .writeback_line_buffer_chroma_buffer_size = 14643,120 .cursor_buffer_size = 8,121 .cursor_chunk_size = 2,122 .max_num_otg = 6,123 .max_num_dpp = 6,124 .max_num_wb = 1,125 .max_dchub_pscl_bw_pix_per_clk = 4,126 .max_pscl_lb_bw_pix_per_clk = 2,127 .max_lb_vscl_bw_pix_per_clk = 4,128 .max_vscl_hscl_bw_pix_per_clk = 4,129 .max_hscl_ratio = 8,130 .max_vscl_ratio = 8,131 .hscl_mults = 4,132 .vscl_mults = 4,133 .max_hscl_taps = 8,134 .max_vscl_taps = 8,135 .dispclk_ramp_margin_percent = 1,136 .underscan_factor = 1.10,137 .min_vblank_lines = 32, //138 .dppclk_delay_subtotal = 77, //139 .dppclk_delay_scl_lb_only = 16,140 .dppclk_delay_scl = 50,141 .dppclk_delay_cnvc_formatter = 8,142 .dppclk_delay_cnvc_cursor = 6,143 .dispclk_delay_subtotal = 87, //144 .dcfclk_cstate_latency = 10, // SRExitTime145 .max_inter_dcn_tile_repeaters = 8,146 .xfc_supported = true,147 .xfc_fill_bw_overhead_percent = 10.0,148 .xfc_fill_constant_bytes = 0,149 .number_of_cursors = 1,150};151 152struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {153 .odm_capable = 1,154 .gpuvm_enable = 0,155 .hostvm_enable = 0,156 .gpuvm_max_page_table_levels = 4,157 .hostvm_max_page_table_levels = 4,158 .hostvm_cached_page_table_levels = 0,159 .num_dsc = 5,160 .rob_buffer_size_kbytes = 168,161 .det_buffer_size_kbytes = 164,162 .dpte_buffer_size_in_pte_reqs_luma = 84,163 .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo164 .dpp_output_buffer_pixels = 2560,165 .opp_output_buffer_lines = 1,166 .pixel_chunk_size_kbytes = 8,167 .pte_enable = 1,168 .max_page_table_levels = 4,169 .pte_chunk_size_kbytes = 2,170 .meta_chunk_size_kbytes = 2,171 .writeback_chunk_size_kbytes = 2,172 .line_buffer_size_bits = 789504,173 .is_line_buffer_bpp_fixed = 0,174 .line_buffer_fixed_bpp = 0,175 .dcc_supported = true,176 .max_line_buffer_lines = 12,177 .writeback_luma_buffer_size_kbytes = 12,178 .writeback_chroma_buffer_size_kbytes = 8,179 .writeback_chroma_line_buffer_width_pixels = 4,180 .writeback_max_hscl_ratio = 1,181 .writeback_max_vscl_ratio = 1,182 .writeback_min_hscl_ratio = 1,183 .writeback_min_vscl_ratio = 1,184 .writeback_max_hscl_taps = 12,185 .writeback_max_vscl_taps = 12,186 .writeback_line_buffer_luma_buffer_size = 0,187 .writeback_line_buffer_chroma_buffer_size = 14643,188 .cursor_buffer_size = 8,189 .cursor_chunk_size = 2,190 .max_num_otg = 5,191 .max_num_dpp = 5,192 .max_num_wb = 1,193 .max_dchub_pscl_bw_pix_per_clk = 4,194 .max_pscl_lb_bw_pix_per_clk = 2,195 .max_lb_vscl_bw_pix_per_clk = 4,196 .max_vscl_hscl_bw_pix_per_clk = 4,197 .max_hscl_ratio = 8,198 .max_vscl_ratio = 8,199 .hscl_mults = 4,200 .vscl_mults = 4,201 .max_hscl_taps = 8,202 .max_vscl_taps = 8,203 .dispclk_ramp_margin_percent = 1,204 .underscan_factor = 1.10,205 .min_vblank_lines = 32, //206 .dppclk_delay_subtotal = 77, //207 .dppclk_delay_scl_lb_only = 16,208 .dppclk_delay_scl = 50,209 .dppclk_delay_cnvc_formatter = 8,210 .dppclk_delay_cnvc_cursor = 6,211 .dispclk_delay_subtotal = 87, //212 .dcfclk_cstate_latency = 10, // SRExitTime213 .max_inter_dcn_tile_repeaters = 8,214 .xfc_supported = true,215 .xfc_fill_bw_overhead_percent = 10.0,216 .xfc_fill_constant_bytes = 0,217 .ptoi_supported = 0,218 .number_of_cursors = 1,219};220 221struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {222 /* Defaults that get patched on driver load from firmware. */223 .clock_limits = {224 {225 .state = 0,226 .dcfclk_mhz = 560.0,227 .fabricclk_mhz = 560.0,228 .dispclk_mhz = 513.0,229 .dppclk_mhz = 513.0,230 .phyclk_mhz = 540.0,231 .socclk_mhz = 560.0,232 .dscclk_mhz = 171.0,233 .dram_speed_mts = 8960.0,234 },235 {236 .state = 1,237 .dcfclk_mhz = 694.0,238 .fabricclk_mhz = 694.0,239 .dispclk_mhz = 642.0,240 .dppclk_mhz = 642.0,241 .phyclk_mhz = 600.0,242 .socclk_mhz = 694.0,243 .dscclk_mhz = 214.0,244 .dram_speed_mts = 11104.0,245 },246 {247 .state = 2,248 .dcfclk_mhz = 875.0,249 .fabricclk_mhz = 875.0,250 .dispclk_mhz = 734.0,251 .dppclk_mhz = 734.0,252 .phyclk_mhz = 810.0,253 .socclk_mhz = 875.0,254 .dscclk_mhz = 245.0,255 .dram_speed_mts = 14000.0,256 },257 {258 .state = 3,259 .dcfclk_mhz = 1000.0,260 .fabricclk_mhz = 1000.0,261 .dispclk_mhz = 1100.0,262 .dppclk_mhz = 1100.0,263 .phyclk_mhz = 810.0,264 .socclk_mhz = 1000.0,265 .dscclk_mhz = 367.0,266 .dram_speed_mts = 16000.0,267 },268 {269 .state = 4,270 .dcfclk_mhz = 1200.0,271 .fabricclk_mhz = 1200.0,272 .dispclk_mhz = 1284.0,273 .dppclk_mhz = 1284.0,274 .phyclk_mhz = 810.0,275 .socclk_mhz = 1200.0,276 .dscclk_mhz = 428.0,277 .dram_speed_mts = 16000.0,278 },279 /*Extra state, no dispclk ramping*/280 {281 .state = 5,282 .dcfclk_mhz = 1200.0,283 .fabricclk_mhz = 1200.0,284 .dispclk_mhz = 1284.0,285 .dppclk_mhz = 1284.0,286 .phyclk_mhz = 810.0,287 .socclk_mhz = 1200.0,288 .dscclk_mhz = 428.0,289 .dram_speed_mts = 16000.0,290 },291 },292 .num_states = 5,293 .sr_exit_time_us = 8.6,294 .sr_enter_plus_exit_time_us = 10.9,295 .urgent_latency_us = 4.0,296 .urgent_latency_pixel_data_only_us = 4.0,297 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,298 .urgent_latency_vm_data_only_us = 4.0,299 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,300 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,301 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,302 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,303 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,304 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,305 .max_avg_sdp_bw_use_normal_percent = 40.0,306 .max_avg_dram_bw_use_normal_percent = 40.0,307 .writeback_latency_us = 12.0,308 .ideal_dram_bw_after_urgent_percent = 40.0,309 .max_request_size_bytes = 256,310 .dram_channel_width_bytes = 2,311 .fabric_datapath_to_dcn_data_return_bytes = 64,312 .dcn_downspread_percent = 0.5,313 .downspread_percent = 0.38,314 .dram_page_open_time_ns = 50.0,315 .dram_rw_turnaround_time_ns = 17.5,316 .dram_return_buffer_per_channel_bytes = 8192,317 .round_trip_ping_latency_dcfclk_cycles = 131,318 .urgent_out_of_order_return_per_channel_bytes = 256,319 .channel_interleave_bytes = 256,320 .num_banks = 8,321 .num_chans = 16,322 .vmm_page_size_bytes = 4096,323 .dram_clock_change_latency_us = 404.0,324 .dummy_pstate_latency_us = 5.0,325 .writeback_dram_clock_change_latency_us = 23.0,326 .return_bus_width_bytes = 64,327 .dispclk_dppclk_vco_speed_mhz = 3850,328 .xfc_bus_transport_time_us = 20,329 .xfc_xbuf_latency_tolerance_us = 4,330 .use_urgent_burst_bw = 0331};332 333struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {334 .clock_limits = {335 {336 .state = 0,337 .dcfclk_mhz = 560.0,338 .fabricclk_mhz = 560.0,339 .dispclk_mhz = 513.0,340 .dppclk_mhz = 513.0,341 .phyclk_mhz = 540.0,342 .socclk_mhz = 560.0,343 .dscclk_mhz = 171.0,344 .dram_speed_mts = 8960.0,345 },346 {347 .state = 1,348 .dcfclk_mhz = 694.0,349 .fabricclk_mhz = 694.0,350 .dispclk_mhz = 642.0,351 .dppclk_mhz = 642.0,352 .phyclk_mhz = 600.0,353 .socclk_mhz = 694.0,354 .dscclk_mhz = 214.0,355 .dram_speed_mts = 11104.0,356 },357 {358 .state = 2,359 .dcfclk_mhz = 875.0,360 .fabricclk_mhz = 875.0,361 .dispclk_mhz = 734.0,362 .dppclk_mhz = 734.0,363 .phyclk_mhz = 810.0,364 .socclk_mhz = 875.0,365 .dscclk_mhz = 245.0,366 .dram_speed_mts = 14000.0,367 },368 {369 .state = 3,370 .dcfclk_mhz = 1000.0,371 .fabricclk_mhz = 1000.0,372 .dispclk_mhz = 1100.0,373 .dppclk_mhz = 1100.0,374 .phyclk_mhz = 810.0,375 .socclk_mhz = 1000.0,376 .dscclk_mhz = 367.0,377 .dram_speed_mts = 16000.0,378 },379 {380 .state = 4,381 .dcfclk_mhz = 1200.0,382 .fabricclk_mhz = 1200.0,383 .dispclk_mhz = 1284.0,384 .dppclk_mhz = 1284.0,385 .phyclk_mhz = 810.0,386 .socclk_mhz = 1200.0,387 .dscclk_mhz = 428.0,388 .dram_speed_mts = 16000.0,389 },390 /*Extra state, no dispclk ramping*/391 {392 .state = 5,393 .dcfclk_mhz = 1200.0,394 .fabricclk_mhz = 1200.0,395 .dispclk_mhz = 1284.0,396 .dppclk_mhz = 1284.0,397 .phyclk_mhz = 810.0,398 .socclk_mhz = 1200.0,399 .dscclk_mhz = 428.0,400 .dram_speed_mts = 16000.0,401 },402 },403 .num_states = 5,404 .sr_exit_time_us = 11.6,405 .sr_enter_plus_exit_time_us = 13.9,406 .urgent_latency_us = 4.0,407 .urgent_latency_pixel_data_only_us = 4.0,408 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,409 .urgent_latency_vm_data_only_us = 4.0,410 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,411 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,412 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,413 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,414 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,415 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,416 .max_avg_sdp_bw_use_normal_percent = 40.0,417 .max_avg_dram_bw_use_normal_percent = 40.0,418 .writeback_latency_us = 12.0,419 .ideal_dram_bw_after_urgent_percent = 40.0,420 .max_request_size_bytes = 256,421 .dram_channel_width_bytes = 2,422 .fabric_datapath_to_dcn_data_return_bytes = 64,423 .dcn_downspread_percent = 0.5,424 .downspread_percent = 0.38,425 .dram_page_open_time_ns = 50.0,426 .dram_rw_turnaround_time_ns = 17.5,427 .dram_return_buffer_per_channel_bytes = 8192,428 .round_trip_ping_latency_dcfclk_cycles = 131,429 .urgent_out_of_order_return_per_channel_bytes = 256,430 .channel_interleave_bytes = 256,431 .num_banks = 8,432 .num_chans = 8,433 .vmm_page_size_bytes = 4096,434 .dram_clock_change_latency_us = 404.0,435 .dummy_pstate_latency_us = 5.0,436 .writeback_dram_clock_change_latency_us = 23.0,437 .return_bus_width_bytes = 64,438 .dispclk_dppclk_vco_speed_mhz = 3850,439 .xfc_bus_transport_time_us = 20,440 .xfc_xbuf_latency_tolerance_us = 4,441 .use_urgent_burst_bw = 0442};443 444struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = {445 .clock_limits = {446 {447 .state = 0,448 .dcfclk_mhz = 560.0,449 .fabricclk_mhz = 560.0,450 .dispclk_mhz = 513.0,451 .dppclk_mhz = 513.0,452 .phyclk_mhz = 540.0,453 .socclk_mhz = 560.0,454 .dscclk_mhz = 171.0,455 .dram_speed_mts = 1069.0,456 },457 {458 .state = 1,459 .dcfclk_mhz = 694.0,460 .fabricclk_mhz = 694.0,461 .dispclk_mhz = 642.0,462 .dppclk_mhz = 642.0,463 .phyclk_mhz = 600.0,464 .socclk_mhz = 694.0,465 .dscclk_mhz = 214.0,466 .dram_speed_mts = 1324.0,467 },468 {469 .state = 2,470 .dcfclk_mhz = 875.0,471 .fabricclk_mhz = 875.0,472 .dispclk_mhz = 734.0,473 .dppclk_mhz = 734.0,474 .phyclk_mhz = 810.0,475 .socclk_mhz = 875.0,476 .dscclk_mhz = 245.0,477 .dram_speed_mts = 1670.0,478 },479 {480 .state = 3,481 .dcfclk_mhz = 1000.0,482 .fabricclk_mhz = 1000.0,483 .dispclk_mhz = 1100.0,484 .dppclk_mhz = 1100.0,485 .phyclk_mhz = 810.0,486 .socclk_mhz = 1000.0,487 .dscclk_mhz = 367.0,488 .dram_speed_mts = 2000.0,489 },490 {491 .state = 4,492 .dcfclk_mhz = 1200.0,493 .fabricclk_mhz = 1200.0,494 .dispclk_mhz = 1284.0,495 .dppclk_mhz = 1284.0,496 .phyclk_mhz = 810.0,497 .socclk_mhz = 1200.0,498 .dscclk_mhz = 428.0,499 .dram_speed_mts = 2000.0,500 },501 {502 .state = 5,503 .dcfclk_mhz = 1200.0,504 .fabricclk_mhz = 1200.0,505 .dispclk_mhz = 1284.0,506 .dppclk_mhz = 1284.0,507 .phyclk_mhz = 810.0,508 .socclk_mhz = 1200.0,509 .dscclk_mhz = 428.0,510 .dram_speed_mts = 2000.0,511 },512 },513 514 .num_states = 5,515 .sr_exit_time_us = 1.9,516 .sr_enter_plus_exit_time_us = 4.4,517 .urgent_latency_us = 3.0,518 .urgent_latency_pixel_data_only_us = 4.0,519 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,520 .urgent_latency_vm_data_only_us = 4.0,521 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,522 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,523 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,524 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,525 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,526 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,527 .max_avg_sdp_bw_use_normal_percent = 40.0,528 .max_avg_dram_bw_use_normal_percent = 40.0,529 .writeback_latency_us = 12.0,530 .ideal_dram_bw_after_urgent_percent = 40.0,531 .max_request_size_bytes = 256,532 .dram_channel_width_bytes = 16,533 .fabric_datapath_to_dcn_data_return_bytes = 64,534 .dcn_downspread_percent = 0.5,535 .downspread_percent = 0.5,536 .dram_page_open_time_ns = 50.0,537 .dram_rw_turnaround_time_ns = 17.5,538 .dram_return_buffer_per_channel_bytes = 8192,539 .round_trip_ping_latency_dcfclk_cycles = 131,540 .urgent_out_of_order_return_per_channel_bytes = 4096,541 .channel_interleave_bytes = 256,542 .num_banks = 8,543 .num_chans = 16,544 .vmm_page_size_bytes = 4096,545 .dram_clock_change_latency_us = 45.0,546 .writeback_dram_clock_change_latency_us = 23.0,547 .return_bus_width_bytes = 64,548 .dispclk_dppclk_vco_speed_mhz = 3850,549 .xfc_bus_transport_time_us = 20,550 .xfc_xbuf_latency_tolerance_us = 50,551 .use_urgent_burst_bw = 0,552};553 554struct _vcs_dpi_ip_params_st dcn2_1_ip = {555 .odm_capable = 1,556 .gpuvm_enable = 1,557 .hostvm_enable = 1,558 .gpuvm_max_page_table_levels = 1,559 .hostvm_max_page_table_levels = 4,560 .hostvm_cached_page_table_levels = 2,561 .num_dsc = 3,562 .rob_buffer_size_kbytes = 168,563 .det_buffer_size_kbytes = 164,564 .dpte_buffer_size_in_pte_reqs_luma = 44,565 .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo566 .dpp_output_buffer_pixels = 2560,567 .opp_output_buffer_lines = 1,568 .pixel_chunk_size_kbytes = 8,569 .pte_enable = 1,570 .max_page_table_levels = 4,571 .pte_chunk_size_kbytes = 2,572 .meta_chunk_size_kbytes = 2,573 .min_meta_chunk_size_bytes = 256,574 .writeback_chunk_size_kbytes = 2,575 .line_buffer_size_bits = 789504,576 .is_line_buffer_bpp_fixed = 0,577 .line_buffer_fixed_bpp = 0,578 .dcc_supported = true,579 .max_line_buffer_lines = 12,580 .writeback_luma_buffer_size_kbytes = 12,581 .writeback_chroma_buffer_size_kbytes = 8,582 .writeback_chroma_line_buffer_width_pixels = 4,583 .writeback_max_hscl_ratio = 1,584 .writeback_max_vscl_ratio = 1,585 .writeback_min_hscl_ratio = 1,586 .writeback_min_vscl_ratio = 1,587 .writeback_max_hscl_taps = 12,588 .writeback_max_vscl_taps = 12,589 .writeback_line_buffer_luma_buffer_size = 0,590 .writeback_line_buffer_chroma_buffer_size = 14643,591 .cursor_buffer_size = 8,592 .cursor_chunk_size = 2,593 .max_num_otg = 4,594 .max_num_dpp = 4,595 .max_num_wb = 1,596 .max_dchub_pscl_bw_pix_per_clk = 4,597 .max_pscl_lb_bw_pix_per_clk = 2,598 .max_lb_vscl_bw_pix_per_clk = 4,599 .max_vscl_hscl_bw_pix_per_clk = 4,600 .max_hscl_ratio = 4,601 .max_vscl_ratio = 4,602 .hscl_mults = 4,603 .vscl_mults = 4,604 .max_hscl_taps = 8,605 .max_vscl_taps = 8,606 .dispclk_ramp_margin_percent = 1,607 .underscan_factor = 1.10,608 .min_vblank_lines = 32, //609 .dppclk_delay_subtotal = 77, //610 .dppclk_delay_scl_lb_only = 16,611 .dppclk_delay_scl = 50,612 .dppclk_delay_cnvc_formatter = 8,613 .dppclk_delay_cnvc_cursor = 6,614 .dispclk_delay_subtotal = 87, //615 .dcfclk_cstate_latency = 10, // SRExitTime616 .max_inter_dcn_tile_repeaters = 8,617 618 .xfc_supported = false,619 .xfc_fill_bw_overhead_percent = 10.0,620 .xfc_fill_constant_bytes = 0,621 .ptoi_supported = 0,622 .number_of_cursors = 1,623};624 625struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {626 .clock_limits = {627 {628 .state = 0,629 .dcfclk_mhz = 400.0,630 .fabricclk_mhz = 400.0,631 .dispclk_mhz = 600.0,632 .dppclk_mhz = 400.00,633 .phyclk_mhz = 600.0,634 .socclk_mhz = 278.0,635 .dscclk_mhz = 205.67,636 .dram_speed_mts = 1600.0,637 },638 {639 .state = 1,640 .dcfclk_mhz = 464.52,641 .fabricclk_mhz = 800.0,642 .dispclk_mhz = 654.55,643 .dppclk_mhz = 626.09,644 .phyclk_mhz = 600.0,645 .socclk_mhz = 278.0,646 .dscclk_mhz = 205.67,647 .dram_speed_mts = 1600.0,648 },649 {650 .state = 2,651 .dcfclk_mhz = 514.29,652 .fabricclk_mhz = 933.0,653 .dispclk_mhz = 757.89,654 .dppclk_mhz = 685.71,655 .phyclk_mhz = 600.0,656 .socclk_mhz = 278.0,657 .dscclk_mhz = 287.67,658 .dram_speed_mts = 1866.0,659 },660 {661 .state = 3,662 .dcfclk_mhz = 576.00,663 .fabricclk_mhz = 1067.0,664 .dispclk_mhz = 847.06,665 .dppclk_mhz = 757.89,666 .phyclk_mhz = 600.0,667 .socclk_mhz = 715.0,668 .dscclk_mhz = 318.334,669 .dram_speed_mts = 2134.0,670 },671 {672 .state = 4,673 .dcfclk_mhz = 626.09,674 .fabricclk_mhz = 1200.0,675 .dispclk_mhz = 900.00,676 .dppclk_mhz = 847.06,677 .phyclk_mhz = 810.0,678 .socclk_mhz = 953.0,679 .dscclk_mhz = 300.0,680 .dram_speed_mts = 2400.0,681 },682 {683 .state = 5,684 .dcfclk_mhz = 685.71,685 .fabricclk_mhz = 1333.0,686 .dispclk_mhz = 1028.57,687 .dppclk_mhz = 960.00,688 .phyclk_mhz = 810.0,689 .socclk_mhz = 278.0,690 .dscclk_mhz = 342.86,691 .dram_speed_mts = 2666.0,692 },693 {694 .state = 6,695 .dcfclk_mhz = 757.89,696 .fabricclk_mhz = 1467.0,697 .dispclk_mhz = 1107.69,698 .dppclk_mhz = 1028.57,699 .phyclk_mhz = 810.0,700 .socclk_mhz = 715.0,701 .dscclk_mhz = 369.23,702 .dram_speed_mts = 3200.0,703 },704 {705 .state = 7,706 .dcfclk_mhz = 847.06,707 .fabricclk_mhz = 1600.0,708 .dispclk_mhz = 1395.0,709 .dppclk_mhz = 1285.00,710 .phyclk_mhz = 1325.0,711 .socclk_mhz = 953.0,712 .dscclk_mhz = 489.0,713 .dram_speed_mts = 4266.0,714 },715 /*Extra state, no dispclk ramping*/716 {717 .state = 8,718 .dcfclk_mhz = 847.06,719 .fabricclk_mhz = 1600.0,720 .dispclk_mhz = 1395.0,721 .dppclk_mhz = 1285.0,722 .phyclk_mhz = 1325.0,723 .socclk_mhz = 953.0,724 .dscclk_mhz = 489.0,725 .dram_speed_mts = 4266.0,726 },727 728 },729 730 .sr_exit_time_us = 12.5,731 .sr_enter_plus_exit_time_us = 17.0,732 .urgent_latency_us = 4.0,733 .urgent_latency_pixel_data_only_us = 4.0,734 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,735 .urgent_latency_vm_data_only_us = 4.0,736 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,737 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,738 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,739 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,740 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,741 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,742 .max_avg_sdp_bw_use_normal_percent = 60.0,743 .max_avg_dram_bw_use_normal_percent = 100.0,744 .writeback_latency_us = 12.0,745 .max_request_size_bytes = 256,746 .dram_channel_width_bytes = 4,747 .fabric_datapath_to_dcn_data_return_bytes = 32,748 .dcn_downspread_percent = 0.5,749 .downspread_percent = 0.38,750 .dram_page_open_time_ns = 50.0,751 .dram_rw_turnaround_time_ns = 17.5,752 .dram_return_buffer_per_channel_bytes = 8192,753 .round_trip_ping_latency_dcfclk_cycles = 128,754 .urgent_out_of_order_return_per_channel_bytes = 4096,755 .channel_interleave_bytes = 256,756 .num_banks = 8,757 .num_chans = 4,758 .vmm_page_size_bytes = 4096,759 .dram_clock_change_latency_us = 23.84,760 .return_bus_width_bytes = 64,761 .dispclk_dppclk_vco_speed_mhz = 3600,762 .xfc_bus_transport_time_us = 4,763 .xfc_xbuf_latency_tolerance_us = 4,764 .use_urgent_burst_bw = 1,765 .num_states = 8766};767 768struct wm_table ddr4_wm_table_gs = {769 .entries = {770 {771 .wm_inst = WM_A,772 .wm_type = WM_TYPE_PSTATE_CHG,773 .pstate_latency_us = 11.72,774 .sr_exit_time_us = 7.09,775 .sr_enter_plus_exit_time_us = 8.14,776 .valid = true,777 },778 {779 .wm_inst = WM_B,780 .wm_type = WM_TYPE_PSTATE_CHG,781 .pstate_latency_us = 11.72,782 .sr_exit_time_us = 10.12,783 .sr_enter_plus_exit_time_us = 11.48,784 .valid = true,785 },786 {787 .wm_inst = WM_C,788 .wm_type = WM_TYPE_PSTATE_CHG,789 .pstate_latency_us = 11.72,790 .sr_exit_time_us = 10.12,791 .sr_enter_plus_exit_time_us = 11.48,792 .valid = true,793 },794 {795 .wm_inst = WM_D,796 .wm_type = WM_TYPE_PSTATE_CHG,797 .pstate_latency_us = 11.72,798 .sr_exit_time_us = 10.12,799 .sr_enter_plus_exit_time_us = 11.48,800 .valid = true,801 },802 }803};804 805struct wm_table lpddr4_wm_table_gs = {806 .entries = {807 {808 .wm_inst = WM_A,809 .wm_type = WM_TYPE_PSTATE_CHG,810 .pstate_latency_us = 11.65333,811 .sr_exit_time_us = 5.32,812 .sr_enter_plus_exit_time_us = 6.38,813 .valid = true,814 },815 {816 .wm_inst = WM_B,817 .wm_type = WM_TYPE_PSTATE_CHG,818 .pstate_latency_us = 11.65333,819 .sr_exit_time_us = 9.82,820 .sr_enter_plus_exit_time_us = 11.196,821 .valid = true,822 },823 {824 .wm_inst = WM_C,825 .wm_type = WM_TYPE_PSTATE_CHG,826 .pstate_latency_us = 11.65333,827 .sr_exit_time_us = 9.89,828 .sr_enter_plus_exit_time_us = 11.24,829 .valid = true,830 },831 {832 .wm_inst = WM_D,833 .wm_type = WM_TYPE_PSTATE_CHG,834 .pstate_latency_us = 11.65333,835 .sr_exit_time_us = 9.748,836 .sr_enter_plus_exit_time_us = 11.102,837 .valid = true,838 },839 }840};841 842struct wm_table lpddr4_wm_table_with_disabled_ppt = {843 .entries = {844 {845 .wm_inst = WM_A,846 .wm_type = WM_TYPE_PSTATE_CHG,847 .pstate_latency_us = 11.65333,848 .sr_exit_time_us = 8.32,849 .sr_enter_plus_exit_time_us = 9.38,850 .valid = true,851 },852 {853 .wm_inst = WM_B,854 .wm_type = WM_TYPE_PSTATE_CHG,855 .pstate_latency_us = 11.65333,856 .sr_exit_time_us = 9.82,857 .sr_enter_plus_exit_time_us = 11.196,858 .valid = true,859 },860 {861 .wm_inst = WM_C,862 .wm_type = WM_TYPE_PSTATE_CHG,863 .pstate_latency_us = 11.65333,864 .sr_exit_time_us = 9.89,865 .sr_enter_plus_exit_time_us = 11.24,866 .valid = true,867 },868 {869 .wm_inst = WM_D,870 .wm_type = WM_TYPE_PSTATE_CHG,871 .pstate_latency_us = 11.65333,872 .sr_exit_time_us = 9.748,873 .sr_enter_plus_exit_time_us = 11.102,874 .valid = true,875 },876 }877};878 879struct wm_table ddr4_wm_table_rn = {880 .entries = {881 {882 .wm_inst = WM_A,883 .wm_type = WM_TYPE_PSTATE_CHG,884 .pstate_latency_us = 11.72,885 .sr_exit_time_us = 11.90,886 .sr_enter_plus_exit_time_us = 12.80,887 .valid = true,888 },889 {890 .wm_inst = WM_B,891 .wm_type = WM_TYPE_PSTATE_CHG,892 .pstate_latency_us = 11.72,893 .sr_exit_time_us = 13.18,894 .sr_enter_plus_exit_time_us = 14.30,895 .valid = true,896 },897 {898 .wm_inst = WM_C,899 .wm_type = WM_TYPE_PSTATE_CHG,900 .pstate_latency_us = 11.72,901 .sr_exit_time_us = 13.18,902 .sr_enter_plus_exit_time_us = 14.30,903 .valid = true,904 },905 {906 .wm_inst = WM_D,907 .wm_type = WM_TYPE_PSTATE_CHG,908 .pstate_latency_us = 11.72,909 .sr_exit_time_us = 13.18,910 .sr_enter_plus_exit_time_us = 14.30,911 .valid = true,912 },913 }914};915 916struct wm_table ddr4_1R_wm_table_rn = {917 .entries = {918 {919 .wm_inst = WM_A,920 .wm_type = WM_TYPE_PSTATE_CHG,921 .pstate_latency_us = 11.72,922 .sr_exit_time_us = 13.90,923 .sr_enter_plus_exit_time_us = 14.80,924 .valid = true,925 },926 {927 .wm_inst = WM_B,928 .wm_type = WM_TYPE_PSTATE_CHG,929 .pstate_latency_us = 11.72,930 .sr_exit_time_us = 13.90,931 .sr_enter_plus_exit_time_us = 14.80,932 .valid = true,933 },934 {935 .wm_inst = WM_C,936 .wm_type = WM_TYPE_PSTATE_CHG,937 .pstate_latency_us = 11.72,938 .sr_exit_time_us = 13.90,939 .sr_enter_plus_exit_time_us = 14.80,940 .valid = true,941 },942 {943 .wm_inst = WM_D,944 .wm_type = WM_TYPE_PSTATE_CHG,945 .pstate_latency_us = 11.72,946 .sr_exit_time_us = 13.90,947 .sr_enter_plus_exit_time_us = 14.80,948 .valid = true,949 },950 }951};952 953struct wm_table lpddr4_wm_table_rn = {954 .entries = {955 {956 .wm_inst = WM_A,957 .wm_type = WM_TYPE_PSTATE_CHG,958 .pstate_latency_us = 11.65333,959 .sr_exit_time_us = 7.32,960 .sr_enter_plus_exit_time_us = 8.38,961 .valid = true,962 },963 {964 .wm_inst = WM_B,965 .wm_type = WM_TYPE_PSTATE_CHG,966 .pstate_latency_us = 11.65333,967 .sr_exit_time_us = 9.82,968 .sr_enter_plus_exit_time_us = 11.196,969 .valid = true,970 },971 {972 .wm_inst = WM_C,973 .wm_type = WM_TYPE_PSTATE_CHG,974 .pstate_latency_us = 11.65333,975 .sr_exit_time_us = 9.89,976 .sr_enter_plus_exit_time_us = 11.24,977 .valid = true,978 },979 {980 .wm_inst = WM_D,981 .wm_type = WM_TYPE_PSTATE_CHG,982 .pstate_latency_us = 11.65333,983 .sr_exit_time_us = 9.748,984 .sr_enter_plus_exit_time_us = 11.102,985 .valid = true,986 },987 }988};989 990void dcn20_populate_dml_writeback_from_context(struct dc *dc,991 struct resource_context *res_ctx,992 display_e2e_pipe_params_st *pipes)993{994 int pipe_cnt, i;995 996 dc_assert_fp_enabled();997 998 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {999 struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];1000 1001 if (!res_ctx->pipe_ctx[i].stream)1002 continue;1003 1004 /* Set writeback information */1005 pipes[pipe_cnt].dout.wb_enable = (wb_info->wb_enabled == true) ? 1 : 0;1006 pipes[pipe_cnt].dout.num_active_wb++;1007 pipes[pipe_cnt].dout.wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_height;1008 pipes[pipe_cnt].dout.wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_width;1009 pipes[pipe_cnt].dout.wb.wb_dst_width = wb_info->dwb_params.dest_width;1010 pipes[pipe_cnt].dout.wb.wb_dst_height = wb_info->dwb_params.dest_height;1011 pipes[pipe_cnt].dout.wb.wb_htaps_luma = 1;1012 pipes[pipe_cnt].dout.wb.wb_vtaps_luma = 1;1013 pipes[pipe_cnt].dout.wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;1014 pipes[pipe_cnt].dout.wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;1015 pipes[pipe_cnt].dout.wb.wb_hratio = 1.0;1016 pipes[pipe_cnt].dout.wb.wb_vratio = 1.0;1017 if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {1018 if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)1019 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_8;1020 else1021 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_10;1022 } else {1023 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_444_32;1024 }1025 1026 pipe_cnt++;1027 }1028}1029 1030void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params,1031 struct dc_state *context,1032 display_e2e_pipe_params_st *pipes,1033 int pipe_cnt, int i)1034{1035 int k;1036 1037 dc_assert_fp_enabled();1038 1039 for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) {1040 wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1041 wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1042 }1043 wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */1044}1045 1046static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)1047{1048 int i;1049 for (i = 0; i < dc->res_pool->pipe_count; i++) {1050 if (!context->res_ctx.pipe_ctx[i].stream)1051 continue;1052 if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))1053 return true;1054 }1055 return false;1056}1057 1058static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context)1059{1060 int plane_count;1061 int i;1062 1063 plane_count = 0;1064 for (i = 0; i < dc->res_pool->pipe_count; i++) {1065 if (context->res_ctx.pipe_ctx[i].plane_state)1066 plane_count++;1067 }1068 1069 /*1070 * Z9 and Z10 allowed cases:1071 * 1. 0 Planes enabled1072 * 2. single eDP, on link 0, 1 plane and stutter period > 5ms1073 * Z10 only cases:1074 * 1. single eDP, on link 0, 1 plane and stutter period >= 5ms1075 * Z8 cases:1076 * 1. stutter period sufficient1077 * Zstate not allowed cases:1078 * 1. Everything else1079 */1080 if (plane_count == 0)1081 return DCN_ZSTATE_SUPPORT_ALLOW;1082 else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {1083 struct dc_link *link = context->streams[0]->sink->link;1084 struct dc_stream_status *stream_status = &context->stream_status[0];1085 int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000;1086 bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;1087 bool is_pwrseq0 = (link && link->link_index == 0);1088 bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||1089 link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr);1090 bool is_replay = link && link->replay_settings.replay_feature_enabled;1091 1092 /* Don't support multi-plane configurations */1093 if (stream_status->plane_count > 1)1094 return DCN_ZSTATE_SUPPORT_DISALLOW;1095 1096 if (is_pwrseq0 && context->bw_ctx.dml.vba.StutterPeriod > 5000.0)1097 return DCN_ZSTATE_SUPPORT_ALLOW;1098 else if (is_pwrseq0 && (is_psr || is_replay))1099 return DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY;1100 else1101 return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY : DCN_ZSTATE_SUPPORT_DISALLOW;1102 } else {1103 return DCN_ZSTATE_SUPPORT_DISALLOW;1104 }1105}1106 1107static void dcn20_adjust_freesync_v_startup(1108 const struct dc_crtc_timing *dc_crtc_timing, int *vstartup_start)1109{1110 struct dc_crtc_timing patched_crtc_timing;1111 uint32_t asic_blank_end = 0;1112 uint32_t asic_blank_start = 0;1113 uint32_t newVstartup = 0;1114 1115 patched_crtc_timing = *dc_crtc_timing;1116 1117 if (patched_crtc_timing.flags.INTERLACE == 1) {1118 if (patched_crtc_timing.v_front_porch < 2)1119 patched_crtc_timing.v_front_porch = 2;1120 } else {1121 if (patched_crtc_timing.v_front_porch < 1)1122 patched_crtc_timing.v_front_porch = 1;1123 }1124 1125 /* blank_start = frame end - front porch */1126 asic_blank_start = patched_crtc_timing.v_total -1127 patched_crtc_timing.v_front_porch;1128 1129 /* blank_end = blank_start - active */1130 asic_blank_end = asic_blank_start -1131 patched_crtc_timing.v_border_bottom -1132 patched_crtc_timing.v_addressable -1133 patched_crtc_timing.v_border_top;1134 1135 /* The newVStartUp is 1 line before vsync point */1136 newVstartup = asic_blank_end + 1;1137 1138 *vstartup_start = ((newVstartup > *vstartup_start) ? newVstartup : *vstartup_start);1139}1140 1141void dcn20_calculate_dlg_params(struct dc *dc,1142 struct dc_state *context,1143 display_e2e_pipe_params_st *pipes,1144 int pipe_cnt,1145 int vlevel)1146{1147 int i, pipe_idx, active_hubp_count = 0;1148 1149 dc_assert_fp_enabled();1150 1151 /* Writeback MCIF_WB arbitration parameters */1152 dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);1153 1154 context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;1155 context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;1156 context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;1157 context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;1158 1159 if (dc->debug.min_dram_clk_khz > context->bw_ctx.bw.dcn.clk.dramclk_khz)1160 context->bw_ctx.bw.dcn.clk.dramclk_khz = dc->debug.min_dram_clk_khz;1161 1162 context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;1163 context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;1164 context->bw_ctx.bw.dcn.clk.p_state_change_support =1165 context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]1166 != dm_dram_clock_change_unsupported;1167 1168 /* Pstate change might not be supported by hardware, but it might be1169 * possible with firmware driven vertical blank stretching.1170 */1171 context->bw_ctx.bw.dcn.clk.p_state_change_support |= context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching;1172 1173 context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;1174 1175 context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);1176 1177 if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz)1178 context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz;1179 1180 for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {1181 if (!context->res_ctx.pipe_ctx[i].stream)1182 continue;1183 if (context->res_ctx.pipe_ctx[i].plane_state)1184 active_hubp_count++;1185 pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);1186 pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);1187 pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);1188 pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);1189 1190 if (dc_state_get_pipe_subvp_type(context, &context->res_ctx.pipe_ctx[i]) == SUBVP_PHANTOM) {1191 // Phantom pipe requires that DET_SIZE = 0 and no unbounded requests1192 context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0;1193 context->res_ctx.pipe_ctx[i].unbounded_req = false;1194 } else {1195 context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;1196 context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;1197 }1198 1199 if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)1200 context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;1201 context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =1202 pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;1203 context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;1204 if (dc->ctx->dce_version < DCN_VERSION_3_1 &&1205 context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid)1206 dcn20_adjust_freesync_v_startup(1207 &context->res_ctx.pipe_ctx[i].stream->timing,1208 &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start);1209 1210 pipe_idx++;1211 }1212 /* If DCN isn't making memory requests we can allow pstate change */1213 if (!active_hubp_count) {1214 context->bw_ctx.bw.dcn.clk.p_state_change_support = true;1215 }1216 /*save a original dppclock copy*/1217 context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;1218 context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;1219 context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;1220 context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;1221 1222 context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes1223 - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx;1224 1225 for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {1226 bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;1227 1228 if (!context->res_ctx.pipe_ctx[i].stream)1229 continue;1230 1231 /* cstate disabled on 201 */1232 if (dc->ctx->dce_version == DCN_VERSION_2_01)1233 cstate_en = false;1234 1235 context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,1236 &context->res_ctx.pipe_ctx[i].dlg_regs,1237 &context->res_ctx.pipe_ctx[i].ttu_regs,1238 pipes,1239 pipe_cnt,1240 pipe_idx,1241 cstate_en,1242 context->bw_ctx.bw.dcn.clk.p_state_change_support,1243 false, false, true);1244 1245 context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,1246 &context->res_ctx.pipe_ctx[i].rq_regs,1247 &pipes[pipe_idx].pipe);1248 pipe_idx++;1249 }1250 context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context);1251}1252 1253static void swizzle_to_dml_params(1254 enum swizzle_mode_values swizzle,1255 unsigned int *sw_mode)1256{1257 switch (swizzle) {1258 case DC_SW_LINEAR:1259 *sw_mode = dm_sw_linear;1260 break;1261 case DC_SW_4KB_S:1262 *sw_mode = dm_sw_4kb_s;1263 break;1264 case DC_SW_4KB_S_X:1265 *sw_mode = dm_sw_4kb_s_x;1266 break;1267 case DC_SW_4KB_D:1268 *sw_mode = dm_sw_4kb_d;1269 break;1270 case DC_SW_4KB_D_X:1271 *sw_mode = dm_sw_4kb_d_x;1272 break;1273 case DC_SW_64KB_S:1274 *sw_mode = dm_sw_64kb_s;1275 break;1276 case DC_SW_64KB_S_X:1277 *sw_mode = dm_sw_64kb_s_x;1278 break;1279 case DC_SW_64KB_S_T:1280 *sw_mode = dm_sw_64kb_s_t;1281 break;1282 case DC_SW_64KB_D:1283 *sw_mode = dm_sw_64kb_d;1284 break;1285 case DC_SW_64KB_D_X:1286 *sw_mode = dm_sw_64kb_d_x;1287 break;1288 case DC_SW_64KB_D_T:1289 *sw_mode = dm_sw_64kb_d_t;1290 break;1291 case DC_SW_64KB_R_X:1292 *sw_mode = dm_sw_64kb_r_x;1293 break;1294 case DC_SW_VAR_S:1295 *sw_mode = dm_sw_var_s;1296 break;1297 case DC_SW_VAR_S_X:1298 *sw_mode = dm_sw_var_s_x;1299 break;1300 case DC_SW_VAR_D:1301 *sw_mode = dm_sw_var_d;1302 break;1303 case DC_SW_VAR_D_X:1304 *sw_mode = dm_sw_var_d_x;1305 break;1306 case DC_SW_VAR_R_X:1307 *sw_mode = dm_sw_var_r_x;1308 break;1309 default:1310 ASSERT(0); /* Not supported */1311 break;1312 }1313}1314 1315int dcn20_populate_dml_pipes_from_context(struct dc *dc,1316 struct dc_state *context,1317 display_e2e_pipe_params_st *pipes,1318 bool fast_validate)1319{1320 int pipe_cnt, i;1321 bool synchronized_vblank = true;1322 struct resource_context *res_ctx = &context->res_ctx;1323 1324 dc_assert_fp_enabled();1325 1326 for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {1327 if (!res_ctx->pipe_ctx[i].stream)1328 continue;1329 1330 if (pipe_cnt < 0) {1331 pipe_cnt = i;1332 continue;1333 }1334 1335 if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream)1336 continue;1337 1338 if (dc->debug.disable_timing_sync ||1339 (!resource_are_streams_timing_synchronizable(1340 res_ctx->pipe_ctx[pipe_cnt].stream,1341 res_ctx->pipe_ctx[i].stream) &&1342 !resource_are_vblanks_synchronizable(1343 res_ctx->pipe_ctx[pipe_cnt].stream,1344 res_ctx->pipe_ctx[i].stream))) {1345 synchronized_vblank = false;1346 break;1347 }1348 }1349 1350 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {1351 struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;1352 unsigned int v_total;1353 unsigned int front_porch;1354 int output_bpc;1355 struct audio_check aud_check = {0};1356 1357 if (!res_ctx->pipe_ctx[i].stream)1358 continue;1359 1360 v_total = timing->v_total;1361 front_porch = timing->v_front_porch;1362 1363 /* todo:1364 pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;1365 pipes[pipe_cnt].pipe.src.dcc = 0;1366 pipes[pipe_cnt].pipe.src.vm = 0;*/1367 1368 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;1369 1370 pipes[pipe_cnt].pipe.dest.use_maximum_vstartup = dc->ctx->dce_version == DCN_VERSION_2_01;1371 1372 pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;1373 /* todo: rotation?*/1374 pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;1375 if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {1376 pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;1377 /* 1/2 vblank */1378 pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =1379 (v_total - timing->v_addressable1380 - timing->v_border_top - timing->v_border_bottom) / 2;1381 /* 36 bytes dp, 32 hdmi */1382 pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =1383 dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;1384 }1385 pipes[pipe_cnt].pipe.src.dcc = false;1386 pipes[pipe_cnt].pipe.src.dcc_rate = 1;1387 pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;1388 pipes[pipe_cnt].pipe.dest.synchronize_timings = synchronized_vblank;1389 pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;1390 pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start1391 - timing->h_addressable1392 - timing->h_border_left1393 - timing->h_border_right;1394 pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;1395 pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start1396 - timing->v_addressable1397 - timing->v_border_top1398 - timing->v_border_bottom;1399 pipes[pipe_cnt].pipe.dest.htotal = timing->h_total;1400 pipes[pipe_cnt].pipe.dest.vtotal = v_total;1401 pipes[pipe_cnt].pipe.dest.hactive =1402 timing->h_addressable + timing->h_border_left + timing->h_border_right;1403 pipes[pipe_cnt].pipe.dest.vactive =1404 timing->v_addressable + timing->v_border_top + timing->v_border_bottom;1405 pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE;1406 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0;1407 if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)1408 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;1409 pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;1410 pipes[pipe_cnt].dout.dp_lanes = 4;1411 pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_na;1412 pipes[pipe_cnt].dout.is_virtual = 0;1413 pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;1414 pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;1415 switch (resource_get_odm_slice_count(&res_ctx->pipe_ctx[i])) {1416 case 2:1417 pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;1418 break;1419 case 4:1420 pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1;1421 break;1422 default:1423 pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;1424 }1425 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;1426 if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state1427 == res_ctx->pipe_ctx[i].plane_state) {1428 struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].top_pipe;1429 int split_idx = 0;1430 1431 while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state1432 == res_ctx->pipe_ctx[i].plane_state) {1433 first_pipe = first_pipe->top_pipe;1434 split_idx++;1435 }1436 /* Treat 4to1 mpc combine as an mpo of 2 2-to-1 combines */1437 if (split_idx == 0)1438 pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;1439 else if (split_idx == 1)1440 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;1441 else if (split_idx == 2)1442 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].top_pipe->pipe_idx;1443 } else if (res_ctx->pipe_ctx[i].prev_odm_pipe) {1444 struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].prev_odm_pipe;1445 1446 while (first_pipe->prev_odm_pipe)1447 first_pipe = first_pipe->prev_odm_pipe;1448 pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;1449 }1450 1451 switch (res_ctx->pipe_ctx[i].stream->signal) {1452 case SIGNAL_TYPE_DISPLAY_PORT_MST:1453 case SIGNAL_TYPE_DISPLAY_PORT:1454 pipes[pipe_cnt].dout.output_type = dm_dp;1455 if (dc->link_srv->dp_is_128b_132b_signal(&res_ctx->pipe_ctx[i]))1456 pipes[pipe_cnt].dout.output_type = dm_dp2p0;1457 break;1458 case SIGNAL_TYPE_EDP:1459 pipes[pipe_cnt].dout.output_type = dm_edp;1460 break;1461 case SIGNAL_TYPE_HDMI_TYPE_A:1462 case SIGNAL_TYPE_DVI_SINGLE_LINK:1463 case SIGNAL_TYPE_DVI_DUAL_LINK:1464 pipes[pipe_cnt].dout.output_type = dm_hdmi;1465 break;1466 default:1467 /* In case there is no signal, set dp with 4 lanes to allow max config */1468 pipes[pipe_cnt].dout.is_virtual = 1;1469 pipes[pipe_cnt].dout.output_type = dm_dp;1470 pipes[pipe_cnt].dout.dp_lanes = 4;1471 }1472 1473 switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {1474 case COLOR_DEPTH_666:1475 output_bpc = 6;1476 break;1477 case COLOR_DEPTH_888:1478 output_bpc = 8;1479 break;1480 case COLOR_DEPTH_101010:1481 output_bpc = 10;1482 break;1483 case COLOR_DEPTH_121212:1484 output_bpc = 12;1485 break;1486 case COLOR_DEPTH_141414:1487 output_bpc = 14;1488 break;1489 case COLOR_DEPTH_161616:1490 output_bpc = 16;1491 break;1492 case COLOR_DEPTH_999:1493 output_bpc = 9;1494 break;1495 case COLOR_DEPTH_111111:1496 output_bpc = 11;1497 break;1498 default:1499 output_bpc = 8;1500 break;1501 }1502 1503 switch (res_ctx->pipe_ctx[i].stream->timing.pixel_encoding) {1504 case PIXEL_ENCODING_RGB:1505 case PIXEL_ENCODING_YCBCR444:1506 pipes[pipe_cnt].dout.output_format = dm_444;1507 pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;1508 break;1509 case PIXEL_ENCODING_YCBCR420:1510 pipes[pipe_cnt].dout.output_format = dm_420;1511 pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;1512 break;1513 case PIXEL_ENCODING_YCBCR422:1514 if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC &&1515 !res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.ycbcr422_simple)1516 pipes[pipe_cnt].dout.output_format = dm_n422;1517 else1518 pipes[pipe_cnt].dout.output_format = dm_s422;1519 pipes[pipe_cnt].dout.output_bpp = output_bpc * 2;1520 break;1521 default:1522 pipes[pipe_cnt].dout.output_format = dm_444;1523 pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;1524 }1525 1526 if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)1527 pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;1528 1529 /* todo: default max for now, until there is logic reflecting this in dc*/1530 pipes[pipe_cnt].dout.dsc_input_bpc = 12;1531 /*fill up the audio sample rate (unit in kHz)*/1532 get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);1533 pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000;1534 /*1535 * For graphic plane, cursor number is 1, nv12 is 01536 * bw calculations due to cursor on/off1537 */1538 if (res_ctx->pipe_ctx[i].plane_state &&1539 (res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||1540 dc_state_get_pipe_subvp_type(context, &res_ctx->pipe_ctx[i]) == SUBVP_PHANTOM))1541 pipes[pipe_cnt].pipe.src.num_cursors = 0;1542 else1543 pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;1544 1545 pipes[pipe_cnt].pipe.src.cur0_src_width = 256;1546 pipes[pipe_cnt].pipe.src.cur0_bpp = dm_cur_32bit;1547 1548 if (!res_ctx->pipe_ctx[i].plane_state) {1549 pipes[pipe_cnt].pipe.src.is_hsplit = pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;1550 pipes[pipe_cnt].pipe.src.source_scan = dm_horz;1551 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;1552 pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_4kb_s;1553 pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;1554 pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;1555 if (pipes[pipe_cnt].pipe.src.viewport_width > 1920)1556 pipes[pipe_cnt].pipe.src.viewport_width = 1920;1557 pipes[pipe_cnt].pipe.src.viewport_height = timing->v_addressable;1558 if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)1559 pipes[pipe_cnt].pipe.src.viewport_height = 1080;1560 pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;1561 pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;1562 pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;1563 pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;1564 pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;1565 pipes[pipe_cnt].pipe.src.source_format = dm_444_32;1566 pipes[pipe_cnt].pipe.src.cur0_src_width = 0;1567 pipes[pipe_cnt].pipe.src.cur1_src_width = 0;1568 pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/1569 pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/1570 pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width; /*when is_hsplit != 1*/1571 pipes[pipe_cnt].pipe.dest.full_recout_height = pipes[pipe_cnt].pipe.dest.recout_height; /*when is_hsplit != 1*/1572 pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;1573 pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = 1.0;1574 pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = 1.0;1575 pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable = 0; /*Lb only or Full scl*/1576 pipes[pipe_cnt].pipe.scale_taps.htaps = 1;1577 pipes[pipe_cnt].pipe.scale_taps.vtaps = 1;1578 pipes[pipe_cnt].pipe.dest.vtotal_min = v_total;1579 pipes[pipe_cnt].pipe.dest.vtotal_max = v_total;1580 1581 if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) {1582 pipes[pipe_cnt].pipe.src.viewport_width /= 2;1583 pipes[pipe_cnt].pipe.dest.recout_width /= 2;1584 } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) {1585 pipes[pipe_cnt].pipe.src.viewport_width /= 4;1586 pipes[pipe_cnt].pipe.dest.recout_width /= 4;1587 }1588 } else {1589 struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;1590 struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;1591 1592 pipes[pipe_cnt].pipe.src.immediate_flip = pln->flip_immediate;1593 pipes[pipe_cnt].pipe.src.is_hsplit = (res_ctx->pipe_ctx[i].bottom_pipe && res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln)1594 || (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == pln)1595 || pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;1596 1597 /* stereo is not split */1598 if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE ||1599 pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) {1600 pipes[pipe_cnt].pipe.src.is_hsplit = false;1601 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;1602 }1603 1604 pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_901605 || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;1606 switch (pln->rotation) {1607 case ROTATION_ANGLE_0:1608 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;1609 break;1610 case ROTATION_ANGLE_90:1611 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_90;1612 break;1613 case ROTATION_ANGLE_180:1614 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_180;1615 break;1616 case ROTATION_ANGLE_270:1617 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_270;1618 break;1619 default:1620 break;1621 }1622 1623 pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;1624 pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;1625 pipes[pipe_cnt].pipe.src.viewport_x_y = scl->viewport.x;1626 pipes[pipe_cnt].pipe.src.viewport_x_c = scl->viewport_c.x;1627 pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;1628 pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;1629 pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;1630 pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;1631 pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;1632 pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;1633 pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;1634 pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;1635 pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;1636 pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;1637 if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA1638 || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {1639 pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;1640 pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;1641 pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;1642 pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;1643 } else {1644 pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;1645 pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;1646 }1647 pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;1648 pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;1649 pipes[pipe_cnt].pipe.dest.recout_height = scl->recout.height;1650 pipes[pipe_cnt].pipe.dest.full_recout_height = scl->recout.height;1651 pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;1652 if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1)1653 pipes[pipe_cnt].pipe.dest.full_recout_width *= 2;1654 else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1)1655 pipes[pipe_cnt].pipe.dest.full_recout_width *= 4;1656 else {1657 struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe;1658 1659 while (split_pipe && split_pipe->plane_state == pln) {1660 pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;1661 split_pipe = split_pipe->bottom_pipe;1662 }1663 split_pipe = res_ctx->pipe_ctx[i].top_pipe;1664 while (split_pipe && split_pipe->plane_state == pln) {1665 pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;1666 split_pipe = split_pipe->top_pipe;1667 }1668 }1669 1670 pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;1671 pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);1672 pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);1673 pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);1674 pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);1675 pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable =1676 scl->ratios.vert.value != dc_fixpt_one.value1677 || scl->ratios.horz.value != dc_fixpt_one.value1678 || scl->ratios.vert_c.value != dc_fixpt_one.value1679 || scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/1680 || dc->debug.always_scale; /*support always scale*/1681 pipes[pipe_cnt].pipe.scale_taps.htaps = scl->taps.h_taps;1682 pipes[pipe_cnt].pipe.scale_taps.htaps_c = scl->taps.h_taps_c;1683 pipes[pipe_cnt].pipe.scale_taps.vtaps = scl->taps.v_taps;1684 pipes[pipe_cnt].pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;1685 1686 pipes[pipe_cnt].pipe.src.macro_tile_size =1687 swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);1688 swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,1689 &pipes[pipe_cnt].pipe.src.sw_mode);1690 1691 switch (pln->format) {1692 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:1693 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:1694 pipes[pipe_cnt].pipe.src.source_format = dm_420_8;1695 break;1696 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:1697 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:1698 pipes[pipe_cnt].pipe.src.source_format = dm_420_10;1699 break;1700 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:1701 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:1702 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:1703 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:1704 pipes[pipe_cnt].pipe.src.source_format = dm_444_64;1705 break;1706 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:1707 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:1708 pipes[pipe_cnt].pipe.src.source_format = dm_444_16;1709 break;1710 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:1711 pipes[pipe_cnt].pipe.src.source_format = dm_444_8;1712 break;1713 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:1714 pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha;1715 break;1716 default:1717 pipes[pipe_cnt].pipe.src.source_format = dm_444_32;1718 break;1719 }1720 }1721 1722 pipe_cnt++;1723 }1724 1725 /* populate writeback information */1726 dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);1727 1728 return pipe_cnt;1729}1730 1731void dcn20_calculate_wm(struct dc *dc, struct dc_state *context,1732 display_e2e_pipe_params_st *pipes,1733 int *out_pipe_cnt,1734 int *pipe_split_from,1735 int vlevel,1736 bool fast_validate)1737{1738 int pipe_cnt, i, pipe_idx;1739 1740 dc_assert_fp_enabled();1741 1742 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {1743 if (!context->res_ctx.pipe_ctx[i].stream)1744 continue;1745 1746 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;1747 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];1748 1749 if (pipe_split_from[i] < 0) {1750 pipes[pipe_cnt].clks_cfg.dppclk_mhz =1751 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];1752 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)1753 pipes[pipe_cnt].pipe.dest.odm_combine =1754 context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];1755 else1756 pipes[pipe_cnt].pipe.dest.odm_combine = 0;1757 pipe_idx++;1758 } else {1759 pipes[pipe_cnt].clks_cfg.dppclk_mhz =1760 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];1761 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])1762 pipes[pipe_cnt].pipe.dest.odm_combine =1763 context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];1764 else1765 pipes[pipe_cnt].pipe.dest.odm_combine = 0;1766 }1767 1768 if (dc->config.forced_clocks) {1769 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;1770 pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;1771 }1772 if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)1773 pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;1774 if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)1775 pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;1776 1777 pipe_cnt++;1778 }1779 1780 if (pipe_cnt != pipe_idx) {1781 if (dc->res_pool->funcs->populate_dml_pipes)1782 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,1783 context, pipes, fast_validate);1784 else1785 pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,1786 context, pipes, fast_validate);1787 }1788 1789 *out_pipe_cnt = pipe_cnt;1790 1791 pipes[0].clks_cfg.voltage = vlevel;1792 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;1793 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;1794 1795 /* only pipe 0 is read for voltage and dcf/soc clocks */1796 if (vlevel < 1) {1797 pipes[0].clks_cfg.voltage = 1;1798 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;1799 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;1800 }1801 context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1802 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1803 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1804 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1805 context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1806 context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1807 context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1808 context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1809 1810 if (vlevel < 2) {1811 pipes[0].clks_cfg.voltage = 2;1812 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;1813 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;1814 }1815 context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1816 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1817 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1818 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1819 context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1820 context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1821 context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1822 1823 if (vlevel < 3) {1824 pipes[0].clks_cfg.voltage = 3;1825 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;1826 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;1827 }1828 context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1829 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1830 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1831 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1832 context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1833 context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1834 context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1835 1836 pipes[0].clks_cfg.voltage = vlevel;1837 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;1838 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;1839 context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1840 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1841 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1842 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1843 context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1844 context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1845 context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;1846}1847 1848void dcn20_update_bounding_box(struct dc *dc,1849 struct _vcs_dpi_soc_bounding_box_st *bb,1850 struct pp_smu_nv_clock_table *max_clocks,1851 unsigned int *uclk_states,1852 unsigned int num_states)1853{1854 int num_calculated_states = 0;1855 int min_dcfclk = 0;1856 int i;1857 1858 dc_assert_fp_enabled();1859 1860 if (num_states == 0)1861 return;1862 1863 memset(bb->clock_limits, 0, sizeof(bb->clock_limits));1864 1865 if (dc->bb_overrides.min_dcfclk_mhz > 0) {1866 min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;1867 } else {1868 if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))1869 min_dcfclk = 310;1870 else1871 // Accounting for SOC/DCF relationship, we can go as high as1872 // 506Mhz in Vmin.1873 min_dcfclk = 506;1874 }1875 1876 for (i = 0; i < num_states; i++) {1877 int min_fclk_required_by_uclk;1878 bb->clock_limits[i].state = i;1879 bb->clock_limits[i].dram_speed_mts = uclk_states[i] * 16 / 1000;1880 1881 // FCLK:UCLK ratio is 1.081882 min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080,1883 1000000);1884 1885 bb->clock_limits[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ?1886 min_dcfclk : min_fclk_required_by_uclk;1887 1888 bb->clock_limits[i].socclk_mhz = (bb->clock_limits[i].fabricclk_mhz > max_clocks->socClockInKhz / 1000.0) ?1889 max_clocks->socClockInKhz / 1000 : bb->clock_limits[i].fabricclk_mhz;1890 1891 bb->clock_limits[i].dcfclk_mhz = (bb->clock_limits[i].fabricclk_mhz > max_clocks->dcfClockInKhz / 1000.0) ?1892 max_clocks->dcfClockInKhz / 1000 : bb->clock_limits[i].fabricclk_mhz;1893 1894 bb->clock_limits[i].dispclk_mhz = max_clocks->displayClockInKhz / 1000;1895 bb->clock_limits[i].dppclk_mhz = max_clocks->displayClockInKhz / 1000;1896 bb->clock_limits[i].dscclk_mhz = max_clocks->displayClockInKhz / (1000 * 3);1897 1898 bb->clock_limits[i].phyclk_mhz = max_clocks->phyClockInKhz / 1000;1899 1900 num_calculated_states++;1901 }1902 1903 bb->clock_limits[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;1904 bb->clock_limits[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;1905 bb->clock_limits[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;1906 1907 bb->num_states = num_calculated_states;1908 1909 // Duplicate the last state, DML always an extra state identical to max state to work1910 memcpy(&bb->clock_limits[num_calculated_states], &bb->clock_limits[num_calculated_states - 1], sizeof(struct _vcs_dpi_voltage_scaling_st));1911 bb->clock_limits[num_calculated_states].state = bb->num_states;1912}1913 1914void dcn20_cap_soc_clocks(struct _vcs_dpi_soc_bounding_box_st *bb,1915 struct pp_smu_nv_clock_table max_clocks)1916{1917 int i;1918 1919 dc_assert_fp_enabled();1920 1921 // First pass - cap all clocks higher than the reported max1922 for (i = 0; i < bb->num_states; i++) {1923 if ((bb->clock_limits[i].dcfclk_mhz > (max_clocks.dcfClockInKhz / 1000.0))1924 && max_clocks.dcfClockInKhz != 0)1925 bb->clock_limits[i].dcfclk_mhz = (max_clocks.dcfClockInKhz / 1000);1926 1927 if ((bb->clock_limits[i].dram_speed_mts > (max_clocks.uClockInKhz / 1000.0) * 16)1928 && max_clocks.uClockInKhz != 0)1929 bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;1930 1931 if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000.0))1932 && max_clocks.fabricClockInKhz != 0)1933 bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);1934 1935 if ((bb->clock_limits[i].dispclk_mhz > (max_clocks.displayClockInKhz / 1000.0))1936 && max_clocks.displayClockInKhz != 0)1937 bb->clock_limits[i].dispclk_mhz = (max_clocks.displayClockInKhz / 1000);1938 1939 if ((bb->clock_limits[i].dppclk_mhz > (max_clocks.dppClockInKhz / 1000.0))1940 && max_clocks.dppClockInKhz != 0)1941 bb->clock_limits[i].dppclk_mhz = (max_clocks.dppClockInKhz / 1000);1942 1943 if ((bb->clock_limits[i].phyclk_mhz > (max_clocks.phyClockInKhz / 1000.0))1944 && max_clocks.phyClockInKhz != 0)1945 bb->clock_limits[i].phyclk_mhz = (max_clocks.phyClockInKhz / 1000);1946 1947 if ((bb->clock_limits[i].socclk_mhz > (max_clocks.socClockInKhz / 1000.0))1948 && max_clocks.socClockInKhz != 0)1949 bb->clock_limits[i].socclk_mhz = (max_clocks.socClockInKhz / 1000);1950 1951 if ((bb->clock_limits[i].dscclk_mhz > (max_clocks.dscClockInKhz / 1000.0))1952 && max_clocks.dscClockInKhz != 0)1953 bb->clock_limits[i].dscclk_mhz = (max_clocks.dscClockInKhz / 1000);1954 }1955 1956 // Second pass - remove all duplicate clock states1957 for (i = bb->num_states - 1; i > 1; i--) {1958 bool duplicate = true;1959 1960 if (bb->clock_limits[i-1].dcfclk_mhz != bb->clock_limits[i].dcfclk_mhz)1961 duplicate = false;1962 if (bb->clock_limits[i-1].dispclk_mhz != bb->clock_limits[i].dispclk_mhz)1963 duplicate = false;1964 if (bb->clock_limits[i-1].dppclk_mhz != bb->clock_limits[i].dppclk_mhz)1965 duplicate = false;1966 if (bb->clock_limits[i-1].dram_speed_mts != bb->clock_limits[i].dram_speed_mts)1967 duplicate = false;1968 if (bb->clock_limits[i-1].dscclk_mhz != bb->clock_limits[i].dscclk_mhz)1969 duplicate = false;1970 if (bb->clock_limits[i-1].fabricclk_mhz != bb->clock_limits[i].fabricclk_mhz)1971 duplicate = false;1972 if (bb->clock_limits[i-1].phyclk_mhz != bb->clock_limits[i].phyclk_mhz)1973 duplicate = false;1974 if (bb->clock_limits[i-1].socclk_mhz != bb->clock_limits[i].socclk_mhz)1975 duplicate = false;1976 1977 if (duplicate)1978 bb->num_states--;1979 }1980}1981 1982void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)1983{1984 dc_assert_fp_enabled();1985 1986 if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns1987 && dc->bb_overrides.sr_exit_time_ns) {1988 bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;1989 }1990 1991 if ((int)(bb->sr_enter_plus_exit_time_us * 1000)1992 != dc->bb_overrides.sr_enter_plus_exit_time_ns1993 && dc->bb_overrides.sr_enter_plus_exit_time_ns) {1994 bb->sr_enter_plus_exit_time_us =1995 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;1996 }1997 1998 if ((int)(bb->sr_exit_z8_time_us * 1000)1999 != dc->bb_overrides.sr_exit_z8_time_ns2000 && dc->bb_overrides.sr_exit_z8_time_ns) {2001 bb->sr_exit_z8_time_us = dc->bb_overrides.sr_exit_z8_time_ns / 1000.0;2002 }2003 2004 if ((int)(bb->sr_enter_plus_exit_z8_time_us * 1000)2005 != dc->bb_overrides.sr_enter_plus_exit_z8_time_ns2006 && dc->bb_overrides.sr_enter_plus_exit_z8_time_ns) {2007 bb->sr_enter_plus_exit_z8_time_us = dc->bb_overrides.sr_enter_plus_exit_z8_time_ns / 1000.0;2008 }2009 if ((int)(bb->urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns2010 && dc->bb_overrides.urgent_latency_ns) {2011 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;2012 }2013 2014 if ((int)(bb->dram_clock_change_latency_us * 1000)2015 != dc->bb_overrides.dram_clock_change_latency_ns2016 && dc->bb_overrides.dram_clock_change_latency_ns) {2017 bb->dram_clock_change_latency_us =2018 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;2019 }2020 2021 if ((int)(bb->dummy_pstate_latency_us * 1000)2022 != dc->bb_overrides.dummy_clock_change_latency_ns2023 && dc->bb_overrides.dummy_clock_change_latency_ns) {2024 bb->dummy_pstate_latency_us =2025 dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;2026 }2027}2028 2029static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,2030 bool fast_validate, display_e2e_pipe_params_st *pipes)2031{2032 bool out = false;2033 2034 BW_VAL_TRACE_SETUP();2035 2036 int vlevel = 0;2037 int pipe_split_from[MAX_PIPES];2038 int pipe_cnt = 0;2039 DC_LOGGER_INIT(dc->ctx->logger);2040 2041 BW_VAL_TRACE_COUNT();2042 2043 out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);2044 2045 if (pipe_cnt == 0)2046 goto validate_out;2047 2048 if (!out)2049 goto validate_fail;2050 2051 BW_VAL_TRACE_END_VOLTAGE_LEVEL();2052 2053 if (fast_validate) {2054 BW_VAL_TRACE_SKIP(fast);2055 goto validate_out;2056 }2057 2058 dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);2059 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);2060 2061 BW_VAL_TRACE_END_WATERMARKS();2062 2063 goto validate_out;2064 2065validate_fail:2066 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",2067 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));2068 2069 BW_VAL_TRACE_SKIP(fail);2070 out = false;2071 2072validate_out:2073 2074 BW_VAL_TRACE_FINISH();2075 2076 return out;2077}2078 2079bool dcn20_validate_bandwidth_fp(struct dc *dc, struct dc_state *context,2080 bool fast_validate, display_e2e_pipe_params_st *pipes)2081{2082 bool voltage_supported = false;2083 bool full_pstate_supported = false;2084 bool dummy_pstate_supported = false;2085 double p_state_latency_us;2086 2087 dc_assert_fp_enabled();2088 2089 p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;2090 context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =2091 dc->debug.disable_dram_clock_change_vactive_support;2092 context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive =2093 dc->debug.enable_dram_clock_change_one_display_vactive;2094 2095 /*Unsafe due to current pipe merge and split logic*/2096 ASSERT(context != dc->current_state);2097 2098 if (fast_validate) {2099 return dcn20_validate_bandwidth_internal(dc, context, true, pipes);2100 }2101 2102 // Best case, we support full UCLK switch latency2103 voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false, pipes);2104 full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;2105 2106 if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||2107 (voltage_supported && full_pstate_supported)) {2108 context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;2109 goto restore_dml_state;2110 }2111 2112 // Fallback: Try to only support G6 temperature read latency2113 context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;2114 2115 memset(pipes, 0, dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st));2116 voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false, pipes);2117 dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;2118 2119 if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {2120 context->bw_ctx.bw.dcn.clk.p_state_change_support = false;2121 goto restore_dml_state;2122 }2123 2124 // ERROR: fallback is supposed to always work.2125 ASSERT(false);2126 2127restore_dml_state:2128 context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;2129 return voltage_supported;2130}2131 2132void dcn20_fpu_set_wm_ranges(int i,2133 struct pp_smu_wm_range_sets *ranges,2134 struct _vcs_dpi_soc_bounding_box_st *loaded_bb)2135{2136 dc_assert_fp_enabled();2137 2138 ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;2139 ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;2140}2141 2142void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v,2143 int vlevel,2144 int max_mpc_comb,2145 int pipe_idx,2146 bool is_validating_bw)2147{2148 dc_assert_fp_enabled();2149 2150 if (is_validating_bw)2151 v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] *= 2;2152 else2153 v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2;2154}2155 2156int dcn21_populate_dml_pipes_from_context(struct dc *dc,2157 struct dc_state *context,2158 display_e2e_pipe_params_st *pipes,2159 bool fast_validate)2160{2161 uint32_t pipe_cnt;2162 int i;2163 2164 dc_assert_fp_enabled();2165 2166 pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);2167 2168 for (i = 0; i < pipe_cnt; i++) {2169 2170 pipes[i].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;2171 pipes[i].pipe.src.gpuvm = 1;2172 }2173 2174 return pipe_cnt;2175}2176 2177static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)2178{2179 int i;2180 2181 if (dc->bb_overrides.sr_exit_time_ns) {2182 for (i = 0; i < WM_SET_COUNT; i++) {2183 dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =2184 dc->bb_overrides.sr_exit_time_ns / 1000.0;2185 }2186 }2187 2188 if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {2189 for (i = 0; i < WM_SET_COUNT; i++) {2190 dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us =2191 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;2192 }2193 }2194 2195 if (dc->bb_overrides.urgent_latency_ns) {2196 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;2197 }2198 2199 if (dc->bb_overrides.dram_clock_change_latency_ns) {2200 for (i = 0; i < WM_SET_COUNT; i++) {2201 dc->clk_mgr->bw_params->wm_table.entries[i].pstate_latency_us =2202 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;2203 }2204 }2205}2206 2207static void calculate_wm_set_for_vlevel(int vlevel,2208 struct wm_range_table_entry *table_entry,2209 struct dcn_watermarks *wm_set,2210 struct display_mode_lib *dml,2211 display_e2e_pipe_params_st *pipes,2212 int pipe_cnt)2213{2214 double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;2215 2216 ASSERT(vlevel < dml->soc.num_states);2217 /* only pipe 0 is read for voltage and dcf/soc clocks */2218 pipes[0].clks_cfg.voltage = vlevel;2219 pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;2220 pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;2221 2222 dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;2223 dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;2224 dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;2225 2226 wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;2227 wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;2228 wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;2229 wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;2230 wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;2231 wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;2232 wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;2233 wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;2234 dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;2235}2236 2237static void dcn21_calculate_wm(struct dc *dc, struct dc_state *context,2238 display_e2e_pipe_params_st *pipes,2239 int *out_pipe_cnt,2240 int *pipe_split_from,2241 int vlevel_req,2242 bool fast_validate)2243{2244 int pipe_cnt, i, pipe_idx;2245 int vlevel, vlevel_max;2246 struct wm_range_table_entry *table_entry;2247 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;2248 2249 ASSERT(bw_params);2250 2251 patch_bounding_box(dc, &context->bw_ctx.dml.soc);2252 2253 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {2254 if (!context->res_ctx.pipe_ctx[i].stream)2255 continue;2256 2257 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;2258 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];2259 2260 if (pipe_split_from[i] < 0) {2261 pipes[pipe_cnt].clks_cfg.dppclk_mhz =2262 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];2263 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)2264 pipes[pipe_cnt].pipe.dest.odm_combine =2265 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];2266 else2267 pipes[pipe_cnt].pipe.dest.odm_combine = 0;2268 pipe_idx++;2269 } else {2270 pipes[pipe_cnt].clks_cfg.dppclk_mhz =2271 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];2272 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])2273 pipes[pipe_cnt].pipe.dest.odm_combine =2274 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];2275 else2276 pipes[pipe_cnt].pipe.dest.odm_combine = 0;2277 }2278 pipe_cnt++;2279 }2280 2281 if (pipe_cnt != pipe_idx) {2282 if (dc->res_pool->funcs->populate_dml_pipes)2283 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,2284 context, pipes, fast_validate);2285 else2286 pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,2287 context, pipes, fast_validate);2288 }2289 2290 *out_pipe_cnt = pipe_cnt;2291 2292 vlevel_max = bw_params->clk_table.num_entries - 1;2293 2294 2295 /* WM Set D */2296 table_entry = &bw_params->wm_table.entries[WM_D];2297 if (table_entry->wm_type == WM_TYPE_RETRAINING)2298 vlevel = 0;2299 else2300 vlevel = vlevel_max;2301 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,2302 &context->bw_ctx.dml, pipes, pipe_cnt);2303 /* WM Set C */2304 table_entry = &bw_params->wm_table.entries[WM_C];2305 vlevel = MIN(MAX(vlevel_req, 3), vlevel_max);2306 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,2307 &context->bw_ctx.dml, pipes, pipe_cnt);2308 /* WM Set B */2309 table_entry = &bw_params->wm_table.entries[WM_B];2310 vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);2311 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,2312 &context->bw_ctx.dml, pipes, pipe_cnt);2313 2314 /* WM Set A */2315 table_entry = &bw_params->wm_table.entries[WM_A];2316 vlevel = MIN(vlevel_req, vlevel_max);2317 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,2318 &context->bw_ctx.dml, pipes, pipe_cnt);2319}2320 2321bool dcn21_validate_bandwidth_fp(struct dc *dc, struct dc_state *context,2322 bool fast_validate, display_e2e_pipe_params_st *pipes)2323{2324 bool out = false;2325 2326 BW_VAL_TRACE_SETUP();2327 2328 int vlevel = 0;2329 int pipe_split_from[MAX_PIPES];2330 int pipe_cnt = 0;2331 DC_LOGGER_INIT(dc->ctx->logger);2332 2333 BW_VAL_TRACE_COUNT();2334 2335 dc_assert_fp_enabled();2336 2337 /*Unsafe due to current pipe merge and split logic*/2338 ASSERT(context != dc->current_state);2339 2340 out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);2341 2342 if (pipe_cnt == 0)2343 goto validate_out;2344 2345 if (!out)2346 goto validate_fail;2347 2348 BW_VAL_TRACE_END_VOLTAGE_LEVEL();2349 2350 if (fast_validate) {2351 BW_VAL_TRACE_SKIP(fast);2352 goto validate_out;2353 }2354 2355 dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);2356 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);2357 2358 BW_VAL_TRACE_END_WATERMARKS();2359 2360 goto validate_out;2361 2362validate_fail:2363 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",2364 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));2365 2366 BW_VAL_TRACE_SKIP(fail);2367 out = false;2368 2369validate_out:2370 2371 BW_VAL_TRACE_FINISH();2372 2373 return out;2374}2375 2376static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_limit_table *clk_table, unsigned int high_voltage_lvl)2377{2378 struct _vcs_dpi_voltage_scaling_st low_pstate_lvl = {0};2379 int i;2380 2381 low_pstate_lvl.state = 1;2382 low_pstate_lvl.dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;2383 low_pstate_lvl.fabricclk_mhz = clk_table->entries[0].fclk_mhz;2384 low_pstate_lvl.socclk_mhz = clk_table->entries[0].socclk_mhz;2385 low_pstate_lvl.dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;2386 2387 low_pstate_lvl.dispclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dispclk_mhz;2388 low_pstate_lvl.dppclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dppclk_mhz;2389 low_pstate_lvl.dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[high_voltage_lvl].dram_bw_per_chan_gbps;2390 low_pstate_lvl.dscclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dscclk_mhz;2391 low_pstate_lvl.dtbclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dtbclk_mhz;2392 low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz;2393 low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz;2394 2395 for (i = clk_table->num_entries; i > 1; i--)2396 clk_table->entries[i] = clk_table->entries[i-1];2397 clk_table->entries[1] = clk_table->entries[0];2398 clk_table->num_entries++;2399 2400 return low_pstate_lvl;2401}2402 2403void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)2404{2405 struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;2406 struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);2407 struct clk_limit_table *clk_table = &bw_params->clk_table;2408 unsigned int i, closest_clk_lvl = 0, k = 0;2409 int j;2410 2411 dc_assert_fp_enabled();2412 2413 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;2414 dcn2_1_ip.max_num_dpp = pool->base.pipe_count;2415 dcn2_1_soc.num_chans = bw_params->num_channels;2416 2417 ASSERT(clk_table->num_entries);2418 /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */2419 memcpy(s, dcn2_1_soc.clock_limits, sizeof(dcn2_1_soc.clock_limits));2420 2421 for (i = 0; i < clk_table->num_entries; i++) {2422 /* loop backwards*/2423 for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {2424 if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {2425 closest_clk_lvl = j;2426 break;2427 }2428 }2429 2430 /* clk_table[1] is reserved for min DF PState. skip here to fill in later. */2431 if (i == 1)2432 k++;2433 2434 s[k].state = k;2435 s[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;2436 s[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;2437 s[k].socclk_mhz = clk_table->entries[i].socclk_mhz;2438 s[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;2439 2440 s[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;2441 s[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;2442 s[k].dram_bw_per_chan_gbps =2443 dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;2444 s[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;2445 s[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;2446 s[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;2447 s[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;2448 2449 k++;2450 }2451 2452 memcpy(&dcn2_1_soc.clock_limits, s, sizeof(dcn2_1_soc.clock_limits));2453 2454 if (clk_table->num_entries) {2455 dcn2_1_soc.num_states = clk_table->num_entries + 1;2456 /* fill in min DF PState */2457 dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl);2458 /* duplicate last level */2459 dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];2460 dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;2461 }2462 2463 dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);2464}2465 2466void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params)2467{2468 dc_assert_fp_enabled();2469 2470 bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY;2471 bw_params->wm_table.entries[WM_D].wm_inst = WM_D;2472 bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING;2473 bw_params->wm_table.entries[WM_D].valid = true;2474}2475 2476void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc,2477 struct resource_context *res_ctx,2478 display_e2e_pipe_params_st *pipes)2479{2480 int pipe_cnt, i, j;2481 double max_calc_writeback_dispclk;2482 double writeback_dispclk;2483 struct writeback_st dout_wb = {0};2484 2485 dc_assert_fp_enabled();2486 2487 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {2488 struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream;2489 2490 if (!stream)2491 continue;2492 max_calc_writeback_dispclk = 0;2493 2494 /* Set writeback information */2495 pipes[pipe_cnt].dout.wb_enable = 0;2496 pipes[pipe_cnt].dout.num_active_wb = 0;2497 for (j = 0; j < stream->num_wb_info; j++) {2498 struct dc_writeback_info *wb_info = &stream->writeback_info[j];2499 2500 if (wb_info->wb_enabled && wb_info->writeback_source_plane &&2501 (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) {2502 pipes[pipe_cnt].dout.wb_enable = 1;2503 pipes[pipe_cnt].dout.num_active_wb++;2504 dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ?2505 wb_info->dwb_params.cnv_params.crop_height :2506 wb_info->dwb_params.cnv_params.src_height;2507 dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ?2508 wb_info->dwb_params.cnv_params.crop_width :2509 wb_info->dwb_params.cnv_params.src_width;2510 dout_wb.wb_dst_width = wb_info->dwb_params.dest_width;2511 dout_wb.wb_dst_height = wb_info->dwb_params.dest_height;2512 dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps;2513 dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;2514 dout_wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;2515 dout_wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;2516 dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ?2517 (double)wb_info->dwb_params.cnv_params.crop_width /2518 (double)wb_info->dwb_params.dest_width :2519 (double)wb_info->dwb_params.cnv_params.src_width /2520 (double)wb_info->dwb_params.dest_width;2521 dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ?2522 (double)wb_info->dwb_params.cnv_params.crop_height /2523 (double)wb_info->dwb_params.dest_height :2524 (double)wb_info->dwb_params.cnv_params.src_height /2525 (double)wb_info->dwb_params.dest_height;2526 if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {2527 if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)2528 dout_wb.wb_pixel_format = dm_420_8;2529 else2530 dout_wb.wb_pixel_format = dm_420_10;2531 } else2532 dout_wb.wb_pixel_format = dm_444_32;2533 2534 /* Workaround for cases where multiple writebacks are connected to same plane2535 * In which case, need to compute worst case and set the associated writeback parameters2536 * This workaround is necessary due to DML computation assuming only 1 set of writeback2537 * parameters per pipe */2538 writeback_dispclk = CalculateWriteBackDISPCLK(2539 dout_wb.wb_pixel_format,2540 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz,2541 dout_wb.wb_hratio,2542 dout_wb.wb_vratio,2543 dout_wb.wb_htaps_luma,2544 dout_wb.wb_vtaps_luma,2545 dout_wb.wb_htaps_chroma,2546 dout_wb.wb_vtaps_chroma,2547 dout_wb.wb_dst_width,2548 pipes[pipe_cnt].pipe.dest.htotal,2549 2);2550 2551 if (writeback_dispclk > max_calc_writeback_dispclk) {2552 max_calc_writeback_dispclk = writeback_dispclk;2553 pipes[pipe_cnt].dout.wb = dout_wb;2554 }2555 }2556 }2557 2558 pipe_cnt++;2559 }2560 2561}2562