xref: /linux/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c (revision 260f6f4fda93c8485c8037865c941b42b9cba5d2)
1e4b0eac3SJasdeep Dhillon /*
2e4b0eac3SJasdeep Dhillon  * Copyright 2020-2021 Advanced Micro Devices, Inc.
3e4b0eac3SJasdeep Dhillon  *
4e4b0eac3SJasdeep Dhillon  * Permission is hereby granted, free of charge, to any person obtaining a
5e4b0eac3SJasdeep Dhillon  * copy of this software and associated documentation files (the "Software"),
6e4b0eac3SJasdeep Dhillon  * to deal in the Software without restriction, including without limitation
7e4b0eac3SJasdeep Dhillon  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e4b0eac3SJasdeep Dhillon  * and/or sell copies of the Software, and to permit persons to whom the
9e4b0eac3SJasdeep Dhillon  * Software is furnished to do so, subject to the following conditions:
10e4b0eac3SJasdeep Dhillon  *
11e4b0eac3SJasdeep Dhillon  * The above copyright notice and this permission notice shall be included in
12e4b0eac3SJasdeep Dhillon  * all copies or substantial portions of the Software.
13e4b0eac3SJasdeep Dhillon  *
14e4b0eac3SJasdeep Dhillon  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15e4b0eac3SJasdeep Dhillon  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16e4b0eac3SJasdeep Dhillon  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17e4b0eac3SJasdeep Dhillon  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18e4b0eac3SJasdeep Dhillon  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19e4b0eac3SJasdeep Dhillon  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20e4b0eac3SJasdeep Dhillon  * OTHER DEALINGS IN THE SOFTWARE.
21e4b0eac3SJasdeep Dhillon  *
22e4b0eac3SJasdeep Dhillon  * Authors: AMD
23e4b0eac3SJasdeep Dhillon  *
24e4b0eac3SJasdeep Dhillon  */
25e4b0eac3SJasdeep Dhillon #include "resource.h"
26e4b0eac3SJasdeep Dhillon #include "clk_mgr.h"
27e4b0eac3SJasdeep Dhillon #include "reg_helper.h"
28e4b0eac3SJasdeep Dhillon #include "dcn_calc_math.h"
29e4b0eac3SJasdeep Dhillon #include "dcn20/dcn20_resource.h"
30e4b0eac3SJasdeep Dhillon #include "dcn30/dcn30_resource.h"
31e4b0eac3SJasdeep Dhillon 
32ddd0fa1fSMelissa Wen #include "clk_mgr/dcn30/dcn30_smu11_driver_if.h"
33e4b0eac3SJasdeep Dhillon #include "display_mode_vba_30.h"
34e4b0eac3SJasdeep Dhillon #include "dcn30_fpu.h"
35e4b0eac3SJasdeep Dhillon 
36e4b0eac3SJasdeep Dhillon #define REG(reg)\
37e4b0eac3SJasdeep Dhillon 	optc1->tg_regs->reg
38e4b0eac3SJasdeep Dhillon 
39e4b0eac3SJasdeep Dhillon #define CTX \
40e4b0eac3SJasdeep Dhillon 	optc1->base.ctx
41e4b0eac3SJasdeep Dhillon 
42e4b0eac3SJasdeep Dhillon #undef FN
43e4b0eac3SJasdeep Dhillon #define FN(reg_name, field_name) \
44e4b0eac3SJasdeep Dhillon 	optc1->tg_shift->field_name, optc1->tg_mask->field_name
45e4b0eac3SJasdeep Dhillon 
46e4b0eac3SJasdeep Dhillon 
47e4b0eac3SJasdeep Dhillon struct _vcs_dpi_ip_params_st dcn3_0_ip = {
48e4b0eac3SJasdeep Dhillon 	.use_min_dcfclk = 0,
49e4b0eac3SJasdeep Dhillon 	.clamp_min_dcfclk = 0,
50e4b0eac3SJasdeep Dhillon 	.odm_capable = 1,
51e4b0eac3SJasdeep Dhillon 	.gpuvm_enable = 0,
52e4b0eac3SJasdeep Dhillon 	.hostvm_enable = 0,
53e4b0eac3SJasdeep Dhillon 	.gpuvm_max_page_table_levels = 4,
54e4b0eac3SJasdeep Dhillon 	.hostvm_max_page_table_levels = 4,
55e4b0eac3SJasdeep Dhillon 	.hostvm_cached_page_table_levels = 0,
56e4b0eac3SJasdeep Dhillon 	.pte_group_size_bytes = 2048,
57e4b0eac3SJasdeep Dhillon 	.num_dsc = 6,
58e4b0eac3SJasdeep Dhillon 	.rob_buffer_size_kbytes = 184,
59e4b0eac3SJasdeep Dhillon 	.det_buffer_size_kbytes = 184,
60e4b0eac3SJasdeep Dhillon 	.dpte_buffer_size_in_pte_reqs_luma = 84,
61e4b0eac3SJasdeep Dhillon 	.pde_proc_buffer_size_64k_reqs = 48,
62e4b0eac3SJasdeep Dhillon 	.dpp_output_buffer_pixels = 2560,
63e4b0eac3SJasdeep Dhillon 	.opp_output_buffer_lines = 1,
64e4b0eac3SJasdeep Dhillon 	.pixel_chunk_size_kbytes = 8,
65e4b0eac3SJasdeep Dhillon 	.pte_enable = 1,
66e4b0eac3SJasdeep Dhillon 	.max_page_table_levels = 2,
67e4b0eac3SJasdeep Dhillon 	.pte_chunk_size_kbytes = 2,  // ?
68e4b0eac3SJasdeep Dhillon 	.meta_chunk_size_kbytes = 2,
69e4b0eac3SJasdeep Dhillon 	.writeback_chunk_size_kbytes = 8,
70e4b0eac3SJasdeep Dhillon 	.line_buffer_size_bits = 789504,
71e4b0eac3SJasdeep Dhillon 	.is_line_buffer_bpp_fixed = 0,  // ?
72e4b0eac3SJasdeep Dhillon 	.line_buffer_fixed_bpp = 0,     // ?
73e4b0eac3SJasdeep Dhillon 	.dcc_supported = true,
74e4b0eac3SJasdeep Dhillon 	.writeback_interface_buffer_size_kbytes = 90,
75e4b0eac3SJasdeep Dhillon 	.writeback_line_buffer_buffer_size = 0,
76e4b0eac3SJasdeep Dhillon 	.max_line_buffer_lines = 12,
77e4b0eac3SJasdeep Dhillon 	.writeback_luma_buffer_size_kbytes = 12,  // writeback_line_buffer_buffer_size = 656640
78e4b0eac3SJasdeep Dhillon 	.writeback_chroma_buffer_size_kbytes = 8,
79e4b0eac3SJasdeep Dhillon 	.writeback_chroma_line_buffer_width_pixels = 4,
80e4b0eac3SJasdeep Dhillon 	.writeback_max_hscl_ratio = 1,
81e4b0eac3SJasdeep Dhillon 	.writeback_max_vscl_ratio = 1,
82e4b0eac3SJasdeep Dhillon 	.writeback_min_hscl_ratio = 1,
83e4b0eac3SJasdeep Dhillon 	.writeback_min_vscl_ratio = 1,
84e4b0eac3SJasdeep Dhillon 	.writeback_max_hscl_taps = 1,
85e4b0eac3SJasdeep Dhillon 	.writeback_max_vscl_taps = 1,
86e4b0eac3SJasdeep Dhillon 	.writeback_line_buffer_luma_buffer_size = 0,
87e4b0eac3SJasdeep Dhillon 	.writeback_line_buffer_chroma_buffer_size = 14643,
88e4b0eac3SJasdeep Dhillon 	.cursor_buffer_size = 8,
89e4b0eac3SJasdeep Dhillon 	.cursor_chunk_size = 2,
90e4b0eac3SJasdeep Dhillon 	.max_num_otg = 6,
91e4b0eac3SJasdeep Dhillon 	.max_num_dpp = 6,
92e4b0eac3SJasdeep Dhillon 	.max_num_wb = 1,
93e4b0eac3SJasdeep Dhillon 	.max_dchub_pscl_bw_pix_per_clk = 4,
94e4b0eac3SJasdeep Dhillon 	.max_pscl_lb_bw_pix_per_clk = 2,
95e4b0eac3SJasdeep Dhillon 	.max_lb_vscl_bw_pix_per_clk = 4,
96e4b0eac3SJasdeep Dhillon 	.max_vscl_hscl_bw_pix_per_clk = 4,
97e4b0eac3SJasdeep Dhillon 	.max_hscl_ratio = 6,
98e4b0eac3SJasdeep Dhillon 	.max_vscl_ratio = 6,
99e4b0eac3SJasdeep Dhillon 	.hscl_mults = 4,
100e4b0eac3SJasdeep Dhillon 	.vscl_mults = 4,
101e4b0eac3SJasdeep Dhillon 	.max_hscl_taps = 8,
102e4b0eac3SJasdeep Dhillon 	.max_vscl_taps = 8,
103e4b0eac3SJasdeep Dhillon 	.dispclk_ramp_margin_percent = 1,
104e4b0eac3SJasdeep Dhillon 	.underscan_factor = 1.11,
105e4b0eac3SJasdeep Dhillon 	.min_vblank_lines = 32,
106e4b0eac3SJasdeep Dhillon 	.dppclk_delay_subtotal = 46,
107e4b0eac3SJasdeep Dhillon 	.dynamic_metadata_vm_enabled = true,
108e4b0eac3SJasdeep Dhillon 	.dppclk_delay_scl_lb_only = 16,
109e4b0eac3SJasdeep Dhillon 	.dppclk_delay_scl = 50,
110e4b0eac3SJasdeep Dhillon 	.dppclk_delay_cnvc_formatter = 27,
111e4b0eac3SJasdeep Dhillon 	.dppclk_delay_cnvc_cursor = 6,
112e4b0eac3SJasdeep Dhillon 	.dispclk_delay_subtotal = 119,
113e4b0eac3SJasdeep Dhillon 	.dcfclk_cstate_latency = 5.2, // SRExitTime
114e4b0eac3SJasdeep Dhillon 	.max_inter_dcn_tile_repeaters = 8,
115e4b0eac3SJasdeep Dhillon 	.max_num_hdmi_frl_outputs = 1,
116e4b0eac3SJasdeep Dhillon 	.odm_combine_4to1_supported = true,
117e4b0eac3SJasdeep Dhillon 
118e4b0eac3SJasdeep Dhillon 	.xfc_supported = false,
119e4b0eac3SJasdeep Dhillon 	.xfc_fill_bw_overhead_percent = 10.0,
120e4b0eac3SJasdeep Dhillon 	.xfc_fill_constant_bytes = 0,
121e4b0eac3SJasdeep Dhillon 	.gfx7_compat_tiling_supported = 0,
122e4b0eac3SJasdeep Dhillon 	.number_of_cursors = 1,
123e4b0eac3SJasdeep Dhillon };
124e4b0eac3SJasdeep Dhillon 
125e4b0eac3SJasdeep Dhillon struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = {
126e4b0eac3SJasdeep Dhillon 	.clock_limits = {
127e4b0eac3SJasdeep Dhillon 			{
128e4b0eac3SJasdeep Dhillon 				.state = 0,
129e4b0eac3SJasdeep Dhillon 				.dispclk_mhz = 562.0,
130e4b0eac3SJasdeep Dhillon 				.dppclk_mhz = 300.0,
131e4b0eac3SJasdeep Dhillon 				.phyclk_mhz = 300.0,
132e4b0eac3SJasdeep Dhillon 				.phyclk_d18_mhz = 667.0,
133e4b0eac3SJasdeep Dhillon 				.dscclk_mhz = 405.6,
134e4b0eac3SJasdeep Dhillon 			},
135e4b0eac3SJasdeep Dhillon 		},
136e4b0eac3SJasdeep Dhillon 
137e4b0eac3SJasdeep Dhillon 	.min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
138e4b0eac3SJasdeep Dhillon 	.num_states = 1,
139e4b0eac3SJasdeep Dhillon 	.sr_exit_time_us = 15.5,
140e4b0eac3SJasdeep Dhillon 	.sr_enter_plus_exit_time_us = 20,
141e4b0eac3SJasdeep Dhillon 	.urgent_latency_us = 4.0,
142e4b0eac3SJasdeep Dhillon 	.urgent_latency_pixel_data_only_us = 4.0,
143e4b0eac3SJasdeep Dhillon 	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
144e4b0eac3SJasdeep Dhillon 	.urgent_latency_vm_data_only_us = 4.0,
145e4b0eac3SJasdeep Dhillon 	.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
146e4b0eac3SJasdeep Dhillon 	.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
147e4b0eac3SJasdeep Dhillon 	.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
148e4b0eac3SJasdeep Dhillon 	.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
149e4b0eac3SJasdeep Dhillon 	.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
150e4b0eac3SJasdeep Dhillon 	.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
151e4b0eac3SJasdeep Dhillon 	.max_avg_sdp_bw_use_normal_percent = 60.0,
152e4b0eac3SJasdeep Dhillon 	.max_avg_dram_bw_use_normal_percent = 40.0,
153e4b0eac3SJasdeep Dhillon 	.writeback_latency_us = 12.0,
154e4b0eac3SJasdeep Dhillon 	.max_request_size_bytes = 256,
155e4b0eac3SJasdeep Dhillon 	.fabric_datapath_to_dcn_data_return_bytes = 64,
156e4b0eac3SJasdeep Dhillon 	.dcn_downspread_percent = 0.5,
157e4b0eac3SJasdeep Dhillon 	.downspread_percent = 0.38,
158e4b0eac3SJasdeep Dhillon 	.dram_page_open_time_ns = 50.0,
159e4b0eac3SJasdeep Dhillon 	.dram_rw_turnaround_time_ns = 17.5,
160e4b0eac3SJasdeep Dhillon 	.dram_return_buffer_per_channel_bytes = 8192,
161e4b0eac3SJasdeep Dhillon 	.round_trip_ping_latency_dcfclk_cycles = 191,
162e4b0eac3SJasdeep Dhillon 	.urgent_out_of_order_return_per_channel_bytes = 4096,
163e4b0eac3SJasdeep Dhillon 	.channel_interleave_bytes = 256,
164e4b0eac3SJasdeep Dhillon 	.num_banks = 8,
165e4b0eac3SJasdeep Dhillon 	.gpuvm_min_page_size_bytes = 4096,
166e4b0eac3SJasdeep Dhillon 	.hostvm_min_page_size_bytes = 4096,
167e4b0eac3SJasdeep Dhillon 	.dram_clock_change_latency_us = 404,
168e4b0eac3SJasdeep Dhillon 	.dummy_pstate_latency_us = 5,
169e4b0eac3SJasdeep Dhillon 	.writeback_dram_clock_change_latency_us = 23.0,
170e4b0eac3SJasdeep Dhillon 	.return_bus_width_bytes = 64,
171e4b0eac3SJasdeep Dhillon 	.dispclk_dppclk_vco_speed_mhz = 3650,
172e4b0eac3SJasdeep Dhillon 	.xfc_bus_transport_time_us = 20,      // ?
173e4b0eac3SJasdeep Dhillon 	.xfc_xbuf_latency_tolerance_us = 4,  // ?
174e4b0eac3SJasdeep Dhillon 	.use_urgent_burst_bw = 1,            // ?
175e4b0eac3SJasdeep Dhillon 	.do_urgent_latency_adjustment = true,
176e4b0eac3SJasdeep Dhillon 	.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
177e4b0eac3SJasdeep Dhillon 	.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
178e4b0eac3SJasdeep Dhillon };
179e4b0eac3SJasdeep Dhillon 
180e4b0eac3SJasdeep Dhillon 
dcn30_fpu_populate_dml_writeback_from_context(struct dc * dc,struct resource_context * res_ctx,display_e2e_pipe_params_st * pipes)181e4b0eac3SJasdeep Dhillon void dcn30_fpu_populate_dml_writeback_from_context(
182e4b0eac3SJasdeep Dhillon 		struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
183e4b0eac3SJasdeep Dhillon {
184e4b0eac3SJasdeep Dhillon 	int pipe_cnt, i, j;
185e4b0eac3SJasdeep Dhillon 	double max_calc_writeback_dispclk;
186e4b0eac3SJasdeep Dhillon 	double writeback_dispclk;
187f851b078SAlex Hung 	struct writeback_st dout_wb = {0};
188e4b0eac3SJasdeep Dhillon 
189e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
190e4b0eac3SJasdeep Dhillon 
191e4b0eac3SJasdeep Dhillon 	for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
192e4b0eac3SJasdeep Dhillon 		struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream;
193e4b0eac3SJasdeep Dhillon 
194e4b0eac3SJasdeep Dhillon 		if (!stream)
195e4b0eac3SJasdeep Dhillon 			continue;
196e4b0eac3SJasdeep Dhillon 		max_calc_writeback_dispclk = 0;
197e4b0eac3SJasdeep Dhillon 
198e4b0eac3SJasdeep Dhillon 		/* Set writeback information */
199e4b0eac3SJasdeep Dhillon 		pipes[pipe_cnt].dout.wb_enable = 0;
200e4b0eac3SJasdeep Dhillon 		pipes[pipe_cnt].dout.num_active_wb = 0;
201e4b0eac3SJasdeep Dhillon 		for (j = 0; j < stream->num_wb_info; j++) {
202e4b0eac3SJasdeep Dhillon 			struct dc_writeback_info *wb_info = &stream->writeback_info[j];
203e4b0eac3SJasdeep Dhillon 
204e4b0eac3SJasdeep Dhillon 			if (wb_info->wb_enabled && wb_info->writeback_source_plane &&
205e4b0eac3SJasdeep Dhillon 					(wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) {
206e4b0eac3SJasdeep Dhillon 				pipes[pipe_cnt].dout.wb_enable = 1;
207e4b0eac3SJasdeep Dhillon 				pipes[pipe_cnt].dout.num_active_wb++;
208e4b0eac3SJasdeep Dhillon 				dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ?
209e4b0eac3SJasdeep Dhillon 					wb_info->dwb_params.cnv_params.crop_height :
210e4b0eac3SJasdeep Dhillon 					wb_info->dwb_params.cnv_params.src_height;
211e4b0eac3SJasdeep Dhillon 				dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ?
212e4b0eac3SJasdeep Dhillon 					wb_info->dwb_params.cnv_params.crop_width :
213e4b0eac3SJasdeep Dhillon 					wb_info->dwb_params.cnv_params.src_width;
214e4b0eac3SJasdeep Dhillon 				dout_wb.wb_dst_width = wb_info->dwb_params.dest_width;
215e4b0eac3SJasdeep Dhillon 				dout_wb.wb_dst_height = wb_info->dwb_params.dest_height;
216e4b0eac3SJasdeep Dhillon 
217e4b0eac3SJasdeep Dhillon 				/* For IP that doesn't support WB scaling, set h/v taps to 1 to avoid DML validation failure */
218e4b0eac3SJasdeep Dhillon 				if (dc->dml.ip.writeback_max_hscl_taps > 1) {
219e4b0eac3SJasdeep Dhillon 					dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps;
220e4b0eac3SJasdeep Dhillon 					dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;
221e4b0eac3SJasdeep Dhillon 				} else {
222e4b0eac3SJasdeep Dhillon 					dout_wb.wb_htaps_luma = 1;
223e4b0eac3SJasdeep Dhillon 					dout_wb.wb_vtaps_luma = 1;
224e4b0eac3SJasdeep Dhillon 				}
225e4b0eac3SJasdeep Dhillon 				dout_wb.wb_htaps_chroma = 0;
226e4b0eac3SJasdeep Dhillon 				dout_wb.wb_vtaps_chroma = 0;
227e4b0eac3SJasdeep Dhillon 				dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ?
228e4b0eac3SJasdeep Dhillon 					(double)wb_info->dwb_params.cnv_params.crop_width /
229e4b0eac3SJasdeep Dhillon 						(double)wb_info->dwb_params.dest_width :
230e4b0eac3SJasdeep Dhillon 					(double)wb_info->dwb_params.cnv_params.src_width /
231e4b0eac3SJasdeep Dhillon 						(double)wb_info->dwb_params.dest_width;
232e4b0eac3SJasdeep Dhillon 				dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ?
233e4b0eac3SJasdeep Dhillon 					(double)wb_info->dwb_params.cnv_params.crop_height /
234e4b0eac3SJasdeep Dhillon 						(double)wb_info->dwb_params.dest_height :
235e4b0eac3SJasdeep Dhillon 					(double)wb_info->dwb_params.cnv_params.src_height /
236e4b0eac3SJasdeep Dhillon 						(double)wb_info->dwb_params.dest_height;
237e4b0eac3SJasdeep Dhillon 				if (wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_ARGB ||
238e4b0eac3SJasdeep Dhillon 					wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_RGBA)
239e4b0eac3SJasdeep Dhillon 					dout_wb.wb_pixel_format = dm_444_64;
240e4b0eac3SJasdeep Dhillon 				else
241e4b0eac3SJasdeep Dhillon 					dout_wb.wb_pixel_format = dm_444_32;
242e4b0eac3SJasdeep Dhillon 
243e4b0eac3SJasdeep Dhillon 				/* Workaround for cases where multiple writebacks are connected to same plane
244e4b0eac3SJasdeep Dhillon 				 * In which case, need to compute worst case and set the associated writeback parameters
245e4b0eac3SJasdeep Dhillon 				 * This workaround is necessary due to DML computation assuming only 1 set of writeback
246e4b0eac3SJasdeep Dhillon 				 * parameters per pipe
247e4b0eac3SJasdeep Dhillon 				 */
248e4b0eac3SJasdeep Dhillon 				writeback_dispclk = dml30_CalculateWriteBackDISPCLK(
249e4b0eac3SJasdeep Dhillon 						dout_wb.wb_pixel_format,
250e4b0eac3SJasdeep Dhillon 						pipes[pipe_cnt].pipe.dest.pixel_rate_mhz,
251e4b0eac3SJasdeep Dhillon 						dout_wb.wb_hratio,
252e4b0eac3SJasdeep Dhillon 						dout_wb.wb_vratio,
253e4b0eac3SJasdeep Dhillon 						dout_wb.wb_htaps_luma,
254e4b0eac3SJasdeep Dhillon 						dout_wb.wb_vtaps_luma,
255e4b0eac3SJasdeep Dhillon 						dout_wb.wb_src_width,
256e4b0eac3SJasdeep Dhillon 						dout_wb.wb_dst_width,
257e4b0eac3SJasdeep Dhillon 						pipes[pipe_cnt].pipe.dest.htotal,
258e4b0eac3SJasdeep Dhillon 						dc->current_state->bw_ctx.dml.ip.writeback_line_buffer_buffer_size);
259e4b0eac3SJasdeep Dhillon 
260e4b0eac3SJasdeep Dhillon 				if (writeback_dispclk > max_calc_writeback_dispclk) {
261e4b0eac3SJasdeep Dhillon 					max_calc_writeback_dispclk = writeback_dispclk;
262e4b0eac3SJasdeep Dhillon 					pipes[pipe_cnt].dout.wb = dout_wb;
263e4b0eac3SJasdeep Dhillon 				}
264e4b0eac3SJasdeep Dhillon 			}
265e4b0eac3SJasdeep Dhillon 		}
266e4b0eac3SJasdeep Dhillon 
267e4b0eac3SJasdeep Dhillon 		pipe_cnt++;
268e4b0eac3SJasdeep Dhillon 	}
269e4b0eac3SJasdeep Dhillon }
270e4b0eac3SJasdeep Dhillon 
dcn30_fpu_set_mcif_arb_params(struct mcif_arb_params * wb_arb_params,struct display_mode_lib * dml,display_e2e_pipe_params_st * pipes,int pipe_cnt,int cur_pipe)271e4b0eac3SJasdeep Dhillon void dcn30_fpu_set_mcif_arb_params(struct mcif_arb_params *wb_arb_params,
272e4b0eac3SJasdeep Dhillon 	struct display_mode_lib *dml,
273e4b0eac3SJasdeep Dhillon 	display_e2e_pipe_params_st *pipes,
274e4b0eac3SJasdeep Dhillon 	int pipe_cnt,
275e4b0eac3SJasdeep Dhillon 	int cur_pipe)
276e4b0eac3SJasdeep Dhillon {
277e4b0eac3SJasdeep Dhillon 	int i;
278e4b0eac3SJasdeep Dhillon 
279e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
280e4b0eac3SJasdeep Dhillon 
28166bd94deSJiapeng Chong 	for (i = 0; i < ARRAY_SIZE(wb_arb_params->cli_watermark); i++) {
282e4b0eac3SJasdeep Dhillon 		wb_arb_params->cli_watermark[i] = get_wm_writeback_urgent(dml, pipes, pipe_cnt) * 1000;
283e4b0eac3SJasdeep Dhillon 		wb_arb_params->pstate_watermark[i] = get_wm_writeback_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
284e4b0eac3SJasdeep Dhillon 	}
285e4b0eac3SJasdeep Dhillon 
286e4b0eac3SJasdeep Dhillon 	wb_arb_params->dram_speed_change_duration = dml->vba.WritebackAllowDRAMClockChangeEndPosition[cur_pipe] * pipes[0].clks_cfg.refclk_mhz; /* num_clock_cycles = us * MHz */
287e4b0eac3SJasdeep Dhillon }
288e4b0eac3SJasdeep Dhillon 
dcn30_fpu_update_soc_for_wm_a(struct dc * dc,struct dc_state * context)289e4b0eac3SJasdeep Dhillon void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
290e4b0eac3SJasdeep Dhillon {
291e4b0eac3SJasdeep Dhillon 
292e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
293e4b0eac3SJasdeep Dhillon 
294e4b0eac3SJasdeep Dhillon 	if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) {
295e0a77e09SRodrigo Siqueira 		if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching ||
296e0a77e09SRodrigo Siqueira 				context->bw_ctx.dml.soc.dram_clock_change_latency_us == 0)
297e4b0eac3SJasdeep Dhillon 			context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
298e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us;
299e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us;
300e4b0eac3SJasdeep Dhillon 	}
301e4b0eac3SJasdeep Dhillon }
302e4b0eac3SJasdeep Dhillon 
dcn30_fpu_calculate_wm_and_dlg(struct dc * dc,struct dc_state * context,display_e2e_pipe_params_st * pipes,int pipe_cnt,int vlevel)303e4b0eac3SJasdeep Dhillon void dcn30_fpu_calculate_wm_and_dlg(
304e4b0eac3SJasdeep Dhillon 		struct dc *dc, struct dc_state *context,
305e4b0eac3SJasdeep Dhillon 		display_e2e_pipe_params_st *pipes,
306e4b0eac3SJasdeep Dhillon 		int pipe_cnt,
307e4b0eac3SJasdeep Dhillon 		int vlevel)
308e4b0eac3SJasdeep Dhillon {
309e4b0eac3SJasdeep Dhillon 	int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
310e4b0eac3SJasdeep Dhillon 	int i, pipe_idx;
311e4b0eac3SJasdeep Dhillon 	double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb];
312e4b0eac3SJasdeep Dhillon 	bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported;
313e8e5cc64SQingqing Zhuo 	unsigned int dummy_latency_index = 0;
314e69d4335SAlvin Lee 	struct dc_stream_status *stream_status = NULL;
315e4b0eac3SJasdeep Dhillon 
316e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
317e4b0eac3SJasdeep Dhillon 
318e8e5cc64SQingqing Zhuo 	context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false;
3194ed79308SAlvin Lee 	for (i = 0; i < context->stream_count; i++) {
320e69d4335SAlvin Lee 		stream_status = NULL;
3214ed79308SAlvin Lee 		if (context->streams[i])
322e69d4335SAlvin Lee 			stream_status = dc_state_get_stream_status(context, context->streams[i]);
323e69d4335SAlvin Lee 		if (stream_status)
324e69d4335SAlvin Lee 			stream_status->fpo_in_use = false;
3254ed79308SAlvin Lee 	}
326e8e5cc64SQingqing Zhuo 
327e8e5cc64SQingqing Zhuo 	if (!pstate_en) {
328e8e5cc64SQingqing Zhuo 		/* only when the mclk switch can not be natural, is the fw based vblank stretch attempted */
329e8e5cc64SQingqing Zhuo 		context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching =
330e8e5cc64SQingqing Zhuo 			dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(dc, context);
331e8e5cc64SQingqing Zhuo 
332e8e5cc64SQingqing Zhuo 		if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
333e8e5cc64SQingqing Zhuo 			dummy_latency_index = dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(dc,
334e8e5cc64SQingqing Zhuo 				context, pipes, pipe_cnt, vlevel);
335e8e5cc64SQingqing Zhuo 
336e8e5cc64SQingqing Zhuo 			/* After calling dcn30_find_dummy_latency_index_for_fw_based_mclk_switch
337e8e5cc64SQingqing Zhuo 			 * we reinstate the original dram_clock_change_latency_us on the context
338e8e5cc64SQingqing Zhuo 			 * and all variables that may have changed up to this point, except the
339e8e5cc64SQingqing Zhuo 			 * newly found dummy_latency_index
340e8e5cc64SQingqing Zhuo 			 */
341e8e5cc64SQingqing Zhuo 			context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
342*269c1d14SYan Li 			dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel,
343*269c1d14SYan Li 				DC_VALIDATE_MODE_AND_PROGRAMMING, true);
344e8e5cc64SQingqing Zhuo 			maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
345e8e5cc64SQingqing Zhuo 			dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
346e8e5cc64SQingqing Zhuo 			pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported;
347e8e5cc64SQingqing Zhuo 		}
348e8e5cc64SQingqing Zhuo 	}
349e8e5cc64SQingqing Zhuo 
350e4b0eac3SJasdeep Dhillon 	if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
351e4b0eac3SJasdeep Dhillon 		dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
352e4b0eac3SJasdeep Dhillon 
353e4b0eac3SJasdeep Dhillon 	pipes[0].clks_cfg.voltage = vlevel;
354e4b0eac3SJasdeep Dhillon 	pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
355e4b0eac3SJasdeep Dhillon 	pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
356e4b0eac3SJasdeep Dhillon 
357e4b0eac3SJasdeep Dhillon 	/* Set B:
358e4b0eac3SJasdeep Dhillon 	 * DCFCLK: 1GHz or min required above 1GHz
359e4b0eac3SJasdeep Dhillon 	 * FCLK/UCLK: Max
360e4b0eac3SJasdeep Dhillon 	 */
361e4b0eac3SJasdeep Dhillon 	if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) {
362e4b0eac3SJasdeep Dhillon 		if (vlevel == 0) {
363e4b0eac3SJasdeep Dhillon 			pipes[0].clks_cfg.voltage = 1;
364e4b0eac3SJasdeep Dhillon 			pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz;
365e4b0eac3SJasdeep Dhillon 		}
366e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us;
367e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us;
368e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us;
369e4b0eac3SJasdeep Dhillon 	}
370e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
371e4b0eac3SJasdeep Dhillon 	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;
372e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
373e4b0eac3SJasdeep Dhillon 	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;
374e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
375e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
376e4b0eac3SJasdeep Dhillon 	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;
377e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
378e4b0eac3SJasdeep Dhillon 
379e4b0eac3SJasdeep Dhillon 	pipes[0].clks_cfg.voltage = vlevel;
380e4b0eac3SJasdeep Dhillon 	pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
381e4b0eac3SJasdeep Dhillon 
382e4b0eac3SJasdeep Dhillon 	/* Set D:
383e4b0eac3SJasdeep Dhillon 	 * DCFCLK: Min Required
384e4b0eac3SJasdeep Dhillon 	 * FCLK(proportional to UCLK): 1GHz or Max
385e4b0eac3SJasdeep Dhillon 	 * MALL stutter, sr_enter_exit = 4, sr_exit = 2us
386e4b0eac3SJasdeep Dhillon 	 */
387e4b0eac3SJasdeep Dhillon 	/*
388e4b0eac3SJasdeep Dhillon 	if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
389e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us;
390e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us;
391e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us;
392e4b0eac3SJasdeep Dhillon 	}
393e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
394e4b0eac3SJasdeep Dhillon 	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;
395e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
396e4b0eac3SJasdeep Dhillon 	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;
397e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
398e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
399e4b0eac3SJasdeep Dhillon 	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;
400e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
401e4b0eac3SJasdeep Dhillon 	*/
402e4b0eac3SJasdeep Dhillon 
403e4b0eac3SJasdeep Dhillon 	/* Set C:
404e4b0eac3SJasdeep Dhillon 	 * DCFCLK: Min Required
405e4b0eac3SJasdeep Dhillon 	 * FCLK(proportional to UCLK): 1GHz or Max
406e4b0eac3SJasdeep Dhillon 	 * pstate latency overridden to 5us
407e4b0eac3SJasdeep Dhillon 	 */
408e4b0eac3SJasdeep Dhillon 	if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
409e4b0eac3SJasdeep Dhillon 		unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
410e4b0eac3SJasdeep Dhillon 		unsigned int min_dram_speed_mts_margin = 160;
411e4b0eac3SJasdeep Dhillon 
412e8e5cc64SQingqing Zhuo 		context->bw_ctx.dml.soc.dram_clock_change_latency_us =
413e8e5cc64SQingqing Zhuo 			dc->clk_mgr->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us;
414e4b0eac3SJasdeep Dhillon 
415e8e5cc64SQingqing Zhuo 		if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
416e8e5cc64SQingqing Zhuo 			dm_dram_clock_change_unsupported) {
417e8e5cc64SQingqing Zhuo 			int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1;
418e8e5cc64SQingqing Zhuo 
419e8e5cc64SQingqing Zhuo 			min_dram_speed_mts =
420e8e5cc64SQingqing Zhuo 				dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
421e8e5cc64SQingqing Zhuo 		}
422e8e5cc64SQingqing Zhuo 
423e8e5cc64SQingqing Zhuo 		if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
424e8e5cc64SQingqing Zhuo 			/* find largest table entry that is lower than dram speed,
425e8e5cc64SQingqing Zhuo 			 * but lower than DPM0 still uses DPM0
426e8e5cc64SQingqing Zhuo 			 */
427e8e5cc64SQingqing Zhuo 			for (dummy_latency_index = 3; dummy_latency_index > 0; dummy_latency_index--)
428e8e5cc64SQingqing Zhuo 				if (min_dram_speed_mts + min_dram_speed_mts_margin >
429e8e5cc64SQingqing Zhuo 					dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dram_speed_mts)
430e4b0eac3SJasdeep Dhillon 					break;
431e8e5cc64SQingqing Zhuo 		}
432e4b0eac3SJasdeep Dhillon 
433e8e5cc64SQingqing Zhuo 		context->bw_ctx.dml.soc.dram_clock_change_latency_us =
434e8e5cc64SQingqing Zhuo 			dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
435e4b0eac3SJasdeep Dhillon 
436e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
437e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
438e4b0eac3SJasdeep Dhillon 	}
439e4b0eac3SJasdeep Dhillon 
440e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
441e4b0eac3SJasdeep Dhillon 	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;
442e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
443e4b0eac3SJasdeep Dhillon 	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;
444e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
445e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
446e4b0eac3SJasdeep Dhillon 	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;
447e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
448e4b0eac3SJasdeep Dhillon 
449e4b0eac3SJasdeep Dhillon 	if (!pstate_en) {
450e4b0eac3SJasdeep Dhillon 		/* The only difference between A and C is p-state latency, if p-state is not supported we want to
451e4b0eac3SJasdeep Dhillon 		 * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark
452e4b0eac3SJasdeep Dhillon 		 */
453e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c;
454e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0;
455e4b0eac3SJasdeep Dhillon 	} else {
456e4b0eac3SJasdeep Dhillon 		/* Set A:
457e4b0eac3SJasdeep Dhillon 		 * DCFCLK: Min Required
458e4b0eac3SJasdeep Dhillon 		 * FCLK(proportional to UCLK): 1GHz or Max
459e4b0eac3SJasdeep Dhillon 		 *
460e4b0eac3SJasdeep Dhillon 		 * Set A calculated last so that following calculations are based on Set A
461e4b0eac3SJasdeep Dhillon 		 */
462e4b0eac3SJasdeep Dhillon 		dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
463e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
464e4b0eac3SJasdeep Dhillon 		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;
465e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
466e4b0eac3SJasdeep Dhillon 		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;
467e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
468e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
469e4b0eac3SJasdeep Dhillon 		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;
470e4b0eac3SJasdeep Dhillon 		context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
471e4b0eac3SJasdeep Dhillon 	}
472e4b0eac3SJasdeep Dhillon 
473e4b0eac3SJasdeep Dhillon 	context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
474e4b0eac3SJasdeep Dhillon 
475e4b0eac3SJasdeep Dhillon 	/* Make set D = set A until set D is enabled */
476e4b0eac3SJasdeep Dhillon 	context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a;
477e4b0eac3SJasdeep Dhillon 
478e4b0eac3SJasdeep Dhillon 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
479e4b0eac3SJasdeep Dhillon 		if (!context->res_ctx.pipe_ctx[i].stream)
480e4b0eac3SJasdeep Dhillon 			continue;
481e4b0eac3SJasdeep Dhillon 
482e4b0eac3SJasdeep Dhillon 		pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
483e4b0eac3SJasdeep Dhillon 		pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
484e4b0eac3SJasdeep Dhillon 
485e4b0eac3SJasdeep Dhillon 		if (dc->config.forced_clocks) {
486e4b0eac3SJasdeep Dhillon 			pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
487e4b0eac3SJasdeep Dhillon 			pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
488e4b0eac3SJasdeep Dhillon 		}
489e4b0eac3SJasdeep Dhillon 		if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
490e4b0eac3SJasdeep Dhillon 			pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
491e4b0eac3SJasdeep Dhillon 		if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
492e4b0eac3SJasdeep Dhillon 			pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
493e4b0eac3SJasdeep Dhillon 
494e4b0eac3SJasdeep Dhillon 		pipe_idx++;
495e4b0eac3SJasdeep Dhillon 	}
496e4b0eac3SJasdeep Dhillon 
497e0a77e09SRodrigo Siqueira 	// WA: restrict FPO to use first non-strobe mode (NV24 BW issue)
498e0a77e09SRodrigo Siqueira 	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching &&
499e0a77e09SRodrigo Siqueira 			dc->dml.soc.num_chans <= 4 &&
500e0a77e09SRodrigo Siqueira 			context->bw_ctx.dml.vba.DRAMSpeed <= 1700 &&
501e0a77e09SRodrigo Siqueira 			context->bw_ctx.dml.vba.DRAMSpeed >= 1500) {
502e0a77e09SRodrigo Siqueira 
503e0a77e09SRodrigo Siqueira 		for (i = 0; i < dc->dml.soc.num_states; i++) {
504e0a77e09SRodrigo Siqueira 			if (dc->dml.soc.clock_limits[i].dram_speed_mts > 1700) {
505e0a77e09SRodrigo Siqueira 				context->bw_ctx.dml.vba.DRAMSpeed = dc->dml.soc.clock_limits[i].dram_speed_mts;
506e0a77e09SRodrigo Siqueira 				break;
507e0a77e09SRodrigo Siqueira 			}
508e0a77e09SRodrigo Siqueira 		}
509e0a77e09SRodrigo Siqueira 	}
510e0a77e09SRodrigo Siqueira 
511e4b0eac3SJasdeep Dhillon 	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
512e4b0eac3SJasdeep Dhillon 
513e4b0eac3SJasdeep Dhillon 	if (!pstate_en)
514e4b0eac3SJasdeep Dhillon 		/* Restore full p-state latency */
515e4b0eac3SJasdeep Dhillon 		context->bw_ctx.dml.soc.dram_clock_change_latency_us =
516e4b0eac3SJasdeep Dhillon 				dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
517e4b0eac3SJasdeep Dhillon 
51800fa7f03SRodrigo Siqueira 	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
51900fa7f03SRodrigo Siqueira 		dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context);
520e4b0eac3SJasdeep Dhillon }
521e4b0eac3SJasdeep Dhillon 
dcn30_fpu_update_dram_channel_width_bytes(struct dc * dc)522e4b0eac3SJasdeep Dhillon void dcn30_fpu_update_dram_channel_width_bytes(struct dc *dc)
523e4b0eac3SJasdeep Dhillon {
524e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
525e4b0eac3SJasdeep Dhillon 
526e4b0eac3SJasdeep Dhillon 	if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
527e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
528e4b0eac3SJasdeep Dhillon }
529e4b0eac3SJasdeep Dhillon 
dcn30_fpu_update_max_clk(struct dc_bounding_box_max_clk * dcn30_bb_max_clk)530e4b0eac3SJasdeep Dhillon void dcn30_fpu_update_max_clk(struct dc_bounding_box_max_clk *dcn30_bb_max_clk)
531e4b0eac3SJasdeep Dhillon {
532e4b0eac3SJasdeep Dhillon 		dc_assert_fp_enabled();
533e4b0eac3SJasdeep Dhillon 
534e4b0eac3SJasdeep Dhillon 		if (!dcn30_bb_max_clk->max_dcfclk_mhz)
535e4b0eac3SJasdeep Dhillon 			dcn30_bb_max_clk->max_dcfclk_mhz = dcn3_0_soc.clock_limits[0].dcfclk_mhz;
536e4b0eac3SJasdeep Dhillon 		if (!dcn30_bb_max_clk->max_dispclk_mhz)
537e4b0eac3SJasdeep Dhillon 			dcn30_bb_max_clk->max_dispclk_mhz = dcn3_0_soc.clock_limits[0].dispclk_mhz;
538e4b0eac3SJasdeep Dhillon 		if (!dcn30_bb_max_clk->max_dppclk_mhz)
539e4b0eac3SJasdeep Dhillon 			dcn30_bb_max_clk->max_dppclk_mhz = dcn3_0_soc.clock_limits[0].dppclk_mhz;
540e4b0eac3SJasdeep Dhillon 		if (!dcn30_bb_max_clk->max_phyclk_mhz)
541e4b0eac3SJasdeep Dhillon 			dcn30_bb_max_clk->max_phyclk_mhz = dcn3_0_soc.clock_limits[0].phyclk_mhz;
542e4b0eac3SJasdeep Dhillon }
543e4b0eac3SJasdeep Dhillon 
dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,unsigned int * optimal_dcfclk,unsigned int * optimal_fclk)544e4b0eac3SJasdeep Dhillon void dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
545e4b0eac3SJasdeep Dhillon 		unsigned int *optimal_dcfclk,
546e4b0eac3SJasdeep Dhillon 		unsigned int *optimal_fclk)
547e4b0eac3SJasdeep Dhillon {
548e4b0eac3SJasdeep Dhillon 	double bw_from_dram, bw_from_dram1, bw_from_dram2;
549e4b0eac3SJasdeep Dhillon 
550e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
551e4b0eac3SJasdeep Dhillon 
552e4b0eac3SJasdeep Dhillon 	bw_from_dram1 = uclk_mts * dcn3_0_soc.num_chans *
553e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_dram_bw_use_normal_percent / 100);
554e4b0eac3SJasdeep Dhillon 	bw_from_dram2 = uclk_mts * dcn3_0_soc.num_chans *
555e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100);
556e4b0eac3SJasdeep Dhillon 
557e4b0eac3SJasdeep Dhillon 	bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
558e4b0eac3SJasdeep Dhillon 
559e4b0eac3SJasdeep Dhillon 	if (optimal_fclk)
560e4b0eac3SJasdeep Dhillon 		*optimal_fclk = bw_from_dram /
561e4b0eac3SJasdeep Dhillon 		(dcn3_0_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100));
562e4b0eac3SJasdeep Dhillon 
563e4b0eac3SJasdeep Dhillon 	if (optimal_dcfclk)
564e4b0eac3SJasdeep Dhillon 		*optimal_dcfclk =  bw_from_dram /
565e4b0eac3SJasdeep Dhillon 		(dcn3_0_soc.return_bus_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100));
566e4b0eac3SJasdeep Dhillon }
567e4b0eac3SJasdeep Dhillon 
dcn30_fpu_update_bw_bounding_box(struct dc * dc,struct clk_bw_params * bw_params,struct dc_bounding_box_max_clk * dcn30_bb_max_clk,unsigned int * dcfclk_mhz,unsigned int * dram_speed_mts)568e4b0eac3SJasdeep Dhillon void dcn30_fpu_update_bw_bounding_box(struct dc *dc,
569e4b0eac3SJasdeep Dhillon 	struct clk_bw_params *bw_params,
570e4b0eac3SJasdeep Dhillon 	struct dc_bounding_box_max_clk *dcn30_bb_max_clk,
571e4b0eac3SJasdeep Dhillon 	unsigned int *dcfclk_mhz,
572e4b0eac3SJasdeep Dhillon 	unsigned int *dram_speed_mts)
573e4b0eac3SJasdeep Dhillon {
574e4b0eac3SJasdeep Dhillon 	unsigned int i;
575e4b0eac3SJasdeep Dhillon 
576e4b0eac3SJasdeep Dhillon 	dc_assert_fp_enabled();
577e4b0eac3SJasdeep Dhillon 
578e4b0eac3SJasdeep Dhillon 	dcn3_0_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
579e4b0eac3SJasdeep Dhillon 	dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
580e4b0eac3SJasdeep Dhillon 
581e4b0eac3SJasdeep Dhillon 	for (i = 0; i < dcn3_0_soc.num_states; i++) {
582e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].state = i;
583e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
584e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
585e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
586e4b0eac3SJasdeep Dhillon 
587e4b0eac3SJasdeep Dhillon 		/* Fill all states with max values of all other clocks */
588e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].dispclk_mhz = dcn30_bb_max_clk->max_dispclk_mhz;
589e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].dppclk_mhz  = dcn30_bb_max_clk->max_dppclk_mhz;
590e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].phyclk_mhz  = dcn30_bb_max_clk->max_phyclk_mhz;
591e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].dtbclk_mhz = dcn3_0_soc.clock_limits[0].dtbclk_mhz;
592e4b0eac3SJasdeep Dhillon 		/* These clocks cannot come from bw_params, always fill from dcn3_0_soc[1] */
593e4b0eac3SJasdeep Dhillon 		/* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */
594e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].phyclk_d18_mhz = dcn3_0_soc.clock_limits[0].phyclk_d18_mhz;
595e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].socclk_mhz = dcn3_0_soc.clock_limits[0].socclk_mhz;
596e4b0eac3SJasdeep Dhillon 		dcn3_0_soc.clock_limits[i].dscclk_mhz = dcn3_0_soc.clock_limits[0].dscclk_mhz;
597e4b0eac3SJasdeep Dhillon 	}
598e4b0eac3SJasdeep Dhillon 	/* re-init DML with updated bb */
599e4b0eac3SJasdeep Dhillon 	dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
600e4b0eac3SJasdeep Dhillon 	if (dc->current_state)
601e4b0eac3SJasdeep Dhillon 		dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
602e4b0eac3SJasdeep Dhillon 
603e4b0eac3SJasdeep Dhillon }
604e4b0eac3SJasdeep Dhillon 
60505674cc9SRodrigo Siqueira /**
6066b37fee5SSrinivasan Shanmugam  * dcn30_find_dummy_latency_index_for_fw_based_mclk_switch() - Finds
6076b37fee5SSrinivasan Shanmugam  * dummy_latency_index when MCLK switching using firmware based vblank stretch
6086b37fee5SSrinivasan Shanmugam  * is enabled. This function will iterate through the table of dummy pstate
6096b37fee5SSrinivasan Shanmugam  * latencies until the lowest value that allows
61005674cc9SRodrigo Siqueira  * dm_allow_self_refresh_and_mclk_switch to happen is found
6116b37fee5SSrinivasan Shanmugam  *
6126b37fee5SSrinivasan Shanmugam  * @dc: Current DC state
6136b37fee5SSrinivasan Shanmugam  * @context: new dc state
6146b37fee5SSrinivasan Shanmugam  * @pipes: DML pipe params
6156b37fee5SSrinivasan Shanmugam  * @pipe_cnt: number of DML pipes
6166b37fee5SSrinivasan Shanmugam  * @vlevel: Voltage level calculated by DML
6176b37fee5SSrinivasan Shanmugam  *
6186b37fee5SSrinivasan Shanmugam  * Return: lowest dummy_latency_index value
61905674cc9SRodrigo Siqueira  */
dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc * dc,struct dc_state * context,display_e2e_pipe_params_st * pipes,int pipe_cnt,int vlevel)62005674cc9SRodrigo Siqueira int dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
62105674cc9SRodrigo Siqueira 							    struct dc_state *context,
62205674cc9SRodrigo Siqueira 							    display_e2e_pipe_params_st *pipes,
62305674cc9SRodrigo Siqueira 							    int pipe_cnt,
62405674cc9SRodrigo Siqueira 							    int vlevel)
62505674cc9SRodrigo Siqueira {
62605674cc9SRodrigo Siqueira 	const int max_latency_table_entries = 4;
62705674cc9SRodrigo Siqueira 	int dummy_latency_index = 0;
62805674cc9SRodrigo Siqueira 
62905674cc9SRodrigo Siqueira 	dc_assert_fp_enabled();
63005674cc9SRodrigo Siqueira 
63105674cc9SRodrigo Siqueira 	while (dummy_latency_index < max_latency_table_entries) {
63205674cc9SRodrigo Siqueira 		context->bw_ctx.dml.soc.dram_clock_change_latency_us =
63305674cc9SRodrigo Siqueira 				dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
634*269c1d14SYan Li 		dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel,
635*269c1d14SYan Li 			DC_VALIDATE_MODE_AND_PROGRAMMING, true);
63605674cc9SRodrigo Siqueira 
63705674cc9SRodrigo Siqueira 		if (context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank ==
63805674cc9SRodrigo Siqueira 			dm_allow_self_refresh_and_mclk_switch)
63905674cc9SRodrigo Siqueira 			break;
64005674cc9SRodrigo Siqueira 
64105674cc9SRodrigo Siqueira 		dummy_latency_index++;
64205674cc9SRodrigo Siqueira 	}
64305674cc9SRodrigo Siqueira 
64405674cc9SRodrigo Siqueira 	if (dummy_latency_index == max_latency_table_entries) {
64505674cc9SRodrigo Siqueira 		ASSERT(dummy_latency_index != max_latency_table_entries);
64605674cc9SRodrigo Siqueira 		/* If the execution gets here, it means dummy p_states are
64705674cc9SRodrigo Siqueira 		 * not possible. This should never happen and would mean
64805674cc9SRodrigo Siqueira 		 * something is severely wrong.
64905674cc9SRodrigo Siqueira 		 * Here we reset dummy_latency_index to 3, because it is
65005674cc9SRodrigo Siqueira 		 * better to have underflows than system crashes.
65105674cc9SRodrigo Siqueira 		 */
65205674cc9SRodrigo Siqueira 		dummy_latency_index = 3;
65305674cc9SRodrigo Siqueira 	}
65405674cc9SRodrigo Siqueira 
65505674cc9SRodrigo Siqueira 	return dummy_latency_index;
65605674cc9SRodrigo Siqueira }
65705674cc9SRodrigo Siqueira 
dcn3_fpu_build_wm_range_table(struct clk_mgr * base)658ddd0fa1fSMelissa Wen void dcn3_fpu_build_wm_range_table(struct clk_mgr *base)
659ddd0fa1fSMelissa Wen {
660ddd0fa1fSMelissa Wen 	/* defaults */
661ddd0fa1fSMelissa Wen 	double pstate_latency_us = base->ctx->dc->dml.soc.dram_clock_change_latency_us;
662ddd0fa1fSMelissa Wen 	double sr_exit_time_us = base->ctx->dc->dml.soc.sr_exit_time_us;
663ddd0fa1fSMelissa Wen 	double sr_enter_plus_exit_time_us = base->ctx->dc->dml.soc.sr_enter_plus_exit_time_us;
664ddd0fa1fSMelissa Wen 	uint16_t min_uclk_mhz = base->bw_params->clk_table.entries[0].memclk_mhz;
665e4b0eac3SJasdeep Dhillon 
666ddd0fa1fSMelissa Wen 	dc_assert_fp_enabled();
667ddd0fa1fSMelissa Wen 
668ddd0fa1fSMelissa Wen 	/* Set A - Normal - default values*/
669ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].valid = true;
670ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us;
671ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us;
672ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
673ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE;
674ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 0;
675ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF;
676ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz;
677ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF;
678ddd0fa1fSMelissa Wen 
679ddd0fa1fSMelissa Wen 	/* Set B - Performance - higher minimum clocks */
680ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].valid = true;
681ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us;
682ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us;
683ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
684ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE;
685ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = TUNED VALUE;
686ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF;
687ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = TUNED VALUE;
688ddd0fa1fSMelissa Wen //	base->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF;
689ddd0fa1fSMelissa Wen 
690ddd0fa1fSMelissa Wen 	/* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */
691ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].valid = true;
692ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 0;
693ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
694ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
695ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE;
696ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = 0;
697ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF;
698ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
699ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
700ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[0].dram_speed_mts = 1600;
701ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38;
702ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[1].dram_speed_mts = 8000;
703ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
704ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[2].dram_speed_mts = 10000;
705ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[2].dummy_pstate_latency_us = 8;
706ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[3].dram_speed_mts = 16000;
707ddd0fa1fSMelissa Wen 	base->bw_params->dummy_pstate_table[3].dummy_pstate_latency_us = 5;
708ddd0fa1fSMelissa Wen 
709ddd0fa1fSMelissa Wen 	/* Set D - MALL - SR enter and exit times adjusted for MALL */
710ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].valid = true;
711ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us;
712ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2;
713ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4;
714ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL;
715ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0;
716ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF;
717ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz;
718ddd0fa1fSMelissa Wen 	base->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF;
719ddd0fa1fSMelissa Wen }
720bdf44733SRodrigo Siqueira 
patch_dcn30_soc_bounding_box(struct dc * dc,struct _vcs_dpi_soc_bounding_box_st * dcn3_0_ip)721bdf44733SRodrigo Siqueira void patch_dcn30_soc_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *dcn3_0_ip)
722bdf44733SRodrigo Siqueira {
723bdf44733SRodrigo Siqueira 	dc_assert_fp_enabled();
724bdf44733SRodrigo Siqueira 
725bdf44733SRodrigo Siqueira 	if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
726bdf44733SRodrigo Siqueira 		struct bp_soc_bb_info bb_info = {0};
727bdf44733SRodrigo Siqueira 
728bdf44733SRodrigo Siqueira 		if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
729bdf44733SRodrigo Siqueira 			if (bb_info.dram_clock_change_latency_100ns > 0)
730bdf44733SRodrigo Siqueira 				dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
731bdf44733SRodrigo Siqueira 
732bdf44733SRodrigo Siqueira 			if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
733bdf44733SRodrigo Siqueira 				dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
734bdf44733SRodrigo Siqueira 
735bdf44733SRodrigo Siqueira 			if (bb_info.dram_sr_exit_latency_100ns > 0)
736bdf44733SRodrigo Siqueira 				dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
737bdf44733SRodrigo Siqueira 		}
738bdf44733SRodrigo Siqueira 	}
739bdf44733SRodrigo Siqueira }
740