xref: /linux/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c (revision 546b928da0427b0d6c663cbb992bd7bfa9ac7971)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024-2025 Advanced Micro Devices, Inc.
4 
5 #include "dml2_core_dcn5_funcs_mode_programming.h"
6 #include "dml2_core_dcn5_calcs_dchub.h"
7 #include "dml2_core_dcn5_calcs_display_pipe.h"
8 #include "dml2_core_utils.h"
9 #include "dml2_debug.h"
10 
dcn5_mode_programming(struct dml2_core_calcs_mode_programming_ex * in_out_params)11 static bool dcn5_mode_programming(struct dml2_core_calcs_mode_programming_ex *in_out_params)
12 {
13 	const struct dml2_display_cfg *display_cfg = in_out_params->in_display_cfg;
14 	const struct dml2_utm_soc_bb *utm_soc_bb = in_out_params->utm_soc_bb;
15 	const struct dml2_sop_table *sop_table = &in_out_params->utm_soc_bb->sop_table;
16 	const struct core_display_cfg_support_info *cfg_support_info = in_out_params->cfg_support_info;
17 	struct dml2_core_internal_display_mode_lib *mode_lib = in_out_params->mode_lib;
18 	const struct dml2_display_cfg_programming *programming = in_out_params->programming;
19 	struct dml2_core_calcs_mode_programming_locals *s = &mode_lib->scratch.dml_core_mode_programming_locals;
20 	struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *CalculateWatermarks_params = &mode_lib->scratch.CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params;
21 	struct dml2_core_calcs_CalculateVMRowAndSwath_params *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params;
22 	struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *CalculateSwathAndDETConfiguration_params = &mode_lib->scratch.CalculateSwathAndDETConfiguration_params;
23 	struct dml2_core_calcs_CalculateStutterEfficiency_params *CalculateStutterEfficiency_params = &mode_lib->scratch.CalculateStutterEfficiency_params;
24 	struct dml2_core_calcs_CalculatePrefetchSchedule_params *CalculatePrefetchSchedule_params = &mode_lib->scratch.CalculatePrefetchSchedule_params;
25 	struct dml2_core_calcs_calculate_mcache_setting_params *calculate_mcache_setting_params = &mode_lib->scratch.calculate_mcache_setting_params;
26 	struct dml2_core_calcs_calculate_tdlut_setting_params *calculate_tdlut_setting_params = &mode_lib->scratch.calculate_tdlut_setting_params;
27 	struct dml2_core_shared_CalculateMetaAndPTETimes_params *CalculateMetaAndPTETimes_params = &mode_lib->scratch.CalculateMetaAndPTETimes_params;
28 	struct dml2_core_calcs_calculate_peak_bandwidth_required_params *calculate_peak_bandwidth_params = &mode_lib->scratch.calculate_peak_bandwidth_params;
29 	struct dml2_core_calcs_calculate_bytes_to_fetch_required_to_hide_latency_params *calculate_bytes_to_fetch_required_to_hide_latency_params = &mode_lib->scratch.calculate_bytes_to_fetch_required_to_hide_latency_params;
30 
31 	unsigned int k, j;
32 	bool must_support_iflip;
33 	const long min_return_uclk_cycles = 83;
34 	const long min_return_fclk_cycles = 75;
35 	struct dml2_soc_operating_point max_sop;
36 	struct dml2_soc_operating_point min_sop;
37 	double min_return_latency_in_DCFCLK_cycles = 0;
38 
39 	DML_LOG_VERBOSE("DML::%s: --- START --- \n", __func__);
40 
41 	s->num_active_planes = display_cfg->num_planes;
42 	dml2_core_utils_get_stream_output_bpp(s->OutputBpp, display_cfg);
43 
44 	mode_lib->mp.num_active_pipes = dml2_core_util_get_num_active_pipes(display_cfg->num_planes, cfg_support_info);
45 	dml2_core_utils_pipe_plane_mapping(cfg_support_info, mode_lib->mp.pipe_plane);
46 
47 	mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4x.dpprefclk_khz / 1000.0;
48 	sop_table->get_max_sop(sop_table, &max_sop);
49 	sop_table->get_min_sop(sop_table, &min_sop);
50 	s->SOCCLK = min_sop.socclk_khz / 1000.0;
51 
52 	for (k = 0; k < s->num_active_planes; ++k) {
53 		unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
54 		DML_ASSERT(cfg_support_info->stream_support_info[stream_index].odms_used <= 4);
55 		DML_ASSERT(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4 ||
56 					cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2 ||
57 					cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1);
58 
59 		if (cfg_support_info->stream_support_info[stream_index].odms_used > 1)
60 			DML_ASSERT(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1);
61 
62 		switch (cfg_support_info->stream_support_info[stream_index].odms_used) {
63 		case (4):
64 			mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_4to1;
65 			break;
66 		case (3):
67 			mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_3to1;
68 			break;
69 		case (2):
70 			mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_2to1;
71 			break;
72 		default:
73 			if (cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4)
74 				mode_lib->mp.ODMMode[k] = dml2_odm_mode_mso_1to4;
75 			else if (cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2)
76 				mode_lib->mp.ODMMode[k] = dml2_odm_mode_mso_1to2;
77 			else
78 				mode_lib->mp.ODMMode[k] = dml2_odm_mode_bypass;
79 			break;
80 		}
81 	}
82 
83 	for (k = 0; k < s->num_active_planes; ++k) {
84 		mode_lib->mp.NoOfDPP[k] = cfg_support_info->plane_support_info[k].dpps_used;
85 		mode_lib->mp.Dppclk[k] = programming->plane_programming[k].min_clocks.dcn4x.dppclk_khz / 1000.0;
86 		DML_ASSERT(mode_lib->mp.Dppclk[k] > 0);
87 	}
88 
89 	for (k = 0; k < s->num_active_planes; ++k) {
90 		unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
91 		mode_lib->mp.DSCCLK[k] = programming->stream_programming[stream_index].min_clocks.dcn4x.dscclk_khz / 1000.0;
92 		DML_LOG_VERBOSE("DML::%s: k=%d stream_index=%d, mode_lib->mp.DSCCLK = %f\n", __func__, k, stream_index, mode_lib->mp.DSCCLK[k]);
93 	}
94 
95 	mode_lib->mp.Dispclk = programming->min_clocks.dcn4x.dispclk_khz / 1000.0;
96 	mode_lib->mp.DCFCLKDeepSleep = programming->min_clocks.dcn4x.deepsleep_dcfclk_khz / 1000.0;
97 
98 	memcpy(mode_lib->mp.uclk_pstate_switch_modes,
99 			in_out_params->uclk_params->pstate_switch_modes,
100 			sizeof(in_out_params->uclk_params->pstate_switch_modes));
101 
102 	DML_ASSERT(mode_lib->mp.Dcfclk > 0);
103 	DML_ASSERT(mode_lib->mp.FabricClock > 0);
104 	DML_ASSERT(mode_lib->mp.uclk_freq_mhz > 0);
105 	DML_ASSERT(mode_lib->mp.GlobalDPPCLK > 0);
106 	DML_ASSERT(mode_lib->mp.Dispclk > 0);
107 	DML_ASSERT(mode_lib->mp.DCFCLKDeepSleep > 0);
108 	DML_ASSERT(s->SOCCLK > 0);
109 
110 	DML_LOG_VERBOSE("DML::%s: num_active_planes = %u\n", __func__, s->num_active_planes);
111 	DML_LOG_VERBOSE("DML::%s: num_active_pipes = %u\n", __func__, mode_lib->mp.num_active_pipes);
112 	DML_LOG_VERBOSE("DML::%s: Dcfclk = %f\n", __func__, mode_lib->mp.Dcfclk);
113 	DML_LOG_VERBOSE("DML::%s: FabricClock = %f\n", __func__, mode_lib->mp.FabricClock);
114 	DML_LOG_VERBOSE("DML::%s: uclk_freq_mhz = %f\n", __func__, mode_lib->mp.uclk_freq_mhz);
115 	DML_LOG_VERBOSE("DML::%s: Dispclk = %f\n", __func__, mode_lib->mp.Dispclk);
116 	for (k = 0; k < s->num_active_planes; ++k) {
117 		DML_LOG_VERBOSE("DML::%s: Dppclk[%0d] = %f\n", __func__, k, mode_lib->mp.Dppclk[k]);
118 	}
119 	DML_LOG_VERBOSE("DML::%s: GlobalDPPCLK = %f\n", __func__, mode_lib->mp.GlobalDPPCLK);
120 	DML_LOG_VERBOSE("DML::%s: DCFCLKDeepSleep = %f\n", __func__, mode_lib->mp.DCFCLKDeepSleep);
121 	DML_LOG_VERBOSE("DML::%s: SOCCLK = %f\n", __func__, s->SOCCLK);
122 	for (k = 0; k < mode_lib->mp.num_active_pipes; ++k) {
123 		DML_LOG_VERBOSE("DML::%s: pipe=%d is in plane=%d\n", __func__, k, mode_lib->mp.pipe_plane[k]);
124 		DML_LOG_VERBOSE("DML::%s: Per-plane DPPPerSurface[%0d] = %d\n", __func__, k, mode_lib->mp.NoOfDPP[k]);
125 	}
126 
127 	for (k = 0; k < s->num_active_planes; k++)
128 		DML_LOG_VERBOSE("DML::%s: plane_%d: reserved_vblank_time_ns = %lu\n", __func__, k, display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns);
129 
130 	dcn5_calculate_max_det_and_min_compressed_buffer_size(
131 		mode_lib->ip.config_return_buffer_size_in_kbytes,
132 		mode_lib->ip.config_return_buffer_segment_size_in_kbytes,
133 		mode_lib->ip.rob_buffer_size_kbytes,
134 		mode_lib->ip.max_num_dpp,
135 		display_cfg->overrides.hw.force_nom_det_size_kbytes.enable,
136 		display_cfg->overrides.hw.force_nom_det_size_kbytes.value,
137 		mode_lib->ip.dcn_mrq_present,
138 
139 		/* Output */
140 		&s->MaxTotalDETInKByte,
141 		&s->NomDETInKByte,
142 		&s->MinCompressedBufferSizeInKByte);
143 
144 
145 	dcn5_adjust_pixel_clock_for_progressive_to_interlace_unit(display_cfg, mode_lib->ip.ptoi_supported, s->PixelClockBackEnd);
146 
147 	for (k = 0; k < s->num_active_planes; ++k) {
148 		dcn5_calculate_single_pipe_dppclk_and_scl_throughput(
149 			display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio,
150 			display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio,
151 			display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio,
152 			display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio,
153 			mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
154 			mode_lib->ip.max_pscl_lb_bw_pix_per_clk,
155 			((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
156 			display_cfg->plane_descriptors[k].pixel_format,
157 			display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps,
158 			display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps,
159 			display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps,
160 			display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps,
161 
162 			/* Output */
163 			&mode_lib->mp.PSCL_THROUGHPUT[k],
164 			&mode_lib->mp.PSCL_THROUGHPUT_CHROMA[k],
165 			&mode_lib->mp.DPPCLKUsingSingleDPP[k]);
166 	}
167 
168 	for (k = 0; k < s->num_active_planes; ++k) {
169 		dcn5_calculate_byte_per_pixel_and_block_sizes(
170 			display_cfg->plane_descriptors[k].pixel_format,
171 			display_cfg->plane_descriptors[k].surface.tiling,
172 			display_cfg->plane_descriptors[k].surface.plane0.pitch,
173 			display_cfg->plane_descriptors[k].surface.plane1.pitch,
174 
175 			// Output
176 			&mode_lib->mp.BytePerPixelY[k],
177 			&mode_lib->mp.BytePerPixelC[k],
178 			&mode_lib->mp.BytePerPixelInDETY[k],
179 			&mode_lib->mp.BytePerPixelInDETC[k],
180 			&mode_lib->mp.Read256BlockHeightY[k],
181 			&mode_lib->mp.Read256BlockHeightC[k],
182 			&mode_lib->mp.Read256BlockWidthY[k],
183 			&mode_lib->mp.Read256BlockWidthC[k],
184 			&mode_lib->mp.MacroTileHeightY[k],
185 			&mode_lib->mp.MacroTileHeightC[k],
186 			&mode_lib->mp.MacroTileWidthY[k],
187 			&mode_lib->mp.MacroTileWidthC[k],
188 			&mode_lib->mp.surf_linear128_l[k],
189 			&mode_lib->mp.surf_linear128_c[k]);
190 	}
191 
192 	dcn5_calculate_swath_width(
193 		display_cfg,
194 		false, // ForceSingleDPP
195 		s->num_active_planes,
196 		mode_lib->mp.ODMMode,
197 		mode_lib->mp.BytePerPixelY,
198 		mode_lib->mp.BytePerPixelC,
199 		mode_lib->mp.Read256BlockHeightY,
200 		mode_lib->mp.Read256BlockHeightC,
201 		mode_lib->mp.Read256BlockWidthY,
202 		mode_lib->mp.Read256BlockWidthC,
203 		mode_lib->mp.surf_linear128_l,
204 		mode_lib->mp.surf_linear128_c,
205 		mode_lib->mp.NoOfDPP,
206 
207 		/* Output */
208 		mode_lib->mp.req_per_swath_ub_l,
209 		mode_lib->mp.req_per_swath_ub_c,
210 		mode_lib->mp.SwathWidthSingleDPPY,
211 		mode_lib->mp.SwathWidthSingleDPPC,
212 		mode_lib->mp.SwathWidthY,
213 		mode_lib->mp.SwathWidthC,
214 		s->dummy_integer_array[0], // unsigned int MaximumSwathHeightY[]
215 		s->dummy_integer_array[1], // unsigned int MaximumSwathHeightC[]
216 		mode_lib->mp.swath_width_luma_ub,
217 		mode_lib->mp.swath_width_chroma_ub,
218 		s->dummy_integer_array[2],
219 		s->dummy_integer_array[3]);
220 
221 	for (k = 0; k < s->num_active_planes; ++k) {
222 		mode_lib->mp.cursor_bw[k] = display_cfg->plane_descriptors[k].cursor.num_cursors * display_cfg->plane_descriptors[k].cursor.cursor_width * display_cfg->plane_descriptors[k].cursor.cursor_bpp / 8.0 /
223 			((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000));
224 		mode_lib->mp.vactive_sw_bw_l[k] = mode_lib->mp.SwathWidthSingleDPPY[k] * mode_lib->mp.BytePerPixelY[k] / (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
225 		mode_lib->mp.vactive_sw_bw_c[k] = mode_lib->mp.SwathWidthSingleDPPC[k] * mode_lib->mp.BytePerPixelC[k] / (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
226 		DML_LOG_VERBOSE("DML::%s: vactive_sw_bw_l[%i] = %fBps\n", __func__, k, mode_lib->mp.vactive_sw_bw_l[k]);
227 		DML_LOG_VERBOSE("DML::%s: vactive_sw_bw_c[%i] = %fBps\n", __func__, k, mode_lib->mp.vactive_sw_bw_c[k]);
228 	}
229 
230 	CalculateSwathAndDETConfiguration_params->display_cfg = display_cfg;
231 	CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ip.config_return_buffer_size_in_kbytes;
232 	CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = s->MaxTotalDETInKByte;
233 	CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = s->MinCompressedBufferSizeInKByte;
234 	CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes;
235 	CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes;
236 	CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes;
237 	CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes;
238 	CalculateSwathAndDETConfiguration_params->ForceSingleDPP = false;
239 	CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = s->num_active_planes;
240 	CalculateSwathAndDETConfiguration_params->nomDETInKByte = s->NomDETInKByte;
241 	CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ip.config_return_buffer_segment_size_in_kbytes;
242 	CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByte = mode_lib->ip.compressed_buffer_segment_size_in_kbytes;
243 	CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = mode_lib->mp.vactive_sw_bw_l;
244 	CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = mode_lib->mp.vactive_sw_bw_c;
245 	CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = s->dummy_single_array[0];
246 	CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = s->dummy_single_array[1];
247 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = mode_lib->mp.Read256BlockHeightY;
248 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = mode_lib->mp.Read256BlockHeightC;
249 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = mode_lib->mp.Read256BlockWidthY;
250 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = mode_lib->mp.Read256BlockWidthC;
251 	CalculateSwathAndDETConfiguration_params->surf_linear128_l = mode_lib->mp.surf_linear128_l;
252 	CalculateSwathAndDETConfiguration_params->surf_linear128_c = mode_lib->mp.surf_linear128_c;
253 	CalculateSwathAndDETConfiguration_params->ODMMode = mode_lib->mp.ODMMode;
254 	CalculateSwathAndDETConfiguration_params->DPPPerSurface = mode_lib->mp.NoOfDPP;
255 	CalculateSwathAndDETConfiguration_params->BytePerPixY = mode_lib->mp.BytePerPixelY;
256 	CalculateSwathAndDETConfiguration_params->BytePerPixC = mode_lib->mp.BytePerPixelC;
257 	CalculateSwathAndDETConfiguration_params->BytePerPixDETY = mode_lib->mp.BytePerPixelInDETY;
258 	CalculateSwathAndDETConfiguration_params->BytePerPixDETC = mode_lib->mp.BytePerPixelInDETC;
259 	CalculateSwathAndDETConfiguration_params->mrq_present = mode_lib->ip.dcn_mrq_present;
260 
261 	// output
262 	CalculateSwathAndDETConfiguration_params->req_per_swath_ub_l = mode_lib->mp.req_per_swath_ub_l;
263 	CalculateSwathAndDETConfiguration_params->req_per_swath_ub_c = mode_lib->mp.req_per_swath_ub_c;
264 	CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = s->dummy_long_array[0];
265 	CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = s->dummy_long_array[1];
266 	CalculateSwathAndDETConfiguration_params->SwathWidth = s->dummy_long_array[2];
267 	CalculateSwathAndDETConfiguration_params->SwathWidthChroma = s->dummy_long_array[3];
268 	CalculateSwathAndDETConfiguration_params->SwathHeightY = mode_lib->mp.SwathHeightY;
269 	CalculateSwathAndDETConfiguration_params->SwathHeightC = mode_lib->mp.SwathHeightC;
270 	CalculateSwathAndDETConfiguration_params->request_size_bytes_luma = mode_lib->mp.request_size_bytes_luma;
271 	CalculateSwathAndDETConfiguration_params->request_size_bytes_chroma = mode_lib->mp.request_size_bytes_chroma;
272 	CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = mode_lib->mp.DETBufferSizeInKByte;
273 	CalculateSwathAndDETConfiguration_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY;
274 	CalculateSwathAndDETConfiguration_params->DETBufferSizeC = mode_lib->mp.DETBufferSizeC;
275 	CalculateSwathAndDETConfiguration_params->full_swath_bytes_l = s->full_swath_bytes_l;
276 	CalculateSwathAndDETConfiguration_params->full_swath_bytes_c = s->full_swath_bytes_c;
277 	CalculateSwathAndDETConfiguration_params->full_swath_bytes_single_dpp_l = s->dummy_long_array[4];
278 	CalculateSwathAndDETConfiguration_params->full_swath_bytes_single_dpp_c = s->dummy_long_array[5];
279 	CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &mode_lib->mp.UnboundedRequestEnabled;
280 	CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &mode_lib->mp.compbuf_reserved_space_64b;
281 	CalculateSwathAndDETConfiguration_params->hw_debug5 = &mode_lib->mp.hw_debug5;
282 	CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &mode_lib->mp.CompressedBufferSizeInkByte;
283 	CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = &s->dummy_boolean_array[0][0];
284 	CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &s->dummy_boolean[0];
285 
286 	// Calculate DET size, swath height here.
287 	dcn5_calculate_swath_and_det_configuration(&mode_lib->scratch, CalculateSwathAndDETConfiguration_params);
288 
289 	// DSC Delay
290 	mode_lib->mp.use_legacy_dsc_delay_formula = mode_lib->ip.use_legacy_dsc_delay_formula;
291 	for (k = 0; k < s->num_active_planes; ++k) {
292 		mode_lib->mp.DSCDelay[k] = dcn5_calculate_dsc_delay_requirement(cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].dsc_enable,
293 			mode_lib->mp.ODMMode[k],
294 			mode_lib->ip.maximum_dsc_bits_per_component,
295 			s->OutputBpp[k],
296 			display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active,
297 			display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total,
298 			cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].num_dsc_slices,
299 			display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format,
300 			display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder,
301 			((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
302 			s->PixelClockBackEnd[k],
303 			mode_lib->mp.use_legacy_dsc_delay_formula);
304 	}
305 
306 	for (k = 0; k < s->num_active_planes; ++k) {
307 		s->SurfaceParameters[k].PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
308 		s->SurfaceParameters[k].DPPPerSurface = mode_lib->mp.NoOfDPP[k];
309 		s->SurfaceParameters[k].RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle;
310 		s->SurfaceParameters[k].ViewportHeight = display_cfg->plane_descriptors[k].composition.viewport.plane0.height;
311 		s->SurfaceParameters[k].ViewportHeightC = display_cfg->plane_descriptors[k].composition.viewport.plane1.height;
312 		s->SurfaceParameters[k].BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY[k];
313 		s->SurfaceParameters[k].BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY[k];
314 		s->SurfaceParameters[k].BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC[k];
315 		s->SurfaceParameters[k].BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC[k];
316 		s->SurfaceParameters[k].BlockWidthY = mode_lib->mp.MacroTileWidthY[k];
317 		s->SurfaceParameters[k].BlockHeightY = mode_lib->mp.MacroTileHeightY[k];
318 		s->SurfaceParameters[k].BlockWidthC = mode_lib->mp.MacroTileWidthC[k];
319 		s->SurfaceParameters[k].BlockHeightC = mode_lib->mp.MacroTileHeightC[k];
320 		s->SurfaceParameters[k].InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced;
321 		s->SurfaceParameters[k].HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total;
322 		s->SurfaceParameters[k].DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable;
323 		s->SurfaceParameters[k].SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format;
324 		s->SurfaceParameters[k].SurfaceTiling = display_cfg->plane_descriptors[k].surface.tiling;
325 		s->SurfaceParameters[k].BytePerPixelY = mode_lib->mp.BytePerPixelY[k];
326 		s->SurfaceParameters[k].BytePerPixelC = mode_lib->mp.BytePerPixelC[k];
327 		s->SurfaceParameters[k].ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported;
328 		s->SurfaceParameters[k].VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
329 		s->SurfaceParameters[k].VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
330 		s->SurfaceParameters[k].VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps;
331 		s->SurfaceParameters[k].VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps;
332 		s->SurfaceParameters[k].PitchY = display_cfg->plane_descriptors[k].surface.plane0.pitch;
333 		s->SurfaceParameters[k].PitchC = display_cfg->plane_descriptors[k].surface.plane1.pitch;
334 		s->SurfaceParameters[k].ViewportStationary = display_cfg->plane_descriptors[k].composition.viewport.stationary;
335 		s->SurfaceParameters[k].ViewportXStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start;
336 		s->SurfaceParameters[k].ViewportYStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start;
337 		s->SurfaceParameters[k].ViewportXStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start;
338 		s->SurfaceParameters[k].ViewportYStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start;
339 		s->SurfaceParameters[k].FORCE_ONE_ROW_FOR_FRAME = display_cfg->plane_descriptors[k].overrides.hw.force_one_row_for_frame;
340 		s->SurfaceParameters[k].SwathHeightY = mode_lib->mp.SwathHeightY[k];
341 		s->SurfaceParameters[k].SwathHeightC = mode_lib->mp.SwathHeightC[k];
342 		s->SurfaceParameters[k].DCCMetaPitchY = display_cfg->plane_descriptors[k].surface.dcc.plane0.pitch;
343 		s->SurfaceParameters[k].DCCMetaPitchC = display_cfg->plane_descriptors[k].surface.dcc.plane1.pitch;
344 		s->SurfaceParameters[k].UPSPEnabled = display_cfg->plane_descriptors[k].composition.scaler_info.upsp_enabled;
345 	}
346 
347 	CalculateVMRowAndSwath_params->display_cfg = display_cfg;
348 	CalculateVMRowAndSwath_params->uclk_pstate_switch_modes = mode_lib->ms.uclk_pstate_switch_modes;
349 	CalculateVMRowAndSwath_params->NumberOfActiveSurfaces = s->num_active_planes;
350 	CalculateVMRowAndSwath_params->myPipe = s->SurfaceParameters;
351 	CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsLuma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma;
352 	CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsChroma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma;
353 	CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->mp.SwathWidthY;
354 	CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->mp.SwathWidthC;
355 	CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ip.dcc_meta_buffer_size_bytes;
356 	CalculateVMRowAndSwath_params->mrq_present = mode_lib->ip.dcn_mrq_present;
357 
358 	// output
359 	CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0];
360 	CalculateVMRowAndSwath_params->dpte_row_width_luma_ub = mode_lib->mp.dpte_row_width_luma_ub;
361 	CalculateVMRowAndSwath_params->dpte_row_width_chroma_ub = mode_lib->mp.dpte_row_width_chroma_ub;
362 	CalculateVMRowAndSwath_params->dpte_row_height_luma = mode_lib->mp.dpte_row_height;
363 	CalculateVMRowAndSwath_params->dpte_row_height_chroma = mode_lib->mp.dpte_row_height_chroma;
364 	CalculateVMRowAndSwath_params->dpte_row_height_linear_luma = mode_lib->mp.dpte_row_height_linear;
365 	CalculateVMRowAndSwath_params->dpte_row_height_linear_chroma = mode_lib->mp.dpte_row_height_linear_chroma;
366 	CalculateVMRowAndSwath_params->vm_group_bytes = mode_lib->mp.vm_group_bytes;
367 	CalculateVMRowAndSwath_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes;
368 	CalculateVMRowAndSwath_params->PixelPTEReqWidthY = mode_lib->mp.PixelPTEReqWidthY;
369 	CalculateVMRowAndSwath_params->PixelPTEReqHeightY = mode_lib->mp.PixelPTEReqHeightY;
370 	CalculateVMRowAndSwath_params->PTERequestSizeY = mode_lib->mp.PTERequestSizeY;
371 	CalculateVMRowAndSwath_params->PixelPTEReqWidthC = mode_lib->mp.PixelPTEReqWidthC;
372 	CalculateVMRowAndSwath_params->PixelPTEReqHeightC = mode_lib->mp.PixelPTEReqHeightC;
373 	CalculateVMRowAndSwath_params->PTERequestSizeC = mode_lib->mp.PTERequestSizeC;
374 	CalculateVMRowAndSwath_params->vmpg_width_y = s->vmpg_width_y;
375 	CalculateVMRowAndSwath_params->vmpg_height_y = s->vmpg_height_y;
376 	CalculateVMRowAndSwath_params->vmpg_width_c = s->vmpg_width_c;
377 	CalculateVMRowAndSwath_params->vmpg_height_c = s->vmpg_height_c;
378 	CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_l = mode_lib->mp.dpde0_bytes_per_frame_ub_l;
379 	CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_c = mode_lib->mp.dpde0_bytes_per_frame_ub_c;
380 	CalculateVMRowAndSwath_params->PrefetchSourceLinesY = mode_lib->mp.PrefetchSourceLinesY;
381 	CalculateVMRowAndSwath_params->PrefetchSourceLinesC = mode_lib->mp.PrefetchSourceLinesC;
382 	CalculateVMRowAndSwath_params->VInitPreFillY = mode_lib->mp.VInitPreFillY;
383 	CalculateVMRowAndSwath_params->VInitPreFillC = mode_lib->mp.VInitPreFillC;
384 	CalculateVMRowAndSwath_params->MaxNumSwathY = mode_lib->mp.MaxNumSwathY;
385 	CalculateVMRowAndSwath_params->MaxNumSwathC = mode_lib->mp.MaxNumSwathC;
386 	CalculateVMRowAndSwath_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
387 	CalculateVMRowAndSwath_params->PixelPTEBytesPerRow = mode_lib->mp.PixelPTEBytesPerRow;
388 	CalculateVMRowAndSwath_params->dpte_row_bytes_per_row_l = s->dpte_row_bytes_per_row_l;
389 	CalculateVMRowAndSwath_params->dpte_row_bytes_per_row_c = s->dpte_row_bytes_per_row_c;
390 	CalculateVMRowAndSwath_params->vm_bytes = mode_lib->mp.vm_bytes;
391 	CalculateVMRowAndSwath_params->use_one_row_for_frame = mode_lib->mp.use_one_row_for_frame;
392 	CalculateVMRowAndSwath_params->use_one_row_for_frame_flip = mode_lib->mp.use_one_row_for_frame_flip;
393 	CalculateVMRowAndSwath_params->PTE_BUFFER_MODE = mode_lib->mp.PTE_BUFFER_MODE;
394 	CalculateVMRowAndSwath_params->BIGK_FRAGMENT_SIZE = mode_lib->mp.BIGK_FRAGMENT_SIZE;
395 	CalculateVMRowAndSwath_params->DCCMetaBufferSizeNotExceeded = s->dummy_boolean_array[1];
396 	CalculateVMRowAndSwath_params->meta_row_bw = mode_lib->mp.meta_row_bw;
397 	CalculateVMRowAndSwath_params->meta_row_bytes = mode_lib->mp.meta_row_bytes;
398 	CalculateVMRowAndSwath_params->meta_row_bytes_per_row_ub_l = s->meta_row_bytes_per_row_ub_l;
399 	CalculateVMRowAndSwath_params->meta_row_bytes_per_row_ub_c = s->meta_row_bytes_per_row_ub_c;
400 	CalculateVMRowAndSwath_params->meta_req_width_luma = mode_lib->mp.meta_req_width;
401 	CalculateVMRowAndSwath_params->meta_req_height_luma = mode_lib->mp.meta_req_height;
402 	CalculateVMRowAndSwath_params->meta_row_width_luma = mode_lib->mp.meta_row_width;
403 	CalculateVMRowAndSwath_params->meta_row_height_luma = mode_lib->mp.meta_row_height;
404 	CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_l = mode_lib->mp.meta_pte_bytes_per_frame_ub_l;
405 	CalculateVMRowAndSwath_params->meta_req_width_chroma = mode_lib->mp.meta_req_width_chroma;
406 	CalculateVMRowAndSwath_params->meta_row_height_chroma = mode_lib->mp.meta_row_height_chroma;
407 	CalculateVMRowAndSwath_params->meta_row_width_chroma = mode_lib->mp.meta_row_width_chroma;
408 	CalculateVMRowAndSwath_params->meta_req_height_chroma = mode_lib->mp.meta_req_height_chroma;
409 	CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_c = mode_lib->mp.meta_pte_bytes_per_frame_ub_c;
410 
411 	dcn5_calculate_vm_row_and_swath(&mode_lib->scratch, CalculateVMRowAndSwath_params);
412 
413 	memset(calculate_mcache_setting_params, 0, sizeof(struct dml2_core_calcs_calculate_mcache_setting_params));
414 	for (k = 0; k < s->num_active_planes; k++) {
415 		mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0[k] = 1.0;
416 		mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0[k] = 1.0;
417 		mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1[k] = 1.0;
418 		mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1[k] = 1.0;
419 	}
420 
421 	dcn5_calculate_hostvm_inefficiency_factor(
422 		&s->HostVMInefficiencyFactor,
423 		&s->HostVMInefficiencyFactorPrefetch,
424 
425 		display_cfg->gpuvm_enable,
426 		display_cfg->hostvm_enable,
427 		mode_lib->ip.remote_iommu_outstanding_translations,
428 		utm_soc_bb->max_outstanding_reqs,
429 		1.0,
430 		0.5);
431 
432 	s->TotalDCCActiveDPP = 0;
433 	s->TotalActiveDPP = 0;
434 	for (k = 0; k < s->num_active_planes; ++k) {
435 		s->TotalActiveDPP = s->TotalActiveDPP + mode_lib->mp.NoOfDPP[k];
436 		if (display_cfg->plane_descriptors[k].surface.dcc.enable)
437 			s->TotalDCCActiveDPP = s->TotalDCCActiveDPP + mode_lib->mp.NoOfDPP[k];
438 	}
439 	// Calculate tdlut schedule related terms
440 	for (k = 0; k <= s->num_active_planes - 1; k++) {
441 		calculate_tdlut_setting_params->dispclk_mhz = mode_lib->mp.Dispclk;
442 		calculate_tdlut_setting_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut;
443 		calculate_tdlut_setting_params->tdlut_width_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_width_mode;
444 		calculate_tdlut_setting_params->tdlut_addressing_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_addressing_mode;
445 		calculate_tdlut_setting_params->cursor_buffer_size = mode_lib->ip.cursor_buffer_size;
446 		calculate_tdlut_setting_params->gpuvm_enable = display_cfg->gpuvm_enable;
447 		calculate_tdlut_setting_params->gpuvm_page_size_kbytes = display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes;
448 
449 		// output
450 		calculate_tdlut_setting_params->tdlut_pte_bytes_per_frame = &s->tdlut_pte_bytes_per_frame[k];
451 		calculate_tdlut_setting_params->tdlut_bytes_per_frame = &s->tdlut_bytes_per_frame[k];
452 		calculate_tdlut_setting_params->tdlut_groups_per_2row_ub = &s->tdlut_groups_per_2row_ub[k];
453 		calculate_tdlut_setting_params->tdlut_opt_time = &s->tdlut_opt_time[k];
454 		calculate_tdlut_setting_params->tdlut_drain_time = &s->tdlut_drain_time[k];
455 		calculate_tdlut_setting_params->tdlut_bytes_per_group = &s->tdlut_bytes_per_group[k];
456 
457 		dcn5_calculate_tdlut_setting(&mode_lib->scratch, calculate_tdlut_setting_params);
458 	}
459 
460 	dcn5_calculate_extra_latency(
461 		display_cfg,
462 		mode_lib->ip.rob_buffer_size_kbytes,
463 		0,
464 		s->ReorderingBytes,
465 		mode_lib->mp.Dcfclk,
466 		mode_lib->mp.FabricClock,
467 		mode_lib->ip.pixel_chunk_size_kbytes,
468 		mode_lib->mp.dram_bw_mbps,
469 		s->num_active_planes,
470 		mode_lib->mp.NoOfDPP,
471 		mode_lib->mp.dpte_group_bytes,
472 		s->tdlut_bytes_per_group,
473 		s->HostVMInefficiencyFactor,
474 		s->HostVMInefficiencyFactorPrefetch,
475 		dml2_qos_param_type_dcn4x,
476 		!(display_cfg->overrides.max_outstanding_when_urgent_expected_disable),
477 		utm_soc_bb->max_outstanding_reqs,
478 		mode_lib->mp.request_size_bytes_luma,
479 		mode_lib->mp.request_size_bytes_chroma,
480 		mode_lib->ip.meta_chunk_size_kbytes,
481 		mode_lib->ip.dchub_arb_to_ret_delay,
482 		mode_lib->mp.TripToMemory,
483 		mode_lib->ip.hostvm_mode,
484 
485 		// output
486 		&mode_lib->mp.ExtraLatency,
487 		&mode_lib->mp.ExtraLatency_sr,
488 		&mode_lib->mp.ExtraLatencyPrefetch);
489 
490 	mode_lib->mp.TCalc = 24.0 / mode_lib->mp.DCFCLKDeepSleep;
491 
492 	for (k = 0; k < s->num_active_planes; ++k) {
493 		mode_lib->mp.WritebackDelay[k] = 0.0;
494 		for (j = 0; j < display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream; ++j) {
495 			mode_lib->mp.WritebackDelay[k] = math_max2(mode_lib->mp.WritebackDelay[k],
496 					utm_soc_bb->writeback_base_latency_us
497 					+ dcn5_calculate_write_back_delay(
498 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].pixel_format,
499 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].h_ratio,
500 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].v_ratio,
501 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].v_taps,
502 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].v_taps_chroma,
503 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].output_width,
504 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].output_height,
505 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].input_width,
506 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].input_height,
507 						display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total)
508 						/ mode_lib->mp.Dispclk);
509 		}
510 	}
511 
512 	/* VActive bytes to fetch for UCLK P-State */
513 	calculate_bytes_to_fetch_required_to_hide_latency_params->display_cfg = display_cfg;
514 	calculate_bytes_to_fetch_required_to_hide_latency_params->mrq_present = mode_lib->ip.dcn_mrq_present;
515 
516 	calculate_bytes_to_fetch_required_to_hide_latency_params->num_active_planes = s->num_active_planes;
517 	calculate_bytes_to_fetch_required_to_hide_latency_params->num_of_dpp = mode_lib->mp.NoOfDPP;
518 	calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_height_l = mode_lib->mp.meta_row_height;
519 	calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_height_c = mode_lib->mp.meta_row_height_chroma;
520 	calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_bytes_per_row_ub_l = s->meta_row_bytes_per_row_ub_l;
521 	calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_bytes_per_row_ub_c = s->meta_row_bytes_per_row_ub_c;
522 	calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_row_height_l = mode_lib->mp.dpte_row_height;
523 	calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_row_height_c = mode_lib->mp.dpte_row_height_chroma;
524 	calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_bytes_per_row_l = s->dpte_row_bytes_per_row_l;
525 	calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_bytes_per_row_c = s->dpte_row_bytes_per_row_c;
526 	calculate_bytes_to_fetch_required_to_hide_latency_params->byte_per_pix_l = mode_lib->mp.BytePerPixelY;
527 	calculate_bytes_to_fetch_required_to_hide_latency_params->byte_per_pix_c = mode_lib->mp.BytePerPixelC;
528 	calculate_bytes_to_fetch_required_to_hide_latency_params->swath_width_l = mode_lib->mp.SwathWidthY;
529 	calculate_bytes_to_fetch_required_to_hide_latency_params->swath_width_c = mode_lib->mp.SwathWidthC;
530 	calculate_bytes_to_fetch_required_to_hide_latency_params->swath_height_l = mode_lib->mp.SwathHeightY;
531 	calculate_bytes_to_fetch_required_to_hide_latency_params->swath_height_c = mode_lib->mp.SwathHeightC;
532 	for (k = 0; k < s->num_active_planes; ++k) {
533 		calculate_bytes_to_fetch_required_to_hide_latency_params->latency_to_hide_us[k] = utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us;
534 	}
535 
536 	/* outputs */
537 	calculate_bytes_to_fetch_required_to_hide_latency_params->bytes_required_l = s->pstate_bytes_required_l[dml2_pstate_type_uclk];
538 	calculate_bytes_to_fetch_required_to_hide_latency_params->bytes_required_c = s->pstate_bytes_required_c[dml2_pstate_type_uclk];
539 
540 	dcn5_calculate_bytes_to_fetch_required_to_hide_latency(calculate_bytes_to_fetch_required_to_hide_latency_params);
541 
542 	/* Excess VActive bandwidth required to fill DET */
543 	dcn5_calculate_excess_vactive_bandwidth_required(
544 			display_cfg,
545 			s->num_active_planes,
546 			s->pstate_bytes_required_l[dml2_pstate_type_uclk],
547 			s->pstate_bytes_required_c[dml2_pstate_type_uclk],
548 			/* outputs */
549 			mode_lib->mp.excess_vactive_fill_bw_l,
550 			mode_lib->mp.excess_vactive_fill_bw_c);
551 
552 	mode_lib->mp.TripToMemory = math_max2(mode_lib->mp.UrgentLatency, mode_lib->mp.TripToMemory);
553 
554 	for (k = 0; k < s->num_active_planes; ++k) {
555 		bool cursor_not_enough_urgent_latency_hiding = 0;
556 		double line_time_us;
557 
558 		dcn5_calculate_cursor_req_attributes(
559 			display_cfg->plane_descriptors[k].cursor.cursor_width,
560 			display_cfg->plane_descriptors[k].cursor.cursor_bpp,
561 
562 			// output
563 			&s->cursor_lines_per_chunk[k],
564 			&s->cursor_bytes_per_line[k],
565 			&s->cursor_bytes_per_chunk[k],
566 			&s->cursor_bytes[k]);
567 
568 		line_time_us = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
569 
570 		dcn5_calculate_cursor_urgent_burst_factor(
571 			mode_lib->ip.cursor_buffer_size,
572 			display_cfg->plane_descriptors[k].cursor.cursor_width,
573 			s->cursor_bytes_per_chunk[k],
574 			s->cursor_lines_per_chunk[k],
575 			line_time_us,
576 			mode_lib->mp.UrgentLatency,
577 
578 			// output
579 			&mode_lib->mp.UrgentBurstFactorCursor[k],
580 			&cursor_not_enough_urgent_latency_hiding);
581 		mode_lib->mp.UrgentBurstFactorCursorPre[k] = mode_lib->mp.UrgentBurstFactorCursor[k];
582 
583 		dcn5_calculate_urgent_burst_factor(
584 			&display_cfg->plane_descriptors[k],
585 			mode_lib->mp.swath_width_luma_ub[k],
586 			mode_lib->mp.swath_width_chroma_ub[k],
587 			mode_lib->mp.SwathHeightY[k],
588 			mode_lib->mp.SwathHeightC[k],
589 			line_time_us,
590 			mode_lib->mp.UrgentLatency,
591 			display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio,
592 			display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio,
593 			mode_lib->mp.BytePerPixelInDETY[k],
594 			mode_lib->mp.BytePerPixelInDETC[k],
595 			mode_lib->mp.DETBufferSizeY[k],
596 			mode_lib->mp.DETBufferSizeC[k],
597 
598 			/* output */
599 			&mode_lib->mp.UrgentBurstFactorLuma[k],
600 			&mode_lib->mp.UrgentBurstFactorChroma[k],
601 			&mode_lib->mp.NotEnoughUrgentLatencyHiding[k]);
602 
603 		mode_lib->mp.NotEnoughUrgentLatencyHiding[k] = mode_lib->mp.NotEnoughUrgentLatencyHiding[k] || cursor_not_enough_urgent_latency_hiding;
604 	}
605 
606 	for (k = 0; k < s->num_active_planes; ++k) {
607 		s->MaxVStartupLines[k] = dcn5_calculate_max_vstartup(
608 			mode_lib->ip.ptoi_supported,
609 			mode_lib->ip.vblank_nom_default_us,
610 			&display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing,
611 			mode_lib->mp.WritebackDelay[k]);
612 		DML_LOG_VERBOSE("DML::%s: k=%u MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
613 		DML_LOG_VERBOSE("DML::%s: k=%u WritebackDelay = %f\n", __func__, k, mode_lib->mp.WritebackDelay[k]);
614 	}
615 
616 	s->immediate_flip_required = false;
617 	for (k = 0; k < s->num_active_planes; ++k) {
618 		s->immediate_flip_required = s->immediate_flip_required || display_cfg->plane_descriptors[k].immediate_flip;
619 	}
620 	DML_LOG_VERBOSE("DML::%s: immediate_flip_required = %u\n", __func__, s->immediate_flip_required);
621 
622 	{
623 		s->DestinationLineTimesForPrefetchLessThan2 = false;
624 		s->VRatioPrefetchMoreThanMax = false;
625 
626 		DML_LOG_VERBOSE("DML::%s: Start one iteration of prefetch schedule evaluation\n", __func__);
627 
628 		for (k = 0; k < s->num_active_planes; ++k) {
629 			struct dml2_core_internal_DmlPipe *myPipe = &s->myPipe;
630 
631 			DML_LOG_VERBOSE("DML::%s: k=%d MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
632 			mode_lib->mp.TWait[k] = dcn5_calculate_t_wait(
633 				display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns,
634 				mode_lib->mp.UrgentLatency,
635 				mode_lib->mp.TripToMemory,
636 				utm_soc_bb->power_management_parameters.g7_ppt_blackout_us,
637 				display_cfg->stream_descriptors->timing.drr_config.enabled);
638 
639 			myPipe->Dppclk = mode_lib->mp.Dppclk[k];
640 			myPipe->Dispclk = mode_lib->mp.Dispclk;
641 			myPipe->PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
642 			myPipe->DCFClkDeepSleep = mode_lib->mp.DCFCLKDeepSleep;
643 			myPipe->DPPPerSurface = mode_lib->mp.NoOfDPP[k];
644 			myPipe->ScalerEnabled = display_cfg->plane_descriptors[k].composition.scaler_info.enabled;
645 			myPipe->VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
646 			myPipe->VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
647 			myPipe->VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps;
648 			myPipe->VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps;
649 			myPipe->RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle;
650 			myPipe->mirrored = display_cfg->plane_descriptors[k].composition.mirrored;
651 			myPipe->BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY[k];
652 			myPipe->BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY[k];
653 			myPipe->BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC[k];
654 			myPipe->BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC[k];
655 			myPipe->InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced;
656 			myPipe->NumberOfCursors = display_cfg->plane_descriptors[k].cursor.num_cursors;
657 			myPipe->VBlank = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active;
658 			myPipe->HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total;
659 			myPipe->HActive = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active;
660 			myPipe->DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable;
661 			myPipe->ODMMode = mode_lib->mp.ODMMode[k];
662 			myPipe->SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format;
663 			myPipe->BytePerPixelY = mode_lib->mp.BytePerPixelY[k];
664 			myPipe->BytePerPixelC = mode_lib->mp.BytePerPixelC[k];
665 			myPipe->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported;
666 			DML_LOG_VERBOSE("DML::%s: Calling CalculatePrefetchSchedule for k=%u\n", __func__, k);
667 
668 			CalculatePrefetchSchedule_params->display_cfg = display_cfg;
669 			CalculatePrefetchSchedule_params->HostVMInefficiencyFactor = s->HostVMInefficiencyFactorPrefetch;
670 			CalculatePrefetchSchedule_params->myPipe = myPipe;
671 			CalculatePrefetchSchedule_params->DSCDelay = mode_lib->mp.DSCDelay[k];
672 			CalculatePrefetchSchedule_params->DPPCLKDelaySubtotalPlusCNVCFormater = mode_lib->ip.dppclk_delay_subtotal + mode_lib->ip.dppclk_delay_cnvc_formatter;
673 			CalculatePrefetchSchedule_params->DPPCLKDelaySCL = mode_lib->ip.dppclk_delay_scl;
674 			CalculatePrefetchSchedule_params->DPPCLKDelaySCLLBOnly = mode_lib->ip.dppclk_delay_scl_lb_only;
675 			CalculatePrefetchSchedule_params->DPPCLKDelayCNVCCursor = mode_lib->ip.dppclk_delay_cnvc_cursor;
676 			CalculatePrefetchSchedule_params->DISPCLKDelaySubtotal = mode_lib->ip.dispclk_delay_subtotal;
677 			CalculatePrefetchSchedule_params->DPP_RECOUT_WIDTH = (unsigned int)(mode_lib->mp.SwathWidthY[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio);
678 			CalculatePrefetchSchedule_params->OutputFormat = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format;
679 			CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ip.max_inter_dcn_tile_repeaters;
680 			CalculatePrefetchSchedule_params->VStartup = s->MaxVStartupLines[k];
681 			CalculatePrefetchSchedule_params->HostVMMinPageSize = display_cfg->plane_descriptors[k].overrides.hostvm_min_page_size_kbytes;
682 			CalculatePrefetchSchedule_params->DynamicMetadataEnable = display_cfg->plane_descriptors[k].dynamic_meta_data.enable;
683 			CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ip.dynamic_metadata_vm_enabled;
684 			CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = display_cfg->plane_descriptors[k].dynamic_meta_data.lines_before_active_required;
685 			CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = display_cfg->plane_descriptors[k].dynamic_meta_data.transmitted_bytes;
686 			CalculatePrefetchSchedule_params->ExtraLatencyPrefetch = mode_lib->mp.ExtraLatencyPrefetch;
687 			CalculatePrefetchSchedule_params->TCalc = mode_lib->mp.TCalc;
688 			CalculatePrefetchSchedule_params->vm_bytes = mode_lib->mp.vm_bytes[k];
689 			CalculatePrefetchSchedule_params->PixelPTEBytesPerRow = mode_lib->mp.PixelPTEBytesPerRow[k];
690 			CalculatePrefetchSchedule_params->PrefetchSourceLinesY = mode_lib->mp.PrefetchSourceLinesY[k];
691 			CalculatePrefetchSchedule_params->VInitPreFillY = mode_lib->mp.VInitPreFillY[k];
692 			CalculatePrefetchSchedule_params->MaxNumSwathY = mode_lib->mp.MaxNumSwathY[k];
693 			CalculatePrefetchSchedule_params->PrefetchSourceLinesC = mode_lib->mp.PrefetchSourceLinesC[k];
694 			CalculatePrefetchSchedule_params->VInitPreFillC = mode_lib->mp.VInitPreFillC[k];
695 			CalculatePrefetchSchedule_params->MaxNumSwathC = mode_lib->mp.MaxNumSwathC[k];
696 			CalculatePrefetchSchedule_params->swath_width_luma_ub = mode_lib->mp.swath_width_luma_ub[k];
697 			CalculatePrefetchSchedule_params->swath_width_chroma_ub = mode_lib->mp.swath_width_chroma_ub[k];
698 			CalculatePrefetchSchedule_params->SwathHeightY = mode_lib->mp.SwathHeightY[k];
699 			CalculatePrefetchSchedule_params->SwathHeightC = mode_lib->mp.SwathHeightC[k];
700 			CalculatePrefetchSchedule_params->TWait = mode_lib->mp.TWait[k];
701 			CalculatePrefetchSchedule_params->Ttrip = mode_lib->mp.TripToMemory;
702 			CalculatePrefetchSchedule_params->Turg = mode_lib->mp.UrgentLatency;
703 			CalculatePrefetchSchedule_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut;
704 			CalculatePrefetchSchedule_params->tdlut_pte_bytes_per_frame = s->tdlut_pte_bytes_per_frame[k];
705 			CalculatePrefetchSchedule_params->tdlut_bytes_per_frame = s->tdlut_bytes_per_frame[k];
706 			CalculatePrefetchSchedule_params->tdlut_opt_time = s->tdlut_opt_time[k];
707 			CalculatePrefetchSchedule_params->tdlut_drain_time = s->tdlut_drain_time[k];
708 			CalculatePrefetchSchedule_params->num_cursors = (display_cfg->plane_descriptors[k].cursor.cursor_width > 0);
709 			CalculatePrefetchSchedule_params->cursor_bytes_per_chunk = s->cursor_bytes_per_chunk[k];
710 			CalculatePrefetchSchedule_params->cursor_bytes_per_line = s->cursor_bytes_per_line[k];
711 			CalculatePrefetchSchedule_params->dcc_enable = display_cfg->plane_descriptors[k].surface.dcc.enable;
712 			CalculatePrefetchSchedule_params->mrq_present = mode_lib->ip.dcn_mrq_present;
713 			CalculatePrefetchSchedule_params->meta_row_bytes = mode_lib->mp.meta_row_bytes[k];
714 
715 			// output
716 			CalculatePrefetchSchedule_params->DSTXAfterScaler = &mode_lib->mp.DSTXAfterScaler[k];
717 			CalculatePrefetchSchedule_params->DSTYAfterScaler = &mode_lib->mp.DSTYAfterScaler[k];
718 			CalculatePrefetchSchedule_params->dst_y_prefetch = &mode_lib->mp.dst_y_prefetch[k];
719 			CalculatePrefetchSchedule_params->dst_y_per_vm_vblank = &mode_lib->mp.dst_y_per_vm_vblank[k];
720 			CalculatePrefetchSchedule_params->dst_y_per_row_vblank = &mode_lib->mp.dst_y_per_row_vblank[k];
721 			CalculatePrefetchSchedule_params->VRatioPrefetchY = &mode_lib->mp.VRatioPrefetchY[k];
722 			CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->mp.VRatioPrefetchC[k];
723 			CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWLuma = &mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k];
724 			CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWChroma = &mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k];
725 			CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->mp.NotEnoughTimeForDynamicMetadata[k];
726 			CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->mp.Tno_bw[k];
727 			CalculatePrefetchSchedule_params->Tno_bw_flip = &mode_lib->mp.Tno_bw_flip[k];
728 			CalculatePrefetchSchedule_params->prefetch_vmrow_bw = &mode_lib->mp.prefetch_vmrow_bw[k];
729 			CalculatePrefetchSchedule_params->Tdmdl_vm = &mode_lib->mp.Tdmdl_vm[k];
730 			CalculatePrefetchSchedule_params->Tdmdl = &mode_lib->mp.Tdmdl[k];
731 			CalculatePrefetchSchedule_params->TSetup = &mode_lib->mp.TSetup[k];
732 			CalculatePrefetchSchedule_params->Tvm_trips = &s->Tvm_trips[k];
733 			CalculatePrefetchSchedule_params->Tr0_trips = &s->Tr0_trips[k];
734 			CalculatePrefetchSchedule_params->Tvm_trips_flip = &s->Tvm_trips_flip[k];
735 			CalculatePrefetchSchedule_params->Tr0_trips_flip = &s->Tr0_trips_flip[k];
736 			CalculatePrefetchSchedule_params->Tvm_trips_flip_rounded = &s->Tvm_trips_flip_rounded[k];
737 			CalculatePrefetchSchedule_params->Tr0_trips_flip_rounded = &s->Tr0_trips_flip_rounded[k];
738 			CalculatePrefetchSchedule_params->VUpdateOffsetPix = &mode_lib->mp.VUpdateOffsetPix[k];
739 			CalculatePrefetchSchedule_params->VUpdateWidthPix = &mode_lib->mp.VUpdateWidthPix[k];
740 			CalculatePrefetchSchedule_params->VReadyOffsetPix = &mode_lib->mp.VReadyOffsetPix[k];
741 			CalculatePrefetchSchedule_params->prefetch_cursor_bw = &mode_lib->mp.prefetch_cursor_bw[k];
742 			CalculatePrefetchSchedule_params->prefetch_sw_bytes = &s->prefetch_sw_bytes[k];
743 			CalculatePrefetchSchedule_params->Tpre_rounded = &s->Tpre_rounded[k];
744 			CalculatePrefetchSchedule_params->Tpre_oto = &s->Tpre_oto[k];
745 
746 			mode_lib->mp.NoTimeToPrefetch[k] = dcn5_calculate_prefetch_schedule(&mode_lib->scratch, CalculatePrefetchSchedule_params);
747 			DML_LOG_VERBOSE("DML::%s: k=%0u NoTimeToPrefetch=%0d\n", __func__, k, mode_lib->mp.NoTimeToPrefetch[k]);
748 			mode_lib->mp.VStartupMin[k] = s->MaxVStartupLines[k];
749 		} // for k
750 
751 		mode_lib->mp.PrefetchModeSupported = true;
752 		for (k = 0; k < s->num_active_planes; ++k) {
753 			if (mode_lib->mp.NoTimeToPrefetch[k] == true ||
754 				mode_lib->mp.NotEnoughTimeForDynamicMetadata[k] ||
755 				mode_lib->mp.DSTYAfterScaler[k] > 8) {
756 				DML_LOG_VERBOSE("DML::%s: k=%u, NoTimeToPrefetch = %0d\n", __func__, k, mode_lib->mp.NoTimeToPrefetch[k]);
757 				DML_LOG_VERBOSE("DML::%s: k=%u, NotEnoughTimeForDynamicMetadata=%u\n", __func__, k, mode_lib->mp.NotEnoughTimeForDynamicMetadata[k]);
758 				DML_LOG_VERBOSE("DML::%s: k=%u, DSTYAfterScaler=%u (should be <= 0)\n", __func__, k, mode_lib->mp.DSTYAfterScaler[k]);
759 				mode_lib->mp.PrefetchModeSupported = false;
760 			}
761 			if (mode_lib->mp.dst_y_prefetch[k] < 2)
762 				s->DestinationLineTimesForPrefetchLessThan2 = true;
763 
764 			if (mode_lib->mp.VRatioPrefetchY[k] > __DML2_CALCS_MAX_VRATIO_PRE__ ||
765 				mode_lib->mp.VRatioPrefetchC[k] > __DML2_CALCS_MAX_VRATIO_PRE__) {
766 				s->VRatioPrefetchMoreThanMax = true;
767 				DML_LOG_VERBOSE("DML::%s: k=%d, VRatioPrefetchY=%f (should not be < %f)\n", __func__, k, mode_lib->mp.VRatioPrefetchY[k], __DML2_CALCS_MAX_VRATIO_PRE__);
768 				DML_LOG_VERBOSE("DML::%s: k=%d, VRatioPrefetchC=%f (should not be < %f)\n", __func__, k, mode_lib->mp.VRatioPrefetchC[k], __DML2_CALCS_MAX_VRATIO_PRE__);
769 				DML_LOG_VERBOSE("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
770 			}
771 
772 			if (mode_lib->mp.NotEnoughUrgentLatencyHiding[k]) {
773 				DML_LOG_VERBOSE("DML::%s: k=%u, NotEnoughUrgentLatencyHiding = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHiding[k]);
774 				mode_lib->mp.PrefetchModeSupported = false;
775 			}
776 		}
777 
778 		if (s->VRatioPrefetchMoreThanMax == true || s->DestinationLineTimesForPrefetchLessThan2 == true) {
779 			DML_LOG_VERBOSE("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
780 			DML_LOG_VERBOSE("DML::%s: DestinationLineTimesForPrefetchLessThan2 = %u\n", __func__, s->DestinationLineTimesForPrefetchLessThan2);
781 			mode_lib->mp.PrefetchModeSupported = false;
782 		}
783 
784 		DML_LOG_VERBOSE("DML::%s: Prefetch schedule is %sOK at vstartup = %u\n", __func__,
785 			mode_lib->mp.PrefetchModeSupported ? "" : "NOT ", CalculatePrefetchSchedule_params->VStartup);
786 
787 		// Prefetch schedule OK, now check prefetch bw
788 		if (mode_lib->mp.PrefetchModeSupported == true) {
789 			for (k = 0; k < s->num_active_planes; ++k) {
790 				double line_time_us = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
791 					((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
792 				dcn5_calculate_urgent_burst_factor(
793 					&display_cfg->plane_descriptors[k],
794 					mode_lib->mp.swath_width_luma_ub[k],
795 					mode_lib->mp.swath_width_chroma_ub[k],
796 					mode_lib->mp.SwathHeightY[k],
797 					mode_lib->mp.SwathHeightC[k],
798 					line_time_us,
799 					mode_lib->mp.UrgentLatency,
800 					mode_lib->mp.VRatioPrefetchY[k],
801 					mode_lib->mp.VRatioPrefetchC[k],
802 					mode_lib->mp.BytePerPixelInDETY[k],
803 					mode_lib->mp.BytePerPixelInDETC[k],
804 					mode_lib->mp.DETBufferSizeY[k],
805 					mode_lib->mp.DETBufferSizeC[k],
806 					/* Output */
807 					&mode_lib->mp.UrgentBurstFactorLumaPre[k],
808 					&mode_lib->mp.UrgentBurstFactorChromaPre[k],
809 					&mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]);
810 
811 				DML_LOG_VERBOSE("DML::%s: k=%0u DPPPerSurface=%u\n", __func__, k, mode_lib->mp.NoOfDPP[k]);
812 				DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorLuma=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorLuma[k]);
813 				DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorChroma=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorChroma[k]);
814 				DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorLumaPre=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorLumaPre[k]);
815 				DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorChromaPre=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorChromaPre[k]);
816 
817 				DML_LOG_VERBOSE("DML::%s: k=%0u VRatioPrefetchY=%f\n", __func__, k, mode_lib->mp.VRatioPrefetchY[k]);
818 				DML_LOG_VERBOSE("DML::%s: k=%0u VRatioY=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio);
819 
820 				DML_LOG_VERBOSE("DML::%s: k=%0u prefetch_vmrow_bw=%f\n", __func__, k, mode_lib->mp.prefetch_vmrow_bw[k]);
821 				DML_LOG_VERBOSE("DML::%s: k=%0u vactive_sw_bw_l=%f\n", __func__, k, mode_lib->mp.vactive_sw_bw_l[k]);
822 				DML_LOG_VERBOSE("DML::%s: k=%0u vactive_sw_bw_c=%f\n", __func__, k, mode_lib->mp.vactive_sw_bw_c[k]);
823 				DML_LOG_VERBOSE("DML::%s: k=%0u cursor_bw=%f\n", __func__, k, mode_lib->mp.cursor_bw[k]);
824 				DML_LOG_VERBOSE("DML::%s: k=%0u dpte_row_bw=%f\n", __func__, k, mode_lib->mp.dpte_row_bw[k]);
825 				DML_LOG_VERBOSE("DML::%s: k=%0u meta_row_bw=%f\n", __func__, k, mode_lib->mp.meta_row_bw[k]);
826 				DML_LOG_VERBOSE("DML::%s: k=%0u RequiredPrefetchPixelDataBWLuma=%f\n", __func__, k, mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k]);
827 				DML_LOG_VERBOSE("DML::%s: k=%0u RequiredPrefetchPixelDataBWChroma=%f\n", __func__, k, mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k]);
828 				DML_LOG_VERBOSE("DML::%s: k=%0u prefetch_cursor_bw=%f\n", __func__, k, mode_lib->mp.prefetch_cursor_bw[k]);
829 			}
830 
831 			for (k = 0; k <= s->num_active_planes - 1; k++)
832 				mode_lib->mp.final_flip_bw[k] = 0;
833 
834 			calculate_peak_bandwidth_params->urg_vactive_bandwidth_required = mode_lib->mp.urg_vactive_bandwidth_required;
835 			calculate_peak_bandwidth_params->urg_bandwidth_required = mode_lib->mp.urg_bandwidth_required;
836 			calculate_peak_bandwidth_params->urg_bandwidth_required_qual = mode_lib->mp.urg_bandwidth_required_qual;
837 			calculate_peak_bandwidth_params->non_urg_bandwidth_required = mode_lib->mp.non_urg_bandwidth_required;
838 			calculate_peak_bandwidth_params->surface_avg_vactive_required_bw = s->surface_dummy_bw;
839 			calculate_peak_bandwidth_params->surface_peak_required_bw = s->surface_dummy_bw0;
840 
841 			calculate_peak_bandwidth_params->display_cfg = display_cfg;
842 			calculate_peak_bandwidth_params->inc_flip_bw = 0;
843 			calculate_peak_bandwidth_params->num_active_planes = s->num_active_planes;
844 			calculate_peak_bandwidth_params->num_of_dpp = mode_lib->mp.NoOfDPP;
845 			calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0;
846 			calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1;
847 			calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0;
848 			calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1;
849 
850 			calculate_peak_bandwidth_params->surface_read_bandwidth_l = mode_lib->mp.vactive_sw_bw_l;
851 			calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c;
852 			calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma;
853 			calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma;
854 			calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l;
855 			calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c;
856 			calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw;
857 			calculate_peak_bandwidth_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
858 			calculate_peak_bandwidth_params->meta_row_bw = mode_lib->mp.meta_row_bw;
859 			calculate_peak_bandwidth_params->prefetch_cursor_bw = mode_lib->mp.prefetch_cursor_bw;
860 			calculate_peak_bandwidth_params->prefetch_vmrow_bw = mode_lib->mp.prefetch_vmrow_bw;
861 			calculate_peak_bandwidth_params->flip_bw = mode_lib->mp.final_flip_bw;
862 			calculate_peak_bandwidth_params->urgent_burst_factor_l = mode_lib->mp.UrgentBurstFactorLuma;
863 			calculate_peak_bandwidth_params->urgent_burst_factor_c = mode_lib->mp.UrgentBurstFactorChroma;
864 			calculate_peak_bandwidth_params->urgent_burst_factor_cursor = mode_lib->mp.UrgentBurstFactorCursor;
865 			calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_l = mode_lib->mp.UrgentBurstFactorLumaPre;
866 			calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_c = mode_lib->mp.UrgentBurstFactorChromaPre;
867 			calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_cursor = mode_lib->mp.UrgentBurstFactorCursorPre;
868 
869 			dcn5_calculate_peak_bandwidth_required(
870 					&mode_lib->scratch,
871 					calculate_peak_bandwidth_params);
872 
873 			// Check urg peak bandwidth against available urg bw
874 			// check at SDP and DRAM, for all soc states (Sys Active)
875 			dcn5_check_urgent_bandwidth_support(
876 				&mode_lib->mp.FractionOfUrgentBandwidth, // double* frac_urg_bandwidth
877 				&mode_lib->mp.PrefetchModeSupported, // prefetch bw ok
878 
879 				**mode_lib->mp.non_urg_bandwidth_required,
880 				**mode_lib->mp.urg_bandwidth_required,
881 				mode_lib->mp.dram_bw_mbps);
882 
883 			if (!mode_lib->mp.PrefetchModeSupported)
884 				DML_LOG_VERBOSE("DML::%s: Bandwidth not sufficient for prefetch!\n", __func__);
885 
886 			for (k = 0; k < s->num_active_planes; ++k) {
887 				if (mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]) {
888 					DML_LOG_VERBOSE("DML::%s: k=%u, NotEnoughUrgentLatencyHidingPre = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]);
889 					mode_lib->mp.PrefetchModeSupported = false;
890 				}
891 			}
892 		} // prefetch schedule ok
893 
894 		// Prefetch schedule and prefetch bw ok, now check flip bw
895 		if (mode_lib->mp.PrefetchModeSupported == true) { // prefetch schedule and prefetch bw ok, now check flip bw
896 
897 			mode_lib->mp.BandwidthAvailableForImmediateFlip =
898 				dcn5_get_bandwidth_available_for_immediate_flip(
899 					**mode_lib->mp.urg_bandwidth_required_qual, // no flip
900 					mode_lib->mp.dram_bw_mbps);
901 
902 			mode_lib->mp.TotImmediateFlipBytes = 0;
903 
904 			for (k = 0; k < s->num_active_planes; ++k) {
905 				if (display_cfg->plane_descriptors[k].immediate_flip) {
906 					s->per_pipe_flip_bytes[k] =  dcn5_get_pipe_flip_bytes(s->HostVMInefficiencyFactor,
907 											mode_lib->mp.vm_bytes[k],
908 											mode_lib->mp.PixelPTEBytesPerRow[k],
909 											mode_lib->mp.meta_row_bytes[k]);
910 				} else {
911 					s->per_pipe_flip_bytes[k] = 0;
912 				}
913 				mode_lib->mp.TotImmediateFlipBytes += s->per_pipe_flip_bytes[k] * mode_lib->mp.NoOfDPP[k];
914 				DML_LOG_VERBOSE("DML::%s: k = %u\n", __func__, k);
915 				DML_LOG_VERBOSE("DML::%s: DPPPerSurface = %u\n", __func__, mode_lib->mp.NoOfDPP[k]);
916 				DML_LOG_VERBOSE("DML::%s: vm_bytes = %u\n", __func__, mode_lib->mp.vm_bytes[k]);
917 				DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, mode_lib->mp.PixelPTEBytesPerRow[k]);
918 				DML_LOG_VERBOSE("DML::%s: meta_row_bytes = %u\n", __func__, mode_lib->mp.meta_row_bytes[k]);
919 				DML_LOG_VERBOSE("DML::%s: TotImmediateFlipBytes = %u\n", __func__, mode_lib->mp.TotImmediateFlipBytes);
920 			}
921 			for (k = 0; k < s->num_active_planes; ++k) {
922 				dcn5_calculate_flip_schedule(
923 					&mode_lib->scratch,
924 					display_cfg->plane_descriptors[k].immediate_flip,
925 					0, // use_lb_flip_bw
926 					s->HostVMInefficiencyFactor,
927 					s->Tvm_trips_flip[k],
928 					s->Tr0_trips_flip[k],
929 					s->Tvm_trips_flip_rounded[k],
930 					s->Tr0_trips_flip_rounded[k],
931 					display_cfg->gpuvm_enable,
932 					mode_lib->mp.vm_bytes[k],
933 					mode_lib->mp.PixelPTEBytesPerRow[k],
934 					mode_lib->mp.BandwidthAvailableForImmediateFlip,
935 					mode_lib->mp.TotImmediateFlipBytes,
936 					display_cfg->plane_descriptors[k].pixel_format,
937 					display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
938 					display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio,
939 					display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio,
940 					mode_lib->mp.Tno_bw[k],
941 					mode_lib->mp.dpte_row_height[k],
942 					mode_lib->mp.dpte_row_height_chroma[k],
943 					mode_lib->mp.use_one_row_for_frame_flip[k],
944 					mode_lib->ip.max_flip_time_us,
945 					mode_lib->ip.max_flip_time_lines,
946 					s->per_pipe_flip_bytes[k],
947 					mode_lib->mp.meta_row_bytes[k],
948 					mode_lib->mp.meta_row_height[k],
949 					mode_lib->mp.meta_row_height_chroma[k],
950 					mode_lib->ip.dcn_mrq_present && display_cfg->plane_descriptors[k].surface.dcc.enable,
951 
952 					// Output
953 					&mode_lib->mp.dst_y_per_vm_flip[k],
954 					&mode_lib->mp.dst_y_per_row_flip[k],
955 					&mode_lib->mp.final_flip_bw[k],
956 					&mode_lib->mp.ImmediateFlipSupportedForPipe[k]);
957 			}
958 
959 			calculate_peak_bandwidth_params->urg_vactive_bandwidth_required = s->dummy_bw;
960 			calculate_peak_bandwidth_params->urg_bandwidth_required = mode_lib->mp.urg_bandwidth_required_flip;
961 			calculate_peak_bandwidth_params->urg_bandwidth_required_qual = s->dummy_bw;
962 			calculate_peak_bandwidth_params->non_urg_bandwidth_required = mode_lib->mp.non_urg_bandwidth_required_flip;
963 			calculate_peak_bandwidth_params->surface_avg_vactive_required_bw = s->surface_dummy_bw;
964 			calculate_peak_bandwidth_params->surface_peak_required_bw = s->surface_dummy_bw0;
965 
966 			calculate_peak_bandwidth_params->display_cfg = display_cfg;
967 			calculate_peak_bandwidth_params->inc_flip_bw = 1;
968 			calculate_peak_bandwidth_params->num_active_planes = s->num_active_planes;
969 			calculate_peak_bandwidth_params->num_of_dpp = mode_lib->mp.NoOfDPP;
970 			calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0;
971 			calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1;
972 			calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0;
973 			calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1;
974 
975 			calculate_peak_bandwidth_params->surface_read_bandwidth_l = mode_lib->mp.vactive_sw_bw_l;
976 			calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c;
977 			calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma;
978 			calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma;
979 			calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l;
980 			calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c;
981 			calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw;
982 			calculate_peak_bandwidth_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
983 			calculate_peak_bandwidth_params->meta_row_bw = mode_lib->mp.meta_row_bw;
984 			calculate_peak_bandwidth_params->prefetch_cursor_bw = mode_lib->mp.prefetch_cursor_bw;
985 			calculate_peak_bandwidth_params->prefetch_vmrow_bw = mode_lib->mp.prefetch_vmrow_bw;
986 			calculate_peak_bandwidth_params->flip_bw = mode_lib->mp.final_flip_bw;
987 			calculate_peak_bandwidth_params->urgent_burst_factor_l = mode_lib->mp.UrgentBurstFactorLuma;
988 			calculate_peak_bandwidth_params->urgent_burst_factor_c = mode_lib->mp.UrgentBurstFactorChroma;
989 			calculate_peak_bandwidth_params->urgent_burst_factor_cursor = mode_lib->mp.UrgentBurstFactorCursor;
990 			calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_l = mode_lib->mp.UrgentBurstFactorLumaPre;
991 			calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_c = mode_lib->mp.UrgentBurstFactorChromaPre;
992 			calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_cursor = mode_lib->mp.UrgentBurstFactorCursorPre;
993 
994 			dcn5_calculate_peak_bandwidth_required(
995 					&mode_lib->scratch,
996 					calculate_peak_bandwidth_params);
997 
998 			dcn5_check_immediate_flip_bandwidth_support(
999 				&mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip, // double* frac_urg_bandwidth_flip
1000 				&mode_lib->mp.ImmediateFlipSupported, // bool* flip_bandwidth_support_ok
1001 				**mode_lib->mp.urg_bandwidth_required_flip,
1002 				**mode_lib->mp.non_urg_bandwidth_required_flip,
1003 				mode_lib->mp.dram_bw_mbps);
1004 
1005 			if (!mode_lib->mp.ImmediateFlipSupported)
1006 				DML_LOG_VERBOSE("DML::%s: Bandwidth not sufficient for flip!", __func__);
1007 
1008 			for (k = 0; k < s->num_active_planes; ++k) {
1009 				if (display_cfg->plane_descriptors[k].immediate_flip && mode_lib->mp.ImmediateFlipSupportedForPipe[k] == false) {
1010 					mode_lib->mp.ImmediateFlipSupported = false;
1011 					DML_LOG_VERBOSE("DML::%s: Pipe %0d not supporting iflip!\n", __func__, k);
1012 				}
1013 			}
1014 		} else { // flip or prefetch not support
1015 			mode_lib->mp.ImmediateFlipSupported = false;
1016 		}
1017 
1018 		// consider flip support is okay if the flip bw is ok or (when user does't require a iflip and there is no host vm)
1019 		must_support_iflip = display_cfg->hostvm_enable || s->immediate_flip_required;
1020 		mode_lib->mp.PrefetchAndImmediateFlipSupported = (mode_lib->mp.PrefetchModeSupported == true && (!must_support_iflip || mode_lib->mp.ImmediateFlipSupported));
1021 
1022 		DML_LOG_VERBOSE("DML::%s: PrefetchModeSupported = %u\n", __func__, mode_lib->mp.PrefetchModeSupported);
1023 		for (k = 0; k < s->num_active_planes; ++k)
1024 			DML_LOG_VERBOSE("DML::%s: immediate_flip_required[%u] = %u\n", __func__, k, display_cfg->plane_descriptors[k].immediate_flip);
1025 		DML_LOG_VERBOSE("DML::%s: HostVMEnable = %u\n", __func__, display_cfg->hostvm_enable);
1026 		DML_LOG_VERBOSE("DML::%s: ImmediateFlipSupported = %u\n", __func__, mode_lib->mp.ImmediateFlipSupported);
1027 		DML_LOG_VERBOSE("DML::%s: PrefetchAndImmediateFlipSupported = %u\n", __func__, mode_lib->mp.PrefetchAndImmediateFlipSupported);
1028 		DML_LOG_VERBOSE("DML::%s: Done one iteration: k=%d, MaxVStartupLines=%u\n", __func__, k, s->MaxVStartupLines[k]);
1029 	}
1030 
1031 	for (k = 0; k < s->num_active_planes; ++k)
1032 		DML_LOG_VERBOSE("DML::%s: k=%d MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
1033 
1034 	if (!mode_lib->mp.PrefetchAndImmediateFlipSupported) {
1035 		DML_LOG_VERBOSE("DML::%s: Bad, Prefetch and flip scheduling solution NOT found!\n", __func__);
1036 	} else {
1037 		DML_LOG_VERBOSE("DML::%s: Good, Prefetch and flip scheduling solution found\n", __func__);
1038 
1039 		// DCC Configuration
1040 		for (k = 0; k < s->num_active_planes; ++k) {
1041 			DML_LOG_VERBOSE("DML::%s: Calculate DCC configuration for surface k=%u\n", __func__, k);
1042 			dcn5_calculate_dcc_configuration(
1043 				display_cfg->plane_descriptors[k].surface.dcc.enable,
1044 				display_cfg->overrides.dcc_programming_assumes_scan_direction_unknown,
1045 				display_cfg->plane_descriptors[k].pixel_format,
1046 				display_cfg->plane_descriptors[k].surface.plane0.width,
1047 				display_cfg->plane_descriptors[k].surface.plane1.width,
1048 				display_cfg->plane_descriptors[k].surface.plane0.height,
1049 				display_cfg->plane_descriptors[k].surface.plane1.height,
1050 				s->NomDETInKByte,
1051 				mode_lib->mp.Read256BlockHeightY[k],
1052 				mode_lib->mp.Read256BlockHeightC[k],
1053 				display_cfg->plane_descriptors[k].surface.tiling,
1054 				mode_lib->mp.BytePerPixelY[k],
1055 				mode_lib->mp.BytePerPixelC[k],
1056 				mode_lib->mp.BytePerPixelInDETY[k],
1057 				mode_lib->mp.BytePerPixelInDETC[k],
1058 				display_cfg->plane_descriptors[k].composition.rotation_angle,
1059 
1060 				/* Output */
1061 				&mode_lib->mp.RequestLuma[k],
1062 				&mode_lib->mp.RequestChroma[k],
1063 				&mode_lib->mp.DCCYMaxUncompressedBlock[k],
1064 				&mode_lib->mp.DCCCMaxUncompressedBlock[k],
1065 				&mode_lib->mp.DCCYMaxCompressedBlock[k],
1066 				&mode_lib->mp.DCCCMaxCompressedBlock[k],
1067 				&mode_lib->mp.DCCYIndependentBlock[k],
1068 				&mode_lib->mp.DCCCIndependentBlock[k]);
1069 		}
1070 
1071 		//Watermarks and NB P-State/DRAM Clock Change Support
1072 		s->mmSOCParameters.UrgentLatency = mode_lib->mp.UrgentLatency;
1073 		s->mmSOCParameters.ExtraLatency = mode_lib->mp.ExtraLatency;
1074 		s->mmSOCParameters.ExtraLatency_sr = mode_lib->mp.ExtraLatency_sr;
1075 		s->mmSOCParameters.WritebackLatency = utm_soc_bb->writeback_base_latency_us;
1076 		s->mmSOCParameters.DRAMClockChangeLatency = utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us;
1077 		s->mmSOCParameters.FCLKChangeLatency = utm_soc_bb->power_management_parameters.fclk_change_blackout_us;
1078 		s->mmSOCParameters.SRExitTime = utm_soc_bb->power_management_parameters.stutter_exit_latency_us;
1079 		s->mmSOCParameters.SREnterPlusExitTime = utm_soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us;
1080 		s->mmSOCParameters.SRExitZ8Time = utm_soc_bb->power_management_parameters.z8_stutter_exit_latency_us;
1081 		s->mmSOCParameters.SREnterPlusExitZ8Time = utm_soc_bb->power_management_parameters.z8_stutter_enter_plus_exit_latency_us;
1082 		s->mmSOCParameters.USRRetrainingLatency = 0;
1083 		s->mmSOCParameters.SMNLatency = 0;
1084 		s->mmSOCParameters.temp_read_or_ppt_blackout_us = utm_soc_bb->power_management_parameters.g7_ppt_blackout_us;
1085 		s->mmSOCParameters.qos_type = dml2_qos_param_type_dcn4x;
1086 
1087 		CalculateWatermarks_params->display_cfg = display_cfg;
1088 		CalculateWatermarks_params->USRRetrainingRequired = false;
1089 		CalculateWatermarks_params->NumberOfActiveSurfaces = s->num_active_planes;
1090 		CalculateWatermarks_params->MaxLineBufferLines = mode_lib->ip.max_line_buffer_lines;
1091 		CalculateWatermarks_params->LineBufferSize = mode_lib->ip.line_buffer_size_bits;
1092 		CalculateWatermarks_params->WritebackInterfaceBufferSize = mode_lib->ip.writeback_interface_buffer_size_kbytes;
1093 		CalculateWatermarks_params->DCFCLK = mode_lib->mp.Dcfclk;
1094 		CalculateWatermarks_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings;
1095 		CalculateWatermarks_params->SynchronizeDRRDisplaysForUCLKPStateChange = display_cfg->overrides.synchronize_ddr_displays_for_uclk_pstate_change;
1096 		CalculateWatermarks_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes;
1097 		CalculateWatermarks_params->mmSOCParameters = s->mmSOCParameters;
1098 		CalculateWatermarks_params->WritebackChunkSize = mode_lib->ip.writeback_chunk_size_kbytes;
1099 		CalculateWatermarks_params->SOCCLK = s->SOCCLK;
1100 		CalculateWatermarks_params->DCFClkDeepSleep = mode_lib->mp.DCFCLKDeepSleep;
1101 		CalculateWatermarks_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY;
1102 		CalculateWatermarks_params->DETBufferSizeC = mode_lib->mp.DETBufferSizeC;
1103 		CalculateWatermarks_params->SwathHeightY = mode_lib->mp.SwathHeightY;
1104 		CalculateWatermarks_params->SwathHeightC = mode_lib->mp.SwathHeightC;
1105 		//CalculateWatermarks_params->LBBitPerPixel = 57; //FIXME_STAGE2
1106 		CalculateWatermarks_params->SwathWidthY = mode_lib->mp.SwathWidthY;
1107 		CalculateWatermarks_params->SwathWidthC = mode_lib->mp.SwathWidthC;
1108 		CalculateWatermarks_params->BytePerPixelDETY = mode_lib->mp.BytePerPixelInDETY;
1109 		CalculateWatermarks_params->BytePerPixelDETC = mode_lib->mp.BytePerPixelInDETC;
1110 		CalculateWatermarks_params->DSTXAfterScaler = mode_lib->mp.DSTXAfterScaler;
1111 		CalculateWatermarks_params->DSTYAfterScaler = mode_lib->mp.DSTYAfterScaler;
1112 		CalculateWatermarks_params->UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled;
1113 		CalculateWatermarks_params->CompressedBufferSizeInkByte = mode_lib->mp.CompressedBufferSizeInkByte;
1114 		CalculateWatermarks_params->meta_row_height_l = mode_lib->mp.meta_row_height;
1115 		CalculateWatermarks_params->meta_row_height_c = mode_lib->mp.meta_row_height_chroma;
1116 		CalculateWatermarks_params->DPPPerSurface = mode_lib->mp.NoOfDPP;
1117 		CalculateWatermarks_params->uclk_pstate_switch_modes = mode_lib->mp.uclk_pstate_switch_modes;
1118 
1119 		// Output
1120 		CalculateWatermarks_params->Watermark = &mode_lib->mp.Watermark;
1121 		CalculateWatermarks_params->DRAMClockChangeSupport = mode_lib->mp.DRAMClockChangeSupport;
1122 		CalculateWatermarks_params->global_dram_clock_change_support_required = &s->dummy_boolean[0];
1123 		CalculateWatermarks_params->global_dram_clock_change_supported = &mode_lib->mp.global_dram_clock_change_supported;
1124 		CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported;
1125 		CalculateWatermarks_params->FCLKChangeSupport = mode_lib->mp.FCLKChangeSupport;
1126 		CalculateWatermarks_params->global_fclk_change_supported = &mode_lib->mp.global_fclk_change_supported;
1127 		CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &mode_lib->mp.MaxActiveFCLKChangeLatencySupported;
1128 		CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->mp.USRRetrainingSupport;
1129 		CalculateWatermarks_params->temp_read_or_ppt_support = mode_lib->mp.temp_read_or_ppt_support;
1130 		CalculateWatermarks_params->global_temp_read_or_ppt_supported = &mode_lib->mp.global_temp_read_or_ppt_supported;
1131 		CalculateWatermarks_params->VActiveLatencyHidingMargin = NULL;
1132 		CalculateWatermarks_params->VActiveLatencyHidingUs = NULL;
1133 
1134 		dcn5_calculate_watermarks_and_dram_speed_change_support(&mode_lib->scratch, CalculateWatermarks_params);
1135 
1136 		for (k = 0; k < s->num_active_planes; ++k) {
1137 			if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream > 0) {
1138 				mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k] = math_max2(0, mode_lib->mp.VStartupMin[k] * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
1139 					((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) - mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark);
1140 				mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k] = math_max2(0, mode_lib->mp.VStartupMin[k] * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
1141 					((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) - mode_lib->mp.Watermark.WritebackFCLKChangeWatermark);
1142 			} else {
1143 				mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k] = 0;
1144 				mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k] = 0;
1145 			}
1146 		}
1147 
1148 		dcn5_calculate_pstate_keepout_dst_lines(display_cfg, &mode_lib->mp.Watermark, mode_lib->mp.pstate_keepout_dst_lines);
1149 
1150 		DML_LOG_VERBOSE("DML::%s: DEBUG stream_index = %0d\n", __func__, display_cfg->plane_descriptors[0].stream_index);
1151 		DML_LOG_VERBOSE("DML::%s: DEBUG PixelClock = %ld kHz\n", __func__, (display_cfg->stream_descriptors[display_cfg->plane_descriptors[0].stream_index].timing.pixel_clock_khz));
1152 
1153 		//Display Pipeline Delivery Time in Prefetch, Groups
1154 		dcn5_calculate_pixel_delivery_times(
1155 			display_cfg,
1156 			mode_lib->mp.NoOfDPP,
1157 			s->num_active_planes,
1158 			mode_lib->mp.VRatioPrefetchY,
1159 			mode_lib->mp.VRatioPrefetchC,
1160 			mode_lib->mp.swath_width_luma_ub,
1161 			mode_lib->mp.swath_width_chroma_ub,
1162 			mode_lib->mp.PSCL_THROUGHPUT,
1163 			mode_lib->mp.PSCL_THROUGHPUT_CHROMA,
1164 			mode_lib->mp.Dppclk,
1165 			mode_lib->mp.DCFCLKDeepSleep,
1166 			mode_lib->mp.BytePerPixelY,
1167 			mode_lib->mp.BytePerPixelC,
1168 			mode_lib->mp.req_per_swath_ub_l,
1169 			mode_lib->mp.req_per_swath_ub_c,
1170 
1171 			/* Output */
1172 			mode_lib->mp.DisplayPipeLineDeliveryTimeLuma,
1173 			mode_lib->mp.DisplayPipeLineDeliveryTimeChroma,
1174 			mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch,
1175 			mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch,
1176 			mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma,
1177 			mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma,
1178 			mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch,
1179 			mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch);
1180 
1181 		CalculateMetaAndPTETimes_params->scratch = &mode_lib->scratch;
1182 		CalculateMetaAndPTETimes_params->display_cfg = display_cfg;
1183 		CalculateMetaAndPTETimes_params->NumberOfActiveSurfaces = s->num_active_planes;
1184 		CalculateMetaAndPTETimes_params->use_one_row_for_frame = mode_lib->mp.use_one_row_for_frame;
1185 		CalculateMetaAndPTETimes_params->dst_y_per_row_vblank = mode_lib->mp.dst_y_per_row_vblank;
1186 		CalculateMetaAndPTETimes_params->dst_y_per_row_flip = mode_lib->mp.dst_y_per_row_flip;
1187 		CalculateMetaAndPTETimes_params->BytePerPixelY = mode_lib->mp.BytePerPixelY;
1188 		CalculateMetaAndPTETimes_params->BytePerPixelC = mode_lib->mp.BytePerPixelC;
1189 		CalculateMetaAndPTETimes_params->dpte_row_height = mode_lib->mp.dpte_row_height;
1190 		CalculateMetaAndPTETimes_params->dpte_row_height_chroma = mode_lib->mp.dpte_row_height_chroma;
1191 		CalculateMetaAndPTETimes_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes;
1192 		CalculateMetaAndPTETimes_params->PTERequestSizeY = mode_lib->mp.PTERequestSizeY;
1193 		CalculateMetaAndPTETimes_params->PTERequestSizeC = mode_lib->mp.PTERequestSizeC;
1194 		CalculateMetaAndPTETimes_params->PixelPTEReqWidthY = mode_lib->mp.PixelPTEReqWidthY;
1195 		CalculateMetaAndPTETimes_params->PixelPTEReqHeightY = mode_lib->mp.PixelPTEReqHeightY;
1196 		CalculateMetaAndPTETimes_params->PixelPTEReqWidthC = mode_lib->mp.PixelPTEReqWidthC;
1197 		CalculateMetaAndPTETimes_params->PixelPTEReqHeightC = mode_lib->mp.PixelPTEReqHeightC;
1198 		CalculateMetaAndPTETimes_params->dpte_row_width_luma_ub = mode_lib->mp.dpte_row_width_luma_ub;
1199 		CalculateMetaAndPTETimes_params->dpte_row_width_chroma_ub = mode_lib->mp.dpte_row_width_chroma_ub;
1200 		CalculateMetaAndPTETimes_params->tdlut_groups_per_2row_ub = s->tdlut_groups_per_2row_ub;
1201 		CalculateMetaAndPTETimes_params->mrq_present = mode_lib->ip.dcn_mrq_present;
1202 
1203 		CalculateMetaAndPTETimes_params->MetaChunkSize = mode_lib->ip.meta_chunk_size_kbytes;
1204 		CalculateMetaAndPTETimes_params->MinMetaChunkSizeBytes = mode_lib->ip.min_meta_chunk_size_bytes;
1205 		CalculateMetaAndPTETimes_params->meta_row_width = mode_lib->mp.meta_row_width;
1206 		CalculateMetaAndPTETimes_params->meta_row_width_chroma = mode_lib->mp.meta_row_width_chroma;
1207 		CalculateMetaAndPTETimes_params->meta_row_height = mode_lib->mp.meta_row_height;
1208 		CalculateMetaAndPTETimes_params->meta_row_height_chroma = mode_lib->mp.meta_row_height_chroma;
1209 		CalculateMetaAndPTETimes_params->meta_req_width = mode_lib->mp.meta_req_width;
1210 		CalculateMetaAndPTETimes_params->meta_req_width_chroma = mode_lib->mp.meta_req_width_chroma;
1211 		CalculateMetaAndPTETimes_params->meta_req_height = mode_lib->mp.meta_req_height;
1212 		CalculateMetaAndPTETimes_params->meta_req_height_chroma = mode_lib->mp.meta_req_height_chroma;
1213 
1214 		CalculateMetaAndPTETimes_params->time_per_tdlut_group = mode_lib->mp.time_per_tdlut_group;
1215 		CalculateMetaAndPTETimes_params->DST_Y_PER_PTE_ROW_NOM_L = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L;
1216 		CalculateMetaAndPTETimes_params->DST_Y_PER_PTE_ROW_NOM_C = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C;
1217 		CalculateMetaAndPTETimes_params->time_per_pte_group_nom_luma = mode_lib->mp.time_per_pte_group_nom_luma;
1218 		CalculateMetaAndPTETimes_params->time_per_pte_group_vblank_luma = mode_lib->mp.time_per_pte_group_vblank_luma;
1219 		CalculateMetaAndPTETimes_params->time_per_pte_group_flip_luma = mode_lib->mp.time_per_pte_group_flip_luma;
1220 		CalculateMetaAndPTETimes_params->time_per_pte_group_nom_chroma = mode_lib->mp.time_per_pte_group_nom_chroma;
1221 		CalculateMetaAndPTETimes_params->time_per_pte_group_vblank_chroma = mode_lib->mp.time_per_pte_group_vblank_chroma;
1222 		CalculateMetaAndPTETimes_params->time_per_pte_group_flip_chroma = mode_lib->mp.time_per_pte_group_flip_chroma;
1223 		CalculateMetaAndPTETimes_params->DST_Y_PER_META_ROW_NOM_L = mode_lib->mp.DST_Y_PER_META_ROW_NOM_L;
1224 		CalculateMetaAndPTETimes_params->DST_Y_PER_META_ROW_NOM_C = mode_lib->mp.DST_Y_PER_META_ROW_NOM_C;
1225 		CalculateMetaAndPTETimes_params->TimePerMetaChunkNominal = mode_lib->mp.TimePerMetaChunkNominal;
1226 		CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkNominal = mode_lib->mp.TimePerChromaMetaChunkNominal;
1227 		CalculateMetaAndPTETimes_params->TimePerMetaChunkVBlank = mode_lib->mp.TimePerMetaChunkVBlank;
1228 		CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkVBlank = mode_lib->mp.TimePerChromaMetaChunkVBlank;
1229 		CalculateMetaAndPTETimes_params->TimePerMetaChunkFlip = mode_lib->mp.TimePerMetaChunkFlip;
1230 		CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkFlip = mode_lib->mp.TimePerChromaMetaChunkFlip;
1231 
1232 		dcn5_calculate_meta_and_pte_times(CalculateMetaAndPTETimes_params);
1233 
1234 		dcn5_calculate_vm_group_and_request_times(
1235 			display_cfg,
1236 			s->num_active_planes,
1237 			mode_lib->mp.BytePerPixelC,
1238 			mode_lib->mp.dst_y_per_vm_vblank,
1239 			mode_lib->mp.dst_y_per_vm_flip,
1240 			mode_lib->mp.dpte_row_width_luma_ub,
1241 			mode_lib->mp.dpte_row_width_chroma_ub,
1242 			mode_lib->mp.vm_group_bytes,
1243 			mode_lib->mp.dpde0_bytes_per_frame_ub_l,
1244 			mode_lib->mp.dpde0_bytes_per_frame_ub_c,
1245 			s->tdlut_pte_bytes_per_frame,
1246 			mode_lib->mp.meta_pte_bytes_per_frame_ub_l,
1247 			mode_lib->mp.meta_pte_bytes_per_frame_ub_c,
1248 			mode_lib->ip.dcn_mrq_present,
1249 
1250 			/* Output */
1251 			mode_lib->mp.TimePerVMGroupVBlank,
1252 			mode_lib->mp.TimePerVMGroupFlip,
1253 			mode_lib->mp.TimePerVMRequestVBlank,
1254 			mode_lib->mp.TimePerVMRequestFlip);
1255 
1256 		// VStartup Adjustment
1257 		for (k = 0; k < s->num_active_planes; ++k) {
1258 			bool isInterlaceTiming;
1259 
1260 			mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.TWait[k] + mode_lib->mp.ExtraLatency;
1261 			if (!display_cfg->plane_descriptors[k].dynamic_meta_data.enable)
1262 				mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.TCalc + mode_lib->mp.MinTTUVBlank[k];
1263 
1264 			DML_LOG_VERBOSE("DML::%s: k=%u, MinTTUVBlank = %f (before vstartup margin)\n", __func__, k, mode_lib->mp.MinTTUVBlank[k]);
1265 			s->Tvstartup_margin = (s->MaxVStartupLines[k] - mode_lib->mp.VStartupMin[k]) * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
1266 			mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.MinTTUVBlank[k] + s->Tvstartup_margin;
1267 
1268 			DML_LOG_VERBOSE("DML::%s: k=%u, Tvstartup_margin = %f\n", __func__, k, s->Tvstartup_margin);
1269 			DML_LOG_VERBOSE("DML::%s: k=%u, MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
1270 			DML_LOG_VERBOSE("DML::%s: k=%u, MinTTUVBlank = %f\n", __func__, k, mode_lib->mp.MinTTUVBlank[k]);
1271 
1272 			mode_lib->mp.Tdmdl[k] = mode_lib->mp.Tdmdl[k] + s->Tvstartup_margin;
1273 			if (display_cfg->plane_descriptors[k].dynamic_meta_data.enable && mode_lib->ip.dynamic_metadata_vm_enabled) {
1274 				mode_lib->mp.Tdmdl_vm[k] = mode_lib->mp.Tdmdl_vm[k] + s->Tvstartup_margin;
1275 			}
1276 
1277 			isInterlaceTiming = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced && !mode_lib->ip.ptoi_supported);
1278 
1279 			// The actual positioning of the vstartup
1280 			mode_lib->mp.VStartup[k] = (isInterlaceTiming ? (2 * s->MaxVStartupLines[k]) : s->MaxVStartupLines[k]);
1281 
1282 			s->dlg_vblank_start = ((isInterlaceTiming ? math_floor2((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch) / 2.0, 1.0) :
1283 				display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total) - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch);
1284 			s->LSetup = math_floor2(4.0 * mode_lib->mp.TSetup[k] / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)), 1.0) / 4.0;
1285 			s->blank_lines_remaining = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active) - mode_lib->mp.VStartup[k];
1286 
1287 			if (s->blank_lines_remaining < 0) {
1288 				DML_LOG_VERBOSE("ERROR: Vstartup is larger than vblank!?\n");
1289 				s->blank_lines_remaining = 0;
1290 				DML_ASSERT(0);
1291 			}
1292 			mode_lib->mp.MIN_DST_Y_NEXT_START[k] = s->dlg_vblank_start + s->blank_lines_remaining + s->LSetup;
1293 
1294 			// debug only
1295 			if (((mode_lib->mp.VUpdateOffsetPix[k] + mode_lib->mp.VUpdateWidthPix[k] + mode_lib->mp.VReadyOffsetPix[k]) / (double) display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total) <=
1296 				(isInterlaceTiming ?
1297 					math_floor2((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch - mode_lib->mp.VStartup[k]) / 2.0, 1.0) :
1298 					(int)(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch - mode_lib->mp.VStartup[k]))) {
1299 				mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k] = true;
1300 			} else {
1301 				mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k] = false;
1302 			}
1303 			DML_LOG_VERBOSE("DML::%s: k=%u, VStartup = %u (max)\n", __func__, k, mode_lib->mp.VStartup[k]);
1304 			DML_LOG_VERBOSE("DML::%s: k=%u, VStartupMin = %u (max)\n", __func__, k, mode_lib->mp.VStartupMin[k]);
1305 			DML_LOG_VERBOSE("DML::%s: k=%u, VUpdateOffsetPix = %u\n", __func__, k, mode_lib->mp.VUpdateOffsetPix[k]);
1306 			DML_LOG_VERBOSE("DML::%s: k=%u, VUpdateWidthPix = %u\n", __func__, k, mode_lib->mp.VUpdateWidthPix[k]);
1307 			DML_LOG_VERBOSE("DML::%s: k=%u, VReadyOffsetPix = %u\n", __func__, k, mode_lib->mp.VReadyOffsetPix[k]);
1308 			DML_LOG_VERBOSE("DML::%s: k=%u, HTotal = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total);
1309 			DML_LOG_VERBOSE("DML::%s: k=%u, VTotal = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total);
1310 			DML_LOG_VERBOSE("DML::%s: k=%u, VActive = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active);
1311 			DML_LOG_VERBOSE("DML::%s: k=%u, VFrontPorch = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch);
1312 			DML_LOG_VERBOSE("DML::%s: k=%u, TSetup = %f\n", __func__, k, mode_lib->mp.TSetup[k]);
1313 			DML_LOG_VERBOSE("DML::%s: k=%u, MIN_DST_Y_NEXT_START = %f\n", __func__, k, mode_lib->mp.MIN_DST_Y_NEXT_START[k]);
1314 			DML_LOG_VERBOSE("DML::%s: k=%u, VREADY_AT_OR_AFTER_VSYNC = %u\n", __func__, k, mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k]);
1315 		}
1316 
1317 		//Maximum Bandwidth Used
1318 		mode_lib->mp.TotalWRBandwidth = 0;
1319 		for (k = 0; k < display_cfg->num_streams; ++k) {
1320 			for (j = 0; j < display_cfg->stream_descriptors[k].writeback.active_writebacks_per_stream; ++j) {
1321 				double writeback_bytes_per_pixel;
1322 				if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_444_64)
1323 					writeback_bytes_per_pixel = 8.0;
1324 				else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_444_32)
1325 					writeback_bytes_per_pixel = 4.0;
1326 				else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_420_8)
1327 					writeback_bytes_per_pixel = 1.5;
1328 				else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_420_10)
1329 					writeback_bytes_per_pixel = 3.0;
1330 				else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_422_packed_8)
1331 					writeback_bytes_per_pixel = 2.0;
1332 				else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_422_packed_10)
1333 					writeback_bytes_per_pixel = 4.0;
1334 				else
1335 					writeback_bytes_per_pixel = 0.0;
1336 				s->WRBandwidth = display_cfg->stream_descriptors[k].writeback.writeback_stream[j].output_height
1337 					* display_cfg->stream_descriptors[k].writeback.writeback_stream[j].output_width
1338 					/ (display_cfg->stream_descriptors[k].timing.h_total
1339 					* display_cfg->stream_descriptors[k].writeback.writeback_stream[j].input_height
1340 					/ ((double)display_cfg->stream_descriptors[k].timing.pixel_clock_khz / 1000)) * writeback_bytes_per_pixel;
1341 				mode_lib->mp.TotalWRBandwidth = mode_lib->mp.TotalWRBandwidth + s->WRBandwidth;
1342 			}
1343 		}
1344 
1345 		mode_lib->mp.TotalDataReadBandwidth = 0;
1346 		for (k = 0; k < s->num_active_planes; ++k) {
1347 			mode_lib->mp.TotalDataReadBandwidth = mode_lib->mp.TotalDataReadBandwidth + mode_lib->mp.vactive_sw_bw_l[k] + mode_lib->mp.vactive_sw_bw_c[k];
1348 			DML_LOG_VERBOSE("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, mode_lib->mp.TotalDataReadBandwidth);
1349 			DML_LOG_VERBOSE("DML::%s: k=%u, vactive_sw_bw_l = %f\n", __func__, k, mode_lib->mp.vactive_sw_bw_l[k]);
1350 			DML_LOG_VERBOSE("DML::%s: k=%u, vactive_sw_bw_c = %f\n", __func__, k, mode_lib->mp.vactive_sw_bw_c[k]);
1351 		}
1352 
1353 		CalculateStutterEfficiency_params->display_cfg = display_cfg;
1354 		CalculateStutterEfficiency_params->CompressedBufferSizeInkByte = mode_lib->mp.CompressedBufferSizeInkByte;
1355 		CalculateStutterEfficiency_params->UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled;
1356 		CalculateStutterEfficiency_params->MetaFIFOSizeInKEntries = mode_lib->ip.meta_fifo_size_in_kentries;
1357 		CalculateStutterEfficiency_params->ZeroSizeBufferEntries = mode_lib->ip.zero_size_buffer_entries;
1358 		CalculateStutterEfficiency_params->PixelChunkSizeInKByte = mode_lib->ip.pixel_chunk_size_kbytes;
1359 		CalculateStutterEfficiency_params->NumberOfActiveSurfaces = s->num_active_planes;
1360 		CalculateStutterEfficiency_params->ROBBufferSizeInKByte = mode_lib->ip.rob_buffer_size_kbytes;
1361 		CalculateStutterEfficiency_params->TotalDataReadBandwidth = mode_lib->mp.TotalDataReadBandwidth;
1362 		CalculateStutterEfficiency_params->DCFCLK = mode_lib->mp.Dcfclk;
1363 		CalculateStutterEfficiency_params->ReturnBW = mode_lib->mp.dram_bw_mbps;
1364 		CalculateStutterEfficiency_params->CompbufReservedSpace64B = mode_lib->mp.compbuf_reserved_space_64b;
1365 		CalculateStutterEfficiency_params->CompbufReservedSpaceZs = mode_lib->ip.compbuf_reserved_space_zs;
1366 		CalculateStutterEfficiency_params->SRExitTime = utm_soc_bb->power_management_parameters.stutter_exit_latency_us;
1367 		CalculateStutterEfficiency_params->SRExitZ8Time = utm_soc_bb->power_management_parameters.z8_stutter_exit_latency_us;
1368 		CalculateStutterEfficiency_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings;
1369 		CalculateStutterEfficiency_params->StutterEnterPlusExitWatermark = mode_lib->mp.Watermark.StutterEnterPlusExitWatermark;
1370 		CalculateStutterEfficiency_params->Z8StutterEnterPlusExitWatermark = mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark;
1371 		CalculateStutterEfficiency_params->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported;
1372 		CalculateStutterEfficiency_params->MinTTUVBlank = mode_lib->mp.MinTTUVBlank;
1373 		CalculateStutterEfficiency_params->DPPPerSurface = mode_lib->mp.NoOfDPP;
1374 		CalculateStutterEfficiency_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY;
1375 		CalculateStutterEfficiency_params->BytePerPixelY = mode_lib->mp.BytePerPixelY;
1376 		CalculateStutterEfficiency_params->BytePerPixelDETY = mode_lib->mp.BytePerPixelInDETY;
1377 		CalculateStutterEfficiency_params->SwathWidthY = mode_lib->mp.SwathWidthY;
1378 		CalculateStutterEfficiency_params->SwathHeightY = mode_lib->mp.SwathHeightY;
1379 		CalculateStutterEfficiency_params->SwathHeightC = mode_lib->mp.SwathHeightC;
1380 		CalculateStutterEfficiency_params->BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY;
1381 		CalculateStutterEfficiency_params->BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY;
1382 		CalculateStutterEfficiency_params->BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC;
1383 		CalculateStutterEfficiency_params->BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC;
1384 		CalculateStutterEfficiency_params->DCCYMaxUncompressedBlock = mode_lib->mp.DCCYMaxUncompressedBlock;
1385 		CalculateStutterEfficiency_params->DCCCMaxUncompressedBlock = mode_lib->mp.DCCCMaxUncompressedBlock;
1386 		CalculateStutterEfficiency_params->ReadBandwidthSurfaceLuma = mode_lib->mp.vactive_sw_bw_l;
1387 		CalculateStutterEfficiency_params->ReadBandwidthSurfaceChroma = mode_lib->mp.vactive_sw_bw_c;
1388 		CalculateStutterEfficiency_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
1389 		CalculateStutterEfficiency_params->meta_row_bw = mode_lib->mp.meta_row_bw;
1390 		CalculateStutterEfficiency_params->rob_alloc_compressed = mode_lib->ip.dcn_mrq_present;
1391 
1392 		// output
1393 		CalculateStutterEfficiency_params->StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.StutterEfficiencyNotIncludingVBlank;
1394 		CalculateStutterEfficiency_params->StutterEfficiency = &mode_lib->mp.StutterEfficiency;
1395 		CalculateStutterEfficiency_params->NumberOfStutterBurstsPerFrame = &mode_lib->mp.NumberOfStutterBurstsPerFrame;
1396 		CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlank;
1397 		CalculateStutterEfficiency_params->Z8StutterEfficiency = &mode_lib->mp.Z8StutterEfficiency;
1398 		CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &mode_lib->mp.Z8NumberOfStutterBurstsPerFrame;
1399 		CalculateStutterEfficiency_params->StutterPeriod = &mode_lib->mp.StutterPeriod;
1400 		CalculateStutterEfficiency_params->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = &mode_lib->mp.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE;
1401 
1402 		// Stutter Efficiency
1403 		dcn5_calculate_stutter_efficiency(&mode_lib->scratch, CalculateStutterEfficiency_params);
1404 
1405 #ifdef __DML_VBA_ALLOW_DELTA__
1406 		// Calculate z8 stutter eff assuming 0 reserved space
1407 		CalculateStutterEfficiency_params->CompbufReservedSpace64B = 0;
1408 		CalculateStutterEfficiency_params->CompbufReservedSpaceZs = 0;
1409 
1410 		CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlankBestCase;
1411 		CalculateStutterEfficiency_params->Z8StutterEfficiency = &mode_lib->mp.Z8StutterEfficiencyBestCase;
1412 		CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase;
1413 		CalculateStutterEfficiency_params->StutterPeriod = &mode_lib->mp.StutterPeriodBestCase;
1414 
1415 		// Stutter Efficiency
1416 		dcn5_calculate_stutter_efficiency(&mode_lib->scratch, CalculateStutterEfficiency_params);
1417 #else
1418 		mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlankBestCase = mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlank;
1419 		mode_lib->mp.Z8StutterEfficiencyBestCase = mode_lib->mp.Z8StutterEfficiency;
1420 		mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase = mode_lib->mp.Z8NumberOfStutterBurstsPerFrame;
1421 		mode_lib->mp.StutterPeriodBestCase = mode_lib->mp.StutterPeriod;
1422 #endif
1423 	} // PrefetchAndImmediateFlipSupported
1424 
1425 	min_return_latency_in_DCFCLK_cycles = (min_return_uclk_cycles / (max_sop.uclk_khz / 1000.0) + min_return_fclk_cycles / (max_sop.fclk_khz / 1000.0)) * mode_lib->mp.Dcfclk;
1426 	mode_lib->mp.min_return_latency_in_dcfclk = (unsigned int)min_return_latency_in_DCFCLK_cycles;
1427 	mode_lib->mp.dcfclk_deep_sleep_hysteresis = (unsigned int)math_max2(32, (double)mode_lib->ip.pixel_chunk_size_kbytes * 1024 * 3 / 4 / 64 - min_return_latency_in_DCFCLK_cycles);
1428 	DML_ASSERT(mode_lib->mp.dcfclk_deep_sleep_hysteresis < 256);
1429 
1430 	DML_LOG_VERBOSE("DML::%s: max_sop.fclk_khz = %d\n", __func__, max_sop.fclk_khz);
1431 	DML_LOG_VERBOSE("DML::%s: max_sop.dcfclk_khz = %d\n", __func__, max_sop.dcfclk_khz);
1432 	DML_LOG_VERBOSE("DML::%s: max_sop.uclk_khz = %d\n", __func__, max_sop.uclk_khz);
1433 	DML_LOG_VERBOSE("DML::%s: min_sop.fclk_khz = %d\n", __func__, min_sop.fclk_khz);
1434 	DML_LOG_VERBOSE("DML::%s: min_sop.dcfclk_khz = %d\n", __func__, min_sop.dcfclk_khz);
1435 	DML_LOG_VERBOSE("DML::%s: min_sop.uclk_khz = %d\n", __func__, min_sop.uclk_khz);
1436 	DML_LOG_VERBOSE("DML::%s: min_return_uclk_cycles = %ld\n", __func__, min_return_uclk_cycles);
1437 	DML_LOG_VERBOSE("DML::%s: min_return_fclk_cycles = %ld\n", __func__, min_return_fclk_cycles);
1438 	DML_LOG_VERBOSE("DML::%s: min_return_latency_in_DCFCLK_cycles = %f\n", __func__, min_return_latency_in_DCFCLK_cycles);
1439 	DML_LOG_VERBOSE("DML::%s: dcfclk_deep_sleep_hysteresis = %d \n", __func__, mode_lib->mp.dcfclk_deep_sleep_hysteresis);
1440 	DML_LOG_VERBOSE("DML::%s: --- END --- \n", __func__);
1441 	return in_out_params->mode_lib->mp.PrefetchAndImmediateFlipSupported;
1442 }
1443 
dcn5_get_global_sync_programming(const struct dml2_core_internal_display_mode_lib * mode_lib,union dml2_global_sync_programming * out,int pipe_index)1444 static void dcn5_get_global_sync_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, union dml2_global_sync_programming *out, int pipe_index)
1445 {
1446 	out->dcn4x.vready_offset_pixels = mode_lib->mp.VReadyOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
1447 	out->dcn4x.vstartup_lines = mode_lib->mp.VStartup[mode_lib->mp.pipe_plane[pipe_index]];
1448 	out->dcn4x.vupdate_offset_pixels = mode_lib->mp.VUpdateOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
1449 	out->dcn4x.vupdate_vupdate_width_pixels = mode_lib->mp.VUpdateWidthPix[mode_lib->mp.pipe_plane[pipe_index]];
1450 	out->dcn4x.pstate_keepout_start_lines = mode_lib->mp.pstate_keepout_dst_lines[mode_lib->mp.pipe_plane[pipe_index]];
1451 }
1452 
dcn5_get_stream_programming(const struct dml2_core_internal_display_mode_lib * mode_lib,struct dml2_per_stream_programming * out,int pipe_index)1453 static void dcn5_get_stream_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_per_stream_programming *out, int pipe_index)
1454 {
1455 	dcn5_get_global_sync_programming(mode_lib, &out->global_sync, pipe_index);
1456 }
1457 
dcn5_populate_fams2_programming(const struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_core_calcs_mode_programming_ex * mode_prog,union dmub_cmd_fams2_config * fams2_base_programming,union dmub_cmd_fams2_config * fams2_sub_programming,enum dml2_pstate_method pstate_method,int plane_index)1458 static void dcn5_populate_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib,
1459 		const struct dml2_core_calcs_mode_programming_ex *mode_prog,
1460 		union dmub_cmd_fams2_config *fams2_base_programming,
1461 		union dmub_cmd_fams2_config *fams2_sub_programming,
1462 		enum dml2_pstate_method pstate_method,
1463 		int plane_index)
1464 {
1465 	const struct dml2_display_cfg *disp_cfg = mode_prog->in_display_cfg;
1466 	const struct dml2_plane_parameters *plane_descriptor = &disp_cfg->plane_descriptors[plane_index];
1467 	const struct dml2_stream_parameters *stream_descriptor = &disp_cfg->stream_descriptors[plane_descriptor->stream_index];
1468 	const struct dml2_pstate_meta *stream_pstate_meta = &mode_prog->uclk_params->stream_pstate_meta[plane_descriptor->stream_index];
1469 
1470 	struct dmub_fams2_cmd_stream_static_base_state *base_programming = &fams2_base_programming->stream_v1.base;
1471 	union dmub_fams2_cmd_stream_static_sub_state *sub_programming = &fams2_sub_programming->stream_v1.sub_state;
1472 
1473 	unsigned int i;
1474 
1475 	if (disp_cfg->overrides.all_streams_blanked) {
1476 		/* stream is blanked, so do nothing */
1477 		return;
1478 	}
1479 
1480 	/* from display configuration */
1481 	base_programming->htotal = (uint16_t)stream_descriptor->timing.h_total;
1482 	base_programming->vtotal = (uint16_t)stream_descriptor->timing.v_total;
1483 	base_programming->vblank_start = (uint16_t)(stream_pstate_meta->nom_vtotal -
1484 		stream_descriptor->timing.v_front_porch);
1485 	base_programming->vblank_end = (uint16_t)(stream_pstate_meta->nom_vtotal -
1486 		stream_descriptor->timing.v_front_porch -
1487 		stream_descriptor->timing.v_active);
1488 	base_programming->config.bits.is_drr = stream_descriptor->timing.drr_config.enabled;
1489 
1490 	/* from meta */
1491 	base_programming->otg_vline_time_ns =
1492 		(unsigned int)(stream_pstate_meta->otg_vline_time_us * 1000.0);
1493 	base_programming->scheduling_delay_otg_vlines = (uint8_t)stream_pstate_meta->scheduling_delay_otg_vlines;
1494 	base_programming->contention_delay_otg_vlines = (uint8_t)stream_pstate_meta->contention_delay_otg_vlines;
1495 	base_programming->vline_int_ack_delay_otg_vlines = (uint8_t)stream_pstate_meta->vertical_interrupt_ack_delay_otg_vlines;
1496 	base_programming->drr_keepout_otg_vline = (uint16_t)(stream_pstate_meta->nom_vtotal -
1497 		stream_descriptor->timing.v_front_porch -
1498 		stream_pstate_meta->method_drr.programming_delay_otg_vlines);
1499 	base_programming->allow_to_target_delay_otg_vlines = (uint8_t)stream_pstate_meta->allow_to_target_delay_otg_vlines;
1500 	base_programming->max_vtotal = (uint16_t)stream_pstate_meta->max_vtotal;
1501 
1502 	/* from core */
1503 	base_programming->config.bits.min_ttu_vblank_usable = true;
1504 	for (i = 0; i < disp_cfg->num_planes; i++) {
1505 		/* check if all planes support p-state in blank */
1506 		if (disp_cfg->plane_descriptors[i].stream_index == plane_descriptor->stream_index &&
1507 			mode_lib->mp.MinTTUVBlank[i] <= mode_lib->mp.Watermark.DRAMClockChangeWatermark) {
1508 			base_programming->config.bits.min_ttu_vblank_usable = false;
1509 			break;
1510 		}
1511 	}
1512 
1513 	switch (pstate_method) {
1514 	case dml2_pstate_method_vactive:
1515 	case dml2_pstate_method_fw_vactive_drr:
1516 		/* legacy vactive */
1517 		base_programming->type = FAMS2_STREAM_TYPE_VACTIVE;
1518 		sub_programming->legacy.vactive_det_fill_delay_otg_vlines =
1519 			(uint8_t)stream_pstate_meta->method_vactive.max_vactive_det_fill_delay_otg_vlines;
1520 		base_programming->allow_start_otg_vline =
1521 			(uint16_t)stream_pstate_meta->method_vactive.common.allow_start_otg_vline;
1522 		base_programming->allow_end_otg_vline =
1523 			(uint16_t)stream_pstate_meta->method_vactive.common.allow_end_otg_vline;
1524 		base_programming->config.bits.clamp_vtotal_min = true;
1525 		break;
1526 	case dml2_pstate_method_vblank:
1527 	case dml2_pstate_method_fw_vblank_drr:
1528 		/* legacy vblank */
1529 		base_programming->type = FAMS2_STREAM_TYPE_VBLANK;
1530 		base_programming->allow_start_otg_vline =
1531 			(uint16_t)stream_pstate_meta->method_vblank.common.allow_start_otg_vline;
1532 		base_programming->allow_end_otg_vline =
1533 			(uint16_t)stream_pstate_meta->method_vblank.common.allow_end_otg_vline;
1534 		base_programming->config.bits.clamp_vtotal_min = true;
1535 		break;
1536 	case dml2_pstate_method_fw_drr:
1537 		/* drr */
1538 		base_programming->type = FAMS2_STREAM_TYPE_DRR;
1539 		sub_programming->drr.programming_delay_otg_vlines =
1540 			(uint8_t)stream_pstate_meta->method_drr.programming_delay_otg_vlines;
1541 		sub_programming->drr.nom_stretched_vtotal =
1542 			(uint16_t)stream_pstate_meta->method_drr.stretched_vtotal;
1543 		base_programming->allow_start_otg_vline =
1544 			(uint16_t)stream_pstate_meta->method_drr.common.allow_start_otg_vline;
1545 		base_programming->allow_end_otg_vline =
1546 			(uint16_t)stream_pstate_meta->method_drr.common.allow_end_otg_vline;
1547 		/* drr only clamps to vtotal min for single display */
1548 		base_programming->config.bits.clamp_vtotal_min = disp_cfg->num_streams == 1;
1549 		sub_programming->drr.only_stretch_if_required = true;
1550 		break;
1551 	case dml2_pstate_method_fw_svp:
1552 	case dml2_pstate_method_fw_svp_drr:
1553 	case dml2_pstate_method_alternate:
1554 	case dml2_pstate_method_reserved_hw:
1555 	case dml2_pstate_method_reserved_fw:
1556 	case dml2_pstate_method_reserved_fw_drr_clamped:
1557 	case dml2_pstate_method_reserved_fw_drr_var:
1558 	case dml2_pstate_method_na:
1559 	case dml2_pstate_method_count:
1560 	default:
1561 		/* this should never happen */
1562 		break;
1563 	}
1564 }
1565 
dcn5_populate_global_fams2_programming(struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_core_calcs_mode_programming_ex * mode_prog,struct dmub_cmd_fams2_global_config * fams2_global_config)1566 static void dcn5_populate_global_fams2_programming(struct dml2_core_internal_display_mode_lib *mode_lib,
1567 		const struct dml2_core_calcs_mode_programming_ex *mode_prog,
1568 		struct dmub_cmd_fams2_global_config *fams2_global_config)
1569 {
1570 	fams2_global_config->features.bits.enable = mode_prog->uclk_params->fams2_required;
1571 
1572 	if (fams2_global_config->features.bits.enable) {
1573 		fams2_global_config->features.bits.enable_stall_recovery = true;
1574 		fams2_global_config->features.bits.allow_delay_check_mode = FAMS2_ALLOW_DELAY_CHECK_FROM_START;
1575 
1576 		fams2_global_config->max_allow_delay_us = mode_lib->ip_caps.fams2.max_allow_delay_us;
1577 		fams2_global_config->lock_wait_time_us = mode_lib->ip_caps.fams2.lock_timeout_us;
1578 		fams2_global_config->recovery_timeout_us = mode_lib->ip_caps.fams2.recovery_timeout_us;
1579 		fams2_global_config->hwfq_flip_programming_delay_us = mode_lib->ip_caps.fams2.flip_programming_delay_us;
1580 
1581 		fams2_global_config->num_streams = mode_prog->in_display_cfg->num_streams;
1582 	}
1583 }
1584 
dcn5_populate_mcache_allocation(struct dml2_display_cfg_programming * programming,const struct dml2_display_solution * solution)1585 static void dcn5_populate_mcache_allocation(struct dml2_display_cfg_programming *programming,
1586 	const struct dml2_display_solution *solution)
1587 {
1588 	unsigned int i;
1589 
1590 	for (i = 0; i < solution->dispcfg.num_planes; i++)
1591 		programming->plane_programming[i].mcache_allocation = solution->mcache_allocations[i];
1592 }
1593 
dcn5_pack_mode_programming_params(struct dml2_core_instance * core,struct dml2_core_calcs_mode_programming_ex * mode_prog,struct dml2_display_cfg_programming * programming)1594 static void dcn5_pack_mode_programming_params(
1595 		struct dml2_core_instance *core,
1596 		struct dml2_core_calcs_mode_programming_ex *mode_prog,
1597 		struct dml2_display_cfg_programming *programming)
1598 {
1599 	struct dml2_core_internal_display_mode_lib *mode_lib = mode_prog->mode_lib;
1600 	const struct dml2_utm_soc_bb *utm_soc_bb = core->utm_soc_bb;
1601 	unsigned int pipe_offset;
1602 	int dml_internal_pipe_index;
1603 	int total_pipe_regs_copied = 0;
1604 	int total_dwb_regs_copied = 0;
1605 	int stream_already_populated_mask = 0;
1606 
1607 	int main_stream_index;
1608 	unsigned int plane_index;
1609 	unsigned int dwb_index;
1610 
1611 	memcpy(&programming->display_config, mode_prog->in_display_cfg, sizeof(struct dml2_display_cfg));
1612 
1613 	dcn5_get_arb_params(&programming->display_config, mode_lib, utm_soc_bb, &programming->global_regs.arb_regs);
1614 	programming->global_regs.num_watermark_sets = 1;
1615 	dcn5_get_watermarks(&programming->display_config, mode_lib, utm_soc_bb, &programming->global_regs.wm_regs[0]);
1616 	dcn5_populate_mcache_allocation(programming, mode_prog->solution);
1617 
1618 	dcn5_get_mcif_arb_params(mode_lib, &programming->mcif_global_regs);
1619 	programming->mcif_global_regs.num_watermark_sets = 1;
1620 
1621 	dml_internal_pipe_index = 0;
1622 
1623 	if (mode_prog->uclk_params) {
1624 		if (programming->uclk_pstate_supported) {
1625 			programming->fams2_required = mode_prog->uclk_params->fams2_required;
1626 			dcn5_populate_global_fams2_programming(mode_lib, mode_prog, &programming->fams2_global_config);
1627 		}
1628 	}
1629 
1630 	DML_LOG_VERBOSE("DML::%s: num_planes=%d\n", __func__, programming->display_config.num_planes);
1631 
1632 	for (plane_index = 0; plane_index < programming->display_config.num_planes; plane_index++) {
1633 		programming->plane_programming[plane_index].num_dpps_required = mode_lib->mp.NoOfDPP[plane_index];
1634 
1635 		// Setup the appropriate p-state strategy for each plane
1636 		if (mode_prog->uclk_params) {
1637 			if (programming->uclk_pstate_supported)
1638 				programming->plane_programming[plane_index].uclk_pstate_support_method = mode_prog->uclk_params->pstate_switch_modes[plane_index];
1639 			else
1640 				programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_na;
1641 		} else {
1642 			if (mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported[plane_index] >= utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us)
1643 				programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_vactive;
1644 			else if (mode_lib->mp.TWait[plane_index] >= utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us)
1645 				programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_vblank;
1646 			else
1647 				programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_na;
1648 		}
1649 
1650 		for (pipe_offset = 0; pipe_offset < programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) {
1651 			programming->plane_programming[plane_index].plane_descriptor = &programming->display_config.plane_descriptors[plane_index];
1652 
1653 			// Assign storage for this pipe's register values
1654 			programming->plane_programming[plane_index].pipe_regs[pipe_offset] = &programming->pipe_regs[total_pipe_regs_copied];
1655 			memset(programming->plane_programming[plane_index].pipe_regs[pipe_offset], 0, sizeof(struct dml2_dchub_per_pipe_register_set));
1656 			total_pipe_regs_copied++;
1657 
1658 			// Populate
1659 			dcn5_get_pipe_regs(&programming->display_config, mode_lib, programming->plane_programming[plane_index].pipe_regs[pipe_offset], dml_internal_pipe_index, utm_soc_bb, &mode_lib->scratch);
1660 
1661 			main_stream_index = programming->display_config.plane_descriptors[plane_index].stream_index;
1662 
1663 			// Multiple planes can refer to the same stream index, so it's only necessary to populate it once
1664 			if (!(stream_already_populated_mask & (0x1 << main_stream_index))) {
1665 				programming->stream_programming[main_stream_index].uclk_pstate_method = programming->plane_programming[plane_index].uclk_pstate_support_method;
1666 				programming->stream_programming[main_stream_index].stream_descriptor = &programming->display_config.stream_descriptors[main_stream_index];
1667 				programming->stream_programming[main_stream_index].num_odms_required = mode_prog->cfg_support_info->stream_support_info[main_stream_index].odms_used;
1668 				dcn5_get_stream_programming(mode_lib, &programming->stream_programming[main_stream_index], dml_internal_pipe_index);
1669 
1670 				if (mode_prog->uclk_params) {
1671 					dcn5_populate_fams2_programming(mode_lib,
1672 							mode_prog,
1673 							&programming->stream_programming[main_stream_index].fams2_base_params,
1674 							&programming->stream_programming[main_stream_index].fams2_sub_params,
1675 							programming->stream_programming[main_stream_index].uclk_pstate_method,
1676 							plane_index);
1677 				}
1678 
1679 				/* populate DWB */
1680 				for (dwb_index = 0; dwb_index < programming->display_config.stream_descriptors[main_stream_index].writeback.active_writebacks_per_stream; dwb_index++) {
1681 					programming->stream_programming[main_stream_index].mcif_regs[dwb_index] = &programming->mcif_regs[total_dwb_regs_copied];
1682 					memset(programming->stream_programming[main_stream_index].mcif_regs[dwb_index], 0, sizeof(struct dml2_mcif_per_pipe_register_set));
1683 					total_dwb_regs_copied++;
1684 
1685 					dcn5_get_per_dwb_params(&programming->display_config,
1686 							mode_lib,
1687 							programming->stream_programming[main_stream_index].mcif_regs[dwb_index],
1688 							main_stream_index,
1689 							dwb_index);
1690 				}
1691 
1692 				stream_already_populated_mask |= (0x1 << main_stream_index);
1693 			}
1694 			dml_internal_pipe_index++;
1695 		}
1696 	}
1697 
1698 	// DCN5: Calculate reduced viewport pstate recout reduction lines per plane
1699 	// Complete the formula calculation using memory clock and base calculation from prefetch schedule
1700 
1701 	// Initialize all planes to default value
1702 	for (unsigned int plane_idx = 0; plane_idx < DML2_MAX_PLANES; plane_idx++) {
1703 		programming->informative.misc.pstate_recout_reduction_lines[plane_idx] = 0;
1704 	}
1705 
1706 	// DCN5: Calculate pstate recout reduction lines feature
1707 	// Get DRAM clock change latency from SOC parameters
1708 	double dram_clk_change_latency_us = utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us;
1709 
1710 	if (programming->display_config.num_planes == 1) {
1711 		// Calculate for all planes (inactive planes should naturally yield 0)
1712 		for (unsigned int plane_idx = 0; plane_idx < programming->display_config.num_planes; plane_idx++) {
1713 			// Use original equation from specifications
1714 			// Formula: (Tmclk – (Tvstartup – (Tsetup + Tcalc + Tpre + Tout))) / LineTime
1715 			// Where Tpre = dst_y_prefetch * line_time (as specified)
1716 
1717 			int stream_index = programming->display_config.plane_descriptors[plane_idx].stream_index;
1718 
1719 			// Calculate line time from display config timing (HTotal / PixelClock)
1720 			double pixel_clock_mhz = (double)programming->display_config.stream_descriptors[stream_index].timing.pixel_clock_khz / 1000.0;
1721 			double htotal = (double)programming->display_config.stream_descriptors[stream_index].timing.h_total;
1722 			double line_time_us = htotal / pixel_clock_mhz;
1723 
1724 			// Use actual calculated values from mode library (not hardcoded defaults)
1725 			double tmclk_us = dram_clk_change_latency_us;
1726 			double tvstartup_us = mode_lib->mp.VStartup[plane_idx] * line_time_us;
1727 			double tsetup_us = mode_lib->mp.TSetup[plane_idx];
1728 			double tcalc_us = mode_lib->mp.TCalc;
1729 			double tpre_us = mode_lib->mp.dst_y_prefetch[plane_idx] * line_time_us; // As specified: dst_y_prefetch * line_time
1730 			double tout_us = (mode_lib->mp.DSTYAfterScaler[plane_idx] +
1731 				((double)mode_lib->mp.DSTXAfterScaler[plane_idx] / htotal)) * line_time_us; // delay_after_scaler per spec
1732 
1733 			// Formula: (Tmclk - (Tvstartup - (Tsetup + Tcalc + Tpre + Tout))) / LineTime
1734 			programming->informative.misc.pstate_recout_reduction_lines[plane_idx] =
1735 				(unsigned int) math_max2(0.0, (tmclk_us - (tvstartup_us - (tsetup_us + tcalc_us + tpre_us + tout_us))) / line_time_us);
1736 		}
1737 	}
1738 }
1739 
dcn5_mp_assign_qos_bound(struct dml2_core_instance * core,struct dml2_display_cfg_programming * programming)1740 static void dcn5_mp_assign_qos_bound(struct dml2_core_instance *core,
1741 		struct dml2_display_cfg_programming *programming)
1742 {
1743 	struct dml2_core_internal_display_mode_lib *mode_lib = &core->clean_me_up.mode_lib;
1744 	struct dml2_core_calcs_mode_programming_locals *s = &mode_lib->scratch.dml_core_mode_programming_locals;
1745 
1746 	mode_lib->mp.Dcfclk = programming->min_clocks.dcn4x.active.dcfclk_khz / 1000.0;
1747 	mode_lib->mp.FabricClock = programming->min_clocks.dcn4x.active.fclk_khz / 1000.0;
1748 	mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4x.active.uclk_khz / 1000.0;
1749 	mode_lib->mp.dram_bw_mbps = programming->qos_bound.bandwidth_lb.dcn5.urgent_bandwidth_kbps / 1000.0;
1750 	mode_lib->mp.urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram] = mode_lib->mp.dram_bw_mbps;
1751 	mode_lib->mp.UrgentLatency = programming->qos_bound.latency_ub.dcn5.urgent_ramp;
1752 	mode_lib->mp.TripToMemory = programming->qos_bound.latency_ub.dcn5.t_trip;
1753 	mode_lib->mp.MetaTripToMemory = programming->qos_bound.latency_ub.dcn5.meta_trip_to_mem;
1754 	s->mmSOCParameters.max_urgent_latency_us = programming->qos_bound.latency_ub.dcn5.max_req_latency_urg;
1755 	s->mmSOCParameters.df_response_time_us = programming->qos_bound.latency_ub.dcn5.df_response_time_us;
1756 
1757 	DML_LOG_VERBOSE("DML::%s: Dcfclk = %f\n", __func__, mode_lib->mp.Dcfclk);
1758 	DML_LOG_VERBOSE("DML::%s: FabricClock = %f\n", __func__, mode_lib->mp.FabricClock);
1759 	DML_LOG_VERBOSE("DML::%s: uclk_freq_mhz = %f\n", __func__, mode_lib->mp.uclk_freq_mhz);
1760 	DML_LOG_VERBOSE("DML::%s: dram_bw_mbps = %f\n", __func__, mode_lib->mp.dram_bw_mbps);
1761 	DML_LOG_VERBOSE("DML::%s: UrgentLatency (urgent ramp) = %f\n", __func__, programming->qos_bound.latency_ub.dcn5.urgent_ramp);
1762 	DML_LOG_VERBOSE("DML::%s: TripToMemory = %f\n", __func__, mode_lib->mp.TripToMemory);
1763 	DML_LOG_VERBOSE("DML::%s: max_urgent_latency_us = %f\n", __func__, s->mmSOCParameters.max_urgent_latency_us);
1764 	DML_LOG_VERBOSE("DML::%s: GlobalDPPCLK = %f\n", __func__, mode_lib->mp.GlobalDPPCLK);
1765 }
1766 
dml2_core_dcn5_funcs_populate_programming(struct dml2_core_instance * core,const struct dml2_display_solution * solution,struct dml2_display_cfg_programming * programming)1767 enum dml2_status dml2_core_dcn5_funcs_populate_programming(struct dml2_core_instance *core,
1768 		const struct dml2_display_solution *solution,
1769 		struct dml2_display_cfg_programming *programming)
1770 {
1771 	struct dml2_core_calcs_mode_programming_ex *params = &core->scratch.mode_programming_locals.mode_programming_ex_params;
1772 	struct dml2_core_internal_display_mode_lib *mode_lib = &core->clean_me_up.mode_lib;
1773 	bool result;
1774 
1775 	memset(&mode_lib->scratch, 0, sizeof(struct dml2_core_internal_scratch));
1776 	memset(&mode_lib->mp, 0, sizeof(struct dml2_core_internal_mode_program));
1777 
1778 	dcn5_mp_assign_qos_bound(core, programming);
1779 	params->mode_lib = mode_lib;
1780 	params->in_display_cfg = &solution->dispcfg;
1781 	params->cfg_support_info = &solution->validation_result.mode_support.cfg_support_info;
1782 	params->programming = programming;
1783 	params->uclk_params = &solution->uclk_pstate_params;
1784 	params->utm_soc_bb = core->utm_soc_bb;
1785 	params->solution = solution;
1786 	result = dcn5_mode_programming(params);
1787 	if (result)
1788 		dcn5_pack_mode_programming_params(core, params, programming);
1789 
1790 	return result ? DML2_STATUS_OK : DML2_STATUS_POPULATE_FAIL_PROGRAMMING;
1791 }
1792