brintos

brintos / linux-shallow public Read only

0
0
Text · 87.8 KiB · e9fea9c Raw
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